# DDC JS Modules
Javascript module library as an npm package.

* [Local development with Docker](#local-development-with-docker)
* [Release New Package Version](#release-new-package-version)
* [Link Development Version](#link-development-version)
* [Unit Tests](#unit-tests)
* [Configure Modules](#configure-modules)
    * [Configure Standalone Module Files](https://github.com/drugscom/ddcjsmodules/blob/master/src/misc/README.md)
* [Javascript Debugging](#javascript-debugging)
  * [Examples](#examples)

## Local development with Docker

### Dependencies

#### Docker Desktop

Download and install Docker Desktop from: https://www.docker.com/products/docker-desktop/

On Windows use the WSL 2 backend.

#### Earthly

- macOS:
    ```shell
    brew install earthly/earthly/earthly && earthly bootstrap
    ```

- Windows (inside WSL):
    ```shell
    sudo /bin/sh -c 'wget https://github.com/earthly/earthly/releases/latest/download/earthly-linux-amd64 -O /usr/local/bin/earthly && chmod +x /usr/local/bin/earthly && /usr/local/bin/earthly bootstrap --with-autocomplete'
    ```

For more details: https://earthly.dev/get-earthly

### Running npm commands

To run npm commands:
```shell
docker-compose run --rm npm <npm options>
```

e.g.:
```shell
docker-compose run --rm npm install --save-dev stylelint
```

### Running CI tests locally

To run the complete set of CI tests:
```shell
earthly +test
```

You can also specify a single test to run. e.g.:
```shell
earthly +jshint
earthly +mocha
```

### Cleaning up

To clean up the project root (node_modules, ...):
```shell
earthly +clean
```

## Release New Package Version

The CI/CD pipeline will automatically bump the package version and publish the new release to [npmjs.com](https://www.npmjs.com/) if the Pull Request has one of the following labels:

- release:major (Bump the major version number e.g. from 1.8.1 to 2.0.0)
- release:minor (Bump the minor version number e.g. from 1.8.1 to 1.9.0)
- release:patch (Bump the patch version number e.g. from 1.8.1 to 1.8.2)

After the workflow has finished running, you can update the dependency in your project by running `npm install '@drugscom/ddcjsmodules@<new version>'` in your project root. E.g.:

```shell
cd ~/dev/ddcwww
npm install '@drugscom/ddcjsmodules@1.8.2'
```

### Manual mode

**Note:** The production staging process depends on the creation of a new project **tag** to get the latest version of the `ddcjsmodules` project.  

#### Step 1: Create new tag (version) for ddcjsmodules
Ensure all changes have been committed (and tested). Use the command `npm version patch` to create a new "patch" version. (e.g. `7.17.11` → `7.17.12`). Alternatively, replace `patch` with `minor` or `major` to increment the "minor" (`7.17.11` → `7.18.0`) or "major" (`7.17.11` → `8.0.0`) versions, if required.
```
[ddcjsmodules]# git status
[ddcjsmodules]# npm version patch
```
Push this tag change to GitHub and run `npm publish` to notify [npmjs.com](https://www.npmjs.com/) of this new version.
```
[ddcjsmodules]# git push --tags origin master
[ddcjsmodules]# npm publish
```
Enter the one-time password from your authenticator app when prompted.

#### Step 2: Update ddcwww

Edit the `package.json` file inside the `ddcwww` project and update the `@drugscom/ddcjsmodules` dependency with the new tag version created in Step 1.
```
"dependencies": {
   "@babel/core": "7.14.5",
   "@babel/preset-env": "7.14.5",
   "@drugscom/ddcjsmodules": "7.17.12", <-- New version here
   "autoprefixer": "9.8.6",
   ...
}
```

From the `ddcwww` project root, run `npm install`:
```
[ddcwww]# npm install
```

This will use the `package.json` file to install the specified version of `ddcjsmodules` into the `/node_modules` directory, updating the project's `package-lock.json` file in the process. Changes from both `package.json` and `package-lock.json` must be committed/pushed to GitHub.



## Link Development Version

Any project can be set up to reference a "**live**" version of the **ddcjsmodules** project (versus using the `package.json` version). This can be very useful in a development environment.

1. Define the **ddcjsmodules** project as a "node modules link". **Note**: This only needs to be done once, anytime after cloning.
```
[home]# git clone git@github.com:drugscom/ddcjsmodules.git
[home]# cd ddcjsmodules/
[ddcjsmodules]# npm install
[ddcjsmodules]# npm link
```

2. Inside the root directory of the **ddcwww** project, use the `npm link` command to link the "live" version of **ddcjsmodules** set up in Step 1:
```
[ddcwww]# npm link @drugscom/ddcjsmodules
```

**Note**: Running `npm install` or `npm update` will break the link, reverting **ddcwww** to use the `package.json` version:
```
[ddcwww]# npm install
- or -
[ddcwww]# npm install @drugscom/ddcjsmodules
- or -
[ddcwww]# npm update @drugscom/ddcjsmodules
```
Simply repeat **Step 2** to recreate the link once again. 



## Unit Tests

To run all unit tests from the command line:
```
[ddcjsmodules]# npm test
```

To run a specific unit test:
```
[ddcjsmodules]# npm test test/helper.js 
```



## Configure Modules

To use a **ddcjsmodules** module inside the **ddcwww** project, the module path will should be aliased inside the `browser` section of the `package.json` file:
```
"browser": {
   "ddc-agent": "./node_modules/@drugscom/ddcjsmodules/src/agent",
   "ddc-analytics": "./node_modules/@drugscom/ddcjsmodules/src/analytics",
   "ddc-config": "./node_modules/@drugscom/ddcjsmodules/src/config",
   "ddc-debug": "./node_modules/@drugscom/ddcjsmodules/src/debug",
   "ddc-error": "./node_modules/@drugscom/ddcjsmodules/src/error",
   "ddc-helper": "./node_modules/@drugscom/ddcjsmodules/src/helper",
   "ddc-timing": "./node_modules/@drugscom/ddcjsmodules/src/timing",
   ...
}
```

Then the module path can be referenced inside a Javascript file using the `require` statement:
```
const Debug = require('ddc-debug');
Debug.log("API response:", data);

const Analytics = require('ddc-analytics');
Analytics.sendEvent({event: 'AdClick', drugName: 'Lexapro'});
```



## Javascript Debugging

Return the current debug configuration (JSON string):
```
> DDC.Debug.get();
```
Set the current debug configuration (overrides any existing configuration):
```
> DDC.Debug.set({options});
```

The `{options}` parameter should follow this structure:

```
{
   show: ['DDC.Class.method', 'DDC.Class2.method2', ...], // Array of strings;
   mark: ['DDC.Class.method', ...]  // Array of strings;
}
```

Console logging the `Debug.trace` data will use the logic:
1. if the trace method name starts with a value in the `[mark]` array, log to console (important color)
2. if the trace method name starts with a value in the `[show]` array, log to console (standard color)
3. else, do not log

### Examples

Use your browser's **Developer Tools Console** to enter the following commands.

Show all debugging:
```
> DDC.Debug.set({show: ['']})
```
Show debugging for methods starting with "**Mednotes.Page**":
```
> DDC.Debug.set({show: ['Mednotes.Page']})
```
Show debugging for methods starting with "**DDC.Ads**" and "**DDC.Page**"; highlight methods starting with "**DDC.Ads.buildAd**":
```
> DDC.Debug.set({show: ['DDC.Ads', 'DDC.Page'], mark: ['DDC.Ads.buildAd']})
```
Stop all debugging:
```
> DDC.Debug.set({show: [], mark: []})
```
