diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
new file mode 100644
index 0000000..c1ff0cc
--- /dev/null
+++ b/.github/workflows/deploy-docs.yml
@@ -0,0 +1,55 @@
+name: Build and Deploy Docs
+
+on:
+ push:
+ branches:
+ - dev
+ release:
+ types: [published]
+
+jobs:
+ build-docs:
+ name: Build Class Documentation
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout the repository
+ uses: actions/checkout@v4
+
+ - name: Use NodeJS v16.14.2
+ uses: actions/setup-node@v3
+ with:
+ node-version: 16.14.2
+
+ - name: Install jsdoc and build
+ run: |
+ chmod u+x scripts/docs-build-gh.sh && ./scripts/docs-build-gh.sh
+ cd app && ./docs-install.sh
+ npm run generate-docs
+
+ - name: Archive Development Artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: docs
+ include-hidden-files: true
+ path: app/docs/
+ retention-days: 3
+
+ deploy-docs:
+ name: Deploy docs to Github Pages
+ needs: build-docs
+ runs-on: ubuntu-latest
+ steps:
+ - name: Download Artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: docs
+
+ - name: List files for publish
+ run: ls -l -a
+
+ - name: Deploy to Github Pages
+ uses: peaceiris/actions-gh-pages@v4
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./
+ publish_branch: gh-pages
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a588612..9f0bada 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -1,4 +1,4 @@
-name: Lint Files
+name: Lint and Test
on:
push:
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..10bede4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2024 ciatph
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
index 9551adc..d3c7998 100644
--- a/README.md
+++ b/README.md
@@ -37,10 +37,22 @@ Extracted municipalities are written in JSON files following the format:
Pre-compiled windows binaries are available for download in the latest [Releases](https://github.com/ciatph/ph-municipalities/releases) download page.
+
+## Class Documentation
+
+- Class and methods documentation are available at [https://ciatph.github.io/ph-municipalities](https://ciatph.github.io/ph-municipalities).
+- Class source codes are available at the [ph-municipalities](https://github.com/ciatph/ph-municipalities) GitHub repository.
+- The documentation website's HTML files are available in the [`gh-pages`](https://github.com/ciatph/ph-municipalities/tree/gh-pages) branch of the GitHub repository.
+- Refer to the [Building the Class Documentation](#building-the-class-documentation) section for more information about updating and building the class documentation.
+
+
## Requirements
The following dependencies are used for this project. Feel free to use other dependency versions as needed.
+
+Requirements list
+
1. Windows 10 OS
2. nvm for Windows v1.1.9
3. NodeJS, installed using nvm
@@ -54,26 +66,194 @@ The following dependencies are used for this project. Feel free to use other dep
5. (Optional) Download URL for a remote excel file.
- See the `EXCEL_FILE_URL` variable on the [Installation](#installation) section.
-## Contents
+
+
+
+## FAQs
+
+
+
+What is the purpose or goal of ph-municipalities?
+
+
+
+
+ph-municipalities aims to provide a simple, organized, and flexible interface for viewing, querying, and listing Philippine provinces and municipalities using the [PAGASA 10-day weather forecast Excel files](https://www.pagasa.dost.gov.ph/climate/climate-prediction/10-day-climate-forecast) as the data source.
+
+Its early stages were written as procedural functions within a _private backend project_ for extracting 10-day weather forecast data from the PAGASA 10-day weather forecast Excel files. When the private project started gaining complexity, a need to separate the logic and management for listing the Philippine province and municipalities per region rose. Creating an independent, public OpenSource version listing the provinces and municipalities per region was decided after experiencing drawbacks and difficulties testing using similar OpenSource libraries (some of which are [listed below](#similar-libraries)) for that project.
+
+> **_ph-municipalities aim to contribute to the OpenSource community by listing ONLY Philippine provinces and municipalities' names, using [PAGASA's 10-day weather forecast Excel files](https://www.pagasa.dost.gov.ph/climate/climate-prediction/10-day-climate-forecast), which are publicly accessible to everyone._**
+
+
+
+
+
+
+
+Can ph-municipalities parse and extract PAGASA 10-day weather forecast data?
+
+
+
+
+While ph-municipalities use a [PAGASA 10-day weather forecast Excel file](https://www.pagasa.dost.gov.ph/climate/climate-prediction/10-day-climate-forecast) as a data source for its provinces and municipalities list, **_NO, it cannot parse and extract PAGASA 10-day weather forecast data_**.
+
+ph-municipalities only have class methods for parsing, extracting, listing and querying provinces and municipalities names data from a PAGASA 10-day weather forecast Excel file. Refer to the **ExcelFile** [class documentation](https://ciatph.github.io/ph-municipalities/ExcelFile.html) for more information about its available methods.
+
+
+
+
+
+
+
+Are there alternative libraries to ph-municipalities for listing Philippine provinces and municipalities?
+
+
+
+
+Yes, several OpenSource libraries and projects similar to ph-municipalities exist, which you can use in its place to list Philippine provinces and municipalities.
+
+Here is a list of several of these libraries and code repositories.
+Note, however, that these items use old and new data sources. These may not be for you if you require using provinces and municipalities' names data from the [PAGASA 10-day weather forecast Excel files](https://www.pagasa.dost.gov.ph/climate/climate-prediction/10-day-climate-forecast).
+
+- [psgc2](https://www.npmjs.com/package/psgc2)
+- [use-postal-ph](https://www.npmjs.com/package/use-postal-ph)
+- [philippine-address-selector](https://github.com/wilfredpine/philippine-address-selector)
+- [philippines](https://www.npmjs.com/package/philippines)
+- [ph-locations](https://github.com/hubertursua/ph-locations)
+- [select-philippines-address](https://www.npmjs.com/package/select-philippines-address)
+- [psgc-api](https://github.com/OSSPhilippines/psgc-api)
+- [phl-admin-psgc](https://github.com/benhur07b/phl-admin-psgc)
+
+
+
+
+
+
+
+Is it possible to make ph-municipalities parse and extract PAGASA 10-day weather forecast data?
+
+
+
+
+While ph-municipalites do not support parsing and extracting PAGASA 10-day weather forecast data, _you can extend the `ExcelFile` or `ExcelAdapter` classes with custom logic and codes to enable parsing and extracting PAGASA 10-day weather forecast data_.
+
+Since the `ExcelFile` or `ExcelAdapter` are [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) (functions in disguise, not true OOP, but inheritance still works), you can extend them with class inheritance, overriding or creating new class methods to accommodate processing the PAGASA 10-day weather forecast data. Refer to the [ph-municipalities class documentation](https://ciatph.github.io/ph-municipalities) to know more about the available classes, member variables, and methods.
+
+An example of extending the classes to parse PAGASA 10-day weather forecast data may go along the lines of:
+
+```javascript
+const { ExcelFile } = require('ph-municipalities')
+
+class PAGASATendayParser extends ExcelFile {
+ /* Override constructor if neccessary
+ constructor (params) {
+ super(params)
+
+ // Custom class initialization logic here
+ }
+ */
+
+ getWeatherData () {
+ // Note: this.#data contains the "raw" original Excel rows data as JSON with weather data
+
+ const weatherData = this.#data.reduce((list, row, index) => {
+ // Write logic to parse and extract weather data here
+ }, [])
+
+ return weatherData
+ }
+}
+
+const parser = new PAGASATendayParser()
+weatherForecast = parser.getWeatherData()
+
+```
+
+
+
+
+
+
+
+
+ How does ph-municipalities determine which provinces belong to a region?
+
+
+
+
+
+The PAGASA 10-day Excel files only contain province and municipality names linked with weather data - _it has no region information_. Therefore, ph-municipalities link the province names in the 10-day Excel files to region/province names defined in the `/app/config/regions.json` file to determine which region they belong to.
+
+### The `/app/config/regions.json` file
+
+This file contains region/province names mapping encoded manually with reference from the region and province names listed in the [PAGASA Seasonal Forecast website's](https://www.pagasa.dost.gov.ph/climate/climate-prediction/seasonal-forecast) Forecast Analysis Rainfall table.
+
+> **NOTE:**
+> The region/province mapping defined in this file may become outdated as time passes. ph-municipalities users are encouraged to [Use a Custom Configuration File](#using-a-custom-configuration-file), defining new region/province name mappings following the file's current format if they will notice region to province inconsistencies in the generated municipality lists.
+
+
+
+
+
+
+
+
+ Are the provinces and municipality list generated by ph-municipalities updated?
+
+
+
+
+
+NO. By default, ph-municipalities use an outdated PAGASA 10-day Excel file by default for its local data source, downloaded on August 8, 2022. However, it also provides several ways for using updated PAGASA 10-day Excel files as data sources by:
+
+- Prompting to download an updated PAGASA 10-day Excel file using the [Interactive CLI Scripts](#interactive-cli-scripts)
+- Providing [class methods](https://ciatph.github.io/ph-municipalities/ExcelFile.html#download) to programmatically download and use a remote PAGASA 10-day Excel file
+- Allowing to override the default region - province list settings during class initialization (See [Class Usage - Using a Custom Configuration File](#using-a-custom-configuration-file))
+
+> **NOTE:**
+> Overall, the provinces and municipality list rely on the latest contents of a [PAGASA 10-day Excel file](https://www.pagasa.dost.gov.ph/climate/climate-prediction/10-day-climate-forecast) and manual configuration of region/province names mapping in the `/app/config/regions.json` file (See [Class Usage - Using a Custom Configuration File](#using-a-custom-configuration-file)). It is not yet known and tested if these are in sync with the latest regions, provinces, and municipalities in the more standard and canon [Philippine Standard Geographic Code (PSGC)](https://psa.gov.ph/classification/psgc) data.
+
+
+
+
+
+
+## Table of Contents
+
+
+
+Click to expand the table of contents
+
+
- [ph-municipalities](#ph-municipalities)
+- [Class Documentation](#class-documentation)
- [Requirements](#requirements)
-- [Contents](#contents)
+- [FAQs](#faqs)
+- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Installation Using Docker](#installation-using-docker)
- [Available Scripts](#available-scripts)
- - [`npm start` / `npm run list:region`](#npm-start--npm-run-listregion)
- - [`npm run list:province`](#npm-run-listprovince)
- - [`npm run example`](#npm-run-example)
- - [`build:win:region`](#buildwinregion)
- - [`build:win:province`](#buildwinprovince)
- - [`build:win:all`](#buildwinall)
- - [`npm run minify:region`](#npm-run-minifyregion)
- - [`npm run minify:province`](#npm-run-minifyprovince)
- - [`npm run minify:all`](#npm-run-minifyall)
- - [`npm run lint`](#npm-run-lint)
- - [`npm run lint:fix`](#npm-run-lintfix)
- - [`npm test`](#npm-test)
+ - [Interactive CLI Scripts](#interactive-cli-scripts)
+ - `npm start` / `npm run list:region`
+ - `npm run list:province`
+ - [NPM Scripts for Building Windows Executable Files of the Interactive CLI Scripts](#npm-scripts-for-building-windows-executable-files-of-the-interactive-cli-scripts)
+ - `npm run build:win:region`
+ - `npm run build:win:province`
+ - `npm run build:win:all`
+ - `npm run minify:region`
+ - [NPM Scripts for Compiling the Interactive CLI Scripts into Stand-Alone Scripts](#npm-scripts-for-compiling-the-interactive-cli-scripts-into-stand-alone-scripts)
+ - `npm run minify:province`
+ - `npm run minify:all`
+ - [NPM Scripts for Building Documentation](#npm-scripts-for-building-documentation)
+ - `npm run generate-docs`
+ - `npm run docs:install`
+ - `npm run docs:build`
+ - [NPM Scripts for Linting Files and Unit Testing](#npm-scripts-for-linting-files-and-unit-testing)
+ - `npm run lint`
+ - `npm run lint:fix`
+ - `npm test`
+ - `npm run example`
- [Class Usage](#class-usage)
- [Load and Parse a Local Excel File](#load-and-parse-a-local-excel-file)
- [Download and Parse a Remote Excel File](#download-and-parse-a-remote-excel-file)
@@ -81,8 +261,14 @@ The following dependencies are used for this project. Feel free to use other dep
- [Using a Custom Configuration File](#using-a-custom-configuration-file)
- [Building Standalone Windows Executables](#building-standalone-windows-executables)
- [Compiling into Single, Minified Files](#compiling-into-single-minified-files)
+- [Building the Class Documentation](#building-the-class-documentation)
+ - [Using Docker](#using-docker)
+ - [Using NodeJS](#using-nodejs)
- [Troubleshooting](#troubleshooting)
+
+
+
## Installation
1. Clone this repository.
@@ -96,6 +282,9 @@ The following dependencies are used for this project. Feel free to use other dep
3. Create a `.env` file from the `.env.example` file inside the `/app` directory. Use the default values for the following environment variables.
+
+ List of .env variables and their description.
+
> **INFO:** If installed as an NPM package with `npm i ph-municipalities`, create the `.env` file inside the NPM project's root directory.
| Variable Name | Description |
@@ -106,13 +295,19 @@ The following dependencies are used for this project. Feel free to use other dep
| SPECIAL_CHARACTERS | Key-value pairs of special characters or garbled text and their normalized text conversions, delimited by the `":"` character.
Multiple key-value pairs are delimited by the `","` character.
If a special character key's value is a an empty string, write it as i.e.,: `"some-garbled-text:"` |
| IMAGE_URL | Raw URL of the README image file from this GitHub repository.
**NOTE:** Only add this variable in the GitHub Secrets for publishing to the NPM registry since NPM does not allow displaying images by relative path.
|
+
+
+
## Installation Using Docker
We can use Docker to run dockerized Node app for local development mode. The following methods require Docker and Docker compose correctly installed and set up on your development machine.
### Docker Dependencies
+
+
The following dependencies are used to build and run the image. Please feel feel free to use other OS and versions as needed.
+
1. Ubuntu 22.04.1
- Docker version 23.0.1, build a5eeb1
@@ -123,8 +318,14 @@ The following dependencies are used to build and run the image. Please feel feel
- Docker Compose version v2.27.1-desktop.1
- Docker Engine version 26.1.4, build 5650f9b
+
+
+
### Docker for Localhost Development
+
+Steps for using Docker with local development
+
1. Set up the environment variables for the `/app` directory. Visit the [Installation](#installation) section, **step #3** for more information.
2. Stop and delete all docker instances for a fresh start.
@@ -149,6 +350,9 @@ The following dependencies are used to build and run the image. Please feel feel
- For new scripts (example only):
`docker exec -it ph-municipalities node ./src/new.js`
+
+
+
## Available Scripts
> _**Note:** These NPM scripts run relative within the `/app` directory, when working on a git-cloned repository of the app. To run using only NodeJS, navigate first to the `/app` directory and execute a target script, for example:_
@@ -158,6 +362,11 @@ cd app
npm run list:region
```
+
+
+ Interactive CLI Scripts
+
+
### `npm start` / `npm run list:region`
- Asks users to enter the download URL of a remote excel file or use the default local excel file
@@ -179,30 +388,39 @@ npm run list:region
- Run the script as follows if installed using `npm i ph-municipalities`:
- `node .\node_modules\ph-municipalities\src\scripts\by_province.js`
-### `npm run example`
-
-- Downloads and parses a remote excel file.
-- Demonstrates sample usage with `await`
+
---
-### `build:win:region`
+
+
+ NPM Scripts for Building Windows Executable Files of the Interactive CLI Scripts
+
+
+### `npm run build:win:region`
- Package the Node.js project's `npm start` script into a stand-alone windows `node16-win-x64` executable.
- The windows executable file will be stored in `/dist/ph-regions-win.exe`. Click the executable file to run.
-### `build:win:province`
+### `npm run build:win:province`
- Package the Node.js project's `npm list:province` script into a stand-alone windows `node16-win-x64` executable.
- The windows executable file will be stored in `/dist/ph-provinces-win.exe`. Click the executable file to run.
-### `build:win:all`
+### `npm run build:win:all`
- Package the Node.js project's `npm start` and `npm list:province` script into a stand-alone windows `node16-win-x64` executables in one go.
- Each window executable file will be stored in the `/dist` directory.
+
+
---
+
+
+ NPM Scripts for Compiling the Interactive CLI Scripts into Stand-Alone Scripts
+
+
### `npm run minify:region`
- Compiles the Node.js project's `npm list:region` script and dependencies into a single script using [**ncc**](https://www.npmjs.com/package/@vercel/ncc).
@@ -220,8 +438,65 @@ npm run list:region
- Run the `npm list:region` and `npm list:province` scripts in one go.
- Each compiled/minified files will be stored in the `/dist` directory.
+
+
+
---
+
+
+ NPM Scripts for Building Documentation
+
+
+### `npm run generate-docs`
+
+Builds the class documentation into the **/docs** directory.
+
+> [!NOTE]
+> This script requires manual installation of the `jsdoc@4.0.3`, `minami@1.2.3`, and `taffydb@2.7.3` packages as **devDependencies** inside the **/app** directory.
+> These libraries, only used for building the class documentation, were excluded from the final package.json to have fewer external dependencies.
+> ```bash
+> npm install --save-dev jsdoc@4.0.3 minami@1.2.3 taffydb@2.7.3
+> ```
+> Installing these libraries will update the `package.json` and `package-lock.json` files. Take care not to push changes caused by installation.
+
+### `npm run docs:install`
+
+Runs the Bash script that installs the JSDoc and theme dependencies for building the class documentation only within the **development Docker environment**.
+
+> [!NOTE]
+> This script requires running from a Bash terminal - it won't work from a Windows command line terminal. It is reserved for building the documentation with Docker.
+
+This script is used for building the class documentation from a local Docker environment along with the `npm run docs:build` NPM script.
+
+```bash
+docker exec -u root -it ph-municipalities npm run docs:install
+docker exec -u root -it ph-municipalities npm run docs:build
+```
+
+### `npm run docs:build`
+
+Runs the Bash script that builds the class documentation using JSDoc only within the **development Docker environment**.
+
+> [!NOTE]
+> This script requires running from a Bash terminal - it won't work from a Windows command line terminal. It is reserved for building the documentation with Docker.
+
+This script is used for building the class documentation from a local Docker environment along with the `npm run docs:install` NPM script.
+
+```bash
+docker exec -u root -it ph-municipalities npm run docs:install
+docker exec -u root -it ph-municipalities npm run docs:build
+```
+
+
+
+---
+
+
+
+ NPM Scripts for Linting Files and Unit Testing
+
+
### `npm run lint`
Lint JavaScript source codes.
@@ -234,6 +509,16 @@ Fix JavaScript lint errors.
Run tests defined in the `/app/__tests__` directory.
+### `npm run example`
+
+- Downloads and parses a remote excel file.
+- Demonstrates sample usage with `await`
+
+
+
+
+
+
## Class Usage
Below are example usages of the `ExcelFile` class, run from the **/app/src/examples** directory. Check out the `/app/src/examples/sample_usage.js` file for more examples.
@@ -242,7 +527,9 @@ Below are example usages of the `ExcelFile` class, run from the **/app/src/examp
This is a simple usage example of the `ExcelFile` class.
-**Simple Usage**
+
+Simple Usage
+
```javascript
const path = require('path')
const ExcelFile = require('../classes/excel')
@@ -286,7 +573,13 @@ file.datalist = [
{ municipality: 'Bucay', province: 'Abra' }]
```
-**Reading regions, provinces and municipalities**
+
+
+
+
+Reading regions, provinces and municipalities
+
+
```javascript
const path = require('path')
const ExcelFile = require('../classes/excel')
@@ -317,10 +610,18 @@ const municipalitiesFromProvince = file.listMunicipalities({ provinces })
console.log(`---municipalities`, municipalitiesFromProvince)
```
+
+
+
### Download and Parse a Remote Excel File
Adding a `url` field in the constructor parameter prepares the class to download a remote Excel file for the data source.
+
+
+Remote Excel file download example
+
+
> **INFO:** Run the `.init()` method after initializing a class with a `url` parameter to start the async file download.
```javascript
@@ -350,9 +651,15 @@ const main = async () => {
main()
```
+
+
+
### Alternate Usage - Events
-Initialize an `ExcelFile` class instance.
+
+
+Initialize an ExcelFile class instance
+
```javascript
require('dotenv').config()
@@ -386,6 +693,9 @@ const main = () => {
main()
```
+
+
+
### Using a Custom Configuration File
The **ph-municipalities** `ExcelFile` and `ExcelFactory` classes use a default configuration file to define their regions and provinces in the `/app/config/regions.json` file. The regions and provinces data in this file syncs with the PAGASA Seasonal and 10-Day Weather Forecast Excel files provinces and municipalities naming convention, encoded by hand as of August 24, 2024.
@@ -394,7 +704,11 @@ Follow the codes to define a custom regions config file, following the format of
> _**Note:** The custom config file's province/municipality names should match those in the 10-day Excel file._
-**config.json**
+
+
+config.json
+
+
```
{
"metadata": {
@@ -425,7 +739,13 @@ Follow the codes to define a custom regions config file, following the format of
}
```
-**Custom config usage**
+
+
+
+
+Custom config usage
+
+
```javascript
require('dotenv').config()
const path = require('path')
@@ -458,9 +778,15 @@ console.log('\nProvince/municipality names should match with those in the 10-day
console.log('---municipalities', municipalities)
```
+
+
+
## Building Standalone Windows Executables
-The main npm scripts can be packaged into standalone windows executables. Pre-compiled windows binaries are available for download in the latest [Releases](https://github.com/ciatph/ph-municipalities/releases) download page.
+
+
+The main npm scripts can be packaged into standalone windows executables. Pre-compiled windows binaries are available for download in the latest Releases download page.
+
1. Run any of the following scripts to build the programs.
```bash
@@ -470,9 +796,15 @@ The main npm scripts can be packaged into standalone windows executables. Pre-co
```
2. Click the resulting executable files in the `/dist` directory to execute.
+
+
+
## Compiling into Single, Minified Files
+
+
The main npm scripts can be compiled into standalone JavaScript files together with all its dependencies.
+
1. Run any of the following scripts to compile the source codes.
```bash
@@ -486,11 +818,71 @@ The main npm scripts can be compiled into standalone JavaScript files together w
node dist/province
```
+
+
+
+## Building the Class Documentation
+
+The class documentation uses [JSDoc](https://jsdoc.app/) annotations where applicable in the JavaScript source codes inside the **/src** directory. There are two (2) options for building the class documentation.
+
+
+
+ Using Docker
+
+
+1. Run docker for localhost development. Refer to the [Docker for Localhost Development](#docker-for-localhost-development) section for more information.
+
+2. Install the dependencies for JSDoc. Suceeding builds will not need to install dependencies after an initial installation. Refer to the [**npm run docs:install**](#npm-run-docsinstall) script usage for more information.
+ ```bash
+ docker exec -u root -it ph-municipalities npm run docs:install
+ ```
+
+3. Build the documentation. Refer to the [**npm run docs:build**](#npm-run-docsbuild) script usage for more information.
+ ```bash
+ docker exec -u root -it ph-municipalities npm run docs:build
+ ```
+
+
+
+
+
+
+
+ Using NodeJS
+
+
+1. Install the dependencies for JSDoc. Refer to the [**`npm run generate-docs`**](#npm-run-generate-docs) Script usage for more information.
+2. Copy Bash scripts to the **/app** directory.
+ - Create a **/scripts** directory inside the **/app** directory.
+ - Copy the `/scripts/docs-install.sh` and `/scripts/docs-build.sh` Bash scripts to the **/scripts** directory created from the previous step.
+3. Copy static assets to the **/app** directory.
+ - Copy the `/docs/diagrams` directory inside the **/app** directory.
+ - Copy the `README.md` file to the **/app** directory.
+4. Add appropriate user permission to the files.
+ ```bash
+ chmod u+x scripts/docs-install.sh
+ chmod u+x scripts/docs-build.sh
+ ```
+5. Run the commands for building the documentation.
+
+ > **INFO:** Use a GitBash terminal if you are working on a Windows OS machine.
+
+ ```bash
+ ./scripts/docs-install.sh
+ ./scripts/docs-build.sh
+ ```
+
+
+
+
## Troubleshooting
This section describes several common errors and related fixes.
-### EACCESS: permission denied
+
+
+ EACCESS: permission denied
+
#### Information
@@ -506,7 +898,9 @@ This section describes several common errors and related fixes.
`sudo chown -R : ./app`
3. Re-run the NPM script.
+
+
@ciatph
20220807
\ No newline at end of file
diff --git a/app/.eslintignore b/app/.eslintignore
index f739bcc..1398766 100644
--- a/app/.eslintignore
+++ b/app/.eslintignore
@@ -6,7 +6,9 @@ node_modules/
*.zip
*.tgz
dist/
+docs/
# Ignore all JSON files except:
!package.json
!package-lock.json
+!.jsdoc.json
diff --git a/app/.gitignore b/app/.gitignore
index f739bcc..87691a7 100644
--- a/app/.gitignore
+++ b/app/.gitignore
@@ -1,12 +1,20 @@
node_modules/
+dist/
+docs/
+diagrams/
+README.md
+README.tmp
.env
.vscode
*.xlsx
*.json
*.zip
*.tgz
-dist/
+*.png
+*.sh
# Ignore all JSON files except:
!package.json
!package-lock.json
+!.jsdoc.json
+!.jsdoc_full.json
diff --git a/app/.jsdoc.json b/app/.jsdoc.json
new file mode 100644
index 0000000..d79859a
--- /dev/null
+++ b/app/.jsdoc.json
@@ -0,0 +1,27 @@
+{
+ "tags": {
+ "allowUnknownTags": true,
+ "dictionaries": ["jsdoc"]
+ },
+ "source": {
+ "include": ["src", "README.md"],
+ "includePattern": ".js$",
+ "excludePattern": "(node_modules/|docs)"
+ },
+ "plugins": [
+ "plugins/markdown"
+ ],
+ "templates": {
+ "cleverLinks": false,
+ "monospaceLinks": true,
+ "useLongnameInNav": false,
+ "showInheritedInNav": true
+ },
+ "opts": {
+ "destination": "./docs/",
+ "encoding": "utf8",
+ "private": true,
+ "recurse": true,
+ "template": "./node_modules/minami"
+ }
+}
diff --git a/app/.jsdoc_full.json b/app/.jsdoc_full.json
new file mode 100644
index 0000000..d79859a
--- /dev/null
+++ b/app/.jsdoc_full.json
@@ -0,0 +1,27 @@
+{
+ "tags": {
+ "allowUnknownTags": true,
+ "dictionaries": ["jsdoc"]
+ },
+ "source": {
+ "include": ["src", "README.md"],
+ "includePattern": ".js$",
+ "excludePattern": "(node_modules/|docs)"
+ },
+ "plugins": [
+ "plugins/markdown"
+ ],
+ "templates": {
+ "cleverLinks": false,
+ "monospaceLinks": true,
+ "useLongnameInNav": false,
+ "showInheritedInNav": true
+ },
+ "opts": {
+ "destination": "./docs/",
+ "encoding": "utf8",
+ "private": true,
+ "recurse": true,
+ "template": "./node_modules/minami"
+ }
+}
diff --git a/app/.npmignore b/app/.npmignore
index 0c204e6..00ab32d 100644
--- a/app/.npmignore
+++ b/app/.npmignore
@@ -6,8 +6,11 @@ dist/
*.xlsx
*.json
*.zip
+*.tgz
*.txt
*.tgz
+*.png
+*.sh
.env.example
.eslintrc.js
@@ -15,6 +18,8 @@ dist/
.gitignore
.npmignore
.eslintignore
+README.md
+README.tmp
# Ignore all JSON files except:
!package.json
@@ -26,6 +31,8 @@ dist/
# Exclude directories
src/examples/
+docs/
+diagrams/
# Docker
Dockerfile
diff --git a/app/__tests__/classInitialization/checkClass.js b/app/__tests__/classInitialization/checkClass.js
index d289501..efad34b 100644
--- a/app/__tests__/classInitialization/checkClass.js
+++ b/app/__tests__/classInitialization/checkClass.js
@@ -4,7 +4,7 @@
* Checks valid `ExcelFile` or `ExcelFactory` class instances.
* @typedef {Object} params - Input parameters
* @param {Function} excelInstance - `ExcelFile` or `ExcelFactory` class instance
- * @param {Bool} isRemote - Flag if the Excel data source is from a remote download. Defaults to `false`.
+ * @param {boolean} isRemote - Flag if the Excel data source is from a remote download. Defaults to `false`.
* @param {Function} classType - `ExcelFile` or `ExcelFactory` class
*/
const checkClass = ({ excelInstance, isRemote = false, classType = null }) => {
diff --git a/app/__tests__/municipalities/createMunicipalityInstance.js b/app/__tests__/municipalities/createMunicipalityInstance.js
index 6b79a32..ec11476 100644
--- a/app/__tests__/municipalities/createMunicipalityInstance.js
+++ b/app/__tests__/municipalities/createMunicipalityInstance.js
@@ -7,8 +7,8 @@ const logger = new ColorLog({ color: ColorLog.COLORS.TEXT.YELLOW, isBold: true }
* Builds objects containing all provinces AND municipality names for the PAGASA seasonal config and 10-Day Excel file to use for comparison checks and logs viewing purposes only.
* @param {Class} excelFile - `ExcelFile` or `ExcelFactory` instance
* @returns {Object} Object containing Arrays and Sets of province and municipality names
- * - `hasMissingInExcel` {Bool} - Flag if province(s) exist in the PAGASA seasonal config but not in the 10-day Excel
- * - `hasMissingInConfig` {Bool} - Flag if municipalities exist in 10-day Excel but not in the municipalities list built from the PAGASA seasonal config
+ * - `hasMissingInExcel` {boolean} - Flag if province(s) exist in the PAGASA seasonal config but not in the 10-day Excel
+ * - `hasMissingInConfig` {boolean} - Flag if municipalities exist in 10-day Excel but not in the municipalities list built from the PAGASA seasonal config
* - `excel` {Object} - Contains full province/municipality names and data from the 10-day Excel file
* - `excel.provinces` {String[]} - all provinces from the 10-day Excel file
* - `excel.municipalities` {Object} - Object with province names as keys and values are String[] array of municipalities under the province
diff --git a/app/package-lock.json b/app/package-lock.json
index 3253d26..f330304 100644
--- a/app/package-lock.json
+++ b/app/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ph-municipalities",
- "version": "1.3.7",
+ "version": "1.4.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ph-municipalities",
- "version": "1.3.7",
+ "version": "1.4.0",
"license": "ISC",
"dependencies": {
"dotenv": "^16.0.1",
diff --git a/app/package.json b/app/package.json
index 76ff49e..60141dd 100644
--- a/app/package.json
+++ b/app/package.json
@@ -1,6 +1,6 @@
{
"name": "ph-municipalities",
- "version": "1.3.7",
+ "version": "1.4.0",
"description": "List and write the `municipalities` of Philippines provinces or regions into JSON files",
"main": "index.js",
"engines": {
@@ -18,6 +18,9 @@
"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:all": "npm run minify:region && npm run minify:province",
+ "docs:install": "./scripts/docs-install.sh",
+ "docs:build": "./scripts/docs-build.sh",
+ "generate-docs": "jsdoc --configure .jsdoc.json --verbose",
"lint": "eslint src __tests__ .",
"lint:fix": "eslint src __tests__ . --fix",
"test": "jest"
diff --git a/app/src/classes/colorlog/index.js b/app/src/classes/colorlog/index.js
index f6efb7c..e2a09de 100644
--- a/app/src/classes/colorlog/index.js
+++ b/app/src/classes/colorlog/index.js
@@ -1,13 +1,34 @@
/**
* Prints colored console.log messages
- * @class
*/
class ColorLog {
+ /**
+ * Text styles for logging.
+ * @static
+ * @type {Object.}
+ * @property {string} BOLD - Bold text style.
+ * @property {string} NORMAL - Normal text style.
+ */
static TEXT = {
BOLD: '\x1b[1m',
NORMAL: '\x1b[0m'
}
+ /**
+ * ANSI colors for coloring the logging text.
+ * @static
+ * @type {Object.}
+ * @property {Object} TEXT - Object containing color properties.
+ * @property {string} TEXT.WHITE - White color.
+ * @property {string} TEXT.GRAY - Gray color.
+ * @property {string} TEXT.GREEN - Green color.
+ * @property {string} TEXT.RED - Red color.
+ * @property {string} TEXT.YELLOW - Yellow color.
+ * @property {string} TEXT.BLUE - Blue color.
+ * @property {string} TEXT.CYAN - Cyan color.
+ * @property {string} TEXT.RESET - Reset color.
+ * @property {string} TEXT.MAGENTA - Magenta color.
+ */
static COLORS = {
TEXT: {
WHITE: '\x1b[37m',
@@ -22,20 +43,29 @@ class ColorLog {
}
}
- /** Message log */
+ /**
+ * Message log text.
+ * @type {string | null}
+ */
#log = null
- /** Text color */
+ /**
+ * Text color
+ * @type {string}
+ */
#color = ColorLog.COLORS.TEXT.GREEN
- /** Text weight (bold, normal) */
+ /**
+ * Text weight (bold, normal)
+ * @type {string}
+ */
#weight = false
/**
* Initializes a ColorLog class
- * @typedef {Object} params - Input parameters
- * @param {String} params.color - ANSI color defined in `ColorLog.COLORS`
- * @param {Bool} params.isBold - Flag to render bold colored text
+ * @param {Object} params - Input parameters
+ * @param {string} params.color - ANSI color defined in `ColorLog.COLORS`
+ * @param {boolean} params.isBold - Flag to render bold colored text
*/
constructor ({ color, isBold = false } = {}) {
this.setColor(color)
@@ -44,11 +74,11 @@ class ColorLog {
/**
* Prints colored log message in console.log()
- * @param {String} message - Log message text
+ * @param {string} message - Log message text
* @param {Object} options - (Optional)
- * @param {String} options.color - ANSI color defined in `ColorLog.COLORS`
- * @param {Bool} options.isBold - Flag to render bold colored text
- * @returns
+ * @param {string} options.color - ANSI color defined in `ColorLog.COLORS`
+ * @param {boolean} options.isBold - Flag to render bold colored text
+ * @returns {boolean}
*/
log (message, options = {}) {
if (!message || typeof message !== 'string') return
@@ -63,8 +93,8 @@ class ColorLog {
/**
* Sets the text color in console.log()
- * @param {String} color - ANSI color defined in `ColorLog.COLORS`
- * @returns
+ * @param {string} color - ANSI color defined in `ColorLog.COLORS`
+ * @returns {boolean}
*/
setColor (color) {
if (!color) return
@@ -78,8 +108,8 @@ class ColorLog {
/**
* Sets the text weight in console.log
- * @param {Bool} isBold - Flag to render bold colored text
- * @returns
+ * @param {boolean} isBold - Flag to render bold colored text
+ * @returns {boolean}
*/
setText (isBold) {
if (![true, false].includes(isBold)) return
diff --git a/app/src/classes/excel/index.js b/app/src/classes/excel/index.js
index 0ff5c57..502770b 100644
--- a/app/src/classes/excel/index.js
+++ b/app/src/classes/excel/index.js
@@ -17,70 +17,107 @@ const { capitalizeText } = require('../../lib/utils')
* "municipalityName (ProvinceName)"
*/
class ExcelFile {
- /** Remote download URL of an excel file */
+ /**
+ * Remote download URL of an excel file
+ * @type {string | null}
+ */
#url = null
- /** Full file path to excel file on local storage */
+ /**
+ * Full file path to excel file on local storage
+ * @type {string | null}
+ */
#pathToFile = null
- /** Region information from the /app/config/regions.json or other config file */
+ /**
+ * Region information from the `/app/config/regions.json` or other JSON config file.
+ * @type {Object | null}
+ */
#settings = null
- /** 10-day Excel file information */
+ /**
+ * 10-day Excel file information
+ * @type {Object.}
+ */
#metadata = {
- // Weather forecast date
+ /**
+ * Weather forecast date
+ * @type {string | null}
+ */
forecastDate: null
}
- /** Other app settings and configurations */
+ /**
+ * Other class settings and configurations
+ * @type {Object.}
+ */
#options = {
/**
* SheetJS array index number translated from the Excel headers row count
* before elements containing "municipalityName (provinceName)" data
+ * @type {number}
*/
dataRowStart: 0,
/** Internal excel file column name read by sheetjs.
* This column contains strings following the pattern
* "municipalityName (provinceName)"
+ * @type {string}
*/
SHEETJS_COL: process.env.SHEETJS_COLUMN || '__EMPTY'
}
- /** Excel workbook object parsed by sheetjs */
+ /**
+ * Excel workbook object parsed by sheetjs
+ * @type {Object[] | null}
+ */
#workbook = null
- /** Excel sheet names parsed by sheetjs */
+ /**
+ * Excel sheet names parsed by sheetjs.
+ * @type {string[] | null}
+ */
#sheets = null
- /** Objects[] Array corresponding to excel rows extracted from the excel sheet by sheetjs */
+ /**
+ * Objects[] Array corresponding to excel rows extracted from the excel sheet by sheetjs.
+ * @type {Object[] | null}
+ */
#data = null
- /** Object[] Array of processed string corresponding to the column in the excel file
- * that contains the list of municipalities following the pattern:
+ /**
+ * 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 }, ... ]
+ * @type {Object[] | null}
*/
#datalist = []
- /** Event emitter for listening to custom events */
+ /**
+ * Node event emitter for listening to custom events.
+ * @type {Function}
+ */
events = new EventEmitter()
- /** List of EventEmitter events */
+ /**
+ * List of EventEmitter events.
+ * @type {Object.}
+ */
EVENTS = {
LOADED: 'loaded'
}
/**
* Initialize an ExcelFile object
- * @typedef {Object} params - Constructor parameter Object
- * @param {String} [params.url] - (Optional) Remote download URL of an excel file
- * @param {String} params.pathToFile
+ * @param {Object} params - Constructor parameter Object
+ * @param {string} [params.url] - (Optional) Remote download URL of an excel file
+ * @param {string} params.pathToFile
* - Full local file path of an existing Excel file, **required** if `params.url` is not provided
* - Full local file path to an existing or non-existent Excel file on which to download/save the remote Excel file from `params.url`,
* if the `params.url` parameter is provided
* @param {Object} [params.settings] - (Optional) Region settings configuration object following the format of the `/app/config/regions.json` file. Defaults to the mentioned file if not provided.
- * @param {Bool} [params.fastload] - (Optional) Start loading and parsing the local excel file on class initialization if the "url" param is not provided.
+ * @param {boolean} [params.fastload] - (Optional) Start loading and parsing the local excel file on class initialization if the "url" param is not provided.
* - If `false` or not provided, call the `.init()` method later on a more convenient time.
*/
constructor ({ url, pathToFile, fastload = true, settings = null, options = null } = {}) {
@@ -233,8 +270,8 @@ class ExcelFile {
/**
* Checks if a string follows the pattern:
* "municipalityName (provinceName)"
- * @param {String} str - String to check
- * @returns {Bool} true | false
+ * @param {string} str - String to check
+ * @returns {boolean} true | false
*/
followsStringPattern (str) {
return /[a-zA-Z,.] *\([^)]*\) *$/.test(str)
@@ -243,7 +280,7 @@ class ExcelFile {
/**
* Sets the local this.#options settings
* @param {Object} options - Miscellaneous app settings defined in this.#options
- * @returns
+ * @returns {boolean}
*/
setOptions (options) {
if (!options) return false
@@ -257,8 +294,8 @@ class ExcelFile {
/**
* Checks if a string contains special characters
- * @param {String} str - String to check
- * @returns {Bool}
+ * @param {string} str - String to check
+ * @returns {boolean}
*/
static hasSpecialChars (str) {
/* eslint-disable no-control-regex */
@@ -268,8 +305,8 @@ class ExcelFile {
/**
* Cleans/removes default-known special characters and garbled text defined in config from string.
- * @param {String} str - String to clean
- * @returns {String} - Clean string
+ * @param {string} str - String to clean
+ * @returns {string} - Clean string
*/
static removeGarbledText (str) {
// Known garbled special text
@@ -304,8 +341,8 @@ class ExcelFile {
/**
* Extracts the municipality name from a string following the pattern:
* "municipalityName (provinceName)"
- * @param {String} str
- * @returns {String} municipality name
+ * @param {string} str
+ * @returns {string} municipality name
*/
getMunicipalityName (str) {
const municipalityName = str.replace(/ *\([^)]*\) */g, '')
@@ -320,8 +357,8 @@ class ExcelFile {
/**
* Extracts the province name from a string following the pattern:
* "municipalityName (provinceName)"
- * @param {String} str
- * @returns {String} province name
+ * @param {string} str
+ * @returns {string} province name
* @returns {null} Returns null if "provinceName" is not found
*/
getProvinceName (str) {
@@ -436,8 +473,8 @@ class ExcelFile {
* 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} fielName - Full file path to a JSON file
- * @param {Bool} prettify - Write the JSON content with proper spacings and newlines
+ * @param {string} fielName - Full file path to a JSON file
+ * @param {boolean} prettify - Write the JSON content with proper spacings and newlines
* @returns {Object} Formatted raw data with misc. metadata
*/
writeMunicipalities ({ provinces, fileName, prettify = false }) {
@@ -466,7 +503,7 @@ class ExcelFile {
/**
* Lists the province names of a region defined in the settings file
- * @param {String} regionName - Region name that matches with the `/app/config/regions.json` file's `data[N].name`
+ * @param {string} regionName - Region name that matches with the `/app/config/regions.json` file's `data[N].name`
* @returns {String[]} List provinces under the `regionName`.
*/
listProvinces (regionName) {
@@ -476,8 +513,8 @@ class ExcelFile {
/**
* Lists the province names of a region defined in the settings (PAGASA seasonal config) file or from the parsed Excel file
- * @param {String} region - Region name that matches with the `/app/config/regions.json` file's `data[N].name`
- * @param {Bool} fromExcel - Flag to return the province names from the parsed 10-day Excel file. Defaults to `false`.
+ * @param {string} region - Region name that matches with the `/app/config/regions.json` file's `data[N].name`
+ * @param {boolean} fromExcel - Flag to return the province names from the parsed 10-day Excel file. Defaults to `false`.
* - Note: Province names from a "remote" Excel file may change without notice.
* - It may differ from the contents of the "default" settings (PAGASA seasonal config) file.
* - If the province names from the "remote" Excel file and "default" settings (PAGASA seasonal config) file vary,
diff --git a/app/src/classes/excelfactory/index.js b/app/src/classes/excelfactory/index.js
index 749dae6..f4307fe 100644
--- a/app/src/classes/excelfactory/index.js
+++ b/app/src/classes/excelfactory/index.js
@@ -16,8 +16,8 @@ const ExcelFile = require('../excel')
class ExcelFactory extends ExcelFile {
/**
* Initializes an `ExcelFactory` class.
- * @typedef {Object} params - Constructor parameter Object
- * @param {String} [params.url] - (Optional) Remote download URL of an excel file
+ * @param {Object} params - Constructor parameter Object
+ * @param {string} [params.url] - (Optional) Remote download URL of an excel file
* @param {Object} [params.settings] - (Optional) Region settings configuration object following the format of the `/app/config/regions.json` file. Defaults to the mentioned file if not provided.
*/
constructor ({ url, settings } = {}) {
diff --git a/app/src/classes/schema/index.js b/app/src/classes/schema/index.js
index d77063a..2603450 100644
--- a/app/src/classes/schema/index.js
+++ b/app/src/classes/schema/index.js
@@ -1,8 +1,11 @@
/**
- * Validates Objects with zod schemas and formats validation error(s) for log output.
+ * Validates Objects with [zod](https://github.com/colinhacks/zod) schemas and formats validation error(s) for log output.
*/
class Schema {
- /** Settings object */
+ /**
+ * Settings object.
+ * @type {Object | null}
+ */
#data = null
/**
@@ -44,7 +47,7 @@ class Schema {
/**
* Formats error messages into a single string
* @param {Object[]} errors - List of zod error messages
- * @returns
+ * @returns {boolean}
*/
formatErrorLog (errors = []) {
if (!Array.isArray(errors)) {
diff --git a/app/src/lib/utils.js b/app/src/lib/utils.js
index cf2a6bb..12ce251 100644
--- a/app/src/lib/utils.js
+++ b/app/src/lib/utils.js
@@ -1,7 +1,7 @@
/**
* Checks if a variable is a true JavaScript Object
* @param {Object} item - JavaScript Object
- * @returns {Bool} true|false
+ * @returns {boolean} true|false
*/
const isObject = (item) => {
return item &&
@@ -12,14 +12,14 @@ const isObject = (item) => {
/**
* Converts an Array of strings (text) into a single comma-separated string
* @param {String[]} arrayOfText - Array containing String items
- * @returns {String} Comma-separated text
+ * @returns {string} Comma-separated text
*/
const arrayToString = (arrayOfText) => arrayOfText.toString().split(',').join(', ')
/**
* Capitalizes the first letter of words in a text
- * @param {String} text - String text
- * @returns {String} Capitalized text
+ * @param {string} text - String text
+ * @returns {string} Capitalized text
*/
const capitalizeText = (text) => {
if (typeof text !== 'string') return null
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index 60dc99e..7385d05 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -12,6 +12,9 @@ services:
- ph-municipalities
volumes:
- ./app:/opt/app
+ - ./scripts:/opt/app/scripts
+ - ./docs/diagrams:/opt/app/diagrams
+ - ./README.md:/opt/app/README.tmp
- /opt/app/node_modules
stdin_open: true
tty: true
diff --git a/docs/diagrams/ph-municipalities-arch-90.png b/docs/diagrams/ph-municipalities-arch-90.png
index cbf3653..86704e4 100644
Binary files a/docs/diagrams/ph-municipalities-arch-90.png and b/docs/diagrams/ph-municipalities-arch-90.png differ
diff --git a/docs/diagrams/ph-municipalities-arch.drawio b/docs/diagrams/ph-municipalities-arch.drawio
index 23f11a8..7dde84b 100644
--- a/docs/diagrams/ph-municipalities-arch.drawio
+++ b/docs/diagrams/ph-municipalities-arch.drawio
@@ -1,4 +1,4 @@
-
+
@@ -26,10 +26,10 @@
-
+
-
+
@@ -40,8 +40,8 @@
-
-
+
+
@@ -127,8 +127,8 @@
-
-
+
+
diff --git a/scripts/docs-build-gh.sh b/scripts/docs-build-gh.sh
new file mode 100644
index 0000000..bb507c2
--- /dev/null
+++ b/scripts/docs-build-gh.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# This script builds the class docs for GH Pages deployment, run from the repo root directory.
+# NOTE: It requires JSDoc and theme dependencies.
+# Run docs-install first before running this script.
+
+# Copy build files
+mkdir app/docs
+cp docs/diagrams/ph-municipalities-arch-90.png app/docs/diagram.png
+
+chmod u+x scripts/docs-install.sh
+cp scripts/docs-install.sh app/
+
+# Copy README file
+sed "s|/docs/diagrams/ph-municipalities-arch-90.png|/ph-municipalities/diagram.png|g" README.md > app/README.md
+cd app
+
+# Log directories
+ls -l -a
+
+# Find and export the active version no.
+# filePath="package.json"
+# version=$(grep -oP '"version":\s*"\K[^"]+' "$filePath")
+
+# Export the version as a GitHub Actions output variable
+# Accessible in the GH Actions steps as: ${{ env.version }}
+
+# echo "$version" >> $GITHUB_ENV
+# echo version: "$version"
diff --git a/scripts/docs-build.sh b/scripts/docs-build.sh
new file mode 100644
index 0000000..6c066db
--- /dev/null
+++ b/scripts/docs-build.sh
@@ -0,0 +1,13 @@
+# This script builds the class documentation from a Docker environment.
+# NOTE: It requires assets from the root directory mounted as volumes.
+# Run docs-install first before running this script.
+
+# Copy picture files
+mkdir docs
+cp diagrams/ph-municipalities-arch-90.png docs/diagram.png
+
+# Copy README file
+sed "s|/docs/diagrams/ph-municipalities-arch-90.png|diagram.png|g" README.tmp > README.md
+
+# Generate the documentation
+npm run generate-docs
diff --git a/scripts/docs-install.sh b/scripts/docs-install.sh
new file mode 100644
index 0000000..194fb9e
--- /dev/null
+++ b/scripts/docs-install.sh
@@ -0,0 +1,2 @@
+# Install JSDoc and theme dependencies
+npm install --save-dev jsdoc@4.0.3 minami@1.2.3 taffydb@2.7.3