diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b0781fc..76a2450 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -77,3 +77,16 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + publish-npm: + runs-on: ubuntu-latest + needs: build-on-win + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: 16 + registry-url: https://registry.npmjs.org/ + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..5d94e66 --- /dev/null +++ b/.npmignore @@ -0,0 +1,23 @@ +node_modules/ +dist/ +.github/ +.env +.vscode +*.xlsx +*.json +*.zip + +.env.example +.eslintrc.js +.eslintrc_win.js +.gitignore +.npmignore + +# Ignore all JSON files except: +!package.json +!package-lock.json +!data/regions.json + +# Ignore all Excel files except: +!data/regions.json +!data/day1.xlsx diff --git a/README.md b/README.md index a177c16..e04c9aa 100644 --- a/README.md +++ b/README.md @@ -156,47 +156,62 @@ Fix JavaScript lint errors. ### Load and Parse a Local Excel File +Below is a simple usage example of the `ExcelFile` class. Check out `/src/scripts/sample_usage.js` for more examples. + ```javascript const path = require('path') -const { ExcelFile } = require('./classes/excel') +const ExcelFile = require('./classes/excel') + +// Use the the following if installed via npm +// const ExcelFile = require('ph-municipalities') // Reads an existing excel file on /data/day1.xlsx file = new ExcelFile({ - pathToFile: path.join(__dirname, '..', 'data', 'day1.xlsx') + pathToFile: path.join(__dirname, 'data', 'day1.xlsx') }) -try { - file.init() -} catch (err) { - console.log(`[ERROR]: ${err.message}`) -} +// listMunicipalities() lists all municipalities +// for each province +const municipalitiesFromProvince = + file.listMunicipalities(['Albay','Masbate','Sorsogon']) + +// writeMunicipalities() writes municipalities data in a JSON file +file.writeMunicipalities({ + provinces: municipalitiesFromProvince, + fileName: path.join(__dirname, 'municipalities.json'), + prettify: true +}) // JSON data of the parsed excel file will be accessible on // file.datalist +console.log(file.datalist) ``` ### Download and Parse a Remote Excel File +Adding a `url` field in the constructor parameter will download a remote excel file for data source. + ```javascript require('dotenv').config() const path = require('path') -const { ExcelFile } = require('./classes/excel') +const ExcelFile = require('./classes/excel') + +// Use the the following if installed via npm +// const ExcelFile = require('ph-municipalities') const main = async () => { // Excel file will be downloaded to /data/day1.xlsx file = new ExcelFile({ - pathToFile: path.join(__dirname, '..', 'data', 'day1.xlsx'), + pathToFile: path.join(__dirname, 'data', 'day1.xlsx'), url: process.env.EXCEL_FILE_URL }) try { await file.init() + console.log(file.datalist) } catch (err) { console.log(err.message) } - - // JSON data of the parsed excel file will be accessible on - // file.datalist } main() diff --git a/index.js b/index.js new file mode 100644 index 0000000..bed975c --- /dev/null +++ b/index.js @@ -0,0 +1,8 @@ +require('dotenv').config() +const ExcelFile = require('./src/classes/excel') +const ExcelFactory = require('./src/classes/excelfactory') + +module.exports = { + ExcelFile, + ExcelFactory +} diff --git a/package.json b/package.json index 44298bb..b482643 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "municipalities-by-province", - "version": "1.0.0", - "description": "Extract the `municipalities` of a given `province` from an excel file and write them in a JSON file.", + "name": "ph-municipalities", + "version": "1.0.5", + "description": "List and write the `municipalities` of Philippines provinces or regions into JSON files", "main": "index.js", "scripts": { "start": "npm run list:region", @@ -11,22 +11,22 @@ "build:win:region": "pkg ./src/scripts/by_region.js -c package.json --compress GZip -o ./dist/ph-regions-win", "build:win:province": "pkg ./src/scripts/by_province.js -c package.json --compress GZip -o ./dist/ph-provinces-win", "build:win:all": "npm run build:win:region && npm run build:win:province", - "minify:region": "ncc build src/scripts/by_region.js -m -o dist/region", - "minify:province": "ncc build src/scripts/by_province.js -m -o dist/province", + "minify:region": "ncc dist src/scripts/by_region.js -m -o dist/region", + "minify:province": "ncc dist src/scripts/by_province.js -m -o dist/province", "minify:all": "npm run minify:region && npm run minify:province", "lint": "eslint src", "lint:fix": "eslint src --fix" }, "repository": { "type": "git", - "url": "git+https://github.com/ciatph/municipalities-by-province.git" + "url": "git+https://github.com/ciatph/ph-municipalities.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/ciatph/municipalities-by-province/issues" + "url": "https://github.com/ciatph/ph-municipalities/issues" }, - "homepage": "https://github.com/ciatph/municipalities-by-province#readme", + "homepage": "https://github.com/ciatph/ph-municipalities#readme", "devDependencies": { "@vercel/ncc": "^0.34.0", "eslint": "^8.21.0", diff --git a/src/classes/excel/excel.js b/src/classes/excel/excel.js deleted file mode 100644 index 19abf96..0000000 --- a/src/classes/excel/excel.js +++ /dev/null @@ -1,297 +0,0 @@ -const https = require('https') -const fs = require('fs') -const EventEmitter = require('events') -const XLSX = require('xlsx') - -/** - * Load, process and parse an Excel File containing a list of PH municipalities. - * The Excel File should contain a column with string pattern: - * "municipalityName (ProvinceName)" - */ -class ExcelFile { - /** Remote download URL of an excel file */ - #url = null - - /** Full file path to excel file on local storage */ - #pathToFile = null - - /** Excel workbook object parsed by sheetjs */ - #workbook = null - - /** Excel sheet names parsed by sheetjs */ - #sheets = null - - /** Objects[] Array corresponding to excel rows extracted from the excel sheet by sheetjs */ - #data = null - - /** Object[] Array of processed string corresponding to the column in the excel file - * that contains the list of municipalities following the pattern: - * "municipalityName (provinceName)" - * Content: [{ municipality, province }, ... ] - */ - #datalist = [] - - /** Internal excel file column name read by sheetjs. - * This column contains strings following the pattern - * "municipalityName (provinceName)" - */ - #SHEETJS_COL = process.env.SHEETJS_COLUMN || '__EMPTY' - - /** Event emitter for listening to custom events */ - events = new EventEmitter() - - /** List of EventEmitter events */ - EVENTS = { - LOADED: 'loaded' - } - - /** - * Initialize an ExcelFile object - * @param {String} url - Remote download URL of an excel file - * @param {String} pathToFile - * - Full local file path of an existing excel file, if "url" is not provided - * - Full local file path of an excel on where to download the remote excel file from "url", - * if the "url" parameter is provided - */ - constructor ({ url, pathToFile }) { - if (url === '' || pathToFile === '') { - throw new Error('Missing remote file url or local file path.') - } - - if (pathToFile === undefined) { - throw new Error('Missing pathToFile.') - } - - if (!pathToFile.includes('.xlsx')) { - throw new Error('pathToFile should contain an excel file name ending in .xlsx') - } - - // Set the local excel file path - this.#pathToFile = pathToFile - - if (url) { - // Set the remote excel file download URL - this.#url = url - } else { - this.init() - } - } - - /** - * Loads an existing excel file contents to a JSON object. - * Downloads a remote excel file if a remote this.#url is provided on the constructor - */ - async init () { - if (this.#url !== null && this.#pathToFile !== null) { - try { - // Download from remote URL - await this.download() - this.events.emit(this.EVENTS.LOADED) - } catch (errMsg) { - throw new Error(errMsg) - } - } - - if (this.#url === null && this.#pathToFile !== null) { - try { - // Read from file - this.load() - - // Add a slight delay before emmiting the loaded event - setTimeout(() => { - this.events.emit(this.EVENTS.LOADED) - }, 300) - } catch (err) { - throw new Error(err.message) - } - } - } - - /** - * Load an excel file from a local directory using sheetjs. - * Store excel file data as JSON in this.#data - */ - load () { - try { - this.#workbook = XLSX.readFile(this.#pathToFile) - this.#sheets = this.#workbook.SheetNames - - // Set data excel row data as Objects - this.#data = XLSX.utils.sheet_to_json(this.#workbook.Sheets[this.#sheets[0]]) - - // Extract the municipality and province names - this.#datalist = this.#data.reduce((acc, row) => { - if (row[this.#SHEETJS_COL] !== undefined && this.followsStringPattern(row[this.#SHEETJS_COL])) { - const municipality = this.getMunicipalityName(row[this.#SHEETJS_COL]) - const province = this.getProvinceName(row[this.#SHEETJS_COL]) - - if (province !== null) { - acc.push({ - municipality: municipality.trim(), - province - }) - } - } - - return acc - }, []) - - console.log(`Loaded ${this.#data.length} rows`) - - if (this.#datalist.length === 0) { - throw new Error('Failed to load data. Please check the SHEETJS_COLUMN name or the excel file contents.') - } - } catch (err) { - throw new Error(err.message) - } - } - - /** - * Downloads a remote excel file to this.#pathToFile - * and loads sheetjs parsed-content - */ - download () { - try { - const file = fs.createWriteStream(this.#pathToFile) - - return new Promise((resolve, reject) => { - https.get(this.#url, (res) => { - res.pipe(file) - - file.on('finish', () => { - file.close(() => { - try { - resolve(this.load()) - } catch (err) { - reject(err.message) - } - }) - }) - }) - }) - } catch (err) { - throw new Error(err.message) - } - } - - /** - * Checks if a string follows the pattern: - * "municipalityName (provinceName)" - * @param {String} str - String to check - * @returns {Bool} true | false - */ - followsStringPattern (str) { - return /[a-zA-z] *\([^)]*\) */.test(str) - } - - /** - * Extract the municipality name from a string following the pattern: - * "municipalityName (provinceName)" - * @param {String} str - * @returns {String} municipality name - */ - getMunicipalityName (str) { - return str.replace(/ *\([^)]*\) */g, '') - } - - /** - * Extract the province name from a string following the pattern: - * "municipalityName (provinceName)" - * @param {String} str - * @returns {String} province name - * @returns {null} Returns null if "provinceName" is not found - */ - getProvinceName (str) { - const match = str.match(/\(([^)]+)\)/) - return (match !== null) - ? match[1] - : match - } - - // Return the processed Object array (masterlist) of municipality and province names - get datalist () { - return this.#datalist - } - - /** - * List the municipalities of given province(s) - * @param {String[]} provinces - Array of case-sensitive province names. Starts with an upper case. - * @returns {Object} Returns an object with the format: - * [ - * { province1: ['municipality1', 'municipality2', .... ] }, - * { province2: ['municipality1', 'municipality2', .... ] }, - * ... - * ] - */ - listMunicipalities ({ provinces }) { - if (this.#datalist.length === 0) { - throw new Error('No data to parse.') - } - - if (provinces === undefined) { - throw new Error('Missing the provinces parameter.') - } - - return this.#datalist - .filter(item => provinces.includes(item.province)) - .reduce((acc, item) => { - if (acc[item.province] === undefined) { - acc[item.province] = [] - } - - acc[item.province].push(item.municipality) - - // Sort municipality names alphabetically - if (process.env.SORT_ALPHABETICAL === '1') { - acc[item.province].sort() - } - - return { ...acc } - }, {}) - } - - /** - * Writes queried municipalities data to a JSON file. - * Lists municipalities by by provinces. - * @param {String} provinces - Array of case-sensitive province names. Starts with an upper case. - * @param {String} filName - Full file path to a JSON file - * @param {Bool} prettify - Write the JSON content with proper spacings and newlines - * @returns - */ - writeMunicipalities ({ provinces, fileName, prettify = false }) { - if (!fileName) { - throw new Error('Please enter a filename ending in .json') - } - - try { - // List the municipalities - const municipalities = this.listMunicipalities({ provinces }) - const str = { - metadata: { - source: process.env.EXCEL_FILE_URL || '', - title: 'List of PH Municipalities By Province and Region', - description: 'This dataset generated with reference to the excel file contents from the source URL.', - date_created: new Date().toDateString() - }, - data: municipalities - } - - const json = (prettify) - ? JSON.stringify(str, null, 2) - : JSON.stringify(str) - - // Write results to a JSON file - fs.writeFileSync(fileName, json, 'utf-8') - - return municipalities - } catch (err) { - throw new Error(err.message) - } - } - - get pathToFile () { - return this.#pathToFile - } -} - -module.exports = ExcelFile diff --git a/src/classes/excel/index.js b/src/classes/excel/index.js index 08afb88..19abf96 100644 --- a/src/classes/excel/index.js +++ b/src/classes/excel/index.js @@ -1,5 +1,297 @@ -const ExcelFile = require('./excel') +const https = require('https') +const fs = require('fs') +const EventEmitter = require('events') +const XLSX = require('xlsx') -module.exports = { - ExcelFile +/** + * Load, process and parse an Excel File containing a list of PH municipalities. + * The Excel File should contain a column with string pattern: + * "municipalityName (ProvinceName)" + */ +class ExcelFile { + /** Remote download URL of an excel file */ + #url = null + + /** Full file path to excel file on local storage */ + #pathToFile = null + + /** Excel workbook object parsed by sheetjs */ + #workbook = null + + /** Excel sheet names parsed by sheetjs */ + #sheets = null + + /** Objects[] Array corresponding to excel rows extracted from the excel sheet by sheetjs */ + #data = null + + /** Object[] Array of processed string corresponding to the column in the excel file + * that contains the list of municipalities following the pattern: + * "municipalityName (provinceName)" + * Content: [{ municipality, province }, ... ] + */ + #datalist = [] + + /** Internal excel file column name read by sheetjs. + * This column contains strings following the pattern + * "municipalityName (provinceName)" + */ + #SHEETJS_COL = process.env.SHEETJS_COLUMN || '__EMPTY' + + /** Event emitter for listening to custom events */ + events = new EventEmitter() + + /** List of EventEmitter events */ + EVENTS = { + LOADED: 'loaded' + } + + /** + * Initialize an ExcelFile object + * @param {String} url - Remote download URL of an excel file + * @param {String} pathToFile + * - Full local file path of an existing excel file, if "url" is not provided + * - Full local file path of an excel on where to download the remote excel file from "url", + * if the "url" parameter is provided + */ + constructor ({ url, pathToFile }) { + if (url === '' || pathToFile === '') { + throw new Error('Missing remote file url or local file path.') + } + + if (pathToFile === undefined) { + throw new Error('Missing pathToFile.') + } + + if (!pathToFile.includes('.xlsx')) { + throw new Error('pathToFile should contain an excel file name ending in .xlsx') + } + + // Set the local excel file path + this.#pathToFile = pathToFile + + if (url) { + // Set the remote excel file download URL + this.#url = url + } else { + this.init() + } + } + + /** + * Loads an existing excel file contents to a JSON object. + * Downloads a remote excel file if a remote this.#url is provided on the constructor + */ + async init () { + if (this.#url !== null && this.#pathToFile !== null) { + try { + // Download from remote URL + await this.download() + this.events.emit(this.EVENTS.LOADED) + } catch (errMsg) { + throw new Error(errMsg) + } + } + + if (this.#url === null && this.#pathToFile !== null) { + try { + // Read from file + this.load() + + // Add a slight delay before emmiting the loaded event + setTimeout(() => { + this.events.emit(this.EVENTS.LOADED) + }, 300) + } catch (err) { + throw new Error(err.message) + } + } + } + + /** + * Load an excel file from a local directory using sheetjs. + * Store excel file data as JSON in this.#data + */ + load () { + try { + this.#workbook = XLSX.readFile(this.#pathToFile) + this.#sheets = this.#workbook.SheetNames + + // Set data excel row data as Objects + this.#data = XLSX.utils.sheet_to_json(this.#workbook.Sheets[this.#sheets[0]]) + + // Extract the municipality and province names + this.#datalist = this.#data.reduce((acc, row) => { + if (row[this.#SHEETJS_COL] !== undefined && this.followsStringPattern(row[this.#SHEETJS_COL])) { + const municipality = this.getMunicipalityName(row[this.#SHEETJS_COL]) + const province = this.getProvinceName(row[this.#SHEETJS_COL]) + + if (province !== null) { + acc.push({ + municipality: municipality.trim(), + province + }) + } + } + + return acc + }, []) + + console.log(`Loaded ${this.#data.length} rows`) + + if (this.#datalist.length === 0) { + throw new Error('Failed to load data. Please check the SHEETJS_COLUMN name or the excel file contents.') + } + } catch (err) { + throw new Error(err.message) + } + } + + /** + * Downloads a remote excel file to this.#pathToFile + * and loads sheetjs parsed-content + */ + download () { + try { + const file = fs.createWriteStream(this.#pathToFile) + + return new Promise((resolve, reject) => { + https.get(this.#url, (res) => { + res.pipe(file) + + file.on('finish', () => { + file.close(() => { + try { + resolve(this.load()) + } catch (err) { + reject(err.message) + } + }) + }) + }) + }) + } catch (err) { + throw new Error(err.message) + } + } + + /** + * Checks if a string follows the pattern: + * "municipalityName (provinceName)" + * @param {String} str - String to check + * @returns {Bool} true | false + */ + followsStringPattern (str) { + return /[a-zA-z] *\([^)]*\) */.test(str) + } + + /** + * Extract the municipality name from a string following the pattern: + * "municipalityName (provinceName)" + * @param {String} str + * @returns {String} municipality name + */ + getMunicipalityName (str) { + return str.replace(/ *\([^)]*\) */g, '') + } + + /** + * Extract the province name from a string following the pattern: + * "municipalityName (provinceName)" + * @param {String} str + * @returns {String} province name + * @returns {null} Returns null if "provinceName" is not found + */ + getProvinceName (str) { + const match = str.match(/\(([^)]+)\)/) + return (match !== null) + ? match[1] + : match + } + + // Return the processed Object array (masterlist) of municipality and province names + get datalist () { + return this.#datalist + } + + /** + * List the municipalities of given province(s) + * @param {String[]} provinces - Array of case-sensitive province names. Starts with an upper case. + * @returns {Object} Returns an object with the format: + * [ + * { province1: ['municipality1', 'municipality2', .... ] }, + * { province2: ['municipality1', 'municipality2', .... ] }, + * ... + * ] + */ + listMunicipalities ({ provinces }) { + if (this.#datalist.length === 0) { + throw new Error('No data to parse.') + } + + if (provinces === undefined) { + throw new Error('Missing the provinces parameter.') + } + + return this.#datalist + .filter(item => provinces.includes(item.province)) + .reduce((acc, item) => { + if (acc[item.province] === undefined) { + acc[item.province] = [] + } + + acc[item.province].push(item.municipality) + + // Sort municipality names alphabetically + if (process.env.SORT_ALPHABETICAL === '1') { + acc[item.province].sort() + } + + return { ...acc } + }, {}) + } + + /** + * Writes queried municipalities data to a JSON file. + * Lists municipalities by by provinces. + * @param {String} provinces - Array of case-sensitive province names. Starts with an upper case. + * @param {String} filName - Full file path to a JSON file + * @param {Bool} prettify - Write the JSON content with proper spacings and newlines + * @returns + */ + writeMunicipalities ({ provinces, fileName, prettify = false }) { + if (!fileName) { + throw new Error('Please enter a filename ending in .json') + } + + try { + // List the municipalities + const municipalities = this.listMunicipalities({ provinces }) + const str = { + metadata: { + source: process.env.EXCEL_FILE_URL || '', + title: 'List of PH Municipalities By Province and Region', + description: 'This dataset generated with reference to the excel file contents from the source URL.', + date_created: new Date().toDateString() + }, + data: municipalities + } + + const json = (prettify) + ? JSON.stringify(str, null, 2) + : JSON.stringify(str) + + // Write results to a JSON file + fs.writeFileSync(fileName, json, 'utf-8') + + return municipalities + } catch (err) { + throw new Error(err.message) + } + } + + get pathToFile () { + return this.#pathToFile + } } + +module.exports = ExcelFile diff --git a/src/classes/excelfactory/index.js b/src/classes/excelfactory/index.js new file mode 100644 index 0000000..c8f5ae3 --- /dev/null +++ b/src/classes/excelfactory/index.js @@ -0,0 +1,27 @@ +const path = require('path') +require('dotenv').config({ + // Set the dotenv path when packaging with pkg + path: path.join(__dirname, '..', '..', '..', '.env') +}) + +const ExcelFile = require('../excel') + +class ExcelFactory extends ExcelFile { + constructor (url) { + if (url) { + super({ + pathToFile: path.join(process.cwd(), 'datasource.xlsx'), + url + }) + } else { + super({ + // When pkg encounters path.join(__dirname, '../path/to/asset'), + // it automatically packages the file specified as an asset. + pathToFile: path.join(__dirname, '..', '..', '..', 'data', 'day1.xlsx') + // url: process.env.EXCEL_FILE_URL + }) + } + } +} + +module.exports = ExcelFactory diff --git a/src/lib/excelfactory.js b/src/lib/excelfactory.js deleted file mode 100644 index a176194..0000000 --- a/src/lib/excelfactory.js +++ /dev/null @@ -1,25 +0,0 @@ -const path = require('path') -require('dotenv').config({ - // Set the dotenv path when packaging with pkg - path: path.join(__dirname, '..', '..', '.env') -}) - -const { ExcelFile } = require('../classes/excel') - -const ExcelFactory = (url) => { - if (url) { - return new ExcelFile({ - pathToFile: path.join(process.cwd(), 'datasource.xlsx'), - url - }) - } else { - return new ExcelFile({ - // When pkg encounters path.join(__dirname, '../path/to/asset'), - // it automatically packages the file specified as an asset. - pathToFile: path.join(__dirname, '..', '..', 'data', 'day1.xlsx') - // url: process.env.EXCEL_FILE_URL - }) - } -} - -module.exports = ExcelFactory diff --git a/src/lib/ph_excelfile.js b/src/lib/ph_excelfile.js index 1135441..c6378f2 100644 --- a/src/lib/ph_excelfile.js +++ b/src/lib/ph_excelfile.js @@ -4,7 +4,7 @@ require('dotenv').config({ path: path.join(__dirname, '..', '..', '.env') }) -const { ExcelFile } = require('../classes/excel') +const ExcelFile = require('../classes/excel') const PHExcel = new ExcelFile({ // When pkg encounters path.join(__dirname, '../path/to/asset'), diff --git a/src/lib/datasource_selector.js b/src/lib/selector.js similarity index 90% rename from src/lib/datasource_selector.js rename to src/lib/selector.js index 26d23b6..6d78158 100644 --- a/src/lib/datasource_selector.js +++ b/src/lib/selector.js @@ -1,6 +1,6 @@ const path = require('path') const prompt = require('./prompt') -const ExcelFactory = require('./excelfactory') +const ExcelFactory = require('../classes/excelfactory') /** * Prompts user to download a new excel file or use the static local excel file as data source @@ -23,7 +23,7 @@ const selectDataSource = async () => { console.log(`Downloading file from ${url}...`) try { - ExcelHandler = ExcelFactory(url) + ExcelHandler = new ExcelFactory(url) await ExcelHandler.init() exit = true @@ -34,7 +34,7 @@ const selectDataSource = async () => { exit = true } } else { - ExcelHandler = ExcelFactory() + ExcelHandler = new ExcelFactory() exit = true url = false diff --git a/src/scripts/by_province.js b/src/scripts/by_province.js index 2d31362..92f1e36 100644 --- a/src/scripts/by_province.js +++ b/src/scripts/by_province.js @@ -1,7 +1,7 @@ const path = require('path') const prompt = require('../lib/prompt') const { formatDisplay } = require('../lib/format_display') -const selectDataSource = require('../lib/datasource_selector') +const selectDataSource = require('../lib/selector') // Asks for a prompt to enter province names. // Lists all municipalities under the specified provinces. diff --git a/src/scripts/by_region.js b/src/scripts/by_region.js index d177a70..fdbf347 100644 --- a/src/scripts/by_region.js +++ b/src/scripts/by_region.js @@ -1,7 +1,7 @@ const path = require('path') const prompt = require('../lib/prompt') const { formatDisplay } = require('../lib/format_display') -const selectDataSource = require('../lib/datasource_selector') +const selectDataSource = require('../lib/selector') const regions = require('../../data/regions.json') // Asks for a prompt to enter a region name. diff --git a/src/scripts/sample_usage.js b/src/scripts/sample_usage.js index 5995a74..bf5f2bc 100644 --- a/src/scripts/sample_usage.js +++ b/src/scripts/sample_usage.js @@ -1,6 +1,6 @@ require('dotenv').config() const path = require('path') -const { ExcelFile } = require('../classes/excel') +const ExcelFile = require('../classes/excel') const regions = require('../../data/regions.json') const main = async () => {