@expressots/shared 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +118 -0
- package/lib/CHANGELOG.md +8 -0
- package/lib/README.md +118 -0
- package/lib/cjs/config/index.js +2 -0
- package/lib/cjs/config/project-config.js +2 -0
- package/lib/cjs/env/cli-options.js +18 -0
- package/lib/cjs/env/constants.js +13 -0
- package/lib/cjs/env/env-options.js +22 -0
- package/lib/cjs/env/environment.js +316 -0
- package/lib/cjs/env/index.js +17 -0
- package/lib/cjs/env/interfaces.js +2 -0
- package/lib/cjs/index.js +19 -0
- package/lib/cjs/types/config/index.d.ts +1 -0
- package/lib/cjs/types/config/project-config.d.ts +37 -0
- package/lib/cjs/types/env/cli-options.d.ts +7 -0
- package/lib/cjs/types/env/constants.d.ts +10 -0
- package/lib/cjs/types/env/env-options.d.ts +9 -0
- package/lib/cjs/types/env/environment.d.ts +83 -0
- package/lib/cjs/types/env/index.d.ts +2 -0
- package/lib/cjs/types/env/interfaces.d.ts +71 -0
- package/lib/cjs/types/index.d.ts +3 -0
- package/lib/cjs/types/utils/compiler.d.ts +17 -0
- package/lib/cjs/types/utils/index.d.ts +1 -0
- package/lib/cjs/types/utils/logger.d.ts +19 -0
- package/lib/cjs/utils/compiler.js +99 -0
- package/lib/cjs/utils/index.js +5 -0
- package/lib/cjs/utils/logger.js +72 -0
- package/lib/package.json +150 -0
- package/package.json +150 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Richard Zampieri
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<a name="readme-top"></a>
|
|
2
|
+
|
|
3
|
+
<!-- PROJECT SHIELDS -->
|
|
4
|
+
|
|
5
|
+
[![Codecov][codecov-shield]][codecov-url]
|
|
6
|
+
[![NPM][npm-shield]][npm-url]
|
|
7
|
+
![Build][build-shield]
|
|
8
|
+
[![Contributors][contributors-shield]][contributors-url]
|
|
9
|
+
[![Forks][forks-shield]][forks-url]
|
|
10
|
+
[![Stargazers][stars-shield]][stars-url]
|
|
11
|
+
[![Issues][issues-shield]][issues-url]
|
|
12
|
+
[![MIT License][license-shield]][license-url]
|
|
13
|
+
[![LinkedIn][linkedin-shield]][linkedin-url]
|
|
14
|
+
|
|
15
|
+
<!-- PROJECT LOGO -->
|
|
16
|
+
<br />
|
|
17
|
+
<div align="center">
|
|
18
|
+
<a href="https://github.com/othneildrew/Best-README-Template">
|
|
19
|
+
<img src="https://github.com/expressots/expressots/blob/main/media/expressots.png" alt="Logo" width="120">
|
|
20
|
+
</a>
|
|
21
|
+
|
|
22
|
+
<h3 align="center">ExpressoTS Framework</h3>
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
Everything you need to know to build applications with ExpressoTS
|
|
26
|
+
<br />
|
|
27
|
+
<a href="https://doc.expresso-ts.com/"><strong>Explore the docs »</strong></a>
|
|
28
|
+
<br />
|
|
29
|
+
<br />
|
|
30
|
+
<a href="https://github.com/expressots/expressots/discussions">Let's discuss</a>
|
|
31
|
+
·
|
|
32
|
+
<a href="https://github.com/expressots/expressots/issues">Report Bug</a>
|
|
33
|
+
·
|
|
34
|
+
<a href="https://github.com/expressots/expressots/issues">Request Feature</a>
|
|
35
|
+
</p>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<!-- TABLE OF CONTENTS -->
|
|
39
|
+
<details>
|
|
40
|
+
<summary>Table of Contents</summary>
|
|
41
|
+
<ol>
|
|
42
|
+
<li><a href="#about-the-project">About The Project</a></li>
|
|
43
|
+
<li><a href="#getting-started">Getting Started</a></li>
|
|
44
|
+
<li><a href="#contributing">Contributing</a></li>
|
|
45
|
+
<li><a href="#support-the-project">Support the project</a></li>
|
|
46
|
+
<li><a href="#license">License</a></li>
|
|
47
|
+
</ol>
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
<!-- ABOUT THE PROJECT -->
|
|
51
|
+
|
|
52
|
+
# About The Project
|
|
53
|
+
|
|
54
|
+
ExpressoTS is a [Typescript](https://www.typescriptlang.org/) + [Node.js](https://nodejs.org/en/) lightweight framework for quick building scalable, easy to read and maintain, server-side applications 🐎
|
|
55
|
+
|
|
56
|
+
## Getting Started
|
|
57
|
+
|
|
58
|
+
- Here is our [Site](https://expresso-ts.com/)
|
|
59
|
+
- You can find our [Documentation here](https://doc.expresso-ts.com/)
|
|
60
|
+
- Checkout our [First Steps documentation](https://doc.expresso-ts.com/docs/overview/first-steps)
|
|
61
|
+
- Our [CLI Documentation](https://doc.expresso-ts.com/docs/cli/overview)
|
|
62
|
+
|
|
63
|
+
## Contributing
|
|
64
|
+
|
|
65
|
+
Welcome to the ExpressoTS community, a place bustling with innovative minds just like yours. We're absolutely thrilled to have you here!
|
|
66
|
+
ExpressoTS is more than just a TypeScript framework; it's a collective effort by developers who are passionate about creating a more efficient, secure, and robust web ecosystem. We firmly believe that the best ideas come from a diversity of perspectives, backgrounds, and skills.
|
|
67
|
+
|
|
68
|
+
Why Contribute to Documentation?
|
|
69
|
+
|
|
70
|
+
- **Share Knowledge**: If you've figured out something cool, why keep it to yourself?
|
|
71
|
+
- **Build Your Portfolio**: Contributing to an open-source project like ExpressoTS is a great way to showcase your skills.
|
|
72
|
+
- **Join a Network**: Get to know a community of like-minded developers.
|
|
73
|
+
- **Improve the Product**: Help us fill in the gaps, correct errors, or make complex topics easier to understand.
|
|
74
|
+
|
|
75
|
+
Ready to contribute?
|
|
76
|
+
|
|
77
|
+
- [Contributing Guidelines](https://github.com/expressots/expressots/blob/main/CONTRIBUTING.md)
|
|
78
|
+
- [How to Contribute](https://github.com/expressots/expressots/blob/main/CONTRIBUTING_HOWTO.md)
|
|
79
|
+
- [Coding Guidelines](https://github.com/rsaz/TypescriptCodingGuidelines)
|
|
80
|
+
|
|
81
|
+
## Support the project
|
|
82
|
+
|
|
83
|
+
ExpressoTS is an independent open source project with ongoing development made possible thanks to your support. If you'd like to help, please consider:
|
|
84
|
+
|
|
85
|
+
- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
|
|
86
|
+
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star ⭐ the project
|
|
87
|
+
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
|
|
88
|
+
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
|
|
89
|
+
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues)**
|
|
90
|
+
- Share the project with your friends and colleagues
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
Distributed under the MIT License. See [`LICENSE.txt`](https://github.com/expressots/expressots/blob/main/LICENSE) for more information.
|
|
95
|
+
|
|
96
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
97
|
+
|
|
98
|
+
<!-- MARKDOWN LINKS & IMAGES -->
|
|
99
|
+
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
|
|
100
|
+
|
|
101
|
+
[codecov-url]: https://codecov.io/gh/expressots/shared
|
|
102
|
+
[codecov-shield]: https://img.shields.io/codecov/c/gh/expressots/shared/main?style=for-the-badge&logo=codecov&labelColor=FB9AD1
|
|
103
|
+
[npm-url]: https://www.npmjs.com/package/@expressots/shared
|
|
104
|
+
[npm-shield]: https://img.shields.io/npm/v/@expressots/shared?style=for-the-badge&logo=npm&color=9B3922
|
|
105
|
+
[build-shield]: https://img.shields.io/github/actions/workflow/status/expressots/adapter-express/build.yaml?branch=main&style=for-the-badge&logo=github
|
|
106
|
+
[contributors-shield]: https://img.shields.io/github/contributors/expressots/shared?style=for-the-badge
|
|
107
|
+
[contributors-url]: https://github.com/expressots/shared/graphs/contributors
|
|
108
|
+
[forks-shield]: https://img.shields.io/github/forks/expressots/shared?style=for-the-badge
|
|
109
|
+
[forks-url]: https://github.com/expressots/shared/forks
|
|
110
|
+
[stars-shield]: https://img.shields.io/github/stars/expressots/shared?style=for-the-badge
|
|
111
|
+
[stars-url]: https://github.com/expressots/shared/stargazers
|
|
112
|
+
[issues-shield]: https://img.shields.io/github/issues/expressots/shared?style=for-the-badge
|
|
113
|
+
[issues-url]: https://github.com/expressots/shared/issues
|
|
114
|
+
[license-shield]: https://img.shields.io/github/license/expressots/shared?style=for-the-badge
|
|
115
|
+
[license-url]: https://github.com/expressots/shared/blob/main/LICENSE
|
|
116
|
+
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
|
|
117
|
+
[linkedin-url]: https://www.linkedin.com/company/expresso-ts/
|
|
118
|
+
[product-screenshot]: images/screenshot.png
|
package/lib/CHANGELOG.md
ADDED
package/lib/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<a name="readme-top"></a>
|
|
2
|
+
|
|
3
|
+
<!-- PROJECT SHIELDS -->
|
|
4
|
+
|
|
5
|
+
[![Codecov][codecov-shield]][codecov-url]
|
|
6
|
+
[![NPM][npm-shield]][npm-url]
|
|
7
|
+
![Build][build-shield]
|
|
8
|
+
[![Contributors][contributors-shield]][contributors-url]
|
|
9
|
+
[![Forks][forks-shield]][forks-url]
|
|
10
|
+
[![Stargazers][stars-shield]][stars-url]
|
|
11
|
+
[![Issues][issues-shield]][issues-url]
|
|
12
|
+
[![MIT License][license-shield]][license-url]
|
|
13
|
+
[![LinkedIn][linkedin-shield]][linkedin-url]
|
|
14
|
+
|
|
15
|
+
<!-- PROJECT LOGO -->
|
|
16
|
+
<br />
|
|
17
|
+
<div align="center">
|
|
18
|
+
<a href="https://github.com/othneildrew/Best-README-Template">
|
|
19
|
+
<img src="https://github.com/expressots/expressots/blob/main/media/expressots.png" alt="Logo" width="120">
|
|
20
|
+
</a>
|
|
21
|
+
|
|
22
|
+
<h3 align="center">ExpressoTS Framework</h3>
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
Everything you need to know to build applications with ExpressoTS
|
|
26
|
+
<br />
|
|
27
|
+
<a href="https://doc.expresso-ts.com/"><strong>Explore the docs »</strong></a>
|
|
28
|
+
<br />
|
|
29
|
+
<br />
|
|
30
|
+
<a href="https://github.com/expressots/expressots/discussions">Let's discuss</a>
|
|
31
|
+
·
|
|
32
|
+
<a href="https://github.com/expressots/expressots/issues">Report Bug</a>
|
|
33
|
+
·
|
|
34
|
+
<a href="https://github.com/expressots/expressots/issues">Request Feature</a>
|
|
35
|
+
</p>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<!-- TABLE OF CONTENTS -->
|
|
39
|
+
<details>
|
|
40
|
+
<summary>Table of Contents</summary>
|
|
41
|
+
<ol>
|
|
42
|
+
<li><a href="#about-the-project">About The Project</a></li>
|
|
43
|
+
<li><a href="#getting-started">Getting Started</a></li>
|
|
44
|
+
<li><a href="#contributing">Contributing</a></li>
|
|
45
|
+
<li><a href="#support-the-project">Support the project</a></li>
|
|
46
|
+
<li><a href="#license">License</a></li>
|
|
47
|
+
</ol>
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
<!-- ABOUT THE PROJECT -->
|
|
51
|
+
|
|
52
|
+
# About The Project
|
|
53
|
+
|
|
54
|
+
ExpressoTS is a [Typescript](https://www.typescriptlang.org/) + [Node.js](https://nodejs.org/en/) lightweight framework for quick building scalable, easy to read and maintain, server-side applications 🐎
|
|
55
|
+
|
|
56
|
+
## Getting Started
|
|
57
|
+
|
|
58
|
+
- Here is our [Site](https://expresso-ts.com/)
|
|
59
|
+
- You can find our [Documentation here](https://doc.expresso-ts.com/)
|
|
60
|
+
- Checkout our [First Steps documentation](https://doc.expresso-ts.com/docs/overview/first-steps)
|
|
61
|
+
- Our [CLI Documentation](https://doc.expresso-ts.com/docs/cli/overview)
|
|
62
|
+
|
|
63
|
+
## Contributing
|
|
64
|
+
|
|
65
|
+
Welcome to the ExpressoTS community, a place bustling with innovative minds just like yours. We're absolutely thrilled to have you here!
|
|
66
|
+
ExpressoTS is more than just a TypeScript framework; it's a collective effort by developers who are passionate about creating a more efficient, secure, and robust web ecosystem. We firmly believe that the best ideas come from a diversity of perspectives, backgrounds, and skills.
|
|
67
|
+
|
|
68
|
+
Why Contribute to Documentation?
|
|
69
|
+
|
|
70
|
+
- **Share Knowledge**: If you've figured out something cool, why keep it to yourself?
|
|
71
|
+
- **Build Your Portfolio**: Contributing to an open-source project like ExpressoTS is a great way to showcase your skills.
|
|
72
|
+
- **Join a Network**: Get to know a community of like-minded developers.
|
|
73
|
+
- **Improve the Product**: Help us fill in the gaps, correct errors, or make complex topics easier to understand.
|
|
74
|
+
|
|
75
|
+
Ready to contribute?
|
|
76
|
+
|
|
77
|
+
- [Contributing Guidelines](https://github.com/expressots/expressots/blob/main/CONTRIBUTING.md)
|
|
78
|
+
- [How to Contribute](https://github.com/expressots/expressots/blob/main/CONTRIBUTING_HOWTO.md)
|
|
79
|
+
- [Coding Guidelines](https://github.com/rsaz/TypescriptCodingGuidelines)
|
|
80
|
+
|
|
81
|
+
## Support the project
|
|
82
|
+
|
|
83
|
+
ExpressoTS is an independent open source project with ongoing development made possible thanks to your support. If you'd like to help, please consider:
|
|
84
|
+
|
|
85
|
+
- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
|
|
86
|
+
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star ⭐ the project
|
|
87
|
+
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
|
|
88
|
+
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
|
|
89
|
+
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues)**
|
|
90
|
+
- Share the project with your friends and colleagues
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
Distributed under the MIT License. See [`LICENSE.txt`](https://github.com/expressots/expressots/blob/main/LICENSE) for more information.
|
|
95
|
+
|
|
96
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
97
|
+
|
|
98
|
+
<!-- MARKDOWN LINKS & IMAGES -->
|
|
99
|
+
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
|
|
100
|
+
|
|
101
|
+
[codecov-url]: https://codecov.io/gh/expressots/shared
|
|
102
|
+
[codecov-shield]: https://img.shields.io/codecov/c/gh/expressots/shared/main?style=for-the-badge&logo=codecov&labelColor=FB9AD1
|
|
103
|
+
[npm-url]: https://www.npmjs.com/package/@expressots/shared
|
|
104
|
+
[npm-shield]: https://img.shields.io/npm/v/@expressots/shared?style=for-the-badge&logo=npm&color=9B3922
|
|
105
|
+
[build-shield]: https://img.shields.io/github/actions/workflow/status/expressots/adapter-express/build.yaml?branch=main&style=for-the-badge&logo=github
|
|
106
|
+
[contributors-shield]: https://img.shields.io/github/contributors/expressots/shared?style=for-the-badge
|
|
107
|
+
[contributors-url]: https://github.com/expressots/shared/graphs/contributors
|
|
108
|
+
[forks-shield]: https://img.shields.io/github/forks/expressots/shared?style=for-the-badge
|
|
109
|
+
[forks-url]: https://github.com/expressots/shared/forks
|
|
110
|
+
[stars-shield]: https://img.shields.io/github/stars/expressots/shared?style=for-the-badge
|
|
111
|
+
[stars-url]: https://github.com/expressots/shared/stargazers
|
|
112
|
+
[issues-shield]: https://img.shields.io/github/issues/expressots/shared?style=for-the-badge
|
|
113
|
+
[issues-url]: https://github.com/expressots/shared/issues
|
|
114
|
+
[license-shield]: https://img.shields.io/github/license/expressots/shared?style=for-the-badge
|
|
115
|
+
[license-url]: https://github.com/expressots/shared/blob/main/LICENSE
|
|
116
|
+
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
|
|
117
|
+
[linkedin-url]: https://www.linkedin.com/company/expresso-ts/
|
|
118
|
+
[product-screenshot]: images/screenshot.png
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.optionMatcher = optionMatcher;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
/**
|
|
6
|
+
* Matches the options passed in the command line
|
|
7
|
+
* @param args - The arguments passed in the command line
|
|
8
|
+
* @returns The options passed in the command line
|
|
9
|
+
*/
|
|
10
|
+
function optionMatcher(args) {
|
|
11
|
+
return args.reduce((previous, current) => {
|
|
12
|
+
const matches = current.match(constants_1.ENV_VAR_REGEX);
|
|
13
|
+
if (matches) {
|
|
14
|
+
previous[matches[1]] = matches[2];
|
|
15
|
+
}
|
|
16
|
+
return previous;
|
|
17
|
+
}, {});
|
|
18
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ENV_VAR_REGEX = exports.LINE_REGEX = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* LINE_REGEX is a regular expression that matches a line in a .env file.
|
|
6
|
+
* It is used to parse the content of the .env file.
|
|
7
|
+
*/
|
|
8
|
+
exports.LINE_REGEX = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/gm;
|
|
9
|
+
/**
|
|
10
|
+
* ENV_VAR_REGEX is a regular expression that matches an environment variable in the command line.
|
|
11
|
+
* It is used to parse the options passed in the command line.
|
|
12
|
+
*/
|
|
13
|
+
exports.ENV_VAR_REGEX = /^dotenv_config_(encoding|path|debug|override|vaultEnvKey)=(.+)$/;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OPTIONS = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The options for the dotenv configuration.
|
|
6
|
+
*/
|
|
7
|
+
exports.OPTIONS = {};
|
|
8
|
+
if (process.env.DOTENV_CONFIG_ENCODING != null) {
|
|
9
|
+
exports.OPTIONS.encoding = process.env.DOTENV_CONFIG_ENCODING;
|
|
10
|
+
}
|
|
11
|
+
if (process.env.DOTENV_CONFIG_PATH != null) {
|
|
12
|
+
exports.OPTIONS.path = process.env.DOTENV_CONFIG_PATH;
|
|
13
|
+
}
|
|
14
|
+
if (process.env.DOTENV_CONFIG_DEBUG != null) {
|
|
15
|
+
exports.OPTIONS.debug = process.env.DOTENV_CONFIG_DEBUG === "true";
|
|
16
|
+
}
|
|
17
|
+
if (process.env.DOTENV_CONFIG_OVERRIDE != null) {
|
|
18
|
+
exports.OPTIONS.override = process.env.DOTENV_CONFIG_OVERRIDE === "true";
|
|
19
|
+
}
|
|
20
|
+
if (process.env.DOTENV_CONFIG_DOTENV_KEY != null) {
|
|
21
|
+
exports.OPTIONS.vaultEnvKey = process.env.DOTENV_CONFIG_DOTENV_KEY;
|
|
22
|
+
}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports._configVault = _configVault;
|
|
7
|
+
exports.config = config;
|
|
8
|
+
exports.configDotenv = configDotenv;
|
|
9
|
+
exports.parse = parse;
|
|
10
|
+
exports.decrypt = decrypt;
|
|
11
|
+
exports.populate = populate;
|
|
12
|
+
exports._parseVault = _parseVault;
|
|
13
|
+
exports._vaultPath = _vaultPath;
|
|
14
|
+
exports._dotenvKey = _dotenvKey;
|
|
15
|
+
exports._instructions = _instructions;
|
|
16
|
+
exports._resolveHome = _resolveHome;
|
|
17
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
18
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
19
|
+
const fs_1 = __importDefault(require("fs"));
|
|
20
|
+
const path_1 = __importDefault(require("path"));
|
|
21
|
+
const os_1 = __importDefault(require("os"));
|
|
22
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
23
|
+
const constants_1 = require("./constants");
|
|
24
|
+
const logger_1 = require("../utils/logger");
|
|
25
|
+
/**
|
|
26
|
+
* Module to parse the .env.vault file
|
|
27
|
+
* @param options - The configuration options
|
|
28
|
+
* @returns The parsed object
|
|
29
|
+
*/
|
|
30
|
+
function _parseVault(options) {
|
|
31
|
+
const vaultPath = _vaultPath(options);
|
|
32
|
+
const result = configDotenv({ path: vaultPath });
|
|
33
|
+
if (!result.parsed) {
|
|
34
|
+
const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
35
|
+
err.name = "MISSING_DATA";
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
//DOTENV_KEY="dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod, // dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod"
|
|
39
|
+
const keys = _dotenvKey(options).split(",");
|
|
40
|
+
const length = keys.length;
|
|
41
|
+
let decrypted = "";
|
|
42
|
+
for (let i = 0; i < length; i++) {
|
|
43
|
+
try {
|
|
44
|
+
const key = keys[i].trim();
|
|
45
|
+
const attrs = _instructions(result, key);
|
|
46
|
+
decrypted = decrypt(attrs.ciphertext, attrs.key);
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (i + 1 >= length) {
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return parse(decrypted);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Module to verify and return the .env.vault file path
|
|
59
|
+
* @param options - The configuration options
|
|
60
|
+
* @returns The .env.vault file path
|
|
61
|
+
*/
|
|
62
|
+
function _vaultPath(options) {
|
|
63
|
+
let possibleVaultPath = null;
|
|
64
|
+
if (options && options.path && options.path.length > 0) {
|
|
65
|
+
if (Array.isArray(options.path)) {
|
|
66
|
+
for (const filepath of options.path) {
|
|
67
|
+
if (fs_1.default.existsSync(filepath)) {
|
|
68
|
+
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
possibleVaultPath = path_1.default.resolve(process.cwd(), ".env.vault");
|
|
78
|
+
}
|
|
79
|
+
if (fs_1.default.existsSync(possibleVaultPath)) {
|
|
80
|
+
return possibleVaultPath;
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Module to verify and return the DOTENV_KEY vault key
|
|
86
|
+
* @param options - The configuration options
|
|
87
|
+
* @returns The DOTENV_KEY as a string
|
|
88
|
+
*/
|
|
89
|
+
function _dotenvKey(options) {
|
|
90
|
+
if (options && options.vaultEnvKey && options.vaultEnvKey.length > 0) {
|
|
91
|
+
return options.vaultEnvKey;
|
|
92
|
+
}
|
|
93
|
+
if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
|
|
94
|
+
return process.env.DOTENV_KEY;
|
|
95
|
+
}
|
|
96
|
+
return "";
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Module to get instructions for decrypting the .env.vault file
|
|
100
|
+
* @param result -
|
|
101
|
+
* @param dotenvKey
|
|
102
|
+
* @returns
|
|
103
|
+
*/
|
|
104
|
+
function _instructions(result, dotenvKey) {
|
|
105
|
+
let uri = null;
|
|
106
|
+
try {
|
|
107
|
+
uri = new URL(dotenvKey);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (error.code === "ERR_INVALID_URL") {
|
|
111
|
+
const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
|
|
112
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
113
|
+
throw err;
|
|
114
|
+
}
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
// Get decrypt key
|
|
118
|
+
const key = uri.password;
|
|
119
|
+
if (!key) {
|
|
120
|
+
const err = new Error("INVALID_DOTENV_KEY: Missing key part");
|
|
121
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
// Get environment
|
|
125
|
+
const environment = uri.searchParams.get("environment");
|
|
126
|
+
if (!environment) {
|
|
127
|
+
const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
|
|
128
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
129
|
+
throw err;
|
|
130
|
+
}
|
|
131
|
+
// Get ciphertext payload
|
|
132
|
+
const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
|
|
133
|
+
const ciphertext = result.parsed[environmentKey]; // DOTENV_VAULT_PRODUCTION
|
|
134
|
+
if (!ciphertext) {
|
|
135
|
+
const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
|
|
136
|
+
err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
return { ciphertext, key };
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Module responsible to resolve home path
|
|
143
|
+
* @param envPath - The path to resolve
|
|
144
|
+
* @returns The resolved path
|
|
145
|
+
*/
|
|
146
|
+
function _resolveHome(envPath) {
|
|
147
|
+
return envPath[0] === "~" ? path_1.default.join(os_1.default.homedir(), envPath.slice(1)) : envPath;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Module to load environment variables from .env.vault file
|
|
151
|
+
* @param options - The configuration options
|
|
152
|
+
* @returns The parsed object
|
|
153
|
+
*/
|
|
154
|
+
function _configVault(options) {
|
|
155
|
+
(0, logger_1.log)("Loading env from encrypted .env.vault");
|
|
156
|
+
const parsed = _parseVault(options);
|
|
157
|
+
let processEnv = process.env;
|
|
158
|
+
if (options && options.envObject != null) {
|
|
159
|
+
processEnv = options.envObject;
|
|
160
|
+
}
|
|
161
|
+
populate(processEnv, parsed, options);
|
|
162
|
+
return { parsed };
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Module to load environment variables from .env file
|
|
166
|
+
* @param options - The configuration options
|
|
167
|
+
* @returns The parsed object
|
|
168
|
+
* @public API
|
|
169
|
+
*/
|
|
170
|
+
function config(options) {
|
|
171
|
+
if (_dotenvKey(options).length === 0) {
|
|
172
|
+
return configDotenv(options);
|
|
173
|
+
}
|
|
174
|
+
const vaultPath = _vaultPath(options);
|
|
175
|
+
console.log(vaultPath);
|
|
176
|
+
if (!vaultPath) {
|
|
177
|
+
(0, logger_1.log)(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`, logger_1.LogLevel.Warn);
|
|
178
|
+
return configDotenv(options);
|
|
179
|
+
}
|
|
180
|
+
return _configVault(options);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Module to load environment variables from .env file
|
|
184
|
+
* @param options - The configuration options
|
|
185
|
+
* @returns The parsed object
|
|
186
|
+
* @public API
|
|
187
|
+
*/
|
|
188
|
+
function configDotenv(options) {
|
|
189
|
+
const dotenvPath = path_1.default.resolve(process.cwd(), String(options?.path ?? ".env"));
|
|
190
|
+
const encoding = (options.encoding ?? "utf8");
|
|
191
|
+
const debug = !!options.debug;
|
|
192
|
+
const paths = Array.isArray(options.path)
|
|
193
|
+
? options.path.map(_resolveHome)
|
|
194
|
+
: [_resolveHome(dotenvPath)];
|
|
195
|
+
const parsed = {};
|
|
196
|
+
let lastError;
|
|
197
|
+
for (const envPath of paths) {
|
|
198
|
+
try {
|
|
199
|
+
const fileContent = fs_1.default.readFileSync(envPath, { encoding });
|
|
200
|
+
const parsedContent = parse(fileContent);
|
|
201
|
+
populate(process.env, parsedContent, options);
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
lastError = error;
|
|
205
|
+
if (debug) {
|
|
206
|
+
(0, logger_1.log)(`Failed to load ${envPath} file with error: ${error.message}`, logger_1.LogLevel.Debug);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return { parsed, error: lastError };
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Module to load environment variables from .env file
|
|
214
|
+
* @param envFile - The source of the .env file
|
|
215
|
+
* @returns The parsed object
|
|
216
|
+
* @public API
|
|
217
|
+
*/
|
|
218
|
+
function parse(envFile) {
|
|
219
|
+
const obj = {};
|
|
220
|
+
const lines = envFile.toString().replace(/\r\n?/gm, "\n");
|
|
221
|
+
let match;
|
|
222
|
+
while ((match = constants_1.LINE_REGEX.exec(lines)) != null) {
|
|
223
|
+
const key = match[1].trim();
|
|
224
|
+
let value = match[2]?.trim() ?? "";
|
|
225
|
+
if (["'", '"', "`"].includes(value[0])) {
|
|
226
|
+
value = value.slice(1, -1);
|
|
227
|
+
}
|
|
228
|
+
value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
|
|
229
|
+
if (match[2]?.[0] === '"') {
|
|
230
|
+
value = value.replace(/\\n/g, "\n").replace(/\\r/g, "\r");
|
|
231
|
+
}
|
|
232
|
+
obj[key] = value;
|
|
233
|
+
}
|
|
234
|
+
return obj;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Decrypts a base64 encoded string
|
|
238
|
+
* @param encrypted - The base64 encoded string to decrypt
|
|
239
|
+
* @param keyStr - The key to use for decryption
|
|
240
|
+
* @returns The decrypted string
|
|
241
|
+
* @public API
|
|
242
|
+
*/
|
|
243
|
+
function decrypt(encrypted, keyStr) {
|
|
244
|
+
const key = Buffer.from(keyStr.slice(-64), "hex");
|
|
245
|
+
let ciphertext = Buffer.from(encrypted, "base64");
|
|
246
|
+
const nonce = ciphertext.subarray(0, 12);
|
|
247
|
+
const authTag = ciphertext.subarray(-16);
|
|
248
|
+
ciphertext = ciphertext.subarray(12, -16);
|
|
249
|
+
try {
|
|
250
|
+
const aesgcm = crypto_1.default.createDecipheriv("aes-256-gcm", key, nonce);
|
|
251
|
+
aesgcm.setAuthTag(authTag);
|
|
252
|
+
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
const isRange = error instanceof RangeError;
|
|
256
|
+
const invalidKeyLength = error.message === "Invalid key length";
|
|
257
|
+
const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
|
|
258
|
+
if (isRange || invalidKeyLength) {
|
|
259
|
+
const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
260
|
+
err.name = "INVALID_DOTENV_KEY";
|
|
261
|
+
throw err;
|
|
262
|
+
}
|
|
263
|
+
else if (decryptionFailed) {
|
|
264
|
+
const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
265
|
+
err.name = "DECRYPTION_FAILED";
|
|
266
|
+
throw err;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
throw error;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Populates the environment with the given parsed object
|
|
275
|
+
* @param envObject - The object to populate the environment with (e.g. process.env)
|
|
276
|
+
* @param parsed - The parsed object
|
|
277
|
+
* @param options - The configuration options
|
|
278
|
+
* @public API
|
|
279
|
+
*/
|
|
280
|
+
function populate(envObject, // Usually process.env
|
|
281
|
+
parsed, options = {}) {
|
|
282
|
+
const debug = Boolean(options && options.debug);
|
|
283
|
+
const override = Boolean(options && options.override);
|
|
284
|
+
if (typeof parsed !== "object") {
|
|
285
|
+
const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
286
|
+
err.name = "OBJECT_REQUIRED";
|
|
287
|
+
throw err;
|
|
288
|
+
}
|
|
289
|
+
// Set process.env (envObject)
|
|
290
|
+
for (const key of Object.keys(parsed)) {
|
|
291
|
+
const parsedValue = parsed[key];
|
|
292
|
+
// Decide whether to override existing env var or not
|
|
293
|
+
if (Object.prototype.hasOwnProperty.call(envObject, key)) {
|
|
294
|
+
if (override) {
|
|
295
|
+
envObject[key] = parsedValue;
|
|
296
|
+
if (debug) {
|
|
297
|
+
(0, logger_1.log)(`"${key}" was overwritten to "${parsedValue}"`, logger_1.LogLevel.Debug);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else if (debug) {
|
|
301
|
+
(0, logger_1.log)(`"${key}" was NOT overwritten (already exists)`, logger_1.LogLevel.Debug);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
// Variable doesn't exist in process.env, so set it
|
|
306
|
+
envObject[key] = parsedValue;
|
|
307
|
+
if (debug) {
|
|
308
|
+
(0, logger_1.log)(`"${key}" was set to "${parsedValue}"`, logger_1.LogLevel.Debug);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// Final debug log to ensure variables are correctly populated
|
|
313
|
+
if (debug) {
|
|
314
|
+
console.log("Final process.env object:", envObject);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./environment"), exports);
|