parser-de-notas-de-corretagem 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/notes-parser.d.ts CHANGED
@@ -83,7 +83,7 @@ export declare class NoteParser {
83
83
  * @param content PDF content
84
84
  * @returns an `Array` of `NegotiationNote`
85
85
  */
86
- parseNote(noteName: string, content: Uint8Array, possiblePasswords?: string[]): Promise<NegotiationNote[]>;
86
+ parseNote(noteName: string, content: string | Uint8Array, possiblePasswords?: string[]): Promise<NegotiationNote[]>;
87
87
  /**
88
88
  * Add stock definition
89
89
  * @param code stock code
@@ -1 +1 @@
1
- {"version":3,"file":"notes-parser.js","mappings":"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","sources":["webpack://parser-de-notas-de-corretagem/./src/asset-crawler.ts","webpack://parser-de-notas-de-corretagem/external commonjs \"axios\"","webpack://parser-de-notas-de-corretagem/external commonjs \"pdfjs-dist\"","webpack://parser-de-notas-de-corretagem/webpack/bootstrap","webpack://parser-de-notas-de-corretagem/./src/notes-parser.ts"],"sourcesContent":["import axios from \"axios\";\r\nimport assets from '../assets.json';\r\n\r\n/** B3 request object constructor */\r\nclass ListedStocksRequest {\r\n language = 'pt-br';\r\n pageNumber: number;\r\n pageSize: 20|40|60|120 = 120;\r\n \r\n constructor(pageNumber: number) {\r\n this.pageNumber = pageNumber;\r\n this.pageSize = 120;\r\n }\r\n\r\n}\r\n\r\n/** Infos about the stock */\r\ninterface StockInfos {\r\n /** CVM code */\r\n codeCVM: string;\r\n /** Issuing Company (B3 Code) */\r\n issuingCompany: string;\r\n /** Company name */\r\n companyName: string;\r\n /** Trading name (same name as in the brokerage note) */\r\n tradingName: string;\r\n /** Company's CNPJ */\r\n cnpj: string;\r\n marketIndicator: string;\r\n typeBDR: string;\r\n dateListing: string;\r\n status: string;\r\n segment: string;\r\n segmentEng: string;\r\n type: string;\r\n market: string;\r\n}\r\n\r\n/** Infos about the page and the total amount of records */\r\ninterface PageInfo {\r\n /** Current page number */\r\n pageNumber: number;\r\n /** Number of results in the page (can be less if it's the last page) */\r\n pageSize: number;\r\n /** Number of total records */\r\n totalRecords: number;\r\n /** Number of total pages */\r\n totalPages: number;\r\n}\r\n\r\n/** Crawler result */\r\ninterface CrawlerRequestResult {\r\n \"page\": PageInfo;\r\n \"results\": StockInfos[];\r\n}\r\n\r\n/** Assets main infos */\r\nexport interface Asset {\r\n /** Asset's code */\r\n code: string;\r\n /** Asset's name */\r\n name: string;\r\n /** Asset's cnpj */\r\n cnpj?: string;\r\n}\r\n\r\n/** Assets crawler manager */\r\nexport class AssetCrawler {\r\n\r\n /** Assets cached */\r\n protected assets: StockInfos[];\r\n /** Assets defined on runtime */\r\n customAssets: Asset[] = [];\r\n /** Auto-update flag */\r\n autoUpdate = false;\r\n /** Auto-update timeout */\r\n private updaterTimeout = 7*24*3600*1000;\r\n /** Auto-update timeout when any failure happens */\r\n private updaterTimeoutIfFailed = 24*3600*1000;\r\n\r\n /** Crawler URLs */\r\n private urls = {\r\n // Using deprecated `atob` because Buffer isn't supported out-of-the-box in browsers\r\n listedStocks: atob('aHR0cHM6Ly9zaXN0ZW1hc3dlYmIzLWxpc3RhZG9zLmIzLmNvbS5ici9saXN0ZWRDb21wYW5pZXNQcm94eS9Db21wYW55Q2FsbC9HZXRJbml0aWFsQ29tcGFuaWVz')\r\n }\r\n\r\n /**\r\n * Instantiate a new `AssetCrawler`\r\n * @param autoUpdate whether the application should auto-update\r\n * the list of assets for new changes. Default is `false`. Require internet connection\r\n */\r\n constructor(autoUpdate?: boolean) {\r\n this.assets = assets;\r\n this.autoUpdate = autoUpdate || false;\r\n if (this.autoUpdate) {\r\n this.updater(0);\r\n }\r\n }\r\n\r\n /**\r\n * Update the listed assets after a timeout\r\n * @param timeout update after `timeout` milliseconds\r\n */\r\n updater(timeout: number = this.updaterTimeout) {\r\n setTimeout(() => {\r\n this.getListedAssets()\r\n .catch(err => {\r\n console.log(`Error getting listed assets. Trying again in 1 day`);\r\n if (err instanceof Error) console.log(err.message);\r\n this.updater(this.updaterTimeoutIfFailed);\r\n })\r\n .then(() => {\r\n this.updater();\r\n })\r\n }, timeout);\r\n }\r\n\r\n /**\r\n * Generate a URL page to get the information from. Input is the page number.\r\n * @param page page number\r\n * @returns the URL to retrieve the information\r\n */\r\n private getUrlByPage(page: number): string {\r\n return `${this.urls.listedStocks}/${Buffer.from(JSON.stringify(new ListedStocksRequest(page))).toString('base64')}`\r\n }\r\n\r\n /** Update the current listed assets */\r\n async getListedAssets(): Promise<void> {\r\n const firstResult = await axios.get(this.getUrlByPage(1));\r\n if (!('data' in firstResult)) throw new Error(`Unexpected response: ${firstResult}`);\r\n\r\n let data: CrawlerRequestResult = firstResult.data;\r\n const results: StockInfos[] = data.results;\r\n \r\n while(data.page.totalPages > data.page.pageNumber) {\r\n const getResult = await axios.get(this.getUrlByPage(data.page.pageNumber + 1));\r\n if (!('data' in getResult)) throw new Error(`Unexpected response: ${getResult}`);\r\n data = getResult.data;\r\n results.push(...data.results);\r\n }\r\n \r\n this.assets = results;\r\n\r\n }\r\n\r\n /**\r\n * Parse the stock name and returns the stock code\r\n * @param name title of the stock in the brokerage note\r\n * @returns the stock code\r\n */\r\n getCodeFromTitle(name: string): Asset {\r\n // If the stock was manually set\r\n const customDefined: Asset | undefined = this.customAssets.find(c => name.includes(c.name));\r\n if (customDefined) return customDefined\r\n\r\n // If it's a FII, the code is in the name\r\n const match = name.match(/FII\\s.*?\\s([^\\s]+?)\\sCI/i);\r\n if (match && match[1]) return {code: match[1], name};\r\n\r\n // Else, parse it\r\n let type: '3'|'4'|'11' = '3';\r\n let indexOf: number;\r\n if (name.indexOf(' ON') !== -1) { indexOf = name.indexOf(' ON'); type = '3'}\r\n else if (name.indexOf(' PN') !== -1) { indexOf = name.indexOf(' PN'); type = '4'}\r\n else if (name.indexOf(' UNT') !== -1) { indexOf = name.indexOf(' UNT'); type = '11'}\r\n else indexOf = name.length;\r\n const justTheName = name.slice(0, indexOf);\r\n const stock = this.assets.find(el => el.tradingName === justTheName);\r\n if (!stock) throw new Error(`No stock found for ${name}`);\r\n\r\n return {code: stock.issuingCompany + type, name, cnpj: stock.cnpj};\r\n\r\n }\r\n\r\n}\r\n","module.exports = require(\"axios\");","module.exports = require(\"pdfjs-dist\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","import { getDocument as openPDF, PDFDocumentProxy as PDFDocument, GlobalWorkerOptions, version as pdfjsVersion } from 'pdfjs-dist';\r\nimport { Asset, AssetCrawler } from \"./asset-crawler\";\r\n\r\n/** Deal made in a `NegotiationNote` type */\r\nexport interface Deal {\r\n /** Deal type */\r\n type: 'buy' | 'sell'\r\n /** Stock/FII code */\r\n code: string\r\n /** Amount bought/sold */\r\n quantity: number\r\n /** Average value bought/sold with fees applied */\r\n average: string\r\n /** Total amount bought/sold with fees applied */\r\n price: string\r\n /** Deal date in format yyyy-MM-dd */\r\n date: string\r\n /** Asset's CNPJ */\r\n cnpj: string\r\n}\r\n\r\n/** A parsed Negotiation Note type */\r\nexport class NegotiationNote {\r\n /** Negotiation note number */\r\n number = '';\r\n /** The total amount bought with fees applied */\r\n buyTotal = '0'\r\n /** The total amount sold with fees applied */\r\n sellTotal = '0'\r\n /** The total amount of buy fees */\r\n buyFees = '0'\r\n /** The total amount of sell fees */\r\n sellFees = '0'\r\n /** The total amount of fees */\r\n fees = '0'\r\n /** Negotiation note date in format yyyy-MM-dd */\r\n date = ''\r\n /** Negotiation note holder */\r\n holder = ''\r\n /** Array of deals with buys and sells */\r\n deals: Deal[] = []\r\n}\r\n\r\n/** Possible date formats to be used */\r\nexport type DateFormat = \"dd/MM/yyyy\" | \"yyyy-MM-dd\";\r\n\r\n/** Wrong password error */\r\nexport class WrongPassword extends Error {}\r\n/** Empty document error */\r\nexport class EmptyDocument extends Error {}\r\n/** Document without note number error */\r\nexport class MissingNoteNumber extends Error {}\r\n/** Document without holder error */\r\nexport class MissingHolder extends Error {}\r\n/** Document without date error */\r\nexport class MissingDate extends Error {}\r\n/** Missing Buy or Sell sums */\r\nexport class MissingBuyOrSellSums extends Error {}\r\n/** Unknown Asset error error */\r\nexport class UnknownAsset extends Error {}\r\n\r\n/** Brokerage notes parser */\r\nexport class NoteParser {\r\n\r\n /** Path to the JSON data file */\r\n private stockParser: AssetCrawler;\r\n /** The date format used. Default is `dd/MM/yyyy` */\r\n private dateFormat: DateFormat = \"dd/MM/yyyy\";\r\n\r\n /**\r\n * Instantiate a new `NoteParser`\r\n * @param autoUpdateLookUpList whether the application should auto-update\r\n * the list of assets for new changes every week. Default is `false`. Require internet connection.\r\n * Updating this package to the latest version also gets the latest infos\r\n */\r\n constructor(autoUpdateLookUpList?: boolean) {\r\n\r\n // ?Required for the browser\r\n // https://github.com/mozilla/pdf.js/issues/12066#issuecomment-659054172\r\n if (typeof window !== 'undefined') GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsVersion}/pdf.worker.min.js`;\r\n \r\n this.stockParser = new AssetCrawler(autoUpdateLookUpList);\r\n\r\n // Some manually defined stocks\r\n this.defineStock('TIET11', 'AES TIETE E UNT');\r\n this.defineStock('AESB3', 'AES TIETE E ON');\r\n this.defineStock('AESB4', 'AES TIETE E PN');\r\n this.defineStock('CSAN11', 'COSAN LOG UNT');\r\n this.defineStock('CSAN3', 'COSAN LOG ON');\r\n this.defineStock('CSAN4', 'COSAN LOG PN');\r\n this.defineStock('MDIA11', 'M.DIASBRANCO UNT');\r\n this.defineStock('MDIA3', 'M.DIASBRANCO ON');\r\n this.defineStock('MDIA4', 'M.DIASBRANCO PN');\r\n this.defineStock('BIDI3', 'BANCO INTER ON');\r\n this.defineStock('BIDI11', 'BANCO INTER UNT');\r\n }\r\n\r\n /**\r\n * Set the date format\r\n * @param format a `DateFormat`\r\n */\r\n setDateFormat(format: DateFormat) {\r\n this.dateFormat = format;\r\n }\r\n\r\n /**\r\n * Read and parse a given PDF negotiation note by its full path\r\n * @param name PDF name\r\n * @param content PDF content\r\n * @returns an `Array` of `NegotiationNote`\r\n */\r\n async parseNote(noteName: string, content: Uint8Array, possiblePasswords?: string[]): Promise<NegotiationNote[]> {\r\n\r\n // Try to open the PDF using the provided passwords, if any\r\n const parseResults: NegotiationNote[] = []\r\n let invalidPassword = false;\r\n let pdf: PDFDocument | undefined;\r\n if (!possiblePasswords || !possiblePasswords.length) {\r\n pdf = await openPDF(content).promise;\r\n } else {\r\n for await (const pass of possiblePasswords) {\r\n try {\r\n pdf = await openPDF({data: content, password: pass}).promise;\r\n break;\r\n } catch (error: unknown) {\r\n /** Prevent the failure and try again with another password */\r\n if (error instanceof Error) {\r\n if (!error.message.includes('No password given') && !error.message.includes('Incorrect Password')) throw error;\r\n else invalidPassword = true;\r\n } else if (typeof error === 'string') {\r\n if (!error.includes('No password given') && !error.includes('Incorrect Password')) throw error;\r\n else invalidPassword = true;\r\n }\r\n else throw error;\r\n }\r\n }\r\n }\r\n\r\n // Check if the open result\r\n if (!pdf && invalidPassword) throw new WrongPassword(`None of the provided passwords could open the note ${noteName}`);\r\n else if (!pdf) throw new EmptyDocument(`Can't open note ${noteName}. The document returned no content`);\r\n\r\n // Parse the PDF content\r\n const holderPattern = /data.*\\s+\\d{2}\\/\\d{2}\\/\\d{4}\\s+(\\w+)/i;\r\n const noteNumberPattern = /Nr\\. nota\\s+(\\d+)/i;\r\n const datePattern = /data.*\\s+(\\d{2}\\/\\d{2}\\/\\d{4})/i;\r\n const buysAndSellsPattern = /\\d[\\d,.]*\\s+(\\d[\\d,.]*)\\s+(\\d[\\d,.]*)\\s+\\d[\\d,.]*\\s+\\d[\\d,.]*\\s+\\d[\\d,.]*\\s+\\d[\\d,.]*\\s+\\d[\\d,.]*\\s*Resumo dos Negócios/;\r\n const feesPattern: RegExp[] = [\r\n /(\\d[\\d,.]*)\\nTaxa de liquidação/,\r\n /(\\d[\\d,.]*)\\nTaxa de Registro/,\r\n /(\\d[\\d,.]*)\\nTaxa de termo\\/opções/,\r\n /(\\d[\\d,.]*)\\nTaxa A.N.A./,\r\n /(\\d[\\d,.]*)\\nEmolumentos/,\r\n /(\\d[\\d,.]*)\\nTaxa Operacional/,\r\n /(\\d[\\d,.]*)\\nExecução/,\r\n /(\\d[\\d,.]*)\\nTaxa de Custódia/,\r\n /(\\d[\\d,.]*)\\nImpostos/,\r\n /(\\d[\\d,.]*)\\nI\\.R\\.R\\.F\\. s\\/ operações, base/,\r\n /(\\d[\\d,.]*)\\nOutros/\r\n ];\r\n const stockPattern = /1-BOVESPA\\s+(\\w)\\s+(\\w+)\\s+([\\t \\s+\\w/.]+)\\s+(?:#\\w*\\s+)?(\\d+)\\s+([\\w,]+)\\s+([\\w,.]+)\\s+/g;\r\n let match: RegExpMatchArray | null;\r\n\r\n // Iterate over the pages\r\n let pageContent = '';\r\n for await (const index of Array(pdf.numPages).keys()) {\r\n const i = index + 1;\r\n const page = await pdf.getPage(i);\r\n const data = await page.getTextContent();\r\n // Get page content\r\n for (let j = 0; j < data.items.length; j++) {\r\n const item = data.items[j];\r\n if ('str' in item) pageContent += `${item.str}\\n`;\r\n }\r\n if (pageContent.match(buysAndSellsPattern) && pageContent.match(noteNumberPattern)) {\r\n\r\n // Get note's number\r\n let noteNumber: string | undefined\r\n match = pageContent.match(noteNumberPattern);\r\n if (match && match[1]) noteNumber = match[1];\r\n else throw new MissingNoteNumber(`No note number found for the negotiation note '${noteName}'`);\r\n let parseResult = parseResults.find(el => el.number === noteNumber);\r\n if (!parseResult) {\r\n parseResult = new NegotiationNote();\r\n parseResults.push(parseResult);\r\n }\r\n parseResult.number = noteNumber;\r\n\r\n // Get the holder\r\n let holder: string | undefined;\r\n match = pageContent.match(holderPattern);\r\n if (match && match[1]) holder = match[1][0].toUpperCase() + match[1].slice(1).toLowerCase();\r\n else throw new MissingHolder(`No holder found for the negotiation note '${noteName}'`);\r\n parseResult.holder = holder.toLocaleLowerCase();\r\n\r\n // Get the date\r\n let date: string | undefined;\r\n match = pageContent.match(datePattern);\r\n if (match && match[1]) date = this.formatDate(match[1]);\r\n else throw new MissingDate(`No date found for the negotiation note '${noteName}'`);\r\n parseResult.date = date;\r\n\r\n // Note total\r\n let buyTotal = 0;\r\n let sellTotal = 0;\r\n if ((match = pageContent.match(buysAndSellsPattern)) !== null) {\r\n sellTotal = parseFloat(match[1].replace(/\\./g, '').replace(',', '.'));\r\n buyTotal = parseFloat(match[2].replace(/\\./g, '').replace(',', '.'));\r\n } else throw new MissingBuyOrSellSums(`Error parsing note '${noteName}'. Couldn't get note buys and sells values`);\r\n\r\n // Get the fees\r\n let fees = 0;\r\n feesPattern.forEach(fee => {\r\n const match = pageContent.match(fee);\r\n if (match && match[1]) {\r\n fees += parseFloat(match[1].replace(/\\./g, '').replace(',', '.')); \r\n }\r\n });\r\n if (fees) parseResult.fees = (parseFloat(parseResult.fees) + fees).toFixed(2);\r\n\r\n // Generate the Checkout for the value bought\r\n if (buyTotal) parseResult.buyTotal = buyTotal.toFixed(2);\r\n \r\n // Generate the Check in for the value sold\r\n if (sellTotal) parseResult.sellTotal = sellTotal.toFixed(2);\r\n\r\n while ((match = stockPattern.exec(pageContent)) != null) {\r\n const op: string = match[1];\r\n // let market: string = match[2];\r\n const stock: Asset = this.stockParser.getCodeFromTitle(match[3].replace(/\\s+/g, ' '));\r\n const quantity: number = parseInt(match[4]);\r\n // let each: number = parseFloat(match[5].replace('.', '').replace(',', '.'));\r\n const transactionValue: number = parseFloat(match[6].replace('.', '').replace(',', '.'));\r\n\r\n if (!stock) throw new UnknownAsset(`Can't find ${match[3]}`);\r\n\r\n // if (market === 'FRACIONARIO') stock += 'F';\r\n \r\n // Set 'buy' or 'sell'\r\n if (op === 'C') {\r\n let deal = parseResult.deals.find(el => el.code === stock.code && el.type === 'buy');\r\n if (!deal) {\r\n deal = {\r\n type: 'buy',\r\n code: stock.code,\r\n quantity: quantity,\r\n average: '0',\r\n price: transactionValue.toFixed(2),\r\n date: parseResult.date,\r\n cnpj: stock.cnpj?stock.cnpj:''\r\n };\r\n parseResult.deals.push(deal);\r\n } else {\r\n deal.price = (parseFloat(deal.price) + transactionValue).toString();\r\n deal.quantity = deal.quantity + quantity;\r\n }\r\n } else {\r\n let deal = parseResult.deals.find(el => el.code === stock.code && el.type === 'sell');\r\n if (!deal) {\r\n deal = {\r\n type: 'sell',\r\n code: stock.code,\r\n quantity: quantity,\r\n average: '0',\r\n price: transactionValue.toFixed(2),\r\n date: parseResult.date,\r\n cnpj: stock.cnpj?stock.cnpj:''\r\n };\r\n parseResult.deals.push(deal);\r\n } else {\r\n deal.price = (parseFloat(deal.price) + transactionValue).toString();\r\n deal.quantity = deal.quantity - quantity\r\n }\r\n }\r\n\r\n }\r\n\r\n pageContent = '';\r\n }\r\n }\r\n\r\n // Process the fees\r\n parseResults.forEach(note => {\r\n const fees: number = parseFloat(note.fees);\r\n if (fees) {\r\n const buyTotal: number = parseFloat(note.buyTotal);\r\n const sellTotal: number = parseFloat(note.sellTotal);\r\n const buyFees: number = fees*buyTotal/(buyTotal+sellTotal);\r\n const sellFees: number = fees*sellTotal/(buyTotal+sellTotal);\r\n note.deals.forEach(deal => {\r\n const price: number = parseFloat(deal.price);\r\n if (deal.type === 'buy') {\r\n deal.price = (Math.fround(10*(price + buyFees*price/buyTotal))/10).toFixed(2);\r\n } else {\r\n deal.price = (Math.fround(10*(price - sellFees*price/sellTotal))/10).toFixed(2);\r\n }\r\n deal.average = (parseFloat(deal.price)/Math.abs(deal.quantity)).toFixed(2);\r\n });\r\n note.buyFees = buyFees.toFixed(2);\r\n note.sellFees = sellFees.toFixed(2);\r\n note.buyTotal = (buyTotal + buyFees).toFixed(2);\r\n note.sellTotal = (sellTotal - sellFees).toFixed(2);\r\n }\r\n });\r\n\r\n // Format the CNPJs\r\n parseResults.forEach(el => {\r\n el.deals.forEach(deal => {\r\n // For some reason, CNPJs starting wit zeros have them suppressed, even thought it's a string and not a number ¯\\_(ツ)_/¯\r\n if (deal.cnpj.length < 14) deal.cnpj = new Array(14 - deal.cnpj.length).fill('0').join('') + deal.cnpj;\r\n\r\n deal.cnpj = deal.cnpj.replace(/^(\\d{2})(\\d{3})(\\d{3})(\\d{4})(\\d{2})/, \"$1.$2.$3/$4-$5\");\r\n })\r\n });\r\n\r\n return parseResults;\r\n }\r\n\r\n /**\r\n * Add stock definition\r\n * @param code stock code\r\n * @param name stock name\r\n * @param cnpj stock CNPJ\r\n */\r\n defineStock(code: string, name: string, cnpj?: string): void {\r\n // Skip duplicates\r\n if (!this.stockParser.customAssets.find(a => a.code === code)) {\r\n this.stockParser.customAssets.push({code, name, cnpj});\r\n }\r\n }\r\n\r\n /**\r\n * Convert a date according to `dateFormat`\r\n * @param date the date to be formatted\r\n * @returns the formatted date\r\n */\r\n private formatDate (date: string) {\r\n if (date.match(/\\d{4}-\\d{2}-\\d{2}/)) {\r\n if (this.dateFormat === 'yyyy-MM-dd') return date;\r\n else return date.split('-').reverse().join('/');\r\n } else {\r\n if (this.dateFormat === 'dd/MM/yyyy') return date;\r\n else return date.split('/').reverse().join('-');\r\n }\r\n }\r\n\r\n}"],"names":["ListedStocksRequest","constructor","pageNumber","language","pageSize","this","autoUpdate","customAssets","updaterTimeout","updaterTimeoutIfFailed","urls","listedStocks","atob","assets","updater","timeout","setTimeout","getListedAssets","catch","err","console","log","Error","message","then","getUrlByPage","page","Buffer","from","JSON","stringify","toString","async","firstResult","get","data","results","totalPages","getResult","push","getCodeFromTitle","name","customDefined","find","c","includes","match","code","indexOf","type","length","justTheName","slice","stock","el","tradingName","issuingCompany","cnpj","module","exports","require","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","call","NegotiationNote","number","buyTotal","sellTotal","buyFees","sellFees","fees","date","holder","deals","WrongPassword","EmptyDocument","MissingNoteNumber","MissingHolder","MissingDate","MissingBuyOrSellSums","UnknownAsset","autoUpdateLookUpList","dateFormat","window","GlobalWorkerOptions","workerSrc","stockParser","AssetCrawler","defineStock","setDateFormat","format","noteName","content","possiblePasswords","parseResults","pdf","invalidPassword","pass","password","promise","error","holderPattern","noteNumberPattern","datePattern","buysAndSellsPattern","feesPattern","stockPattern","pageContent","index","Array","numPages","keys","i","getPage","getTextContent","j","items","item","str","noteNumber","parseResult","toUpperCase","toLowerCase","toLocaleLowerCase","formatDate","parseFloat","replace","forEach","fee","toFixed","exec","op","quantity","parseInt","transactionValue","deal","price","average","note","Math","fround","abs","fill","join","a","split","reverse"],"sourceRoot":""}
1
+ {"version":3,"file":"notes-parser.js","mappings":"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","sources":["webpack://parser-de-notas-de-corretagem/./src/asset-crawler.ts","webpack://parser-de-notas-de-corretagem/external commonjs \"axios\"","webpack://parser-de-notas-de-corretagem/external commonjs \"pdfjs-dist\"","webpack://parser-de-notas-de-corretagem/webpack/bootstrap","webpack://parser-de-notas-de-corretagem/./src/notes-parser.ts"],"sourcesContent":["import axios from \"axios\";\r\nimport assets from '../assets.json';\r\n\r\n/** B3 request object constructor */\r\nclass ListedStocksRequest {\r\n language = 'pt-br';\r\n pageNumber: number;\r\n pageSize: 20|40|60|120 = 120;\r\n \r\n constructor(pageNumber: number) {\r\n this.pageNumber = pageNumber;\r\n this.pageSize = 120;\r\n }\r\n\r\n}\r\n\r\n/** Infos about the stock */\r\ninterface StockInfos {\r\n /** CVM code */\r\n codeCVM: string;\r\n /** Issuing Company (B3 Code) */\r\n issuingCompany: string;\r\n /** Company name */\r\n companyName: string;\r\n /** Trading name (same name as in the brokerage note) */\r\n tradingName: string;\r\n /** Company's CNPJ */\r\n cnpj: string;\r\n marketIndicator: string;\r\n typeBDR: string;\r\n dateListing: string;\r\n status: string;\r\n segment: string;\r\n segmentEng: string;\r\n type: string;\r\n market: string;\r\n}\r\n\r\n/** Infos about the page and the total amount of records */\r\ninterface PageInfo {\r\n /** Current page number */\r\n pageNumber: number;\r\n /** Number of results in the page (can be less if it's the last page) */\r\n pageSize: number;\r\n /** Number of total records */\r\n totalRecords: number;\r\n /** Number of total pages */\r\n totalPages: number;\r\n}\r\n\r\n/** Crawler result */\r\ninterface CrawlerRequestResult {\r\n \"page\": PageInfo;\r\n \"results\": StockInfos[];\r\n}\r\n\r\n/** Assets main infos */\r\nexport interface Asset {\r\n /** Asset's code */\r\n code: string;\r\n /** Asset's name */\r\n name: string;\r\n /** Asset's cnpj */\r\n cnpj?: string;\r\n}\r\n\r\n/** Assets crawler manager */\r\nexport class AssetCrawler {\r\n\r\n /** Assets cached */\r\n protected assets: StockInfos[];\r\n /** Assets defined on runtime */\r\n customAssets: Asset[] = [];\r\n /** Auto-update flag */\r\n autoUpdate = false;\r\n /** Auto-update timeout */\r\n private updaterTimeout = 7*24*3600*1000;\r\n /** Auto-update timeout when any failure happens */\r\n private updaterTimeoutIfFailed = 24*3600*1000;\r\n\r\n /** Crawler URLs */\r\n private urls = {\r\n // Using deprecated `atob` because Buffer isn't supported out-of-the-box in browsers\r\n listedStocks: atob('aHR0cHM6Ly9zaXN0ZW1hc3dlYmIzLWxpc3RhZG9zLmIzLmNvbS5ici9saXN0ZWRDb21wYW5pZXNQcm94eS9Db21wYW55Q2FsbC9HZXRJbml0aWFsQ29tcGFuaWVz')\r\n }\r\n\r\n /**\r\n * Instantiate a new `AssetCrawler`\r\n * @param autoUpdate whether the application should auto-update\r\n * the list of assets for new changes. Default is `false`. Require internet connection\r\n */\r\n constructor(autoUpdate?: boolean) {\r\n this.assets = assets;\r\n this.autoUpdate = autoUpdate || false;\r\n if (this.autoUpdate) {\r\n this.updater(0);\r\n }\r\n }\r\n\r\n /**\r\n * Update the listed assets after a timeout\r\n * @param timeout update after `timeout` milliseconds\r\n */\r\n updater(timeout: number = this.updaterTimeout) {\r\n setTimeout(() => {\r\n this.getListedAssets()\r\n .catch(err => {\r\n console.log(`Error getting listed assets. Trying again in 1 day`);\r\n if (err instanceof Error) console.log(err.message);\r\n this.updater(this.updaterTimeoutIfFailed);\r\n })\r\n .then(() => {\r\n this.updater();\r\n })\r\n }, timeout);\r\n }\r\n\r\n /**\r\n * Generate a URL page to get the information from. Input is the page number.\r\n * @param page page number\r\n * @returns the URL to retrieve the information\r\n */\r\n private getUrlByPage(page: number): string {\r\n return `${this.urls.listedStocks}/${Buffer.from(JSON.stringify(new ListedStocksRequest(page))).toString('base64')}`\r\n }\r\n\r\n /** Update the current listed assets */\r\n async getListedAssets(): Promise<void> {\r\n const firstResult = await axios.get(this.getUrlByPage(1));\r\n if (!('data' in firstResult)) throw new Error(`Unexpected response: ${firstResult}`);\r\n\r\n let data: CrawlerRequestResult = firstResult.data;\r\n const results: StockInfos[] = data.results;\r\n \r\n while(data.page.totalPages > data.page.pageNumber) {\r\n const getResult = await axios.get(this.getUrlByPage(data.page.pageNumber + 1));\r\n if (!('data' in getResult)) throw new Error(`Unexpected response: ${getResult}`);\r\n data = getResult.data;\r\n results.push(...data.results);\r\n }\r\n \r\n this.assets = results;\r\n\r\n }\r\n\r\n /**\r\n * Parse the stock name and returns the stock code\r\n * @param name title of the stock in the brokerage note\r\n * @returns the stock code\r\n */\r\n getCodeFromTitle(name: string): Asset {\r\n // If the stock was manually set\r\n const customDefined: Asset | undefined = this.customAssets.find(c => name.includes(c.name));\r\n if (customDefined) return customDefined\r\n\r\n // If it's a FII, the code is in the name\r\n const match = name.match(/FII\\s.*?\\s([^\\s]+?)\\sCI/i);\r\n if (match && match[1]) return {code: match[1], name};\r\n\r\n // Else, parse it\r\n let type: '3'|'4'|'11' = '3';\r\n let indexOf: number;\r\n if (name.indexOf(' ON') !== -1) { indexOf = name.indexOf(' ON'); type = '3'}\r\n else if (name.indexOf(' PN') !== -1) { indexOf = name.indexOf(' PN'); type = '4'}\r\n else if (name.indexOf(' UNT') !== -1) { indexOf = name.indexOf(' UNT'); type = '11'}\r\n else indexOf = name.length;\r\n const justTheName = name.slice(0, indexOf);\r\n const stock = this.assets.find(el => el.tradingName === justTheName);\r\n if (!stock) throw new Error(`No stock found for ${name}`);\r\n\r\n return {code: stock.issuingCompany + type, name, cnpj: stock.cnpj};\r\n\r\n }\r\n\r\n}\r\n","module.exports = require(\"axios\");","module.exports = require(\"pdfjs-dist\");","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","import { getDocument as openPDF, PDFDocumentProxy as PDFDocument, GlobalWorkerOptions, version as pdfjsVersion } from 'pdfjs-dist';\r\nimport { Asset, AssetCrawler } from \"./asset-crawler\";\r\n\r\n/** Deal made in a `NegotiationNote` type */\r\nexport interface Deal {\r\n /** Deal type */\r\n type: 'buy' | 'sell'\r\n /** Stock/FII code */\r\n code: string\r\n /** Amount bought/sold */\r\n quantity: number\r\n /** Average value bought/sold with fees applied */\r\n average: string\r\n /** Total amount bought/sold with fees applied */\r\n price: string\r\n /** Deal date in format yyyy-MM-dd */\r\n date: string\r\n /** Asset's CNPJ */\r\n cnpj: string\r\n}\r\n\r\n/** A parsed Negotiation Note type */\r\nexport class NegotiationNote {\r\n /** Negotiation note number */\r\n number = '';\r\n /** The total amount bought with fees applied */\r\n buyTotal = '0'\r\n /** The total amount sold with fees applied */\r\n sellTotal = '0'\r\n /** The total amount of buy fees */\r\n buyFees = '0'\r\n /** The total amount of sell fees */\r\n sellFees = '0'\r\n /** The total amount of fees */\r\n fees = '0'\r\n /** Negotiation note date in format yyyy-MM-dd */\r\n date = ''\r\n /** Negotiation note holder */\r\n holder = ''\r\n /** Array of deals with buys and sells */\r\n deals: Deal[] = []\r\n}\r\n\r\n/** Possible date formats to be used */\r\nexport type DateFormat = \"dd/MM/yyyy\" | \"yyyy-MM-dd\";\r\n\r\n/** Wrong password error */\r\nexport class WrongPassword extends Error {}\r\n/** Empty document error */\r\nexport class EmptyDocument extends Error {}\r\n/** Document without note number error */\r\nexport class MissingNoteNumber extends Error {}\r\n/** Document without holder error */\r\nexport class MissingHolder extends Error {}\r\n/** Document without date error */\r\nexport class MissingDate extends Error {}\r\n/** Missing Buy or Sell sums */\r\nexport class MissingBuyOrSellSums extends Error {}\r\n/** Unknown Asset error error */\r\nexport class UnknownAsset extends Error {}\r\n\r\n/** Brokerage notes parser */\r\nexport class NoteParser {\r\n\r\n /** Path to the JSON data file */\r\n private stockParser: AssetCrawler;\r\n /** The date format used. Default is `dd/MM/yyyy` */\r\n private dateFormat: DateFormat = \"dd/MM/yyyy\";\r\n\r\n /**\r\n * Instantiate a new `NoteParser`\r\n * @param autoUpdateLookUpList whether the application should auto-update\r\n * the list of assets for new changes every week. Default is `false`. Require internet connection.\r\n * Updating this package to the latest version also gets the latest infos\r\n */\r\n constructor(autoUpdateLookUpList?: boolean) {\r\n\r\n // ?Required for the browser\r\n // https://github.com/mozilla/pdf.js/issues/12066#issuecomment-659054172\r\n if (typeof window !== 'undefined') GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsVersion}/pdf.worker.min.js`;\r\n \r\n this.stockParser = new AssetCrawler(autoUpdateLookUpList);\r\n\r\n // Some manually defined stocks\r\n this.defineStock('TIET11', 'AES TIETE E UNT');\r\n this.defineStock('AESB3', 'AES TIETE E ON');\r\n this.defineStock('AESB4', 'AES TIETE E PN');\r\n this.defineStock('CSAN11', 'COSAN LOG UNT');\r\n this.defineStock('CSAN3', 'COSAN LOG ON');\r\n this.defineStock('CSAN4', 'COSAN LOG PN');\r\n this.defineStock('MDIA11', 'M.DIASBRANCO UNT');\r\n this.defineStock('MDIA3', 'M.DIASBRANCO ON');\r\n this.defineStock('MDIA4', 'M.DIASBRANCO PN');\r\n this.defineStock('BIDI3', 'BANCO INTER ON');\r\n this.defineStock('BIDI11', 'BANCO INTER UNT');\r\n }\r\n\r\n /**\r\n * Set the date format\r\n * @param format a `DateFormat`\r\n */\r\n setDateFormat(format: DateFormat) {\r\n this.dateFormat = format;\r\n }\r\n\r\n /**\r\n * Read and parse a given PDF negotiation note by its full path\r\n * @param name PDF name\r\n * @param content PDF content\r\n * @returns an `Array` of `NegotiationNote`\r\n */\r\n async parseNote(noteName: string, content: string | Uint8Array, possiblePasswords?: string[]): Promise<NegotiationNote[]> {\r\n\r\n // Try to open the PDF using the provided passwords, if any\r\n const parseResults: NegotiationNote[] = []\r\n let invalidPassword = false;\r\n let pdf: PDFDocument | undefined;\r\n if (!possiblePasswords || !possiblePasswords.length) {\r\n pdf = await openPDF(content).promise;\r\n } else {\r\n for await (const pass of possiblePasswords) {\r\n try {\r\n pdf = await openPDF({data: content, password: pass}).promise;\r\n break;\r\n } catch (error: unknown) {\r\n /** Prevent the failure and try again with another password */\r\n if (error instanceof Error) {\r\n if (!error.message.includes('No password given') && !error.message.includes('Incorrect Password')) throw error;\r\n else invalidPassword = true;\r\n } else if (typeof error === 'string') {\r\n if (!error.includes('No password given') && !error.includes('Incorrect Password')) throw error;\r\n else invalidPassword = true;\r\n }\r\n else throw error;\r\n }\r\n }\r\n }\r\n\r\n // Check if the open result\r\n if (!pdf && invalidPassword) throw new WrongPassword(`None of the provided passwords could open the note ${noteName}`);\r\n else if (!pdf) throw new EmptyDocument(`Can't open note ${noteName}. The document returned no content`);\r\n\r\n // Parse the PDF content\r\n const holderPattern = /data.*\\s+\\d{2}\\/\\d{2}\\/\\d{4}\\s+(\\w+)/i;\r\n const noteNumberPattern = /Nr\\. nota\\s+(\\d+)/i;\r\n const datePattern = /data.*\\s+(\\d{2}\\/\\d{2}\\/\\d{4})/i;\r\n const buysAndSellsPattern = /\\d[\\d,.]*\\s+(\\d[\\d,.]*)\\s+(\\d[\\d,.]*)\\s+\\d[\\d,.]*\\s+\\d[\\d,.]*\\s+\\d[\\d,.]*\\s+\\d[\\d,.]*\\s+\\d[\\d,.]*\\s*Resumo dos Negócios/;\r\n const feesPattern: RegExp[] = [\r\n /(\\d[\\d,.]*)\\nTaxa de liquidação/,\r\n /(\\d[\\d,.]*)\\nTaxa de Registro/,\r\n /(\\d[\\d,.]*)\\nTaxa de termo\\/opções/,\r\n /(\\d[\\d,.]*)\\nTaxa A.N.A./,\r\n /(\\d[\\d,.]*)\\nEmolumentos/,\r\n /(\\d[\\d,.]*)\\nTaxa Operacional/,\r\n /(\\d[\\d,.]*)\\nExecução/,\r\n /(\\d[\\d,.]*)\\nTaxa de Custódia/,\r\n /(\\d[\\d,.]*)\\nImpostos/,\r\n /(\\d[\\d,.]*)\\nI\\.R\\.R\\.F\\. s\\/ operações, base/,\r\n /(\\d[\\d,.]*)\\nOutros/\r\n ];\r\n const stockPattern = /1-BOVESPA\\s+(\\w)\\s+(\\w+)\\s+([\\t \\s+\\w/.]+)\\s+(?:#\\w*\\s+)?(\\d+)\\s+([\\w,]+)\\s+([\\w,.]+)\\s+/g;\r\n let match: RegExpMatchArray | null;\r\n\r\n // Iterate over the pages\r\n let pageContent = '';\r\n for await (const index of Array(pdf.numPages).keys()) {\r\n const i = index + 1;\r\n const page = await pdf.getPage(i);\r\n const data = await page.getTextContent();\r\n // Get page content\r\n for (let j = 0; j < data.items.length; j++) {\r\n const item = data.items[j];\r\n if ('str' in item) pageContent += `${item.str}\\n`;\r\n }\r\n if (pageContent.match(buysAndSellsPattern) && pageContent.match(noteNumberPattern)) {\r\n\r\n // Get note's number\r\n let noteNumber: string | undefined\r\n match = pageContent.match(noteNumberPattern);\r\n if (match && match[1]) noteNumber = match[1];\r\n else throw new MissingNoteNumber(`No note number found for the negotiation note '${noteName}'`);\r\n let parseResult = parseResults.find(el => el.number === noteNumber);\r\n if (!parseResult) {\r\n parseResult = new NegotiationNote();\r\n parseResults.push(parseResult);\r\n }\r\n parseResult.number = noteNumber;\r\n\r\n // Get the holder\r\n let holder: string | undefined;\r\n match = pageContent.match(holderPattern);\r\n if (match && match[1]) holder = match[1][0].toUpperCase() + match[1].slice(1).toLowerCase();\r\n else throw new MissingHolder(`No holder found for the negotiation note '${noteName}'`);\r\n parseResult.holder = holder.toLocaleLowerCase();\r\n\r\n // Get the date\r\n let date: string | undefined;\r\n match = pageContent.match(datePattern);\r\n if (match && match[1]) date = this.formatDate(match[1]);\r\n else throw new MissingDate(`No date found for the negotiation note '${noteName}'`);\r\n parseResult.date = date;\r\n\r\n // Note total\r\n let buyTotal = 0;\r\n let sellTotal = 0;\r\n if ((match = pageContent.match(buysAndSellsPattern)) !== null) {\r\n sellTotal = parseFloat(match[1].replace(/\\./g, '').replace(',', '.'));\r\n buyTotal = parseFloat(match[2].replace(/\\./g, '').replace(',', '.'));\r\n } else throw new MissingBuyOrSellSums(`Error parsing note '${noteName}'. Couldn't get note buys and sells values`);\r\n\r\n // Get the fees\r\n let fees = 0;\r\n feesPattern.forEach(fee => {\r\n const match = pageContent.match(fee);\r\n if (match && match[1]) {\r\n fees += parseFloat(match[1].replace(/\\./g, '').replace(',', '.')); \r\n }\r\n });\r\n if (fees) parseResult.fees = (parseFloat(parseResult.fees) + fees).toFixed(2);\r\n\r\n // Generate the Checkout for the value bought\r\n if (buyTotal) parseResult.buyTotal = buyTotal.toFixed(2);\r\n \r\n // Generate the Check in for the value sold\r\n if (sellTotal) parseResult.sellTotal = sellTotal.toFixed(2);\r\n\r\n while ((match = stockPattern.exec(pageContent)) != null) {\r\n const op: string = match[1];\r\n // let market: string = match[2];\r\n const stock: Asset = this.stockParser.getCodeFromTitle(match[3].replace(/\\s+/g, ' '));\r\n const quantity: number = parseInt(match[4]);\r\n // let each: number = parseFloat(match[5].replace('.', '').replace(',', '.'));\r\n const transactionValue: number = parseFloat(match[6].replace('.', '').replace(',', '.'));\r\n\r\n if (!stock) throw new UnknownAsset(`Can't find ${match[3]}`);\r\n\r\n // if (market === 'FRACIONARIO') stock += 'F';\r\n \r\n // Set 'buy' or 'sell'\r\n if (op === 'C') {\r\n let deal = parseResult.deals.find(el => el.code === stock.code && el.type === 'buy');\r\n if (!deal) {\r\n deal = {\r\n type: 'buy',\r\n code: stock.code,\r\n quantity: quantity,\r\n average: '0',\r\n price: transactionValue.toFixed(2),\r\n date: parseResult.date,\r\n cnpj: stock.cnpj?stock.cnpj:''\r\n };\r\n parseResult.deals.push(deal);\r\n } else {\r\n deal.price = (parseFloat(deal.price) + transactionValue).toString();\r\n deal.quantity = deal.quantity + quantity;\r\n }\r\n } else {\r\n let deal = parseResult.deals.find(el => el.code === stock.code && el.type === 'sell');\r\n if (!deal) {\r\n deal = {\r\n type: 'sell',\r\n code: stock.code,\r\n quantity: quantity,\r\n average: '0',\r\n price: transactionValue.toFixed(2),\r\n date: parseResult.date,\r\n cnpj: stock.cnpj?stock.cnpj:''\r\n };\r\n parseResult.deals.push(deal);\r\n } else {\r\n deal.price = (parseFloat(deal.price) + transactionValue).toString();\r\n deal.quantity = deal.quantity - quantity\r\n }\r\n }\r\n\r\n }\r\n\r\n pageContent = '';\r\n }\r\n }\r\n\r\n // Process the fees\r\n parseResults.forEach(note => {\r\n const fees: number = parseFloat(note.fees);\r\n if (fees) {\r\n const buyTotal: number = parseFloat(note.buyTotal);\r\n const sellTotal: number = parseFloat(note.sellTotal);\r\n const buyFees: number = fees*buyTotal/(buyTotal+sellTotal);\r\n const sellFees: number = fees*sellTotal/(buyTotal+sellTotal);\r\n note.deals.forEach(deal => {\r\n const price: number = parseFloat(deal.price);\r\n if (deal.type === 'buy') {\r\n deal.price = (Math.fround(10*(price + buyFees*price/buyTotal))/10).toFixed(2);\r\n } else {\r\n deal.price = (Math.fround(10*(price - sellFees*price/sellTotal))/10).toFixed(2);\r\n }\r\n deal.average = (parseFloat(deal.price)/Math.abs(deal.quantity)).toFixed(2);\r\n });\r\n note.buyFees = buyFees.toFixed(2);\r\n note.sellFees = sellFees.toFixed(2);\r\n note.buyTotal = (buyTotal + buyFees).toFixed(2);\r\n note.sellTotal = (sellTotal - sellFees).toFixed(2);\r\n }\r\n });\r\n\r\n // Format the CNPJs\r\n parseResults.forEach(el => {\r\n el.deals.forEach(deal => {\r\n // For some reason, CNPJs starting wit zeros have them suppressed, even thought it's a string and not a number ¯\\_(ツ)_/¯\r\n if (deal.cnpj.length < 14) deal.cnpj = new Array(14 - deal.cnpj.length).fill('0').join('') + deal.cnpj;\r\n\r\n deal.cnpj = deal.cnpj.replace(/^(\\d{2})(\\d{3})(\\d{3})(\\d{4})(\\d{2})/, \"$1.$2.$3/$4-$5\");\r\n })\r\n });\r\n\r\n return parseResults;\r\n }\r\n\r\n /**\r\n * Add stock definition\r\n * @param code stock code\r\n * @param name stock name\r\n * @param cnpj stock CNPJ\r\n */\r\n defineStock(code: string, name: string, cnpj?: string): void {\r\n // Skip duplicates\r\n if (!this.stockParser.customAssets.find(a => a.code === code)) {\r\n this.stockParser.customAssets.push({code, name, cnpj});\r\n }\r\n }\r\n\r\n /**\r\n * Convert a date according to `dateFormat`\r\n * @param date the date to be formatted\r\n * @returns the formatted date\r\n */\r\n private formatDate (date: string) {\r\n if (date.match(/\\d{4}-\\d{2}-\\d{2}/)) {\r\n if (this.dateFormat === 'yyyy-MM-dd') return date;\r\n else return date.split('-').reverse().join('/');\r\n } else {\r\n if (this.dateFormat === 'dd/MM/yyyy') return date;\r\n else return date.split('/').reverse().join('-');\r\n }\r\n }\r\n\r\n}"],"names":["ListedStocksRequest","constructor","pageNumber","language","pageSize","this","autoUpdate","customAssets","updaterTimeout","updaterTimeoutIfFailed","urls","listedStocks","atob","assets","updater","timeout","setTimeout","getListedAssets","catch","err","console","log","Error","message","then","getUrlByPage","page","Buffer","from","JSON","stringify","toString","async","firstResult","get","data","results","totalPages","getResult","push","getCodeFromTitle","name","customDefined","find","c","includes","match","code","indexOf","type","length","justTheName","slice","stock","el","tradingName","issuingCompany","cnpj","module","exports","require","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","call","NegotiationNote","number","buyTotal","sellTotal","buyFees","sellFees","fees","date","holder","deals","WrongPassword","EmptyDocument","MissingNoteNumber","MissingHolder","MissingDate","MissingBuyOrSellSums","UnknownAsset","autoUpdateLookUpList","dateFormat","window","GlobalWorkerOptions","workerSrc","stockParser","AssetCrawler","defineStock","setDateFormat","format","noteName","content","possiblePasswords","parseResults","pdf","invalidPassword","pass","password","promise","error","holderPattern","noteNumberPattern","datePattern","buysAndSellsPattern","feesPattern","stockPattern","pageContent","index","Array","numPages","keys","i","getPage","getTextContent","j","items","item","str","noteNumber","parseResult","toUpperCase","toLowerCase","toLocaleLowerCase","formatDate","parseFloat","replace","forEach","fee","toFixed","exec","op","quantity","parseInt","transactionValue","deal","price","average","note","Math","fround","abs","fill","join","a","split","reverse"],"sourceRoot":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "parser-de-notas-de-corretagem",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Parse Brazilian brokerage notes PDFs (Inter and Clear holders available)",
5
5
  "main": "notes-parser.js",
6
6
  "types": "notes-parser.d.ts",