# Add Distribution Header
<img src=https://centerkey.com/graphics/center-key-logo.svg align=right width=200 alt=logo>

_Prepend a one-line banner comment (with license notice) to distribution files_

[![License:MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/center-key/add-dist-header/blob/main/LICENSE.txt)
[![npm](https://img.shields.io/npm/v/add-dist-header.svg)](https://www.npmjs.com/package/add-dist-header)
[![Build](https://github.com/center-key/add-dist-header/actions/workflows/run-spec-on-push.yaml/badge.svg)](https://github.com/center-key/add-dist-header/actions/workflows/run-spec-on-push.yaml)

**add-dist-header** uses the `name`, `homepage`, and `license` from your project's **package.json**
file to create a header comment and prepend it to a build file.

<img src=https://raw.githubusercontent.com/center-key/add-dist-header/main/screenshot.png
width=800 alt=screenshot>

Example header comment for a **.js** file:
```javascript
//! my-app v3.1.4 ~~ https://github.com/my-org/my-app ~~ MIT License
```
Example header comment for a **.css** file:
```css
/*! my-app v3.1.4 ~~ https://github.com/my-org/my-app ~~ MIT License */
```
Example header comment for a **.xml** file:
```xml
<!-- my-app v3.1.4 ~~ https://github.com/my-org/my-app ~~ MIT License -->
```

Header comments are only prepended to text files.&nbsp;
Binary files are ignored (unless the `--all-files` flag is specified).

Automatically prepending headers to distribution files is particularly handy when your build
tools are configured to remove comments (such as if `"removeComments": true` in set
in **tsconfig.json**).
For a real-world example, see the files in the **dist** folder at
[w3c-html-validator](https://github.com/center-key/w3c-html-validator/tree/main/dist)

## A) Setup
Install package for node:
```shell
$ npm install --save-dev add-dist-header
```

## B) Usage
### 1. Synopsis
```
add-dist-header [SOURCE] [TARGET]
```
Parameters:
* The **first** parameter is the *source* file (defaults to `"build/*"`).
* The **second** parameter is the *output* folder (defaults to `"dist"`).

### 2. npm package.json scripts
Run `dist-header` from the `"scripts"` section of your **package.json** file.

Example **package.json** script:
```json
   "scripts": {
      "add-headers": "add-dist-header build dist"
   },
```

### 3. Command-line npx
Example terminal commands:
```shell
$ npm install --save-dev add-dist-header
$ npx add-dist-header "build" "dist"
[17:13:50] add-dist-header build/my-app.d.ts --> dist/my-app.d.ts (413.11 KB)
[17:13:51] add-dist-header build/my-app.js --> dist/my-app.js (1,569.70 KB)
```
The parameters are optional:
```shell
$ add-dist-header  #same as above since "build/*" "dist" are the default parameter values
[17:13:50] add-dist-header build/my-app.d.ts --> dist/my-app.d.ts (413.11 KB)
[17:13:51] add-dist-header build/my-app.js --> dist/my-app.js (1,569.70 KB)
$ add-dist-header "meta/config.js"  #creates "dist/config.js" prepended with header
[17:15:03] add-dist-header meta/config.js --> dist/config.js (3.91 KB)
```
You can also install **add-dist-header** globally (`--global`) and then run it anywhere directly from the terminal.

### 4. CLI flags
Command-line flags:
| Flag           | Description                                               | Values     | Default |
| -------------- | --------------------------------------------------------- | ---------- | ------- |
| `--all-files`  | Add headers to text files and just copy binary files.     | N/A        | N/A     |
| `--delimiter`  | Characters separating the parts of the header comment.    | **string** | `~~`    |
| `--ext`        | Filter files by file extension, such as `.js`.<br>Use a comma to specify multiple extensions. | **string** | N/A |
| `--keep-first` | Do not delete the original first line comment.            | N/A        | N/A     |
| `--new-ext`    | Rename target files to use the specificed file extention. | **string** | N/A |
| `--no-version` | Do not substitute occurrences of `{{package.version}}`<br>with the **package.json** version number. | N/A | N/A |
| `--note`       | Place to add a comment only for humans.                   | **string** | N/A     |
| `--quiet`      | Suppress informational messages.                          | N/A        | N/A     |
| `--recursive`  | Include subfolders of the source folder.                  | N/A        | N/A     |

#### Version number substitution:
In addition to prepending the header comment, **add-dist-header** also replaces all occurrences of
`{{package.version}}` in each file with the version number found in **package.json**.
This enables inserting the current package version number into your distribution files.

The substitution feature is disabled with the `--no-version` flag.

### 5. Examples
   - `add-dist-header build/minimized dist`<br>
   Copy the files in the **build/minimized** folder to the **dist** folder and add comment headers.

   - `add-dist-header build/minimized dist --all-files`<br>
   Same as above command except that binary files, such as .png files, will also be copied over unmodified.

   - `add-dist-header build dist --no-version --delimiter=🔥`<br>
   Add comment headers but do not substitute the version number and use "🔥" as the separator in the header comment instead of "~~".

   - `add-dist-header build dist --no-version '--delimiter= --- '`<br>
   Specify a delimiter with a leading and trailing space.

   - `add-dist-header build dist --ext=.js,.css --recursive`<br>
   Process only JavaScript and CSS files in the **build** folder and its subfolders.

   - `add-dist-header build dist --ext=.css --new-ext=.style.css`<br>
   Process only CSS files and change the **.css** file extension to **.style.css** for each target file.

> [!NOTE]
> _Single quotes in commands are normalized so they work cross-platform and avoid the errors often encountered on Microsoft Windows._

## C) Application Code
Even though **add-dist-header** is primarily intended for build scripts, the package can be used programmatically in ESM and TypeScript projects.

Example:
``` typescript
import { addDistHeader } from 'add-dist-header';

const options = {
   dist:      'dist',
   delimiter: '🚀🚀🚀',
   };
const result = addDistHeader.prepend('build/rocket.js', options);

console.info('The size of the new file is:', result.size);
```

See the **TypeScript Declarations** at the top of [add-dist-header.ts](src/add-dist-header.ts) for documentation.

<br>

---
[MIT License](LICENSE.txt)

[🛡️ npm Security Aggregator](https://center-key.github.io/npm-security-aggregator/?package=add-dist-header)

See the `runScriptsConfig` section of [`package.json`](package.json) for a clean way to organize build tasks:
   - 🎋 [`add-dist-header`](https://github.com/center-key/add-dist-header) &mdash;&nbsp; _Prepend a one-line banner comment (with license notice) to distribution files_
   - 📄 [`copy-file-util`](https://github.com/center-key/copy-file-util) &mdash;&nbsp; _Copy or rename a file with optional package version number_
   - 📂 [`copy-folder-util`](https://github.com/center-key/copy-folder-util) &mdash;&nbsp; _Recursively copy files from one folder to another folder_
   - 🪺 [`recursive-exec`](https://github.com/center-key/recursive-exec) &mdash;&nbsp; _Run a command on each file in a folder and its subfolders_
   - 🔍 [`replacer-util`](https://github.com/center-key/replacer-util) &mdash;&nbsp; _Find and replace strings or template outputs in text files_
   - 🔢 [`rev-web-assets`](https://github.com/center-key/rev-web-assets) &mdash;&nbsp; _Revision web asset filenames with cache busting content hash fingerprints_
   - 🚆 [`run-scripts-util`](https://github.com/center-key/run-scripts-util) &mdash;&nbsp; _Organize npm package.json scripts into groups of easy-to-manage commands_
   - 🚦 [`w3c-html-validator`](https://github.com/center-key/w3c-html-validator) &mdash;&nbsp; _Check the markup validity of HTML files using the W3C validator_
