├── .changeset ├── README.md └── config.json ├── .dockerignore ├── .github └── workflows │ ├── docs.yml │ ├── main.yml │ └── release.yml ├── .gitignore ├── .husky └── pre-commit ├── .npmrc ├── CNAME ├── Dockerfile ├── README.md ├── docs ├── .dockerignore ├── .gitignore ├── CHANGELOG.md ├── README.md ├── astro.config.mjs ├── package.json ├── public │ └── favicon.svg ├── src │ ├── assets │ │ └── houston.webp │ ├── content │ │ ├── config.ts │ │ └── docs │ │ │ ├── getting-started │ │ │ ├── about.md │ │ │ ├── architecture.md │ │ │ ├── command-line.md │ │ │ ├── comparison.md │ │ │ ├── env-files.md │ │ │ ├── expand.md │ │ │ ├── loading-priorities.md │ │ │ ├── monorepo-setup.md │ │ │ ├── options.md │ │ │ └── quick-start.md │ │ │ ├── index.mdx │ │ │ ├── integrations │ │ │ ├── babel.md │ │ │ ├── cli.md │ │ │ ├── core.md │ │ │ ├── esbuild.md │ │ │ ├── loader.md │ │ │ ├── node.md │ │ │ ├── rollup.md │ │ │ ├── vite.md │ │ │ └── webpack.md │ │ │ └── recipes │ │ │ └── angular.md │ ├── env.d.ts │ └── styles │ │ └── custom.css └── tsconfig.json ├── examples ├── nx-workspace-old │ ├── .dockerignore │ ├── .env.app │ ├── .env.app.dev │ ├── .env.app.prod │ ├── .gitignore │ ├── .secrets │ ├── .secrets.prod │ ├── .verdaccio │ │ └── config.yml │ ├── apps │ │ ├── cli-app │ │ │ ├── .secrets │ │ │ ├── .secrets.local │ │ │ ├── .secrets.prod │ │ │ ├── .secrets.prod.local │ │ │ ├── __snapshots__ │ │ │ │ └── cli.test.ts.snap │ │ │ ├── cli.test.ts │ │ │ ├── package.json │ │ │ ├── project.json │ │ │ └── turbo.json │ │ ├── ng-app-cli │ │ │ ├── .app.prod │ │ │ ├── .editorconfig │ │ │ ├── .env │ │ │ ├── .env.local │ │ │ ├── .env.prod │ │ │ ├── .env.test │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── jest.config.mjs │ │ │ ├── karma.conf.js │ │ │ ├── package.json │ │ │ ├── playwright.config.ts │ │ │ ├── project.json │ │ │ ├── setup-jest.ts │ │ │ ├── src │ │ │ │ ├── app │ │ │ │ │ ├── app.component.css │ │ │ │ │ ├── app.component.html │ │ │ │ │ ├── app.component.spec.ts │ │ │ │ │ ├── app.component.ts │ │ │ │ │ ├── app.config.server.ts │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.routes.ts │ │ │ │ │ └── hello │ │ │ │ │ │ ├── hello.component.css │ │ │ │ │ │ ├── hello.component.html │ │ │ │ │ │ ├── hello.component.spec.ts │ │ │ │ │ │ └── hello.component.ts │ │ │ │ ├── assets │ │ │ │ │ └── .gitkeep │ │ │ │ ├── env.d.ts │ │ │ │ ├── environments │ │ │ │ │ ├── environment.prod.ts │ │ │ │ │ └── environment.ts │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── locale │ │ │ │ │ ├── messages.fr.xlf │ │ │ │ │ └── messages.xlf │ │ │ │ ├── main.server.ts │ │ │ │ ├── main.ts │ │ │ │ ├── server.ts │ │ │ │ └── styles.css │ │ │ ├── tests │ │ │ │ └── app.spec.ts │ │ │ ├── tsconfig.app.json │ │ │ ├── tsconfig.json │ │ │ └── tsconfig.spec.json │ │ ├── ng-app-webpack │ │ │ ├── .editorconfig │ │ │ ├── .env.app │ │ │ ├── .env.app.local │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.ignore.json │ │ │ ├── playwright.config.ts │ │ │ ├── project.ignore.json │ │ │ ├── src │ │ │ │ ├── app │ │ │ │ │ ├── app.component.html │ │ │ │ │ ├── app.component.ts │ │ │ │ │ └── app.module.ts │ │ │ │ ├── assets │ │ │ │ │ └── .gitkeep │ │ │ │ ├── env.d.ts │ │ │ │ ├── environments │ │ │ │ │ ├── environment.prod.ts │ │ │ │ │ └── environment.ts │ │ │ │ ├── favicon.ico │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ ├── polyfills.ts │ │ │ │ ├── styles.css │ │ │ │ └── test.ts │ │ │ ├── tsconfig.app.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.spec.json │ │ │ └── webpack.config.ts │ │ ├── rspack-app │ │ │ ├── __snapshots__ │ │ │ │ ├── rspack-dev.test.ts.snap │ │ │ │ └── rspack-prod.test.ts.snap │ │ │ ├── package.json │ │ │ ├── project.json │ │ │ ├── rspack-dev.test.ts │ │ │ ├── rspack-prod.test.ts │ │ │ ├── rspack.config.mjs │ │ │ └── src │ │ │ │ └── index.js │ │ └── webpack-app │ │ │ ├── __snapshots__ │ │ │ ├── webpack-dev.test.ts.snap │ │ │ └── webpack-prod.test.ts.snap │ │ │ ├── package.json │ │ │ ├── project.json │ │ │ ├── src │ │ │ └── index.js │ │ │ ├── webpack-dev.test.ts │ │ │ ├── webpack-prod.test.ts │ │ │ └── webpack.config.mjs │ ├── libs │ │ └── rollup-lib │ │ │ ├── package.json │ │ │ ├── project.json │ │ │ ├── rollup.config.mjs │ │ │ └── src │ │ │ ├── index.mjs │ │ │ └── index.test.js │ ├── nx.json │ ├── package.json │ └── project.json └── nx-workspace │ ├── .editorconfig │ ├── .github │ └── workflows │ │ └── ci.yml │ ├── .gitignore │ ├── .prettierignore │ ├── .prettierrc │ ├── README.md │ ├── apps │ ├── ng-app-cli-e2e │ │ ├── eslint.config.js │ │ ├── playwright.config.ts │ │ ├── project.json │ │ ├── src │ │ │ └── example.spec.ts │ │ └── tsconfig.json │ └── ng-app-cli │ │ ├── eslint.config.js │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── project.json │ │ ├── public │ │ └── favicon.ico │ │ ├── server.ts │ │ ├── src │ │ ├── app │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ ├── app.config.server.ts │ │ │ ├── app.config.ts │ │ │ └── app.routes.ts │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── main.server.ts │ │ ├── main.ts │ │ ├── styles.css │ │ └── test-setup.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.editor.json │ │ ├── tsconfig.json │ │ └── tsconfig.spec.json │ ├── eslint.config.js │ ├── jest.config.ts │ ├── jest.preset.js │ ├── nx.json │ ├── package.json │ └── tsconfig.base.json ├── package.json ├── packages ├── .env ├── angular │ ├── CHANGELOG.md │ ├── README.md │ ├── builders.json │ ├── collection.json │ ├── logo.svg │ ├── manekinekko.png │ ├── motdotla.png │ ├── package.json │ ├── runtime.mjs │ ├── src │ │ ├── builders │ │ │ ├── application │ │ │ │ ├── application.json │ │ │ │ └── index.ts │ │ │ ├── browser-esbuild │ │ │ │ ├── browser-esbuild.json │ │ │ │ └── index.ts │ │ │ ├── browser │ │ │ │ ├── browser.json │ │ │ │ └── index.ts │ │ │ ├── dev-server │ │ │ │ ├── dev-server.json │ │ │ │ └── index.ts │ │ │ ├── extract-i18n │ │ │ │ ├── extract-i18n.json │ │ │ │ └── index.ts │ │ │ ├── karma │ │ │ │ ├── index.ts │ │ │ │ └── karma.json │ │ │ ├── ngx-env │ │ │ │ ├── ngx-env-schema.ts │ │ │ │ └── ngx-env.json │ │ │ ├── server │ │ │ │ ├── index.ts │ │ │ │ └── server.json │ │ │ └── utils │ │ │ │ ├── escape-string-regexp.ts │ │ │ │ ├── get-environment.ts │ │ │ │ ├── index-html-build.ts │ │ │ │ ├── index-html-serve.ts │ │ │ │ ├── project.ts │ │ │ │ ├── variables-reducer.ts │ │ │ │ ├── webpack-plugin.ts │ │ │ │ └── workspace.ts │ │ └── schematics │ │ │ └── ng-add │ │ │ ├── index.ts │ │ │ ├── schema.json │ │ │ └── template │ │ │ └── env.d.ts │ ├── tools │ │ ├── cli-targets.ts │ │ ├── schema-copy-run.ts │ │ ├── schema-copy.ts │ │ ├── schema-dist.ts │ │ └── schema-generate.ts │ └── tsconfig.json ├── cli │ ├── .env.dev │ ├── .env.prod │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.mts │ │ └── run.ts │ ├── test │ │ └── cli.test.ts │ └── tsconfig.json ├── core │ ├── .env.dev │ ├── .env.prod │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── build.ts │ │ ├── env.ts │ │ ├── expand.ts │ │ ├── index.ts │ │ ├── options.ts │ │ ├── root.ts │ │ └── utils.ts │ ├── test │ │ ├── dev.test.ts │ │ └── prod.test.ts │ └── tsconfig.json ├── esbuild │ ├── .env │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── test │ │ ├── __snapshots__ │ │ │ └── index.test.ts.snap │ │ ├── app.js │ │ ├── index.test.ts │ │ └── util.js │ └── tsconfig.json ├── jest-angular │ ├── CHANGELOG.md │ ├── README.md │ ├── index.mjs │ └── package.json ├── jest │ ├── package.json │ └── src │ │ └── jest-env.mjs ├── load │ ├── .env │ ├── .env.dev │ ├── .env.prod │ ├── CHANGELOG.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── test │ │ ├── load.test.ts │ │ └── server.js │ └── tsconfig.json ├── rollup │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── rspack │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── vite │ ├── README.md │ ├── package.json │ ├── src │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── mapper.ts │ │ └── options.ts │ └── tsconfig.json └── webpack │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ └── index.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── turbo.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": ["!@dotenv-run/**", "!@ngx-env/**"] 11 | } 12 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .vscode 3 | .DS_Store 4 | node_modules 5 | dist 6 | tmp 7 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub Pages 2 | 3 | on: 4 | # Trigger the workflow every time you push to the `main` branch 5 | # Using a different branch name? Replace `main` with your branch’s name 6 | push: 7 | branches: [main] 8 | # Allows you to run this workflow manually from the Actions tab on GitHub. 9 | workflow_dispatch: 10 | 11 | # Allow this job to clone the repo and create a page deployment 12 | permissions: 13 | contents: read 14 | pages: write 15 | id-token: write 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout your repository using git 22 | uses: actions/checkout@v4 23 | - name: Install, build, and upload your site 24 | uses: withastro/action@v2 25 | with: 26 | node-version: 20 27 | path: ./docs # The root location of your Astro project inside the repository. (optional) 28 | package-manager: pnpm@10 # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional) 29 | 30 | deploy: 31 | needs: build 32 | runs-on: ubuntu-latest 33 | environment: 34 | name: github-pages 35 | url: ${{ steps.deployment.outputs.page_url }} 36 | steps: 37 | - name: Deploy to GitHub Pages 38 | id: deployment 39 | uses: actions/deploy-pages@v4 40 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | pull_request: 5 | branches: [main] 6 | 7 | jobs: 8 | build: 9 | name: Build 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-node@v3 14 | with: 15 | node-version: 20 16 | - uses: pnpm/action-setup@v4 17 | - name: Install Packages 18 | run: | 19 | pnpm i 20 | - name: Build Packages 21 | run: | 22 | pnpm build 23 | pnpm i # create bin scripts 24 | - name: Test Packages 25 | run: | 26 | pnpm test 27 | - name: Build and Test Examples 28 | run: | 29 | cd examples/nx-workspace-old 30 | pnpm playwright install --with-deps 31 | cd apps/ng-app-cli 32 | # npx ng add ../../../packages/angular --skip-confirmation 33 | npx tsc --noEmit --project tsconfig.app.json 34 | cd - 35 | pnpm build:all 36 | pnpm test:all 37 | pnpm e2e:all 38 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | release: 9 | name: Release 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-node@v3 14 | with: 15 | node-version: 20 16 | - uses: pnpm/action-setup@v4 17 | - name: Prepare Packages 18 | run: | 19 | pnpm i 20 | pnpm build 21 | pnpm build:docs 22 | - name: Publish @dotenv-run packages 23 | id: changesets 24 | uses: changesets/action@v1 25 | with: 26 | publish: pnpm publish -r --no-git-checks --access public 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 30 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .vscode 3 | .DS_Store 4 | node_modules 5 | dist 6 | tmp 7 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npm test 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | auto-install-peers=false -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | dotenv.run -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18 2 | 3 | RUN npm install -g pnpm 4 | 5 | WORKDIR /app 6 | 7 | COPY . /app 8 | RUN pnpm install --frozen-lockfile 9 | RUN cd examples/nx-workspace-old && pnpm playwright install --with-deps && cd - 10 | RUN CI=1 pnpm test 11 | RUN pnpm build && \ 12 | cd examples/nx-workspace-old && \ 13 | cd apps/ng-app-cli && \ 14 | # npx ng add ../../../packages/angular --skip-confirmation 15 | npx tsc --noEmit --project tsconfig.app.json && \ 16 | cd - && \ 17 | pnpm build:all && \ 18 | CI=1 pnpm test:all && \ 19 | pnpm e2e:all 20 | 21 | CMD echo "Build successful" 22 | -------------------------------------------------------------------------------- /docs/.dockerignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/docs 2 | 3 | ## 0.1.5 4 | 5 | ### Patch Changes 6 | 7 | - chore: use pnpm workspace protocol for dependencies 8 | 9 | ## 0.1.4 10 | 11 | ### Patch Changes 12 | 13 | - docs: updates packages' README files 14 | 15 | ## 0.1.3 16 | 17 | ### Patch Changes 18 | 19 | - fix(cli): fix unsecure mode alias 20 | 21 | ## 0.1.2 22 | 23 | ### Patch Changes 24 | 25 | - feat(angular): add unsecure mode option 26 | 27 | ## 0.1.1 28 | 29 | ### Patch Changes 30 | 31 | - feat: add secure mode to debug info 32 | 33 | ## 0.1.0 34 | 35 | ### Minor Changes 36 | 37 | - refactor and docs initialization 38 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Starlight Starter Kit: Basics 2 | 3 | ``` 4 | npm create astro@latest -- --template starlight 5 | ``` 6 | 7 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) 8 | [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) 9 | 10 | > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 11 | 12 | ## 🚀 Project Structure 13 | 14 | Inside of your Astro + Starlight project, you'll see the following folders and files: 15 | 16 | ``` 17 | . 18 | ├── public/ 19 | ├── src/ 20 | │ ├── assets/ 21 | │ ├── content/ 22 | │ │ ├── docs/ 23 | │ │ └── config.ts 24 | │ └── env.d.ts 25 | ├── astro.config.mjs 26 | ├── package.json 27 | └── tsconfig.json 28 | ``` 29 | 30 | Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. 31 | 32 | Images can be added to `src/assets/` and embedded in Markdown with a relative link. 33 | 34 | Static assets, like favicons, can be placed in the `public/` directory. 35 | 36 | ## 🧞 Commands 37 | 38 | All commands are run from the root of the project, from a terminal: 39 | 40 | | Command | Action | 41 | | :------------------------ | :----------------------------------------------- | 42 | | `npm install` | Installs dependencies | 43 | | `npm run dev` | Starts local dev server at `localhost:3000` | 44 | | `npm run build` | Build your production site to `./dist/` | 45 | | `npm run preview` | Preview your build locally, before deploying | 46 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | 47 | | `npm run astro -- --help` | Get help using the Astro CLI | 48 | 49 | ## 👀 Want to learn more? 50 | 51 | Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). 52 | -------------------------------------------------------------------------------- /docs/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config'; 2 | import starlight from '@astrojs/starlight'; 3 | 4 | // https://astro.build/config 5 | export default defineConfig({ 6 | site: 'https://dotenv.run', 7 | base: '/', 8 | integrations: [ 9 | starlight({ 10 | title: 'dotenv.run', 11 | social: { 12 | github: 'https://github.com/chihab/dotenv-run', 13 | }, 14 | sidebar: [ 15 | { 16 | label: 'Getting Started', 17 | items: [ 18 | { label: 'Introduction', link: '/' }, 19 | { label: 'Quick Start', link: '/getting-started/quick-start/' }, 20 | { label: 'Variables', items: [{ label: '.env files', link: '/getting-started/env-files/' }, { label: 'expand', link: '/getting-started/expand/' }, { label: 'command line', link: '/getting-started/command-line/' }] }, 21 | { label: 'Loading Priorities', link: '/getting-started/loading-priorities/' }, 22 | { label: 'Monorepo Setup ✨', link: '/getting-started/monorepo-setup/' }, 23 | // { label: 'Comparison', link: '/getting-started/comparison/' }, 24 | // { label: 'About', link: '/getting-started/about/' }, 25 | ], 26 | }, 27 | { 28 | label: 'Integrations', 29 | items: [ 30 | { label: 'CLI', link: '/integrations/cli/' }, 31 | { label: 'Node.js', link: '/integrations/loader/' }, 32 | { label: 'Rollup', link: '/integrations/rollup/' }, 33 | { label: 'Webpack', link: '/integrations/webpack/' }, 34 | { label: 'Vite', link: '/integrations/vite/' }, 35 | // { label: 'Babel', link: '/integrations/webpack/' }, 36 | // { label: 'Jest', link: '/integrations/jest/' }, 37 | // { label: 'SWC', link: '/integrations/swc/' }, 38 | // { label: 'ESBuild', link: '/integrations/esbuild/' }, 39 | { label: 'Core', link: '/integrations/core/' }, 40 | ], 41 | }, 42 | // { 43 | // label: 'Recipes', 44 | // items: [ 45 | // { label: 'Nx', link: '/recipes/nx/' }, 46 | // { label: 'Turbo', link: '/recipes/turbo/' }, 47 | // { label: 'Docker', link: '/recipes/docker/' }, 48 | // { label: 'Next.js', link: '/recipes/next.js/' }, 49 | // { label: 'Angular', link: '/integrations/angular/' }, 50 | // ], 51 | // }, 52 | ], 53 | customCss: [ 54 | // Relative path to your custom CSS file 55 | './src/styles/custom.css', 56 | ], 57 | }), 58 | ], 59 | image: { service: { entrypoint: 'astro/assets/services/sharp' } }, 60 | }); 61 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/docs", 3 | "private": true, 4 | "type": "module", 5 | "version": "0.1.5", 6 | "scripts": { 7 | "dev": "astro dev", 8 | "start": "astro dev", 9 | "build": "astro build", 10 | "preview": "astro preview", 11 | "astro": "astro" 12 | }, 13 | "dependencies": { 14 | "@astrojs/starlight": "^0.15.4", 15 | "astro": "^4.15.11", 16 | "sharp": "^0.33.5" 17 | } 18 | } -------------------------------------------------------------------------------- /docs/public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/src/assets/houston.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/docs/src/assets/houston.webp -------------------------------------------------------------------------------- /docs/src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection } from 'astro:content'; 2 | import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; 3 | 4 | export const collections = { 5 | docs: defineCollection({ schema: docsSchema() }), 6 | i18n: defineCollection({ type: 'data', schema: i18nSchema() }), 7 | }; 8 | -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | --- 4 | 5 | TODO -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/architecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Architecture 3 | --- 4 | 5 | @dotenv-run/cli 6 | |- @dotenv-run/core 7 | * Locate .env files and creates a `dotenv` object 8 | * Expands variables in .env files 9 | * Filter variables by prefix 10 | 11 | @dotenv-run/webpack 12 | * Webpack plugin that injects environment variables into the build 13 | |- @dotenv-run/core 14 | 15 | @angular-builders/custom-webpack 16 | |- @dotenv-run/webpack 17 | 18 | @ngx-env/builder 19 | |- @dotenv-run/webpack 20 | 21 | @ngx-env/esbuilder 22 | |- @dotenv-run/esbuilder -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/command-line.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Command Line 3 | --- 4 | 5 | Defining environment variables can vary between OSes. It’s also important to know that this manner is temporary for the life of the shell session. 6 | 7 | 8 | ## Windows (cmd.exe) 9 | 10 | ```cmd 11 | set "API_URL=abcdef" && dotenv-run -- npm start 12 | ``` 13 | 14 | (Note: Quotes around the variable assignment are required to avoid a trailing whitespace.) 15 | 16 | ## Windows (Powershell) 17 | 18 | ```Powershell 19 | ($env:API_URL = "abcdef") -and (dotenv-run -- npm start) 20 | ``` 21 | 22 | ## Linux, macOS (Bash) 23 | 24 | ```sh 25 | API_URL=abcdef dotenv-run -- npm start 26 | ``` -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/comparison.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Comparison 3 | --- 4 | 5 | TODO -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/env-files.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: .env files 3 | --- 4 | 5 | A .env file is a simple text file that stores environment variables. Environment variables are key-value pairs that are used to configure applications and services. They can be used to store things like database passwords, API keys, and other sensitive information. 6 | 7 | .env files are typically located in the root directory of a project. They are ignored by version control systems, so you can store sensitive information in them without worrying about it being exposed. 8 | 9 | To use a .env file, you need to load it into your application's environment. There are a number of ways to do this, depending on the programming language and framework you are using. 10 | 11 | Here is an example of a .env file: 12 | 13 | ``` 14 | DATABASE_URL=postgres://user:password@localhost:5432/my_database 15 | API_KEY=1234567890 16 | ``` 17 | 18 | This file defines two environment variables: 19 | 20 | * DATABASE_URL: The URL of the database server 21 | * API_KEY: The API key for a third-party service 22 | 23 | .env files are a convenient way to store environment variables. They are easy to use and secure, making them a valuable tool for developers. 24 | 25 | Here are some additional things to keep in mind when using .env files: 26 | 27 | * Use a consistent naming convention for your environment variables. This will make it easier to find and manage them. 28 | * Use comments in your .env file to document what each variable is used for. This will be helpful for future developers who need to work on your project. 29 | * Don't commit your .env file to version control. This will help to keep your sensitive information secure. -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/expand.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Expanding Variables 3 | --- 4 | 5 | 6 | You can expand variables already available on your machine for use in your `.env` 7 | 8 | For example: 9 | 10 | ```shell 11 | VERSION=$npm_package_version 12 | HOSTNAME=$HOSTNAME 13 | ``` 14 | 15 | Or expand variables local to the current `.env` file: 16 | 17 | ```shell 18 | DOMAIN=www.example.com 19 | FOO=$DOMAIN/foo 20 | BAR=$DOMAIN/bar 21 | ``` -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/loading-priorities.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Loading Priorities 3 | --- 4 | 5 | `@dotenv-run/cli` uses [dotenv](https://github.com/motdotla/dotenv) to support loading environment variables from `.env` files. 6 | 7 | `@dotenv-run/cli` loads `.env` files with these specific names for the following `-e ENV` value, files on the top have less priority than files on the bottom. 8 | 9 | An env file for a specific mode (e.g. .env.production) will take higher priority than a generic one (e.g. .env). 10 | 11 | | valid `.env` filenames | `ENV=*` | `ENV=test` | 12 | | -------------------------- | -------------- | --------------- | 13 | | `.env` | ✔️ | ✔️ | 14 | | `.env.local` | ✔️ | ✖️ | 15 | | `.env.${ENV}` | ✔️ | ✔️ | 16 | | `.env.${ENV}.local` | ✔️ | ✔️ | 17 | 18 | In addition, environment variables that already exist when the CLI is executed have the highest priority and will not be overwritten by .env files. For example, when running `SOME_KEY=123 dotenv-run`. 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/monorepo-setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Monorepo Setup 3 | --- 4 | 5 | In a monorepo configuration, `.env.*` files can be defined in the root workspace and overriden by each application: 6 | 7 | Let's say we have the following monorepo structure: 8 | 9 | ```shell 10 | platform 11 | ├── apps 12 | │ ├── vite-app 13 | │ │ ├── .env.local # API_USERS=http://localhost:3001/users 14 | │ │ └── vite.config.js 15 | │ └── webpack-app 16 | │ │ ├── package.json 17 | │ │ └── webapp.config.mjs 18 | │ └── node-app 19 | │ └── package.json 20 | ├── libs 21 | │ └── rollup-lib 22 | │ ├── package.json 23 | │ └── rollup.config.mjs 24 | ├── .env.dev # API_BASE=https://dotenv-run.dev 25 | ├── .env.prod # API_BASE=https://dotenv-run.app 26 | ├── .env # API_USERS=$API_BASE/api/v1/users API_AUTH=https://$API_BASE/auth 27 | ├── nx.json 28 | └── package.json 29 | ``` 30 | 31 | `dotenv-run` will search and load `.env.*` files located in the root workspace down to the current working directory. 32 | 33 | ### cli 34 | 35 | ```sh 36 | NODE_ENV=prod nx run build 37 | ✔ /platform/.env.prod 38 | ✔ /platform/.env 39 | https://dotenv-run.app/api/v1/users 40 | ``` 41 | 42 | ```shell 43 | cd /platform/apps/frontend1 44 | NODE_ENV=dev vite 45 | ✔ /platform/apps/frontend1/.env.local 46 | ✔ /platform/.env.dev 47 | ✔ /platform/.env 48 | API_USERS http://localhost:3001/users 49 | ``` 50 | 51 | See [vite plugin](/docs/integrations/vite) for more details. 52 | -------------------------------------------------------------------------------- /docs/src/content/docs/getting-started/options.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Options 3 | --- -------------------------------------------------------------------------------- /docs/src/content/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | --- 4 | 5 | Defining configuration as environment variables is one of the tenets of a [twelve-factor app](https://12factor.net/config), it separates the config from your codebase and keeps it under your control. 6 | 7 | `dotenv-run` is a collection of packages that use **dotenv** to support loading environment variables from `.env` files with multiple integrations. 8 | 9 | Here are some of the benefits of using @dotenv-run: 10 | 11 | - **Simple**: seamelessly integrates with your existing workflow. 12 | - **Flexible**: supports multiple `.env` files and loading priorities. 13 | - **Expand**: supports expanding variables already available on your machine for use in your `.env` files. 14 | - **Secure**: supports filtering environment variables by prefix. 15 | - **Monorepo ✨**: supports monorepo projects with multiple applications. .env files can be defined in the root workspace and overriden by each application. 16 | - **TypeScript**: supports TypeScript projects with type definitions for `process.env` and `import.meta.env`. 17 | - **ESM**: supports `process.env` and `import.meta.env` in ESM modules. 18 | - **Universal**: supports multiple intergrations including CLI, Node.js preload, Webpack, Rollup, Vite, and esbuild. 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/src/content/docs/integrations/babel.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Babel 3 | --- -------------------------------------------------------------------------------- /docs/src/content/docs/integrations/core.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Core 3 | --- 4 | 5 | ## install 6 | 7 | ```console 8 | npm add @dotenv-run/core 9 | ``` 10 | 11 | ## usage 12 | 13 | ```js 14 | // index.js 15 | import { expand, paths } from "@dotenv-run/core"; 16 | expand(paths(process.env.NODE_ENV, '../../')); 17 | console.log(process.env.API_USERS); 18 | ``` 19 | 20 | given the following files: 21 | 22 | ```shell 23 | .env 24 | API_USERS=$API_BASE/v1/users 25 | API_AUTH=$API_BASE/v1/auth 26 | .env.dev 27 | API_BASE=https://localhost:3000 28 | .env.prod 29 | API_BASE=https://dotenv-run.app 30 | ``` 31 | 32 | then: 33 | 34 | ```shell 35 | NODE_ENV=dev node index.js 36 | https://localhost:3000/v1/users 37 | ``` 38 | 39 | ```shell 40 | NODE_ENV=prod node index.js 41 | https://dotenv-run.app/v1/users 42 | ``` 43 | 44 | The list of options is the same as the ones supported by `@dotenv-run/core`. Please refer to the [API](#api) section for more details. 45 | -------------------------------------------------------------------------------- /docs/src/content/docs/integrations/esbuild.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ESBuild 3 | --- -------------------------------------------------------------------------------- /docs/src/content/docs/integrations/loader.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Loader 3 | --- 4 | 5 | # install 6 | 7 | ```console 8 | npm add @dotenv-run/load 9 | ``` 10 | 11 | # usage 12 | 13 | ```js 14 | // index.js 15 | console.log(process.env.API_USERS); 16 | ``` 17 | 18 | Given the following `.env` files: 19 | 20 | ```shell 21 | .env 22 | API_USERS=$API_BASE/v1/users 23 | API_AUTH=$API_BASE/v1/auth 24 | .env.dev 25 | API_BASE=https://localhost:3000 26 | .env.prod 27 | API_BASE=https://dotenv-run.app 28 | ``` 29 | 30 | ```shell 31 | NODE_ENV=dev node -r @dotenv-run/load ./index.js 32 | https://localhost:3000/v1/users 33 | ``` 34 | 35 | ```shell 36 | NODE_ENV=prod node -r @dotenv-run/load ./index.js 37 | https://dotenv-run.app/v1/users 38 | ``` 39 | 40 | ```shell 41 | NODE_ENV=prod NODE_OPTIONS='-r @dotenv-run/load' node ./index.js 42 | https://dotenv-run.app/v1/users 43 | ``` 44 | 45 | 46 | -------------------------------------------------------------------------------- /docs/src/content/docs/integrations/node.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Node.js 3 | --- -------------------------------------------------------------------------------- /docs/src/content/docs/integrations/rollup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Rollup 3 | --- 4 | 5 | ## install 6 | 7 | 8 | ```console 9 | npm add @dotenv-run/rollup --save-dev 10 | ``` 11 | 12 | ## usage 13 | 14 | Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin: 15 | 16 | ```js 17 | import env from '@dotenv-run/rollup'; 18 | 19 | export default { 20 | input: 'src/index.js', 21 | output: { 22 | file: 'dist/index.js', 23 | }, 24 | plugins: [ 25 | env({ prefix: 'API', verbose: true, root: '../../..' }) 26 | ] 27 | }; 28 | ``` 29 | 30 | Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api). 31 | 32 | 33 | The list of options is the same as the ones supported by `@dotenv-run/core`. Please refer to the [API](#api) section for more details. -------------------------------------------------------------------------------- /docs/src/content/docs/integrations/vite.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vite 3 | --- 4 | 5 | ## Install 6 | 7 | ```console 8 | npm add @dotenv-run/vite --save-dev 9 | ``` 10 | 11 | ## Usage 12 | 13 | Create a `vite.config.js` [configuration file](https://vite.dev/config) and import the plugin: 14 | 15 | ```js 16 | import env from "@dotenv-run/vite"; 17 | 18 | export default { 19 | envPrefix: 'MY_PREFIX_', 20 | envDir: './my-env-directory', 21 | plugins: [env()], 22 | }; 23 | ``` 24 | 25 | Then call `vite` or `vite build` either via the [CLI](https://vite.dev/guide/cli.html). 26 | 27 | The available options are similar to those supported by [`@dotenv-run/core`](https://www.npmjs.com/package/@dotenv-run/core), but this plugin seamlessly integrates with Vite by automatically deriving the root, prefix, and environment values from its standard configuration, ensuring a more cohesive experience. For more details, refer to the API section. 28 | -------------------------------------------------------------------------------- /docs/src/content/docs/integrations/webpack.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Webpack 3 | --- 4 | 5 | ## install 6 | 7 | ```console 8 | npm add @dotenv-run/webpack --save-dev 9 | ``` 10 | 11 | ## usage 12 | 13 | Create a `webpack.config.js` [configuration file](https://www.webpackjs.org/guide/en/#configuration-files) and import the plugin: 14 | 15 | ```js 16 | import { DotenvRunPlugin } from '@dotenv-run/webpack'; 17 | import path from 'path'; 18 | 19 | const __dirname = path.resolve(); 20 | 21 | export default { 22 | entry: './src/index.js', 23 | output: { 24 | filename: 'main.js', 25 | path: path.resolve(__dirname, 'dist'), 26 | }, 27 | plugins: [ 28 | new DotenvRunPlugin( 29 | { prefix: 'API', verbose: true, root: '../../..' }, 30 | __dirname 31 | ) 32 | ] 33 | } 34 | ``` 35 | 36 | The list of options is the same as the ones supported by `@dotenv-run/core`. Please refer to the [API](#api) section for more details. -------------------------------------------------------------------------------- /docs/src/content/docs/recipes/angular.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Angular 3 | --- -------------------------------------------------------------------------------- /docs/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /docs/src/styles/custom.css: -------------------------------------------------------------------------------- 1 | /* Dark mode colors. */ 2 | :root { 3 | --sl-color-accent-low: #331833; 4 | --sl-color-accent: #2db492; 5 | --sl-color-accent-high: #5f937f; 6 | --sl-color-white: #ffffff; 7 | --sl-color-gray-1: #e1f0ff; 8 | --sl-color-gray-2: #a7c6e5; 9 | --sl-color-gray-5: #3c4348; 10 | --sl-color-gray-5: #3c4348; 11 | --sl-color-gray-5: #3c4348; 12 | --sl-color-gray-5: #3c4348; 13 | --sl-color-gray-5: #3c4348; 14 | } 15 | 16 | /* Light mode colors. */ 17 | :root[data-theme='light'] { 18 | --sl-color-accent-low: #e8cde7; 19 | --sl-color-accent: #2db492; 20 | --sl-color-accent-high: #5f937f; 21 | --sl-color-white: #011930; 22 | --sl-color-gray-1: #002849; 23 | --sl-color-gray-2: #003a66; 24 | --sl-color-gray-3: #195b93; 25 | --sl-color-gray-4: #5290cc; 26 | --sl-color-gray-5: #a7c6e5; 27 | --sl-color-gray-6: #e1f0ff; 28 | --sl-color-gray-7: #f0f7ff; 29 | --sl-color-black: #ffffff; 30 | } -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict" 3 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/.dockerignore: -------------------------------------------------------------------------------- 1 | .nx 2 | test-results 3 | tests 4 | playwright-report 5 | tests-examples -------------------------------------------------------------------------------- /examples/nx-workspace-old/.env.app: -------------------------------------------------------------------------------- 1 | API_USERS=$API_BASE/api/v1/users 2 | API_AUTH=$API_BASE/api/v1/auth -------------------------------------------------------------------------------- /examples/nx-workspace-old/.env.app.dev: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-run.dev -------------------------------------------------------------------------------- /examples/nx-workspace-old/.env.app.prod: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-run.app -------------------------------------------------------------------------------- /examples/nx-workspace-old/.gitignore: -------------------------------------------------------------------------------- 1 | .nx 2 | test-results 3 | playwright-report 4 | tests-examples -------------------------------------------------------------------------------- /examples/nx-workspace-old/.secrets: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-secret-root-run.app -------------------------------------------------------------------------------- /examples/nx-workspace-old/.secrets.prod: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-secret-root-prod-run.app -------------------------------------------------------------------------------- /examples/nx-workspace-old/.verdaccio/config.yml: -------------------------------------------------------------------------------- 1 | # path to a directory with all packages 2 | storage: /tmp/local-registry/storage 3 | 4 | # a list of other known repositories we can talk to 5 | uplinks: 6 | npmjs: 7 | url: https://registry.npmjs.org/ 8 | maxage: 60m 9 | 10 | packages: 11 | "**": 12 | # give all users (including non-authenticated users) full access 13 | # because it is a local registry 14 | access: $all 15 | publish: $all 16 | unpublish: $all 17 | 18 | # if package is not available locally, proxy requests to npm registry 19 | proxy: npmjs 20 | 21 | # log settings 22 | logs: 23 | type: stdout 24 | format: pretty 25 | level: warn 26 | 27 | publish: 28 | allow_offline: true # set offline to true to allow publish offline 29 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/.secrets: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-secret-subapp-run.app -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/.secrets.local: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-secret-subapp-local-run.app -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/.secrets.prod: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-secret-subapp-prod-run.app -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/.secrets.prod.local: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-secret-subapp-prod-local-run.app -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/__snapshots__/cli.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`dotenv-run should give the expected output > dev 1`] = ` 4 | "Hello World https://dotenv-run.dev/api/v1/users 5 | " 6 | `; 7 | 8 | exports[`dotenv-run should give the expected output > empty 1`] = ` 9 | "Hello World /api/v1/users 10 | " 11 | `; 12 | 13 | exports[`dotenv-run should give the expected output > multi 1`] = ` 14 | "Hello World https://dotenv-secret-subapp-prod-local-run.app/api/v1/users 15 | " 16 | `; 17 | 18 | exports[`dotenv-run should give the expected output > prod 1`] = ` 19 | "Hello World https://dotenv-run.app/api/v1/users 20 | " 21 | `; 22 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/cli.test.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from "child_process"; 2 | import { describe, it, expect } from "vitest"; 3 | 4 | describe("dotenv-run should give the expected output", () => { 5 | it("empty", () => { 6 | const actual = execSync( 7 | "dotenv-run -f .env.app -- bash -c 'echo \"Hello World $API_USERS\"'", 8 | { 9 | encoding: "utf8", 10 | } 11 | ); 12 | expect(actual).toMatchSnapshot(); 13 | }); 14 | 15 | it("dev", () => { 16 | const actual = execSync( 17 | "NODE_ENV=dev dotenv-run -f .env.app -- bash -c 'echo \"Hello World $API_USERS\"'", 18 | { 19 | encoding: "utf8", 20 | } 21 | ); 22 | expect(actual).toMatchSnapshot(); 23 | }); 24 | 25 | it("prod", () => { 26 | const actual = execSync( 27 | "NODE_ENV=prod dotenv-run -f .env.app -e prod -- bash -c 'echo \"Hello World $API_USERS\"'", 28 | { 29 | encoding: "utf8", 30 | } 31 | ); 32 | expect(actual).toMatchSnapshot(); 33 | }); 34 | 35 | it("multi", () => { 36 | const actual = execSync( 37 | "NODE_ENV=prod dotenv-run -e prod -f .secrets,.env.app -- bash -c 'echo \"Hello World $API_USERS\"'", 38 | { 39 | encoding: "utf8", 40 | } 41 | ); 42 | expect(actual).toMatchSnapshot(); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cli-app", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "test": "vitest", 7 | "test:dev": "NODE_ENV=dev dotenv-run -r ../../ -f .env,.secrets -- bash -c 'echo \"Hello World $API_USERS\"'", 8 | "build": "echo $API_USERS" 9 | } 10 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/project.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/cli-app/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "//" 3 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/.app.prod: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace-old/apps/ng-app-cli/.app.prod -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/.env: -------------------------------------------------------------------------------- 1 | NGX_VERSION=IGNORED_SINCE_SET_IN_ENV_LOCAL 2 | NGX_BRANCH=main 3 | 4 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/.env.local: -------------------------------------------------------------------------------- 1 | NGX_VERSION=$npm_package_version -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/.env.prod: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace-old/apps/ng-app-cli/.env.prod -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/.env.test: -------------------------------------------------------------------------------- 1 | NGX_VERSION=12.0.0 2 | NGX_BRANCH=test -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/README.md: -------------------------------------------------------------------------------- 1 | # NgxEnvDemo 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.0.0. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. 28 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/jest.config.mjs: -------------------------------------------------------------------------------- 1 | const jestConfig = { 2 | preset: "jest-preset-angular/presets/defaults-esm", 3 | setupFilesAfterEnv: ["/setup-jest.ts"], 4 | testMatch: ["/src/app/**/*.(spec|jest).ts"], 5 | cache: false, 6 | moduleNameMapper: { 7 | "^rxjs(/operators$)?$": 8 | "/node_modules/rxjs/dist/bundles/rxjs.umd.js", 9 | tslib: "/node_modules/tslib/tslib.es6.mjs", 10 | }, 11 | transform: { 12 | "^.+\\.(ts)$": [ 13 | "@dotenv-run/jest-angular", 14 | { 15 | useESM: true, 16 | stringifyContentPathRegex: "\\.(html|svg)$", 17 | }, 18 | ], 19 | }, 20 | }; 21 | 22 | export default jestConfig; 23 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: "", 7 | frameworks: ["jasmine", "@angular-devkit/build-angular"], 8 | plugins: [ 9 | require("karma-jasmine"), 10 | require("karma-chrome-launcher"), 11 | require("karma-jasmine-html-reporter"), 12 | require("karma-coverage"), 13 | require("@angular-devkit/build-angular/plugins/karma"), 14 | ], 15 | client: { 16 | jasmine: { 17 | // you can add configuration options for Jasmine here 18 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html 19 | // for example, you can disable the random execution with `random: false` 20 | // or set a specific seed with `seed: 4321` 21 | }, 22 | clearContext: false, // leave Jasmine Spec Runner output visible in browser 23 | }, 24 | jasmineHtmlReporter: { 25 | suppressAll: true, // removes the duplicated traces 26 | }, 27 | coverageReporter: { 28 | dir: require("path").join(__dirname, "./coverage/ng-app-cli"), 29 | subdir: ".", 30 | reporters: [{ type: "html" }, { type: "text-summary" }], 31 | }, 32 | reporters: ["progress", "kjhtml"], 33 | port: 9876, 34 | colors: true, 35 | logLevel: config.LOG_INFO, 36 | autoWatch: true, 37 | browsers: ["ChromeHeadless"], 38 | singleRun: false, 39 | restartOnFileChange: true, 40 | }); 41 | }; 42 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from "@playwright/test"; 2 | 3 | export default defineConfig({ 4 | // Look for test files in the "tests" directory, relative to this configuration file. 5 | testDir: "tests", 6 | 7 | // Run all tests in parallel. 8 | fullyParallel: true, 9 | 10 | use: { 11 | // Base URL to use in actions like `await page.goto('/')`. 12 | baseURL: "http://127.0.0.1:8081", 13 | 14 | // Collect trace when retrying the failed test. 15 | trace: "on-first-retry", 16 | }, 17 | // Configure projects for major browsers. 18 | projects: [ 19 | { 20 | name: "chromium", 21 | use: { ...devices["Desktop Chrome"] }, 22 | }, 23 | ], 24 | // Run your local dev server before starting the tests. 25 | webServer: { 26 | command: "npm run static -- -p 8081", 27 | url: "http://127.0.0.1:8081" 28 | }, 29 | }); 30 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-app-cli" 3 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/setup-jest.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular/setup-jest.mjs'; 2 | import { env } from '@dotenv-run/core'; 3 | env({ root: '../../..', files: ['.env', '.env.app'] }); 4 | 5 | import '@angular/localize/init'; 6 | import { TextEncoder } from 'util'; 7 | Object.defineProperty(window, 'TextEncoder', { 8 | writable: true, 9 | value: TextEncoder, 10 | }); 11 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace-old/apps/ng-app-cli/src/app/app.component.css -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

{{ title }}

2 | 3 |
element string
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 28 | 29 | 30 |
NAMEVALUE
ENV 14 | {{ env }} 15 |
VERSION 20 | {{ version }} 21 |
BRANCH 26 | {{ branch }} 27 |
31 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | let component: AppComponent; 6 | let fixture: ComponentFixture; 7 | 8 | beforeEach(async () => { 9 | await TestBed.configureTestingModule({ 10 | imports: [AppComponent], 11 | }).compileComponents(); 12 | fixture = TestBed.createComponent(AppComponent); 13 | component = fixture.componentInstance; 14 | fixture.detectChanges(); 15 | }); 16 | 17 | it('should create the app 2', () => { 18 | expect(component).toBeTruthy(); 19 | }); 20 | 21 | it(`should have the 'Hello world' title`, () => { 22 | expect(component.title).toEqual('Hello world'); 23 | expect(component.env).toEqual('test'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { Component } from '@angular/core'; 3 | import { RouterOutlet } from '@angular/router'; 4 | import { environment } from '../environments/environment'; 5 | 6 | @Component({ 7 | selector: 'app-root', 8 | standalone: true, 9 | templateUrl: './app.component.html', 10 | styleUrls: ['./app.component.css'], 11 | }) 12 | export class AppComponent { 13 | title = $localize`Hello world`; 14 | env = import.meta.env['NODE_ENV']; 15 | version = environment.env.NGX_VERSION; 16 | branch = import.meta.env['NGX_BRANCH']; 17 | } 18 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/app.config.server.ts: -------------------------------------------------------------------------------- 1 | import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; 2 | import { provideServerRendering } from '@angular/platform-server'; 3 | import { appConfig } from './app.config'; 4 | 5 | const serverConfig: ApplicationConfig = { 6 | providers: [provideServerRendering()], 7 | }; 8 | 9 | export const config = mergeApplicationConfig(appConfig, serverConfig); 10 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | 4 | import { provideClientHydration } from '@angular/platform-browser'; 5 | import { routes } from './app.routes'; 6 | 7 | export const appConfig: ApplicationConfig = { 8 | providers: [provideRouter(routes), provideClientHydration()], 9 | }; 10 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const routes: Routes = []; 4 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/hello/hello.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace-old/apps/ng-app-cli/src/app/hello/hello.component.css -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/hello/hello.component.html: -------------------------------------------------------------------------------- 1 |

hello works!

2 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/hello/hello.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HelloComponent } from './hello.component'; 4 | 5 | describe('HelloComponent', () => { 6 | let component: HelloComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [HelloComponent] 12 | }) 13 | .compileComponents(); 14 | 15 | fixture = TestBed.createComponent(HelloComponent); 16 | component = fixture.componentInstance; 17 | fixture.detectChanges(); 18 | }); 19 | 20 | it('should create', () => { 21 | expect(component).toBeTruthy(); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/app/hello/hello.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-hello', 5 | standalone: true, 6 | imports: [], 7 | templateUrl: './hello.component.html', 8 | styleUrl: './hello.component.css' 9 | }) 10 | export class HelloComponent { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace-old/apps/ng-app-cli/src/assets/.gitkeep -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/env.d.ts: -------------------------------------------------------------------------------- 1 | // Define the type of the environment variables. 2 | declare interface Env { 3 | readonly NODE_ENV: string; 4 | // Replace the following with your own environment variables. 5 | // Example: NGX_VERSION: string; 6 | NGX_BRANCH: string; 7 | NGX_VERSION: string; 8 | [key: string]: any; 9 | } 10 | 11 | declare interface ImportMeta { 12 | env: Env; 13 | } 14 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | env: { 4 | NGX_VERSION: import.meta.env['NGX_VERSION'], 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | env: { 8 | NGX_VERSION: import.meta.env['NGX_VERSION'], 9 | }, 10 | }; 11 | 12 | /* 13 | * For easier debugging in development mode, you can import the following file 14 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 15 | * 16 | * This import should be commented out in production mode because it will have a negative impact 17 | * on performance if an error is thrown. 18 | */ 19 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 20 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace-old/apps/ng-app-cli/src/favicon.ico -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %NGX_VERSION% 9 | 10 | 11 |

%NODE_ENV%

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/locale/messages.fr.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Attribute string 7 | 8 | src/app/app.component.html 9 | 3 10 | 11 | 12 | 13 | element string 14 | 15 | src/app/app.component.html 16 | 3,4 17 | 18 | 19 | 20 | Hello world 21 | 22 | src/app/app.component.ts 23 | 14 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/locale/messages.xlf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Attribute string 7 | 8 | src/app/app.component.html 9 | 3 10 | 11 | 12 | 13 | element string 14 | 15 | src/app/app.component.html 16 | 3,4 17 | 18 | 19 | 20 | Hello world 21 | 22 | src/app/app.component.ts 23 | 14 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/main.server.ts: -------------------------------------------------------------------------------- 1 | import '@ngx-env/builder/runtime'; 2 | 3 | import { bootstrapApplication } from '@angular/platform-browser'; 4 | import { AppComponent } from './app/app.component'; 5 | import { config } from './app/app.config.server'; 6 | 7 | const bootstrap = () => bootstrapApplication(AppComponent, config); 8 | 9 | export default bootstrap; 10 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/main.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { bootstrapApplication } from '@angular/platform-browser'; 4 | import { appConfig } from './app/app.config'; 5 | import { AppComponent } from './app/app.component'; 6 | 7 | bootstrapApplication(AppComponent, appConfig).catch((err) => 8 | console.error(err) 9 | ); 10 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/server.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AngularNodeAppEngine, 3 | createNodeRequestHandler, 4 | isMainModule, 5 | writeResponseToNodeResponse, 6 | } from '@angular/ssr/node'; 7 | import express from 'express'; 8 | import { dirname, resolve } from 'node:path'; 9 | import { fileURLToPath } from 'node:url'; 10 | 11 | const serverDistFolder = dirname(fileURLToPath(import.meta.url)); 12 | const browserDistFolder = resolve(serverDistFolder, '../browser'); 13 | 14 | const app = express(); 15 | const angularApp = new AngularNodeAppEngine(); 16 | 17 | /** 18 | * Example Express Rest API endpoints can be defined here. 19 | * Uncomment and define endpoints as necessary. 20 | * 21 | * Example: 22 | * ```ts 23 | * app.get('/api/**', (req, res) => { 24 | * // Handle API request 25 | * }); 26 | * ``` 27 | */ 28 | 29 | /** 30 | * Serve static files from /browser 31 | */ 32 | app.use( 33 | express.static(browserDistFolder, { 34 | maxAge: '1y', 35 | index: false, 36 | redirect: false, 37 | }) 38 | ); 39 | 40 | /** 41 | * Handle all other requests by rendering the Angular application. 42 | */ 43 | app.use('/**', (req, res, next) => { 44 | angularApp 45 | .handle(req) 46 | .then((response) => 47 | response ? writeResponseToNodeResponse(response, res) : next() 48 | ) 49 | .catch(next); 50 | }); 51 | 52 | /** 53 | * Start the server if this module is the main entry point. 54 | * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000. 55 | */ 56 | if (isMainModule(import.meta.url)) { 57 | const port = process.env['PORT'] || 4000; 58 | app.listen(port, () => { 59 | console.log(`Node Express server listening on http://localhost:${port}`); 60 | }); 61 | } 62 | 63 | /** 64 | * The request handler used by the Angular CLI (dev-server and during build). 65 | */ 66 | export const reqHandler = createNodeRequestHandler(app); 67 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/tests/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('has title', async ({ page }) => { 4 | await page.goto('/'); 5 | await expect(page).toHaveTitle('10'); 6 | await expect(page.locator('h1')).toHaveText('production'); 7 | }); 8 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": ["node", "@angular/localize"] 7 | }, 8 | "files": ["src/main.ts", "src/main.server.ts", "src/server.ts"], 9 | "include": ["src/**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "outDir": "./dist/out-tsc", 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "noImplicitOverride": true, 9 | "noPropertyAccessFromIndexSignature": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "esModuleInterop": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "downlevelIteration": true, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "node", 18 | "importHelpers": true, 19 | "target": "ES2022", 20 | "module": "es2022", 21 | "useDefineForClassFields": false, 22 | "lib": ["ES2022", "dom"] 23 | }, 24 | "angularCompilerOptions": { 25 | "enableI18nLegacyMessageIdFormat": false, 26 | "strictInjectionParameters": true, 27 | "strictInputAccessModifiers": true, 28 | "strictTemplates": true 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-cli/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": ["jasmine", "@angular/localize"], 6 | "esModuleInterop": true, 7 | "module": "es2022" 8 | }, 9 | "include": ["src/**/*.spec.ts", "src/**/*.jest.ts", "src/**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/.env.app: -------------------------------------------------------------------------------- 1 | USER_HOME=/home/chihab 2 | NGX_VERSION=ERROR_HERE_SINCE_SET_IN_ENV_LOCAL 3 | NGX_USER_HOME=$USER_HOME -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/.env.app.local: -------------------------------------------------------------------------------- 1 | NGX_VERSION=$npm_package_version 2 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | 16 | # IDEs and editors 17 | /.idea 18 | .project 19 | .classpath 20 | .c9/ 21 | *.launch 22 | .settings/ 23 | *.sublime-workspace 24 | 25 | # IDE - VSCode 26 | .vscode/* 27 | !.vscode/settings.json 28 | !.vscode/tasks.json 29 | !.vscode/launch.json 30 | !.vscode/extensions.json 31 | .history/* 32 | 33 | # misc 34 | /.angular/cache 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | testem.log 41 | /typings 42 | 43 | # System Files 44 | .DS_Store 45 | Thumbs.db 46 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/README.md: -------------------------------------------------------------------------------- 1 | # NgxEnv 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.1.4. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. 28 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/package.ignore.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-app", 3 | "version": "16.1.1", 4 | "private": true, 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "cross-env NODE_ENV=dev ng serve", 8 | "prepare:build": "npx ng config projects.ng-app-webpack.architect.build.options.ngxEnv.prefix 'NGX_'", 9 | "build": "ng build", 10 | "e2e": "playwright test", 11 | "static": "npx serve dist/ng-app-webpack/browser" 12 | }, 13 | "dependencies": { 14 | "@angular/common": "^18.2.7", 15 | "@angular/compiler": "^18.2.7", 16 | "@angular/core": "^18.2.7", 17 | "@angular/platform-browser": "^18.2.7", 18 | "@angular/platform-browser-dynamic": "^18.2.7", 19 | "rxjs": "~7.6.0", 20 | "tslib": "^2.7.0", 21 | "zone.js": "~0.14.10" 22 | }, 23 | "devDependencies": { 24 | "@angular-builders/custom-webpack": "^18.0.0", 25 | "@angular-devkit/build-angular": "^18.2.7", 26 | "@angular/cli": "^18.2.7", 27 | "@angular/compiler-cli": "^18.2.7", 28 | "@dotenv-run/webpack": "workspace:^1.4.1", 29 | "@types/node": "^18.19.54", 30 | "cross-env": "^7.0.3", 31 | "typescript": "~5.4.5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from "@playwright/test"; 2 | 3 | export default defineConfig({ 4 | // Look for test files in the "tests" directory, relative to this configuration file. 5 | testDir: "tests", 6 | 7 | // Run all tests in parallel. 8 | fullyParallel: true, 9 | 10 | use: { 11 | // Base URL to use in actions like `await page.goto('/')`. 12 | baseURL: "http://127.0.0.1:8080", 13 | 14 | // Collect trace when retrying the failed test. 15 | trace: "on-first-retry", 16 | }, 17 | // Configure projects for major browsers. 18 | projects: [ 19 | { 20 | name: "chromium", 21 | use: { ...devices["Desktop Chrome"] }, 22 | }, 23 | ], 24 | // Run your local dev server before starting the tests. 25 | webServer: { 26 | command: "npm run static -- -p 8080", 27 | url: "http://127.0.0.1:8080" 28 | }, 29 | }); 30 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/project.ignore.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-app-webpack" 3 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

{{ env }} {{ version }}

2 |

{{ api }}

3 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { environment } from 'src/environments/environment'; 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | templateUrl: './app.component.html', 7 | }) 8 | export class AppComponent { 9 | env = process.env['NODE_ENV']; 10 | version = environment.env.NGX_VERSION; 11 | api = environment.env.API_USERS; 12 | } 13 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { AppComponent } from './app.component'; 4 | 5 | @NgModule({ 6 | declarations: [AppComponent], 7 | imports: [BrowserModule], 8 | bootstrap: [AppComponent], 9 | }) 10 | export class AppModule {} 11 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace-old/apps/ng-app-webpack/src/assets/.gitkeep -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/env.d.ts: -------------------------------------------------------------------------------- 1 | interface ImportMeta { 2 | env: ImportMetaEnv; 3 | } 4 | 5 | interface ImportMetaEnv { 6 | readonly NG_APP_ENV: string; 7 | readonly API_USERS: string; 8 | readonly NGX_VERSION: string; 9 | } 10 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | env: { 4 | NGX_VERSION: import.meta.env['NGX_VERSION'], 5 | API_USERS: import.meta.env['API_USERS'], 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | env: { 8 | NGX_VERSION: import.meta.env['NGX_VERSION'], 9 | API_USERS: import.meta.env['API_USERS'], 10 | }, 11 | }; 12 | 13 | /* 14 | * For easier debugging in development mode, you can import the following file 15 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 16 | * 17 | * This import should be commented out in production mode because it will have a negative impact 18 | * on performance if an error is thrown. 19 | */ 20 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 21 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace-old/apps/ng-app-webpack/src/favicon.ico -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %NGX_VERSION% 9 | 10 | 11 | %NODE_ENV% 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic() 12 | .bootstrapModule(AppModule) 13 | .catch((err) => console.error(err)); 14 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment( 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting(), { 14 | teardown: { destroyAfterEach: false } 15 | } 16 | ); 17 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app" 6 | }, 7 | "files": ["src/main.ts", "src/polyfills.ts"], 8 | "include": ["src/env.d.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "sourceMap": true, 13 | "declaration": false, 14 | "downlevelIteration": true, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "node", 17 | "importHelpers": true, 18 | "target": "ES2022", 19 | "module": "es2020", 20 | "lib": [ 21 | "es2018", 22 | "dom" 23 | ], 24 | "useDefineForClassFields": false 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": ["jasmine"] 7 | }, 8 | "files": ["src/test.ts"], 9 | "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/ng-app-webpack/webpack.config.ts: -------------------------------------------------------------------------------- 1 | import { DotenvRunPlugin } from '@dotenv-run/webpack'; 2 | import type { Configuration } from 'webpack'; 3 | 4 | export default (config: Configuration) => { 5 | config.plugins?.push( 6 | new DotenvRunPlugin({ 7 | root: '../..', 8 | cwd: process.cwd(), 9 | prefix: /^API|NGX/, 10 | verbose: true, 11 | files: ['.env.app'], 12 | nodeEnv: false, 13 | }) 14 | ); 15 | return config; 16 | }; 17 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/rspack-app/__snapshots__/rspack-dev.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`dotenv-run should give the expected output > dev 1`] = ` 4 | "https://dotenv-run.dev/api/v1/users 5 | development 6 | " 7 | `; 8 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/rspack-app/__snapshots__/rspack-prod.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`dotenv-run should give the expected output > prod 1`] = ` 4 | "https://dotenv-run.app/api/v1/users 5 | production 6 | " 7 | `; 8 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/rspack-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rspack-app", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "concurrently npm:build:*", 7 | "build:prod": "NODE_ENV=prod rspack build --mode production --output-path dist/prod", 8 | "build:dev": "NODE_ENV=dev rspack build --mode development --output-path dist/dev", 9 | "test": "concurrently npm:test:*", 10 | "test:dev": "vitest ./rspack-dev.test.ts", 11 | "test:prod": "vitest ./rspack-prod.test.ts" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/rspack-app/project.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/rspack-app/rspack-dev.test.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from "child_process"; 2 | import { describe, it, expect } from "vitest"; 3 | 4 | describe("dotenv-run should give the expected output", () => { 5 | it("dev", () => { 6 | const actual = execSync("node dist/dev/main.js", { 7 | encoding: "utf8", 8 | }); 9 | expect(actual).toMatchSnapshot(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/rspack-app/rspack-prod.test.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from "child_process"; 2 | import { describe, it, expect } from "vitest"; 3 | 4 | describe("dotenv-run should give the expected output", () => { 5 | it("prod", () => { 6 | const actual = execSync("node dist/prod/main.js", { 7 | encoding: "utf8", 8 | }); 9 | expect(actual).toMatchSnapshot(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/rspack-app/rspack.config.mjs: -------------------------------------------------------------------------------- 1 | import { DotenvRunPlugin } from "@dotenv-run/rspack"; 2 | import path from "path"; 3 | 4 | const __dirname = path.resolve(); 5 | 6 | export default { 7 | plugins: [ 8 | new DotenvRunPlugin( 9 | { 10 | environment: process.env.NODE_ENV, 11 | prefix: "^API", 12 | cwd: process.cwd(), 13 | verbose: true, 14 | root: "../..", 15 | files: [".env.app"], 16 | nodeEnv: false, 17 | dotenv: { override: true }, 18 | }, 19 | __dirname 20 | ), 21 | ], 22 | entry: "./src/index.js", 23 | output: { 24 | filename: "main.js", 25 | path: path.resolve(__dirname, "dist"), 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/rspack-app/src/index.js: -------------------------------------------------------------------------------- 1 | console.log(process.env.API_USERS) 2 | console.log(process.env.NODE_ENV) -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/webpack-app/__snapshots__/webpack-dev.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`dotenv-run should give the expected output > dev 1`] = ` 4 | "https://dotenv-run.dev/api/v1/users 5 | development 6 | " 7 | `; 8 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/webpack-app/__snapshots__/webpack-prod.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`dotenv-run should give the expected output > prod 1`] = ` 4 | "https://dotenv-run.app/api/v1/users 5 | production 6 | " 7 | `; 8 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/webpack-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-app", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "concurrently npm:build:*", 7 | "build:prod": "NODE_ENV=prod webpack build --mode production --output-path dist/prod", 8 | "build:dev": "NODE_ENV=dev webpack build --mode development --output-path dist/dev", 9 | "test": "concurrently npm:test:*", 10 | "test:dev": "vitest ./webpack-dev.test.ts", 11 | "test:prod": "vitest ./webpack-prod.test.ts" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/webpack-app/project.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/webpack-app/src/index.js: -------------------------------------------------------------------------------- 1 | console.log(process.env.API_USERS) 2 | console.log(process.env.NODE_ENV) -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/webpack-app/webpack-dev.test.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from "child_process"; 2 | import { describe, it, expect } from "vitest"; 3 | 4 | describe("dotenv-run should give the expected output", () => { 5 | it("dev", () => { 6 | const actual = execSync("node dist/dev/main.js", { 7 | encoding: "utf8", 8 | }); 9 | expect(actual).toMatchSnapshot(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/webpack-app/webpack-prod.test.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from "child_process"; 2 | import { describe, it, expect } from "vitest"; 3 | 4 | describe("dotenv-run should give the expected output", () => { 5 | it("prod", () => { 6 | const actual = execSync("node dist/prod/main.js", { 7 | encoding: "utf8", 8 | }); 9 | expect(actual).toMatchSnapshot(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/apps/webpack-app/webpack.config.mjs: -------------------------------------------------------------------------------- 1 | import { DotenvRunPlugin } from "@dotenv-run/webpack"; 2 | import path from "path"; 3 | 4 | const __dirname = path.resolve(); 5 | 6 | export default { 7 | plugins: [ 8 | new DotenvRunPlugin( 9 | { 10 | environment: process.env.NODE_ENV, 11 | prefix: "^API", 12 | cwd: process.cwd(), 13 | verbose: true, 14 | root: "../..", 15 | files: [".env.app"], 16 | nodeEnv: false, 17 | dotenv: { override: true }, 18 | }, 19 | __dirname 20 | ), 21 | ], 22 | entry: "./src/index.js", 23 | output: { 24 | filename: "main.js", 25 | path: path.resolve(__dirname, "dist"), 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/libs/rollup-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup-lib", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "NODE_ENV=dev rollup -c rollup.config.mjs", 7 | "test": "vitest" 8 | } 9 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/libs/rollup-lib/project.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /examples/nx-workspace-old/libs/rollup-lib/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | import env from "@dotenv-run/rollup"; 2 | 3 | export default { 4 | input: "src/index.mjs", 5 | output: { 6 | file: "dist/index.js", 7 | }, 8 | plugins: [ 9 | env({ 10 | prefix: "^API", 11 | verbose: true, 12 | root: "../../..", 13 | files: [".env.app"], 14 | environment: process.env.NODE_ENV, 15 | cwd: process.cwd(), 16 | }), 17 | ], 18 | }; 19 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/libs/rollup-lib/src/index.mjs: -------------------------------------------------------------------------------- 1 | export function getApiUrl() { 2 | return process.env.API_USERS; 3 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/libs/rollup-lib/src/index.test.js: -------------------------------------------------------------------------------- 1 | import { it, expect } from "vitest"; 2 | import { getApiUrl } from "../dist/index.js"; 3 | 4 | it("dotenv-run should give the expected output", () => { 5 | expect(getApiUrl()).toBe("https://dotenv-run.dev/api/v1/users"); 6 | }); 7 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasksRunnerOptions": { 3 | "default": { 4 | "runner": "nx/tasks-runners/default", 5 | "options": { 6 | "cacheableOperations": [ 7 | "build" 8 | ] 9 | } 10 | } 11 | }, 12 | "targetDefaults": { 13 | "test": { 14 | "inputs": [ 15 | "^test" 16 | ] 17 | } 18 | }, 19 | "affected": { 20 | "defaultBase": "main" 21 | } 22 | } -------------------------------------------------------------------------------- /examples/nx-workspace-old/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "platform", 3 | "private": true, 4 | "version": "2.0.0", 5 | "scripts": { 6 | "build:all": "nx run-many --target=build --all --parallel", 7 | "test:all": "nx run-many --target=test,test:jest --all --parallel --verbose", 8 | "e2e:all": "nx run-many --target=e2e --all --parallel" 9 | }, 10 | "devDependencies": { 11 | "@dotenv-run/cli": "workspace:^1.3.6", 12 | "@dotenv-run/load": "workspace:^1.3.6", 13 | "@dotenv-run/rollup": "workspace:^1.3.6", 14 | "@dotenv-run/webpack": "workspace:^1.5.0", 15 | "@dotenv-run/rspack": "workspace:^1.0.0", 16 | "@nx/js": "^18.3.5", 17 | "@playwright/test": "^1.47.2", 18 | "@types/node": "^20.16.10", 19 | "nx": "^16.10.0", 20 | "playwright": "^1.47.2", 21 | "rollup": "^3.29.5", 22 | "serve": "^14.2.3", 23 | "verdaccio": "^5.32.2", 24 | "webpack": "5.96.1", 25 | "webpack-cli": "^5.1.4", 26 | "@rspack/cli": "^1.0.10", 27 | "@rspack/core": "^1.0.10" 28 | }, 29 | "nx": { 30 | "includedScripts": [] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/nx-workspace-old/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "platform", 3 | "$schema": "node_modules/nx/schemas/project-schema.json", 4 | "targets": { 5 | "local-registry": { 6 | "executor": "@nx/js:verdaccio", 7 | "options": { 8 | "port": 4873, 9 | "config": ".verdaccio/config.yml", 10 | "storage": "tmp/local-registry/storage" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/nx-workspace/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /examples/nx-workspace/.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | permissions: 10 | actions: read 11 | contents: read 12 | 13 | jobs: 14 | main: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | 21 | # This enables task distribution via Nx Cloud 22 | # Run this command as early as possible, before dependencies are installed 23 | # Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun 24 | # Uncomment this line to enable task distribution 25 | # - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci" 26 | 27 | # Cache node_modules 28 | - uses: actions/setup-node@v4 29 | with: 30 | node-version: 20 31 | cache: 'npm' 32 | 33 | - run: npm ci --legacy-peer-deps 34 | - run: npx playwright install --with-deps 35 | - uses: nrwl/nx-set-shas@v4 36 | 37 | # Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud 38 | # - run: npx nx-cloud record -- echo Hello World 39 | # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected 40 | # When you enable task distribution, run the e2e-ci task instead of e2e 41 | - run: npx nx affected -t lint test build e2e 42 | -------------------------------------------------------------------------------- /examples/nx-workspace/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | dist 5 | tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | 41 | .nx/cache 42 | .nx/workspace-data 43 | 44 | .angular 45 | -------------------------------------------------------------------------------- /examples/nx-workspace/.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | /dist 3 | /coverage 4 | /.nx/cache 5 | /.nx/workspace-data 6 | .angular 7 | -------------------------------------------------------------------------------- /examples/nx-workspace/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli-e2e/eslint.config.js: -------------------------------------------------------------------------------- 1 | const playwright = require('eslint-plugin-playwright'); 2 | const baseConfig = require('../../eslint.config.js'); 3 | 4 | module.exports = [ 5 | playwright.configs['flat/recommended'], 6 | 7 | ...baseConfig, 8 | { 9 | files: ['**/*.ts', '**/*.js'], 10 | // Override or add rules here 11 | rules: {}, 12 | }, 13 | ]; 14 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli-e2e/playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from '@playwright/test'; 2 | import { nxE2EPreset } from '@nx/playwright/preset'; 3 | 4 | import { workspaceRoot } from '@nx/devkit'; 5 | 6 | // For CI, you may want to set BASE_URL to the deployed application. 7 | const baseURL = process.env['BASE_URL'] || 'http://localhost:4200'; 8 | 9 | /** 10 | * Read environment variables from file. 11 | * https://github.com/motdotla/dotenv 12 | */ 13 | // require('dotenv').config(); 14 | 15 | /** 16 | * See https://playwright.dev/docs/test-configuration. 17 | */ 18 | export default defineConfig({ 19 | ...nxE2EPreset(__filename, { testDir: './src' }), 20 | /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ 21 | use: { 22 | baseURL, 23 | /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ 24 | trace: 'on-first-retry', 25 | }, 26 | /* Run your local dev server before starting the tests */ 27 | webServer: { 28 | command: 'npx nx run ng-app-cli:serve', 29 | url: 'http://localhost:4200', 30 | reuseExistingServer: !process.env.CI, 31 | cwd: workspaceRoot, 32 | }, 33 | projects: [ 34 | { 35 | name: 'chromium', 36 | use: { ...devices['Desktop Chrome'] }, 37 | }, 38 | 39 | { 40 | name: 'firefox', 41 | use: { ...devices['Desktop Firefox'] }, 42 | }, 43 | 44 | { 45 | name: 'webkit', 46 | use: { ...devices['Desktop Safari'] }, 47 | }, 48 | 49 | // Uncomment for mobile browsers support 50 | /* { 51 | name: 'Mobile Chrome', 52 | use: { ...devices['Pixel 5'] }, 53 | }, 54 | { 55 | name: 'Mobile Safari', 56 | use: { ...devices['iPhone 12'] }, 57 | }, */ 58 | 59 | // Uncomment for branded browsers 60 | /* { 61 | name: 'Microsoft Edge', 62 | use: { ...devices['Desktop Edge'], channel: 'msedge' }, 63 | }, 64 | { 65 | name: 'Google Chrome', 66 | use: { ...devices['Desktop Chrome'], channel: 'chrome' }, 67 | } */ 68 | ], 69 | }); 70 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli-e2e/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-app-cli-e2e", 3 | "$schema": "../../node_modules/nx/schemas/project-schema.json", 4 | "projectType": "application", 5 | "sourceRoot": "apps/ng-app-cli-e2e/src", 6 | "implicitDependencies": ["ng-app-cli"], 7 | "// targets": "to see all targets run: nx show project ng-app-cli-e2e --web", 8 | "targets": {} 9 | } 10 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli-e2e/src/example.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('has title', async ({ page }) => { 4 | await page.goto('/'); 5 | 6 | // Expect h1 to contain a substring. 7 | expect(await page.locator('h1').innerText()).toContain('Welcome'); 8 | }); 9 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli-e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "outDir": "../../dist/out-tsc", 6 | "sourceMap": false, 7 | "module": "commonjs", 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitOverride": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true 14 | }, 15 | "include": [ 16 | "**/*.ts", 17 | "**/*.js", 18 | "playwright.config.ts", 19 | "src/**/*.spec.ts", 20 | "src/**/*.spec.js", 21 | "src/**/*.test.ts", 22 | "src/**/*.test.js", 23 | "src/**/*.d.ts" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/eslint.config.js: -------------------------------------------------------------------------------- 1 | const nx = require('@nx/eslint-plugin'); 2 | const baseConfig = require('../../eslint.config.js'); 3 | 4 | module.exports = [ 5 | ...baseConfig, 6 | ...nx.configs['flat/angular'], 7 | ...nx.configs['flat/angular-template'], 8 | { 9 | files: ['**/*.ts'], 10 | rules: { 11 | '@angular-eslint/directive-selector': [ 12 | 'error', 13 | { 14 | type: 'attribute', 15 | prefix: 'app', 16 | style: 'camelCase', 17 | }, 18 | ], 19 | '@angular-eslint/component-selector': [ 20 | 'error', 21 | { 22 | type: 'element', 23 | prefix: 'app', 24 | style: 'kebab-case', 25 | }, 26 | ], 27 | }, 28 | }, 29 | { 30 | files: ['**/*.html'], 31 | // Override or add rules here 32 | rules: {}, 33 | }, 34 | ]; 35 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | preset: 'jest-preset-angular/presets/defaults-esm', 3 | setupFilesAfterEnv: ['/src/test-setup.ts'], 4 | cache: false, 5 | testMatch: ['/src/app/**/*.(spec|jest).ts'], 6 | moduleNameMapper: { 7 | '^rxjs(/operators$)?$': 8 | '/../../node_modules/rxjs/dist/bundles/rxjs.umd.js', 9 | tslib: '/../../node_modules/tslib/tslib.es6.mjs', 10 | }, 11 | transform: { 12 | '^.+\\.(ts)$': [ 13 | '@dotenv-run/jest-angular', 14 | { 15 | useESM: true, 16 | stringifyContentPathRegex: '\\.(html|svg)$', 17 | }, 18 | ], 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-app-cli", 3 | "private": true, 4 | "scripts": { 5 | "test:esm": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace/apps/ng-app-cli/public/favicon.ico -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/server.ts: -------------------------------------------------------------------------------- 1 | import { APP_BASE_HREF } from '@angular/common'; 2 | import { CommonEngine } from '@angular/ssr'; 3 | import express from 'express'; 4 | import { fileURLToPath } from 'node:url'; 5 | import { dirname, join, resolve } from 'node:path'; 6 | import bootstrap from './src/main.server'; 7 | 8 | // The Express app is exported so that it can be used by serverless Functions. 9 | export function app(): express.Express { 10 | const server = express(); 11 | const serverDistFolder = dirname(fileURLToPath(import.meta.url)); 12 | const browserDistFolder = resolve(serverDistFolder, '../browser'); 13 | const indexHtml = join(serverDistFolder, 'index.server.html'); 14 | 15 | const commonEngine = new CommonEngine(); 16 | 17 | server.set('view engine', 'html'); 18 | server.set('views', browserDistFolder); 19 | 20 | // Example Express Rest API endpoints 21 | // server.get('/api/**', (req, res) => { }); 22 | // Serve static files from /browser 23 | server.get( 24 | '**', 25 | express.static(browserDistFolder, { 26 | maxAge: '1y', 27 | index: 'index.html', 28 | }) 29 | ); 30 | 31 | // All regular routes use the Angular engine 32 | server.get('**', (req, res, next) => { 33 | const { protocol, originalUrl, baseUrl, headers } = req; 34 | 35 | commonEngine 36 | .render({ 37 | bootstrap, 38 | documentFilePath: indexHtml, 39 | url: `${protocol}://${headers.host}${originalUrl}`, 40 | publicPath: browserDistFolder, 41 | providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }], 42 | }) 43 | .then((html) => res.send(html)) 44 | .catch((err) => next(err)); 45 | }); 46 | 47 | return server; 48 | } 49 | 50 | function run(): void { 51 | const port = process.env['PORT'] || 4000; 52 | 53 | // Start up the Node server 54 | const server = app(); 55 | server.listen(port, () => { 56 | console.log(`Node Express server listening on http://localhost:${port}`); 57 | }); 58 | } 59 | 60 | run(); 61 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/examples/nx-workspace/apps/ng-app-cli/src/app/app.component.css -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

{{ title }}

2 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | import { RouterModule } from '@angular/router'; 4 | 5 | const title = 'test'; 6 | 7 | describe('AppComponent', () => { 8 | beforeEach(async () => { 9 | await TestBed.configureTestingModule({ 10 | imports: [AppComponent, RouterModule.forRoot([])], 11 | }).compileComponents(); 12 | }); 13 | 14 | it('should render title', () => { 15 | const fixture = TestBed.createComponent(AppComponent); 16 | fixture.detectChanges(); 17 | const compiled = fixture.nativeElement as HTMLElement; 18 | expect(compiled.querySelector('h1')?.textContent).toContain(title); 19 | }); 20 | 21 | it(`should have as title 'ng-app-cli'`, () => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | const app = fixture.componentInstance; 24 | expect(app.title).toEqual(title); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | standalone: true, 5 | selector: 'app-root', 6 | templateUrl: './app.component.html', 7 | }) 8 | export class AppComponent { 9 | title = 'Title: ' + import.meta.env.NODE_ENV; 10 | } 11 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/app/app.config.server.ts: -------------------------------------------------------------------------------- 1 | import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; 2 | import { provideServerRendering } from '@angular/platform-server'; 3 | import { appConfig } from './app.config'; 4 | 5 | const serverConfig: ApplicationConfig = { 6 | providers: [provideServerRendering()], 7 | }; 8 | 9 | export const config = mergeApplicationConfig(appConfig, serverConfig); 10 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | import { appRoutes } from './app.routes'; 4 | import { provideClientHydration } from '@angular/platform-browser'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [ 8 | provideClientHydration(), 9 | provideZoneChangeDetection({ eventCoalescing: true }), 10 | provideRouter(appRoutes), 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | export const appRoutes: Route[] = []; 4 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/env.d.ts: -------------------------------------------------------------------------------- 1 | // Define the type of the environment variables. 2 | declare interface Env { 3 | readonly NODE_ENV: string; 4 | // Replace the following with your own environment variables. 5 | // Example: NGX_VERSION: string; 6 | [key: string]: any; 7 | } 8 | 9 | // Choose how to access the environment variables. 10 | // Remove the unused options. 11 | 12 | // 1. Use import.meta.env.YOUR_ENV_VAR in your code. (conventional) 13 | declare interface ImportMeta { 14 | readonly env: Env; 15 | } 16 | 17 | // 2. Use _NGX_ENV_.YOUR_ENV_VAR in your code. (customizable) 18 | // You can modify the name of the variable in angular.json. 19 | // ngxEnv: { 20 | // define: '_NGX_ENV_', 21 | // } 22 | declare const _NGX_ENV_: Env; 23 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ng-app-cli 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/main.server.ts: -------------------------------------------------------------------------------- 1 | import '@ngx-env/builder/runtime'; 2 | 3 | import { bootstrapApplication } from '@angular/platform-browser'; 4 | import { AppComponent } from './app/app.component'; 5 | import { config } from './app/app.config.server'; 6 | 7 | const bootstrap = () => bootstrapApplication(AppComponent, config); 8 | 9 | export default bootstrap; 10 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { appConfig } from './app/app.config'; 3 | import { AppComponent } from './app/app.component'; 4 | 5 | bootstrapApplication(AppComponent, appConfig).catch((err) => 6 | console.error(err) 7 | ); 8 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-preset-angular/setup-jest.mjs'; 2 | 3 | // import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone/index.mjs'; 4 | // setupZoneTestEnv(); 5 | 6 | import { env } from '@dotenv-run/core'; 7 | env({ root: '../../..', files: ['.env', '.env.app'] }); 8 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": ["node"] 6 | }, 7 | "files": ["src/main.ts", "src/main.server.ts", "server.ts"], 8 | "include": ["src/**/*.d.ts"], 9 | "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/tsconfig.editor.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src/**/*.ts"], 4 | "compilerOptions": {}, 5 | "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] 6 | } 7 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "esModuleInterop": true, 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true 11 | }, 12 | "files": [], 13 | "include": [], 14 | "references": [ 15 | { 16 | "path": "./tsconfig.editor.json" 17 | }, 18 | { 19 | "path": "./tsconfig.app.json" 20 | }, 21 | { 22 | "path": "./tsconfig.spec.json" 23 | } 24 | ], 25 | "extends": "../../tsconfig.base.json", 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/nx-workspace/apps/ng-app-cli/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": ["jest"], 6 | "esModuleInterop": true, 7 | "module": "es2022" 8 | }, 9 | "files": ["src/test-setup.ts"], 10 | "include": [ 11 | "jest.config.ts", 12 | "src/**/*.test.ts", 13 | "src/**/*.spec.ts", 14 | "src/**/*.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /examples/nx-workspace/eslint.config.js: -------------------------------------------------------------------------------- 1 | const nx = require('@nx/eslint-plugin'); 2 | 3 | module.exports = [ 4 | ...nx.configs['flat/base'], 5 | ...nx.configs['flat/typescript'], 6 | ...nx.configs['flat/javascript'], 7 | { 8 | ignores: ['**/dist'], 9 | }, 10 | { 11 | files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'], 12 | rules: { 13 | '@nx/enforce-module-boundaries': [ 14 | 'error', 15 | { 16 | enforceBuildableLibDependency: true, 17 | allow: ['^.*/eslint(\\.base)?\\.config\\.[cm]?js$'], 18 | depConstraints: [ 19 | { 20 | sourceTag: '*', 21 | onlyDependOnLibsWithTags: ['*'], 22 | }, 23 | ], 24 | }, 25 | ], 26 | }, 27 | }, 28 | { 29 | files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'], 30 | // Override or add rules here 31 | rules: {}, 32 | }, 33 | ]; 34 | -------------------------------------------------------------------------------- /examples/nx-workspace/jest.config.ts: -------------------------------------------------------------------------------- 1 | import { getJestProjectsAsync } from '@nx/jest'; 2 | 3 | export default async () => ({ 4 | projects: await getJestProjectsAsync(), 5 | }); 6 | -------------------------------------------------------------------------------- /examples/nx-workspace/jest.preset.js: -------------------------------------------------------------------------------- 1 | const nxPreset = require('@nx/jest/preset').default; 2 | 3 | module.exports = { ...nxPreset }; 4 | -------------------------------------------------------------------------------- /examples/nx-workspace/nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/nx/schemas/nx-schema.json", 3 | "namedInputs": { 4 | "default": ["{projectRoot}/**/*", "sharedGlobals"], 5 | "production": [ 6 | "default", 7 | "!{projectRoot}/.eslintrc.json", 8 | "!{projectRoot}/eslint.config.js", 9 | "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", 10 | "!{projectRoot}/tsconfig.spec.json", 11 | "!{projectRoot}/jest.config.[jt]s", 12 | "!{projectRoot}/src/test-setup.[jt]s", 13 | "!{projectRoot}/test-setup.[jt]s" 14 | ], 15 | "sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"] 16 | }, 17 | "targetDefaults": { 18 | "@angular-devkit/build-angular:application": { 19 | "cache": true, 20 | "dependsOn": ["^build"], 21 | "inputs": ["production", "^production"] 22 | }, 23 | "@nx/eslint:lint": { 24 | "cache": true, 25 | "inputs": [ 26 | "default", 27 | "{workspaceRoot}/.eslintrc.json", 28 | "{workspaceRoot}/.eslintignore", 29 | "{workspaceRoot}/eslint.config.js" 30 | ] 31 | }, 32 | "@nx/jest:jest": { 33 | "cache": true, 34 | "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"], 35 | "options": { 36 | "passWithNoTests": true 37 | }, 38 | "configurations": { 39 | "ci": { 40 | "ci": true, 41 | "codeCoverage": true 42 | } 43 | } 44 | }, 45 | "e2e-ci--**/*": { 46 | "dependsOn": ["^build"] 47 | } 48 | }, 49 | "plugins": [ 50 | { 51 | "plugin": "@nx/playwright/plugin", 52 | "options": { 53 | "targetName": "e2e" 54 | } 55 | }, 56 | { 57 | "plugin": "@nx/eslint/plugin", 58 | "options": { 59 | "targetName": "lint" 60 | } 61 | } 62 | ], 63 | "generators": { 64 | "@nx/angular:application": { 65 | "e2eTestRunner": "playwright", 66 | "linter": "eslint", 67 | "style": "css", 68 | "unitTestRunner": "jest" 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /examples/nx-workspace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nx-workspace/source", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "test": "NODE_ENV=test nx run-many -t test:esm", 7 | "build": "NODE_ENV=dev nx run-many -t build" 8 | }, 9 | "private": true, 10 | "dependencies": { 11 | "@angular/animations": "~18.2.0", 12 | "@angular/common": "~18.2.0", 13 | "@angular/compiler": "~18.2.0", 14 | "@angular/core": "~18.2.0", 15 | "@angular/forms": "~18.2.0", 16 | "@angular/platform-browser": "~18.2.0", 17 | "@angular/platform-browser-dynamic": "~18.2.0", 18 | "@angular/platform-server": "~18.2.0", 19 | "@angular/router": "~18.2.0", 20 | "@angular/ssr": "~18.2.0", 21 | "express": "~4.18.2", 22 | "rxjs": "~7.8.0", 23 | "zone.js": "~0.14.3" 24 | }, 25 | "devDependencies": { 26 | "@angular-devkit/build-angular": "~18.2.0", 27 | "@angular-devkit/core": "~18.2.0", 28 | "@angular-devkit/schematics": "~18.2.0", 29 | "@angular/cli": "~18.2.0", 30 | "@angular/compiler-cli": "~18.2.0", 31 | "@angular/language-service": "~18.2.0", 32 | "@dotenv-run/jest-angular": "^0.1.1", 33 | "@eslint/js": "^9.8.0", 34 | "@ngx-env/builder": "^18.0.2", 35 | "@nx/angular": "20.1.1", 36 | "@nx/devkit": "20.1.1", 37 | "@nx/eslint": "20.1.1", 38 | "@nx/eslint-plugin": "20.1.1", 39 | "@nx/jest": "^20.1.1", 40 | "@nx/js": "20.1.1", 41 | "@nx/playwright": "20.1.1", 42 | "@nx/web": "20.1.1", 43 | "@nx/workspace": "20.1.1", 44 | "@playwright/test": "^1.36.0", 45 | "@schematics/angular": "~18.2.0", 46 | "@swc-node/register": "~1.9.1", 47 | "@swc/core": "~1.5.7", 48 | "@swc/helpers": "~0.5.11", 49 | "@types/express": "4.17.14", 50 | "@types/jest": "^29.5.12", 51 | "@types/node": "18.16.9", 52 | "@typescript-eslint/utils": "^8.0.0", 53 | "angular-eslint": "^18.3.0", 54 | "eslint": "^9.8.0", 55 | "eslint-config-prettier": "^9.0.0", 56 | "eslint-plugin-playwright": "^1.6.2", 57 | "jest": "^29.7.0", 58 | "jest-environment-jsdom": "^29.7.0", 59 | "jest-preset-angular": "~14.1.0", 60 | "nx": "20.1.1", 61 | "prettier": "^2.6.2", 62 | "ts-jest": "^29.1.0", 63 | "ts-node": "10.9.1", 64 | "tslib": "^2.3.0", 65 | "typescript": "~5.5.2", 66 | "typescript-eslint": "^8.0.0" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /examples/nx-workspace/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "importHelpers": true, 11 | "target": "es2015", 12 | "module": "esnext", 13 | "lib": ["es2020", "dom"], 14 | "skipLibCheck": true, 15 | "skipDefaultLibCheck": true, 16 | "baseUrl": ".", 17 | "paths": {} 18 | }, 19 | "exclude": ["node_modules", "tmp"] 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dotenv-run", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "turbo run dev --parallel --no-cache --filter=./packages/*", 7 | "test": "CI=1 turbo test --filter=./packages/*", 8 | "build": "turbo build --filter=./packages/*", 9 | "build:docs": "turbo build --filter=./docs", 10 | "prepare": "husky install", 11 | "docker:build": "docker build -t temp-build . && docker rmi --force temp-build" 12 | }, 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@changesets/cli": "^2.27.9", 16 | "concurrently": "^8.2.2", 17 | "husky": "^8.0.3", 18 | "turbo": "^1.13.4", 19 | "typescript": "~5.6.2", 20 | "vitest": "^0.33.0" 21 | }, 22 | "packageManager": "pnpm@10.6.2" 23 | } 24 | -------------------------------------------------------------------------------- /packages/.env: -------------------------------------------------------------------------------- 1 | API_USERS=$API_BASE/api/v1/users 2 | API_AUTH=$API_BASE/api/v1/auth -------------------------------------------------------------------------------- /packages/angular/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @ngx-env/builder 2 | 3 | ## 19.0.4 4 | 5 | ### Patch Changes 6 | 7 | - doc: remove karma non support 8 | 9 | ## 19.0.3 10 | 11 | ### Patch Changes 12 | 13 | - add support to karma browser builder after cli fix 14 | 15 | ## 19.0.2 16 | 17 | ### Patch Changes 18 | 19 | - dfb69c0: fix: csr angular 19 support 20 | 21 | ## 19.0.0 22 | 23 | ### Major Changes 24 | 25 | - 8f83f0c: feat: add compatibility with Angular 19 26 | 27 | ### Patch Changes 28 | 29 | - Updated dependencies [8f83f0c] 30 | - @dotenv-run/webpack@1.5.0 31 | -------------------------------------------------------------------------------- /packages/angular/builders.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular-devkit/architect/src/builders-schema.json", 3 | "builders": { 4 | "browser": { 5 | "implementation": "./dist/builders/browser", 6 | "schema": "./dist/builders/schemas/browser.json", 7 | "description": "Build browser app extended with ngx-env config" 8 | }, 9 | "dev-server": { 10 | "implementation": "./dist/builders/dev-server", 11 | "schema": "./dist/builders/schemas/dev-server.json", 12 | "description": "Dev server extended with ngx-env config" 13 | }, 14 | "karma": { 15 | "implementation": "./dist/builders/karma", 16 | "schema": "./dist/builders/schemas/karma.json", 17 | "description": "Karma server extended with ngx-env config" 18 | }, 19 | "extract-i18n": { 20 | "implementation": "./dist/builders/extract-i18n", 21 | "schema": "./dist/builders/schemas/extract-i18n.json", 22 | "description": "Extract i18n extended with ngx-env config" 23 | }, 24 | "server": { 25 | "implementation": "./dist/builders/server", 26 | "schema": "./dist/builders/schemas/server.json", 27 | "description": "Build server app extended with ngx-env config" 28 | }, 29 | "application": { 30 | "implementation": "./dist/builders/application", 31 | "schema": "./dist/builders/schemas/application.json", 32 | "description": "Build application extended with ngx-env config" 33 | }, 34 | "browser-esbuild": { 35 | "implementation": "./dist/builders/browser-esbuild", 36 | "schema": "./dist/builders/schemas/browser-esbuild.json", 37 | "description": "Build browser app extended with ngx-env config using esbuild" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/angular/collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular-devkit/schematics/collection-schema.json", 3 | "schematics": { 4 | "ng-add": { 5 | "description": "Add ngx-env to your Angular Application", 6 | "factory": "./dist/schematics/ng-add/index", 7 | "schema": "./dist/schematics/ng-add/schema.json", 8 | "aliases": ["install"] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/angular/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | . 13 | ENV 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /packages/angular/manekinekko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/packages/angular/manekinekko.png -------------------------------------------------------------------------------- /packages/angular/motdotla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chihab/dotenv-run/5f2442a008acfbfd1108d43fbc4e78c985e64531/packages/angular/motdotla.png -------------------------------------------------------------------------------- /packages/angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ngx-env/builder", 3 | "version": "19.0.4", 4 | "description": "Easily inject environment variables into your Angular applications", 5 | "author": "chihab ", 6 | "homepage": "https://github.com/chihab/ngx-env/tree/main/packages/angular", 7 | "license": "MIT", 8 | "keywords": [ 9 | "angular", 10 | "dotenv", 11 | "environment", 12 | "builder", 13 | "schematics" 14 | ], 15 | "files": [ 16 | "dist", 17 | "builders.json", 18 | "collection.json", 19 | "README.md", 20 | "runtime.mjs" 21 | ], 22 | "builders": "builders.json", 23 | "schematics": "./collection.json", 24 | "ng-add": { 25 | "save": "devDependencies" 26 | }, 27 | "scripts": { 28 | "dev": "tsc -w", 29 | "build": "tsc && ts-node tools/schema-copy-run.ts", 30 | "copy-dist": "ts-node tools/schema-dist.ts" 31 | }, 32 | "dependencies": { 33 | "@dotenv-run/webpack": "workspace:^1.5.0", 34 | "glob": "^10.4.5" 35 | }, 36 | "devDependencies": { 37 | "@angular/build": "^19.0.4", 38 | "@angular-devkit/architect": "^0.1900.4", 39 | "@angular-devkit/build-angular": "^19.0.4", 40 | "@angular-devkit/core": "^19.0.4", 41 | "@angular-devkit/schematics": "^19.0.4", 42 | "@angular/router": "^19.0.4", 43 | "@angular/animations": "^19.0.4", 44 | "@angular/common": "^19.0.4", 45 | "@angular/platform-browser": "^19.0.4", 46 | "@dotenv-run/core": "workspace:^1.3.6", 47 | "cpy": "^8.1.2", 48 | "karma": "^6.4.4", 49 | "rxjs": "^7.8.1", 50 | "ts-node": "^10.9.2", 51 | "typescript": "~5.6.2", 52 | "webpack": "5.96.1", 53 | "zone.js": "~0.15.0" 54 | }, 55 | "peerDpendencies": { 56 | "rxjs": "^7.0.0", 57 | "webpack": "5.96.1" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/angular/runtime.mjs: -------------------------------------------------------------------------------- 1 | globalThis._NGX_ENV_ = process.env; 2 | -------------------------------------------------------------------------------- /packages/angular/src/builders/application/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BuilderContext, 3 | BuilderOutput, 4 | createBuilder, 5 | fromAsyncIterable, 6 | } from "@angular-devkit/architect"; 7 | import { 8 | ApplicationBuilderOptions, 9 | buildApplication, 10 | } from "@angular-devkit/build-angular"; 11 | import { env, type DotenvRunOptions } from "@dotenv-run/core"; 12 | import { join } from "path"; 13 | import { Observable, from, switchMap, tap } from "rxjs"; 14 | import { NgxEnvSchema } from "../ngx-env/ngx-env-schema"; 15 | import { indexHtml } from "../utils/index-html-build"; 16 | import { getEnvironment } from "../utils/get-environment"; 17 | import { getProjectCwd } from "../utils/project"; 18 | 19 | export const buildWithPlugin = ( 20 | options: ApplicationBuilderOptions & NgxEnvSchema, 21 | context: BuilderContext 22 | ): Observable => { 23 | const dotEnvOptions: DotenvRunOptions = options.ngxEnv; 24 | return from(getProjectCwd(context)).pipe( 25 | switchMap((cwd) => { 26 | const { full, raw } = env({ 27 | ...dotEnvOptions, 28 | cwd, 29 | global: "_NGX_ENV_", 30 | environment: getEnvironment(context.target.configuration), 31 | }); 32 | options.define = full; 33 | return fromAsyncIterable( 34 | buildApplication(options, context) 35 | ).pipe( 36 | tap(() => { 37 | const outputDir = join( 38 | context.workspaceRoot, 39 | options.outputPath.toString() 40 | ); 41 | indexHtml( 42 | join(outputDir, "browser"), 43 | options.ssr ? join(outputDir, "server") : null, 44 | Array.isArray(options.localize) ? options.localize : [], 45 | raw, 46 | dotEnvOptions.runtime 47 | ); 48 | }) 49 | ); 50 | }) 51 | ); 52 | }; 53 | 54 | export default createBuilder(buildWithPlugin); 55 | -------------------------------------------------------------------------------- /packages/angular/src/builders/browser-esbuild/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BuilderContext, 3 | createBuilder, 4 | fromAsyncIterable, 5 | } from "@angular-devkit/architect"; 6 | import { buildEsbuildBrowser } from "@angular-devkit/build-angular/src/builders/browser-esbuild"; 7 | import { Schema as BrowserBuilderOptions } from "@angular-devkit/build-angular/src/builders/browser-esbuild/schema"; 8 | import { env, type DotenvRunOptions } from "@dotenv-run/core"; 9 | import { join } from "path"; 10 | import { from, switchMap, tap } from "rxjs"; 11 | import { NgxEnvSchema } from "../ngx-env/ngx-env-schema"; 12 | import { indexHtml } from "../utils/index-html-build"; 13 | import { getEnvironment } from "../utils/get-environment"; 14 | import { getProjectCwd } from "../utils/project"; 15 | 16 | export const buildWithPlugin = ( 17 | options: BrowserBuilderOptions & NgxEnvSchema, 18 | context: BuilderContext 19 | ) => { 20 | const dotEnvOptions: DotenvRunOptions = options.ngxEnv; 21 | return from(getProjectCwd(context)).pipe( 22 | switchMap((cwd) => { 23 | const { full, raw } = env({ 24 | ...dotEnvOptions, 25 | cwd, 26 | global: "_NGX_ENV_", 27 | environment: getEnvironment(context.target.configuration), 28 | }); 29 | (options as any).define = full; 30 | return fromAsyncIterable( 31 | buildEsbuildBrowser(options, context, undefined) 32 | ).pipe( 33 | tap(() => { 34 | indexHtml( 35 | join( 36 | context.workspaceRoot, 37 | options.outputPath.toString(), 38 | "browser" 39 | ), 40 | null, // no ssr support with browser-esbuild, 41 | Array.isArray(options.localize) ? options.localize : [], 42 | raw, 43 | dotEnvOptions.runtime 44 | ); 45 | }) 46 | ); 47 | }) 48 | ); 49 | }; 50 | 51 | export default createBuilder(buildWithPlugin); 52 | -------------------------------------------------------------------------------- /packages/angular/src/builders/browser/index.ts: -------------------------------------------------------------------------------- 1 | import { BuilderContext, createBuilder } from "@angular-devkit/architect"; 2 | import { 3 | BrowserBuilderOptions, 4 | executeBrowserBuilder, 5 | } from "@angular-devkit/build-angular"; 6 | import { from, switchMap, tap } from "rxjs"; 7 | import { NgxEnvSchema } from "../ngx-env/ngx-env-schema"; 8 | import { getEnvironment } from "../utils/get-environment"; 9 | import { getProjectCwd } from "../utils/project"; 10 | import { plugin } from "../utils/webpack-plugin"; 11 | import { indexHtml } from "../utils/index-html-build"; 12 | import { join } from "path"; 13 | 14 | export const buildWithPlugin = ( 15 | options: BrowserBuilderOptions & NgxEnvSchema, 16 | context: BuilderContext 17 | ): ReturnType => { 18 | return from(getProjectCwd(context)).pipe( 19 | switchMap((cwd: string) => { 20 | const { raw, webpackConfiguration } = plugin({ 21 | ...options.ngxEnv, 22 | cwd, 23 | environment: getEnvironment(context.target.configuration), 24 | }); 25 | return executeBrowserBuilder(options, context, { 26 | webpackConfiguration, 27 | }).pipe( 28 | tap(() => { 29 | indexHtml( 30 | join(context.workspaceRoot, options.outputPath.toString()), 31 | null, // no ssr support with browser, 32 | Array.isArray(options.localize) ? options.localize : [], 33 | raw, 34 | options.ngxEnv.runtime 35 | ); 36 | }) 37 | ); 38 | }) 39 | ); 40 | }; 41 | 42 | export default createBuilder(buildWithPlugin); 43 | -------------------------------------------------------------------------------- /packages/angular/src/builders/extract-i18n/extract-i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "title": "Extract i18n Target", 4 | "description": "Extract i18n target options for Build Facade.", 5 | "type": "object", 6 | "properties": { 7 | "buildTarget": { 8 | "type": "string", 9 | "description": "A builder target to extract i18n messages in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.", 10 | "pattern": "^[^:\\s]*:[^:\\s]*(:[^\\s]+)?$" 11 | }, 12 | "format": { 13 | "type": "string", 14 | "description": "Output format for the generated file.", 15 | "default": "xlf", 16 | "enum": ["xmb", "xlf", "xlif", "xliff", "xlf2", "xliff2", "json", "arb", "legacy-migrate"] 17 | }, 18 | "progress": { 19 | "type": "boolean", 20 | "description": "Log progress to the console.", 21 | "default": true 22 | }, 23 | "outputPath": { 24 | "type": "string", 25 | "description": "Path where output will be placed." 26 | }, 27 | "outFile": { 28 | "type": "string", 29 | "description": "Name of the file to output." 30 | } 31 | }, 32 | "additionalProperties": false 33 | } 34 | -------------------------------------------------------------------------------- /packages/angular/src/builders/extract-i18n/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BuilderContext, 3 | createBuilder, 4 | targetFromTargetString, 5 | } from "@angular-devkit/architect"; 6 | import { 7 | ExtractI18nBuilderOptions, 8 | executeExtractI18nBuilder, 9 | } from "@angular-devkit/build-angular"; 10 | import { combineLatest, switchMap } from "rxjs"; 11 | import { NgxEnvSchema } from "../ngx-env/ngx-env-schema"; 12 | import { JsonObject } from "@angular-devkit/core"; 13 | 14 | export const buildWithPlugin = ( 15 | options: ExtractI18nBuilderOptions & NgxEnvSchema, 16 | context: BuilderContext 17 | ) => { 18 | const buildTarget = targetFromTargetString(options.buildTarget); 19 | // options.buildTarget = "@angular-devkit/build-angular:application"; 20 | async function setup() { 21 | const targetOptions = await context.getTargetOptions(buildTarget); 22 | if ((await builderName()) === "@ngx-env/builder:application") { 23 | // Because of ngxEnv being removed from the options, we need to validate it here 24 | await context.validateOptions( 25 | targetOptions, 26 | "@ngx-env/builder:application" 27 | ); 28 | } 29 | return targetOptions; 30 | } 31 | async function builderName() { 32 | return context.getBuilderNameForTarget(buildTarget); 33 | } 34 | return combineLatest([setup(), builderName()]).pipe( 35 | switchMap(([_options, builderName]) => { 36 | if (builderName === "@ngx-env/builder:browser") { 37 | return executeExtractI18nBuilder(options, context); 38 | } else { 39 | delete _options.ngxEnv; 40 | context.getTargetOptions = async () => _options as JsonObject; 41 | return executeExtractI18nBuilder(options, { 42 | ...context, 43 | getBuilderNameForTarget: async () => 44 | "@angular-devkit/build-angular:" + builderName.split(":")[1], 45 | }); 46 | } 47 | }) 48 | ); 49 | }; 50 | 51 | export default createBuilder(buildWithPlugin); 52 | -------------------------------------------------------------------------------- /packages/angular/src/builders/karma/index.ts: -------------------------------------------------------------------------------- 1 | import { BuilderContext, createBuilder } from "@angular-devkit/architect"; 2 | import { 3 | executeKarmaBuilder, 4 | KarmaBuilderOptions, 5 | } from "@angular-devkit/build-angular"; 6 | import { NgxEnvSchema } from "../ngx-env/ngx-env-schema"; 7 | // import { plugin } from "../utils/webpack-plugin"; 8 | import { from, of, switchMap, throwError } from "rxjs"; 9 | import { getProjectCwd } from "../utils/project"; 10 | import { env } from "@dotenv-run/core"; 11 | import { getEnvironment } from "../utils/get-environment"; 12 | import { plugin } from "../utils/webpack-plugin"; 13 | import { BuilderMode } from "@angular-devkit/build-angular/src/builders/karma/schema"; 14 | // import { getEnvironment } from "../utils/get-environment"; 15 | // import { env } from "@dotenv-run/core"; 16 | 17 | export const buildWithPlugin = ( 18 | options: KarmaBuilderOptions & NgxEnvSchema, 19 | context: BuilderContext 20 | ): ReturnType => { 21 | return from(getProjectCwd(context)).pipe( 22 | switchMap((cwd: string) => { 23 | const { full } = env({ 24 | ...options.ngxEnv, 25 | cwd, 26 | environment: getEnvironment(context.target.configuration), 27 | }); 28 | switch (options.builderMode) { 29 | case "application": 30 | case "detect": 31 | console.warn("@ngx-env/builder:"); 32 | console.warn( 33 | " Application builder is not supported yet due to a limitation in the Angular CLI. " 34 | ); 35 | console.warn(" Falling back to the Browser builder."); 36 | // (options as any).define = full; 37 | // Does not work with application builder yet see: https://github.com/chihab/dotenv-run/issues/113 and https://github.com/angular/angular-cli/issues/29003 38 | return executeKarmaBuilder( 39 | { 40 | ...options, 41 | builderMode: BuilderMode.Browser, 42 | }, 43 | context, 44 | plugin(full) 45 | ); 46 | case "browser": 47 | return executeKarmaBuilder(options, context, plugin(full)); 48 | default: 49 | return throwError(() => "@ngx-env/builder: Invalid builder mode"); 50 | } 51 | }) 52 | ); 53 | }; 54 | export default createBuilder(buildWithPlugin); 55 | -------------------------------------------------------------------------------- /packages/angular/src/builders/ngx-env/ngx-env-schema.ts: -------------------------------------------------------------------------------- 1 | import { DotenvRunOptions } from "@dotenv-run/core"; 2 | 3 | export interface NgxEnvSchema { 4 | ngxEnv?: DotenvRunOptions; 5 | } 6 | -------------------------------------------------------------------------------- /packages/angular/src/builders/ngx-env/ngx-env.json: -------------------------------------------------------------------------------- 1 | { 2 | "ngxEnv": { 3 | "type": "object", 4 | "properties": { 5 | "prefix": { 6 | "type": "string", 7 | "description": "Regexp prefix of the environment variables to be replaced", 8 | "default": "NG_APP" 9 | }, 10 | "verbose": { 11 | "type": "boolean", 12 | "description": "Display environment files and variables in the console", 13 | "default": true 14 | }, 15 | "runtime": { 16 | "type": "boolean", 17 | "description": "Load environment variables at runtime", 18 | "default": false 19 | }, 20 | "define": { 21 | "type": "string", 22 | "description": "Global identifier to access environment variables", 23 | "default": "_NGX_ENV_" 24 | }, 25 | "unsecure": { 26 | "type": "boolean", 27 | "description": "Display environment variables values in the console", 28 | "default": false 29 | }, 30 | "root": { 31 | "type": "string", 32 | "description": "Root directory of the project to find .env files" 33 | }, 34 | "files": { 35 | "type": "array", 36 | "description": "List of .env files to be loaded", 37 | "default": [".env"], 38 | "items": { 39 | "type": "string" 40 | } 41 | } 42 | }, 43 | "additionalProperties": false 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/angular/src/builders/server/index.ts: -------------------------------------------------------------------------------- 1 | import { createBuilder, type BuilderContext } from "@angular-devkit/architect"; 2 | import { 3 | ServerBuilderOptions, 4 | executeServerBuilder, 5 | } from "@angular-devkit/build-angular"; 6 | import { from, switchMap } from "rxjs"; 7 | import { type NgxEnvSchema } from "../ngx-env/ngx-env-schema"; 8 | import { getEnvironment } from "../utils/get-environment"; 9 | import { getProjectCwd } from "../utils/project"; 10 | import { plugin } from "../utils/webpack-plugin"; 11 | 12 | export const buildWithPlugin = ( 13 | options: ServerBuilderOptions & NgxEnvSchema, 14 | context: BuilderContext 15 | ): ReturnType => { 16 | return from(getProjectCwd(context)).pipe( 17 | switchMap((cwd: string) => { 18 | return executeServerBuilder( 19 | options, 20 | context, 21 | plugin( 22 | { 23 | ...options.ngxEnv, 24 | cwd, 25 | environment: getEnvironment(context.target.configuration), 26 | }, 27 | true 28 | ) 29 | ); 30 | }) 31 | ); 32 | }; 33 | 34 | export default createBuilder(buildWithPlugin); 35 | -------------------------------------------------------------------------------- /packages/angular/src/builders/utils/escape-string-regexp.ts: -------------------------------------------------------------------------------- 1 | export function escapeStringRegexp(str: string) { 2 | return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"); 3 | } 4 | -------------------------------------------------------------------------------- /packages/angular/src/builders/utils/get-environment.ts: -------------------------------------------------------------------------------- 1 | export function getEnvironment(configuration: string) { 2 | return ( 3 | process.env.NG_APP_ENV || // @deprecated 4 | process.env.NODE_ENV || // default in @dotenv-run/core 5 | configuration // default in @angular-devkit/build-angular 6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /packages/angular/src/builders/utils/index-html-build.ts: -------------------------------------------------------------------------------- 1 | import { type Dict } from "@dotenv-run/core"; 2 | import { readFileSync, writeFileSync } from "fs"; 3 | import * as glob from "glob"; 4 | import { variablesReducer } from "./variables-reducer"; 5 | 6 | export function indexHtml( 7 | browserOutputDir: string, 8 | serverOutputDir: string | null, 9 | locales: string[] = [], 10 | raw: Dict, 11 | runtime = false 12 | ) { 13 | try { 14 | glob.sync(`${browserOutputDir}/**/index{.html,.csr.html}`).forEach((filePath) => { 15 | const html = readFileSync(filePath, "utf-8"); 16 | const content = variablesReducer(html, raw); // Replace %VARIABLE% with the actual value 17 | try { 18 | writeFileSync( 19 | filePath, 20 | runtime 21 | ? content.replace( 22 | //, 23 | `` 24 | ) 25 | : content 26 | ); 27 | } catch (e) { 28 | console.log(`❌ Failed to replace variables in ${filePath} ❌`); 29 | throw e; 30 | } 31 | }); 32 | if (serverOutputDir) { 33 | glob 34 | .sync(`${serverOutputDir}/**/index.server.html`) 35 | .forEach((filePath) => { 36 | const html = readFileSync(filePath, "utf-8"); 37 | const content = variablesReducer(html, raw); // Replace %VARIABLE% with the actual value 38 | try { 39 | writeFileSync(filePath, content); 40 | } catch (e) { 41 | console.log(`❌ Failed to replace variables in ${filePath} ❌`); 42 | throw e; 43 | } 44 | }); 45 | } 46 | if (runtime) { 47 | const runtimeStmt = `globalThis._NGX_ENV_ = ${JSON.stringify( 48 | raw, 49 | null, 50 | 2 51 | )};`; 52 | if (locales.length > 0) { 53 | locales.forEach((locale) => { 54 | console.log( 55 | `📦 Writing ngx-env.js to ${browserOutputDir}/${locale}/ngx-env.js` 56 | ); 57 | writeFileSync( 58 | `${browserOutputDir}/${locale}/ngx-env.js`, 59 | runtimeStmt 60 | ); 61 | }); 62 | } else { 63 | console.log(`📦 Writing ngx-env.js to ${browserOutputDir}/ngx-env.js`); 64 | writeFileSync(`${browserOutputDir}/ngx-env.js`, runtimeStmt); 65 | } 66 | } 67 | } catch (e) { 68 | console.error(e); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /packages/angular/src/builders/utils/index-html-serve.ts: -------------------------------------------------------------------------------- 1 | import type { Dict } from "@dotenv-run/core"; 2 | import { variablesReducer } from "./variables-reducer"; 3 | 4 | export function indexHtml(content: string, raw: Dict, runtime = false) { 5 | const html = variablesReducer(content, raw); 6 | return runtime 7 | ? html.replace( 8 | //, 9 | `` 10 | ) 11 | : html; 12 | } 13 | -------------------------------------------------------------------------------- /packages/angular/src/builders/utils/project.ts: -------------------------------------------------------------------------------- 1 | import { BuilderContext } from "@angular-devkit/architect"; 2 | import * as path from "path"; 3 | 4 | export async function getProjectCwd(context: BuilderContext) { 5 | const metadata = (await context.getProjectMetadata( 6 | context.target.project 7 | )) as { root: string }; 8 | return path.resolve(context.workspaceRoot, metadata.root); 9 | } 10 | -------------------------------------------------------------------------------- /packages/angular/src/builders/utils/variables-reducer.ts: -------------------------------------------------------------------------------- 1 | import { Dict } from "@dotenv-run/core"; 2 | import { escapeStringRegexp } from "./escape-string-regexp"; 3 | 4 | export const variablesReducer = (content: string, raw: Dict) => { 5 | return Object.keys(raw).reduce( 6 | (html, key) => 7 | html.replace( 8 | new RegExp("%" + escapeStringRegexp(key) + "%", "g"), 9 | raw[key] 10 | ), 11 | content 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /packages/angular/src/builders/utils/webpack-plugin.ts: -------------------------------------------------------------------------------- 1 | import type { DotenvRunOptions } from "@dotenv-run/core"; 2 | import { DotenvRunPlugin } from "@dotenv-run/webpack"; 3 | import type { Configuration } from "webpack"; 4 | import { indexHtml } from "./index-html-serve"; 5 | 6 | export function plugin(options: DotenvRunOptions, ssr = false) { 7 | const dotEnvPlugin = new DotenvRunPlugin( 8 | { ...options, environment: process.env.NODE_ENV, nodeEnv: false }, 9 | ssr 10 | ); 11 | const raw = dotEnvPlugin.raw; 12 | return { 13 | raw, 14 | webpackConfiguration: (webpackConfig: Configuration) => { 15 | webpackConfig.plugins.push(dotEnvPlugin); 16 | return webpackConfig; 17 | }, 18 | indexHtml: async (content: string) => { 19 | return indexHtml(content, raw, options.runtime); 20 | }, 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /packages/angular/src/builders/utils/workspace.ts: -------------------------------------------------------------------------------- 1 | import { SchematicsException, Tree } from '@angular-devkit/schematics'; 2 | 3 | export interface WorkspaceProject { 4 | projectType?: string; 5 | architect?: Record< 6 | string, 7 | { builder: string; options?: Record } 8 | >; 9 | } 10 | 11 | export interface Workspace { 12 | defaultProject?: string; 13 | projects: Record; 14 | } 15 | 16 | export function getWorkspace(host: Tree): { 17 | path: string; 18 | workspace: Workspace; 19 | } { 20 | const possibleFiles = ['/angular.json', './angular.json']; 21 | const path = possibleFiles.find((path) => host.exists(path)); 22 | const configBuffer = path ? host.read(path) : undefined; 23 | 24 | if (!path || !configBuffer) { 25 | throw new SchematicsException(`Could not find angular.json`); 26 | } 27 | 28 | const content = configBuffer.toString(); 29 | let workspace: Workspace; 30 | try { 31 | workspace = JSON.parse(content); 32 | } catch (e: any) { 33 | throw new SchematicsException( 34 | `Could not parse angular.json: ${e?.message}` 35 | ); 36 | } 37 | 38 | return { path, workspace }; 39 | } 40 | -------------------------------------------------------------------------------- /packages/angular/src/schematics/ng-add/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/schema", 3 | "$id": "ngx-env-ng-add", 4 | "title": "ngx-env schematic", 5 | "type": "object", 6 | "properties": { 7 | "project": { 8 | "type": "string", 9 | "description": "The name of the project.", 10 | "$default": { 11 | "$source": "projectName" 12 | } 13 | } 14 | }, 15 | "required": ["project"] 16 | } 17 | -------------------------------------------------------------------------------- /packages/angular/src/schematics/ng-add/template/env.d.ts: -------------------------------------------------------------------------------- 1 | // Define the type of the environment variables. 2 | declare interface Env { 3 | readonly NODE_ENV: string; 4 | // Replace the following with your own environment variables. 5 | // Example: NGX_VERSION: string; 6 | [key: string]: any; 7 | } 8 | 9 | // Choose how to access the environment variables. 10 | // Remove the unused options. 11 | 12 | // 1. Use import.meta.env.YOUR_ENV_VAR in your code. (conventional) 13 | declare interface ImportMeta { 14 | readonly env: Env; 15 | } 16 | 17 | // 2. Use _NGX_ENV_.YOUR_ENV_VAR in your code. (customizable) 18 | // You can modify the name of the variable in angular.json. 19 | // ngxEnv: { 20 | // define: '_NGX_ENV_', 21 | // } 22 | declare const _NGX_ENV_: Env; 23 | 24 | // 3. Use process.env.YOUR_ENV_VAR in your code. (deprecated) 25 | declare namespace NodeJS { 26 | export interface ProcessEnv extends Env {} 27 | } 28 | -------------------------------------------------------------------------------- /packages/angular/tools/cli-targets.ts: -------------------------------------------------------------------------------- 1 | export const cliTargets = [ 2 | "application", 3 | "browser-esbuild", 4 | "browser", 5 | "dev-server", 6 | "extract-i18n", 7 | "karma", 8 | "server", 9 | ]; 10 | -------------------------------------------------------------------------------- /packages/angular/tools/schema-copy-run.ts: -------------------------------------------------------------------------------- 1 | import copySchematicsSchema from './schema-copy'; 2 | import copyBuildersSchemas from './schema-generate'; 3 | 4 | (async () => { 5 | await copySchematicsSchema(); 6 | await copyBuildersSchemas(); 7 | })(); 8 | -------------------------------------------------------------------------------- /packages/angular/tools/schema-copy.ts: -------------------------------------------------------------------------------- 1 | import * as cpy from "cpy"; 2 | 3 | async function copySchema(name: string) { 4 | await cpy([`src/schematics/${name}/schema.json`], `dist/schematics/${name}`); 5 | await cpy( 6 | [`src/schematics/${name}/template`], 7 | `dist/schematics/${name}/template` 8 | ); 9 | } 10 | 11 | export default async function () { 12 | await copySchema("ng-add"); 13 | } 14 | -------------------------------------------------------------------------------- /packages/angular/tools/schema-dist.ts: -------------------------------------------------------------------------------- 1 | import * as cpy from "cpy"; 2 | import * as fs from "fs"; 3 | import { cliTargets } from "./cli-targets"; 4 | 5 | async function copyDistSchemas() { 6 | console.log("Copying Angular CLI target schemas"); 7 | // All but the application target 8 | cliTargets 9 | .filter((target) => target != "application") 10 | .forEach(async (target) => { 11 | await cpy( 12 | [ 13 | `./node_modules/@angular-devkit/build-angular/src/builders/${target}/schema.json`, 14 | ], 15 | `src/builders/${target}` 16 | ); 17 | console.log( 18 | `./node_modules/@angular-devkit/build-angular/src/builders/${target}/schema.json ==> src/builders/${target} ✅` 19 | ); 20 | fs.renameSync( 21 | `src/builders/${target}/schema.json`, 22 | `src/builders/${target}/${target}.json` 23 | ); 24 | }); 25 | // Application target 26 | await cpy( 27 | [`./node_modules/@angular/build/src/builders/application/schema.json`], 28 | `src/builders/application` 29 | ); 30 | console.log( 31 | `./node_modules/@angular/build/src/builders/application/schema.json ==> src/builders/application ✅` 32 | ); 33 | fs.renameSync( 34 | `src/builders/application/schema.json`, 35 | `src/builders/application/application.json` 36 | ); 37 | } 38 | (async () => { 39 | await copyDistSchemas(); 40 | })(); 41 | -------------------------------------------------------------------------------- /packages/angular/tools/schema-generate.ts: -------------------------------------------------------------------------------- 1 | import * as cpy from "cpy"; 2 | import * as fs from "fs"; 3 | import { cliTargets } from "./cli-targets"; 4 | 5 | export default async function () { 6 | console.log("Adding @ngx-env/builder schema"); 7 | const ngxEnvConf = JSON.parse( 8 | fs.readFileSync(`src/builders/ngx-env/ngx-env.json`, "utf-8") 9 | ); 10 | await cpy(["src/builders/**/*.json"], "dist/builders/schemas"); 11 | cliTargets.forEach(async (target) => { 12 | const builderConf = JSON.parse( 13 | fs.readFileSync(`src/builders/${target}/${target}.json`, "utf-8") 14 | ); 15 | builderConf.properties = { ...builderConf.properties, ...ngxEnvConf }; 16 | await fs.writeFileSync( 17 | `dist/builders/schemas/${target}.json`, 18 | JSON.stringify(builderConf, null, 4) 19 | ); 20 | console.log( 21 | `src/builders/${target}/${target}.json ==> dist/builders/schemas/${target}.json ✅` 22 | ); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /packages/angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "moduleResolution": "node", 6 | "module": "commonjs", 7 | "target": "es6", 8 | "lib": ["dom", "es2015", "es2016", "es2017"], 9 | "strict": true, 10 | "allowSyntheticDefaultImports": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "strictPropertyInitialization": false, 13 | "strictNullChecks": false, 14 | "pretty": true, 15 | "sourceMap": false, 16 | "declaration": true, 17 | "stripInternal": true, 18 | "skipLibCheck": true 19 | }, 20 | "exclude": ["node_modules"], 21 | "compileOnSave": false, 22 | "buildOnSave": false 23 | } 24 | -------------------------------------------------------------------------------- /packages/cli/.env.dev: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-run.dev -------------------------------------------------------------------------------- /packages/cli/.env.prod: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-run.app -------------------------------------------------------------------------------- /packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/cli", 3 | "version": "1.3.6", 4 | "description": "cli to load environment variables with monorepo support", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "type": "module", 7 | "main": "dist/index.mjs", 8 | "bin": { 9 | "dotenv-run": "dist/index.mjs" 10 | }, 11 | "files": [ 12 | "dist", 13 | "README.md" 14 | ], 15 | "scripts": { 16 | "dev": "tsc -w", 17 | "test": "vitest", 18 | "build": "tsc" 19 | }, 20 | "keywords": [ 21 | "dotenv", 22 | "run", 23 | "cli" 24 | ], 25 | "author": "Chihab Otmani ", 26 | "license": "ISC", 27 | "dependencies": { 28 | "@dotenv-run/core": "workspace:^1.3.6", 29 | "chalk": "^4.1.2", 30 | "cross-spawn": "^7.0.3", 31 | "minimist": "^1.2.8" 32 | }, 33 | "devDependencies": { 34 | "@types/cross-spawn": "^6.0.6", 35 | "@types/minimist": "^1.2.5" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/cli/src/index.mts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { env } from "@dotenv-run/core"; 4 | import minimist from "minimist"; 5 | import { run } from "./run.js"; 6 | 7 | const argv = minimist(process.argv.slice(2), { 8 | string: ["verbose", "env", "file", "root"], 9 | boolean: ["help", "unsecure", "override"], 10 | alias: { 11 | verbose: "v", 12 | unsecure: "u", 13 | env: "e", 14 | root: "r", 15 | file: "f", 16 | help: "h", 17 | override: "o", 18 | }, 19 | default: { 20 | unsecure: false, 21 | help: false, 22 | override: false, 23 | }, 24 | }); 25 | 26 | function help() { 27 | console.log(` 28 | Usage: dotenv-run [options] -- 29 | 30 | Options: 31 | -v, --verbose [regexp] print debug information, display environment variables filtered by regexp if provided 32 | -u, --unsecure display environment variables in debug output (default: false) 33 | -e, --env [environment] environment to load (default: NODE_ENV) 34 | -r, --root root directory to start searching for .env files (default: root workspace directory) 35 | -f, --file [.env,.secrets,.env.api] specific .env files to load (default: .env) 36 | -o, --override override existing environment variables (default: false) 37 | -h, --help output usage information 38 | 39 | Examples: 40 | dotenv-run -d 41 | dotenv-run -- npm start 42 | dotenv-run -f .env,.env.api -- npm start 43 | `); 44 | } 45 | 46 | function parseList(input: string | string[]): string[] { 47 | return typeof input === "string" ? input.split(",") : input; 48 | } 49 | 50 | if (argv.h) { 51 | help(); 52 | } else { 53 | const cmd = argv._[0]; 54 | const verbose = argv.hasOwnProperty("v"); 55 | if (!verbose && !cmd) { 56 | help(); 57 | process.exit(1); 58 | } 59 | const root = argv.r; 60 | const files = parseList(argv.f ?? ".env"); 61 | const cwd = process.cwd(); 62 | env({ 63 | environment: argv.e ?? process.env.NODE_ENV, 64 | cwd, 65 | root, 66 | files, 67 | prefix: argv.v, 68 | verbose, 69 | unsecure: argv.u, 70 | dotenv: { override: argv.o }, 71 | }); 72 | if (cmd) run(cmd, argv._.slice(1)); 73 | } 74 | -------------------------------------------------------------------------------- /packages/cli/src/run.ts: -------------------------------------------------------------------------------- 1 | import spawn from "cross-spawn"; 2 | 3 | export const run = (cmd: string, args: string[]) => { 4 | spawn(cmd, args, { stdio: "inherit" }).on( 5 | "exit", 6 | function (exitCode, signal) { 7 | if (typeof exitCode === "number") { 8 | process.exit(exitCode); 9 | } else { 10 | process.kill(process.pid, signal); 11 | } 12 | } 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /packages/cli/test/cli.test.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from "child_process"; 2 | import { describe, it, expect } from "vitest"; 3 | 4 | describe("dotenv-run should give the expected output", () => { 5 | it("empty", () => { 6 | const actual = execSync( 7 | "node ./dist/index.mjs -- node -e 'console.log(process.env.API_USERS)'", 8 | { encoding: "utf8" } 9 | ); 10 | expect(actual).not.toContain("https://dotenv-run"); 11 | }); 12 | 13 | it("dev", () => { 14 | const actual = execSync( 15 | "NODE_ENV=dev node ./dist/index.mjs -- node -e 'console.log(process.env.API_USERS)'", 16 | { encoding: "utf8" } 17 | ); 18 | expect(actual).toContain("https://dotenv-run.dev/"); 19 | }); 20 | 21 | it("prod", () => { 22 | const actual = execSync( 23 | "NODE_ENV=prod node ./dist/index.mjs -- node -e 'console.log(process.env.API_USERS)'", 24 | { encoding: "utf8" } 25 | ); 26 | expect(actual).toContain("https://dotenv-run.app/"); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "src" 4 | ], 5 | "compilerOptions": { 6 | "outDir": "dist", 7 | "moduleResolution": "node", 8 | "target": "ES2020", 9 | "module": "ES2020", 10 | "strict": true, 11 | "strictNullChecks": false, 12 | "pretty": true, 13 | "sourceMap": false, 14 | "declaration": false, 15 | "stripInternal": true, 16 | "skipLibCheck": true, 17 | "allowSyntheticDefaultImports": true 18 | }, 19 | "exclude": [ 20 | "node_modules" 21 | ], 22 | "compileOnSave": false, 23 | "buildOnSave": false 24 | } -------------------------------------------------------------------------------- /packages/core/.env.dev: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-run.dev -------------------------------------------------------------------------------- /packages/core/.env.prod: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-run.app -------------------------------------------------------------------------------- /packages/core/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/core 2 | 3 | ## 1.3.6 4 | 5 | ### Patch Changes 6 | 7 | - chore: use pnpm workspace protocol for dependencies 8 | 9 | ## 1.3.4 10 | 11 | ### Patch Changes 12 | 13 | - docs: updates packages' README files 14 | 15 | ## 1.3.3 16 | 17 | ### Patch Changes 18 | 19 | - fix(cli): fix unsecure mode alias 20 | 21 | ## 1.3.2 22 | 23 | ### Patch Changes 24 | 25 | - feat(angular): add unsecure mode option 26 | 27 | ## 1.3.1 28 | 29 | ### Patch Changes 30 | 31 | - feat: add secure mode to debug info 32 | 33 | ## 1.3.0 34 | 35 | ### Minor Changes 36 | 37 | - refactor and docs initialization 38 | 39 | ## 1.2.3 40 | 41 | ### Patch Changes 42 | 43 | - feat(core): support sub-module level turbo.json 44 | 45 | ## 1.2.2 46 | 47 | ### Patch Changes 48 | 49 | - fix(core): filter out undefined env values 50 | 51 | ## 1.2.1 52 | 53 | ### Patch Changes 54 | 55 | - refactor(esbuild): usde esbuild define option 56 | 57 | ## 1.2.0 58 | 59 | ### Minor Changes 60 | 61 | - f63ecac: feat: add esbuild plugin 62 | 63 | ## 1.1.0 64 | 65 | ### Minor Changes 66 | 67 | - af82054: feat: add cjs format and doc 68 | 69 | ## 1.0.0 70 | 71 | ### Major Changes 72 | 73 | - feat: add bundler plugins 74 | 75 | ## 0.5.0 76 | 77 | ### Minor Changes 78 | 79 | - 5efdd8f: add environment option 80 | 81 | ## 0.4.1 82 | 83 | ### Patch Changes 84 | 85 | - fix(cli): fallback root workspace to package.json path 86 | 87 | ## 0.4.0 88 | 89 | ### Minor Changes 90 | 91 | - 98967ed: feat(cli): search for monorepo tools configuration file 92 | 93 | ## 0.3.0 94 | 95 | ### Minor Changes 96 | 97 | - feat(cli): search for root workspace 98 | 99 | ## 0.2.0 100 | 101 | ### Minor Changes 102 | 103 | - 3551e4d: @dotenv-run/cli a cli to load command line and .env environment variables with monorepo support 104 | -------------------------------------------------------------------------------- /packages/core/README.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/core 2 | 3 | - ✅ Load environment variables from the command line `API_BASE=/v1/ core` 4 | - ✅ Load environment variables from `.env` files 5 | - ✅ Expand environment variables `API_URL=$API_BASE/users` 6 | - ✅ Define environment variables for a specific environment (e.g. `.env.production`) 7 | - ✅ Load priorities of `.env.*` files (e.g. `.env.production` > `.env`) 8 | - ✅ Hierarchical cascading configuration in monorepo projects ([Nx](https://nx.dev), [Turbo](https://turborepo.com/), etc.) 9 | `apps/next-app/.env` > `apps/.env` > `.env` 10 | 11 | # Install 12 | 13 | ```console 14 | npm add @dotenv-run/core 15 | ``` 16 | 17 | # Usage 18 | 19 | ```js 20 | // index.js 21 | import { env } from "@dotenv-run/core"; 22 | env({ 23 | root: "../..", 24 | verbose: true, 25 | prefix: "^API_", 26 | files: [".env"], 27 | }); 28 | console.log(process.env.API_USERS); 29 | ``` 30 | 31 | given the following files: 32 | 33 | ```shell 34 | .env 35 | API_USERS=$API_BASE/v1/users 36 | API_AUTH=$API_BASE/v1/auth 37 | .env.dev 38 | API_BASE=https://localhost:3000 39 | .env.prod 40 | API_BASE=https://dotenv-run.app 41 | ``` 42 | 43 | then: 44 | 45 | ```shell 46 | NODE_ENV=dev node index.js 47 | https://localhost:3000/v1/users 48 | 49 | NODE_ENV=prod node index.js 50 | https://dotenv-run.app/v1/users 51 | ``` 52 | 53 | # License 54 | 55 | MIT © [Chihab Otmani](mailto:chihab@gmail.com) 56 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/core", 3 | "version": "1.3.6", 4 | "description": "core library to load environment variables with monorepo support", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "main": "dist/cjs/index.js", 7 | "module": "dist/esm/index.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "dev": "tsc -w", 11 | "test": "vitest", 12 | "build": "concurrently npm:build:*", 13 | "build:esm": "tsc --module esnext --outDir dist/esm", 14 | "build:cjs": "tsc --module commonjs --outDir dist/cjs", 15 | "build:types": "tsc --emitDeclarationOnly --declaration --declarationMap --module esnext --outDir dist" 16 | }, 17 | "files": [ 18 | "dist", 19 | "README.md" 20 | ], 21 | "keywords": [ 22 | "dotenv", 23 | "run", 24 | "cli" 25 | ], 26 | "author": "Chihab Otmani ", 27 | "license": "ISC", 28 | "dependencies": { 29 | "chalk": "^4.1.2", 30 | "dotenv": "^16.4.5", 31 | "dotenv-expand": "^10.0.0", 32 | "find-up": "^5.0.0" 33 | }, 34 | "devDependencies": { 35 | "@types/node": "^16.18.112" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/core/src/build.ts: -------------------------------------------------------------------------------- 1 | export type Dict = Record; 2 | 3 | export type DotenvRun = { 4 | raw: Dict; 5 | stringified: Dict; 6 | full: Dict; 7 | }; 8 | 9 | export function build( 10 | processEnv: Dict, 11 | runtime: boolean, 12 | globalVar: string, 13 | define?: string 14 | ) { 15 | const values = Object.keys(processEnv).reduce( 16 | (env, key) => { 17 | const value = runtime 18 | ? `globalThis.${globalVar}.${key}` 19 | : JSON.stringify(processEnv[key]); 20 | env.raw[key] = processEnv[key]; 21 | env.stringified[key] = value; 22 | env.full[`process.env.${key}`] = value; 23 | env.full[`import.meta.env.${key}`] = value; 24 | return env; 25 | }, 26 | { 27 | raw: {}, 28 | stringified: define 29 | ? { 30 | [define]: runtime 31 | ? `globalThis.${globalVar}` 32 | : JSON.stringify(processEnv), 33 | } 34 | : {}, 35 | full: define 36 | ? { 37 | [define]: runtime 38 | ? `globalThis.${globalVar}` 39 | : JSON.stringify(processEnv), 40 | } 41 | : {}, 42 | } 43 | ); 44 | return values; 45 | } 46 | -------------------------------------------------------------------------------- /packages/core/src/expand.ts: -------------------------------------------------------------------------------- 1 | import { config, DotenvConfigOptions } from "dotenv"; 2 | import { expand as dotenvExpand } from "dotenv-expand"; 3 | 4 | export function expand(envPaths: string[], dotenvConfig?: DotenvConfigOptions) { 5 | envPaths.forEach((dotenvFile) => { 6 | dotenvExpand( 7 | config({ 8 | path: dotenvFile, 9 | ...dotenvConfig, 10 | }) 11 | ); 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./env.js"; 2 | export * from "./options.js"; 3 | export * from "./root.js"; 4 | export * from "./build.js"; 5 | 6 | declare global { 7 | interface ImportMeta { 8 | env: ImportMetaEnv; 9 | } 10 | 11 | interface ImportMetaEnv { 12 | [key: string]: any; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/core/src/options.ts: -------------------------------------------------------------------------------- 1 | import type { DotenvConfigOptions } from "dotenv"; 2 | import { Dict } from "./build"; 3 | 4 | export interface DotenvRunOptions { 5 | cwd?: string; // Path to current working directory 6 | dotenv?: DotenvConfigOptions; 7 | environment?: string; // Environment to load 8 | files?: string[]; // Environment files to load 9 | prefix?: string | RegExp; // Filter keys to inject 10 | unsecure?: boolean; // Display environment variables in debug output 11 | root?: string; // Path to root workspace 12 | nodeEnv?: boolean; // Node environment 13 | verbose?: boolean; // Print verbose output 14 | builtIn?: Dict; // Built-in environment variables 15 | runtime?: boolean; // Whether to use runtime variables 16 | define?: string; // Define key to replace in code 17 | global?: string; // Global variable name 18 | } 19 | -------------------------------------------------------------------------------- /packages/core/src/root.ts: -------------------------------------------------------------------------------- 1 | import * as findUp from "find-up"; 2 | import { readFileSync } from "fs"; 3 | import * as path from "path"; 4 | 5 | /** 6 | * Return root `turbo.json` file path if found, else return original input. 7 | * 8 | * @param turboPath existing turbo.json file path. 9 | * @throws {Error} if `turboPath` is not exist. 10 | */ 11 | function findTurboRootPath(turboPath: string): string { 12 | // test if file content has `"extends": ["//"]` 13 | const isSubProject = readFileSync(turboPath, "utf8").includes('"extends"'); 14 | if (isSubProject) { 15 | const parent = path.dirname(path.dirname(turboPath)); 16 | const rootPath = findUp.sync("turbo.json", { cwd: parent }); 17 | if (rootPath) return rootPath; 18 | } 19 | return turboPath; 20 | } 21 | 22 | export function findRootPath() { 23 | if (process.env.NX_WORKSPACE_ROOT) { 24 | return process.env.NX_WORKSPACE_ROOT; 25 | } 26 | let p = findUp.sync([ 27 | "turbo.json", 28 | "nx.json", // Just in case NX_WORKSPACE_ROOT is not set 29 | "lerna.json", 30 | "pnpm-workspace.yaml", 31 | ]); 32 | 33 | if (p && p.endsWith("turbo.json")) { 34 | p = findTurboRootPath(p); 35 | } 36 | 37 | if (!p) p = findUp.sync(["package.json"]); 38 | return p ? path.dirname(p) : process.cwd(); 39 | } 40 | -------------------------------------------------------------------------------- /packages/core/src/utils.ts: -------------------------------------------------------------------------------- 1 | import * as fs from "fs"; 2 | import * as path from "path"; 3 | 4 | export function isSubfolder(parent: string, child: string) { 5 | return path.relative(parent, child).startsWith(".."); 6 | } 7 | 8 | export function getAbsoluteEnvPath(envPath: string, cwd: string) { 9 | const _envPath = path.isAbsolute(envPath) 10 | ? envPath 11 | : path.resolve(cwd, envPath); 12 | return fs.existsSync(_envPath) 13 | ? fs.lstatSync(_envPath).isDirectory() 14 | ? _envPath 15 | : path.dirname(_envPath) 16 | : cwd; 17 | } 18 | 19 | export function getPathsDownTo(envPath: string, destination: string) { 20 | let currentPath = destination; 21 | const paths = [currentPath]; 22 | while (currentPath !== envPath && currentPath !== "/") { 23 | currentPath = path.dirname(currentPath); 24 | paths.push(currentPath); 25 | } 26 | return paths; 27 | } 28 | -------------------------------------------------------------------------------- /packages/core/test/dev.test.ts: -------------------------------------------------------------------------------- 1 | import { it, expect } from "vitest"; 2 | import { env } from "../src"; 3 | 4 | it("should load dev environment from the root workspace", () => { 5 | process.env.NODE_ENV = "dev"; 6 | const { full, stringified, raw } = env({ 7 | root: "..", 8 | verbose: true, 9 | prefix: "^API_", 10 | files: [".env"], 11 | }); 12 | expect(raw).toEqual({ 13 | API_AUTH: "https://dotenv-run.dev/api/v1/auth", 14 | API_BASE: "https://dotenv-run.dev", 15 | API_USERS: "https://dotenv-run.dev/api/v1/users", 16 | NODE_ENV: "dev", 17 | }); 18 | expect(stringified).toEqual({ 19 | API_AUTH: '"https://dotenv-run.dev/api/v1/auth"', 20 | API_BASE: '"https://dotenv-run.dev"', 21 | API_USERS: '"https://dotenv-run.dev/api/v1/users"', 22 | NODE_ENV: '"dev"', 23 | }); 24 | expect(full).toEqual({ 25 | "import.meta.env.API_AUTH": '"https://dotenv-run.dev/api/v1/auth"', 26 | "import.meta.env.API_BASE": '"https://dotenv-run.dev"', 27 | "import.meta.env.API_USERS": '"https://dotenv-run.dev/api/v1/users"', 28 | "import.meta.env.NODE_ENV": '"dev"', 29 | "process.env.API_AUTH": '"https://dotenv-run.dev/api/v1/auth"', 30 | "process.env.API_BASE": '"https://dotenv-run.dev"', 31 | "process.env.API_USERS": '"https://dotenv-run.dev/api/v1/users"', 32 | "process.env.NODE_ENV": '"dev"', 33 | }); 34 | expect(process.env.API_USERS).toBe("https://dotenv-run.dev/api/v1/users"); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/core/test/prod.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, it } from "vitest"; 2 | import { env } from "../src"; 3 | 4 | it("should load prod environment", () => { 5 | process.env.NODE_ENV = "prod"; 6 | const { full, stringified, raw } = env({ 7 | root: "..", 8 | verbose: true, 9 | prefix: "^API_", 10 | }); 11 | expect(raw).toEqual({ 12 | API_AUTH: "https://dotenv-run.app/api/v1/auth", 13 | API_BASE: "https://dotenv-run.app", 14 | API_USERS: "https://dotenv-run.app/api/v1/users", 15 | NODE_ENV: "prod", 16 | }); 17 | expect(stringified).toEqual({ 18 | API_AUTH: '"https://dotenv-run.app/api/v1/auth"', 19 | API_BASE: '"https://dotenv-run.app"', 20 | API_USERS: '"https://dotenv-run.app/api/v1/users"', 21 | NODE_ENV: '"prod"', 22 | }); 23 | expect(full).toEqual({ 24 | "import.meta.env.API_AUTH": '"https://dotenv-run.app/api/v1/auth"', 25 | "import.meta.env.API_BASE": '"https://dotenv-run.app"', 26 | "import.meta.env.API_USERS": '"https://dotenv-run.app/api/v1/users"', 27 | "import.meta.env.NODE_ENV": '"prod"', 28 | "process.env.API_AUTH": '"https://dotenv-run.app/api/v1/auth"', 29 | "process.env.API_BASE": '"https://dotenv-run.app"', 30 | "process.env.API_USERS": '"https://dotenv-run.app/api/v1/users"', 31 | "process.env.NODE_ENV": '"prod"', 32 | }); 33 | expect(process.env.API_USERS).toBe("https://dotenv-run.app/api/v1/users"); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "moduleResolution": "node", 6 | "target": "ES2022", 7 | "module": "ES2022", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "strictPropertyInitialization": false, 12 | "strictNullChecks": false, 13 | "pretty": true, 14 | "sourceMap": true, 15 | "skipLibCheck": true 16 | }, 17 | "exclude": ["node_modules"], 18 | "compileOnSave": false, 19 | "buildOnSave": false 20 | } 21 | -------------------------------------------------------------------------------- /packages/esbuild/.env: -------------------------------------------------------------------------------- 1 | MY_API_BASE=https://dotenv-run.app -------------------------------------------------------------------------------- /packages/esbuild/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/esbuild 2 | 3 | ## 1.5.0 4 | 5 | ### Minor Changes 6 | 7 | - 8f83f0c: feat: add compatibility with Angular 19 8 | 9 | ## 1.4.2 10 | 11 | ### Patch Changes 12 | 13 | - chore: use pnpm workspace protocol for dependencies 14 | - Updated dependencies 15 | - @dotenv-run/core@1.3.6 16 | 17 | ## 1.4.0 18 | 19 | ### Minor Changes 20 | 21 | - bump up webpack and esbuild versions 22 | 23 | ## 1.3.4 24 | 25 | ### Patch Changes 26 | 27 | - docs: updates packages' README files 28 | - Updated dependencies 29 | - @dotenv-run/core@1.3.4 30 | 31 | ## 1.3.3 32 | 33 | ### Patch Changes 34 | 35 | - fix(cli): fix unsecure mode alias 36 | - Updated dependencies 37 | - @dotenv-run/core@1.3.3 38 | 39 | ## 1.3.2 40 | 41 | ### Patch Changes 42 | 43 | - feat(angular): add unsecure mode option 44 | - Updated dependencies 45 | - @dotenv-run/core@1.3.2 46 | 47 | ## 1.3.1 48 | 49 | ### Patch Changes 50 | 51 | - feat: add secure mode to debug info 52 | - Updated dependencies 53 | - @dotenv-run/core@1.3.1 54 | 55 | ## 1.3.0 56 | 57 | ### Minor Changes 58 | 59 | - refactor and docs initialization 60 | 61 | ### Patch Changes 62 | 63 | - Updated dependencies 64 | - @dotenv-run/core@1.3.0 65 | 66 | ## 1.2.3 67 | 68 | ### Patch Changes 69 | 70 | - feat(core): support sub-module level turbo.json 71 | - Updated dependencies 72 | - @dotenv-run/core@1.2.3 73 | 74 | ## 1.2.2 75 | 76 | ### Patch Changes 77 | 78 | - fix(core): filter out undefined env values 79 | - Updated dependencies 80 | - @dotenv-run/core@1.2.2 81 | 82 | ## 1.2.1 83 | 84 | ### Patch Changes 85 | 86 | - refactor(esbuild): usde esbuild define option 87 | - Updated dependencies 88 | - @dotenv-run/core@1.2.1 89 | 90 | ## 1.2.0 91 | 92 | ### Minor Changes 93 | 94 | - f63ecac: feat: add esbuild plugin 95 | 96 | ### Patch Changes 97 | 98 | - Updated dependencies [f63ecac] 99 | - @dotenv-run/core@1.2.0 100 | -------------------------------------------------------------------------------- /packages/esbuild/README.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/esbuild 2 | 3 | - ✅ Load environment variables from the command line `API_BASE=/v1/ node esbuild.mjs` 4 | - ✅ Load environment variables from `.env` files 5 | - ✅ Expand environment variables `API_URL=$API_BASE/users` 6 | - ✅ Define environment variables for a specific environment (e.g. `.env.production`) 7 | - ✅ Load priorities of `.env.*` files (e.g. `.env.production` > `.env`) 8 | - ✅ Hierarchical cascading configuration in monorepo projects ([Nx](https://nx.dev), [Turbo](https://turborepo.com/), etc.) 9 | `apps/next-app/.env` > `apps/.env` > `.env` 10 | 11 | ## Install 12 | 13 | ```console 14 | npm add @dotenv-run/esbuild --save-dev 15 | ``` 16 | 17 | ## Usage 18 | 19 | ### Using define (recommended) 20 | 21 | ```js 22 | import { build } from "esbuild"; 23 | import { env } from "@dotenv-run/esbuild"; 24 | 25 | const { full } = env({ 26 | prefix: "MY_", 27 | verbose: false, 28 | files: [".env"], 29 | }); 30 | 31 | const results = await build({ 32 | bundle: true, 33 | write: false, 34 | entryPoints: [`test/app.js`], 35 | define: full, 36 | }); 37 | ``` 38 | 39 | ### Using esbuild plugin 40 | 41 | ```js 42 | import { build } from "esbuild"; 43 | import { dotenvRun } from "@dotenv-run/esbuild"; 44 | 45 | await build({ 46 | write: false, 47 | bundle: true, 48 | entryPoints: [`test/app.js`], 49 | plugins: [ 50 | dotenvRun({ 51 | verbose: true, 52 | root: "../../", 53 | prefix: "^API", 54 | }), 55 | ], 56 | }); 57 | ``` 58 | -------------------------------------------------------------------------------- /packages/esbuild/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/esbuild", 3 | "version": "1.5.0", 4 | "description": "Run your scripts with dotenv variables", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "main": "dist/cjs/index.js", 7 | "module": "dist/esm/index.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "dev": "tsc -w", 11 | "test": "vitest", 12 | "build": "concurrently npm:build:*", 13 | "build:esm": "tsc --module esnext --outDir dist/esm", 14 | "build:cjs": "tsc --module commonjs --outDir dist/cjs", 15 | "build:types": "tsc --emitDeclarationOnly --declaration --declarationMap --module esnext --outDir dist" 16 | }, 17 | "files": [ 18 | "dist", 19 | "README.md" 20 | ], 21 | "keywords": [ 22 | "dotenv", 23 | "run", 24 | "cli" 25 | ], 26 | "author": "Chihab Otmani ", 27 | "license": "ISC", 28 | "dependencies": { 29 | "@dotenv-run/core": "workspace:~1.3.6" 30 | }, 31 | "peerDependencies": { 32 | "esbuild": "^0.21.0" 33 | }, 34 | "devDependencies": { 35 | "@types/node": "^16.18.112", 36 | "esbuild": "^0.23.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/esbuild/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Dict, env, type DotenvRunOptions } from "@dotenv-run/core"; 2 | import type { Plugin, PluginBuild } from "esbuild"; 3 | 4 | function definePluginBuild(build: PluginBuild, env: Dict): void { 5 | const define = build.initialOptions.define ?? {}; 6 | build.initialOptions.define = { 7 | ...env, 8 | ...define, 9 | }; 10 | } 11 | 12 | const dotenvRun = (options: DotenvRunOptions): Plugin => { 13 | return { 14 | name: "dotenv-run", 15 | setup(build) { 16 | const full = env(options).full; 17 | definePluginBuild(build, full); 18 | }, 19 | }; 20 | }; 21 | 22 | const dotenvRunDefine = (env: Dict): Plugin => { 23 | return { 24 | name: "dotenv-run-define", 25 | setup(build) { 26 | definePluginBuild(build, env); 27 | }, 28 | }; 29 | }; 30 | 31 | export { DotenvRunOptions, dotenvRun, dotenvRunDefine }; 32 | export default dotenvRun; 33 | -------------------------------------------------------------------------------- /packages/esbuild/test/__snapshots__/index.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Usage with esbuild > should replace environment variables using define option 1`] = ` 4 | "\\"use strict\\"; 5 | (() => { 6 | // test/util.js 7 | function meta() { 8 | return \\"https://dotenv-run.app\\"; 9 | } 10 | 11 | // test/app.js 12 | console.log(\\"https://dotenv-run.app\\"); 13 | console.log(meta()); 14 | })();" 15 | `; 16 | 17 | exports[`Usage with esbuild > should replace environment variables using esbuild plugin 1`] = ` 18 | "\\"use strict\\"; 19 | (() => { 20 | // test/util.js 21 | function meta() { 22 | return \\"https://dotenv-run.app\\"; 23 | } 24 | 25 | // test/app.js 26 | console.log(\\"https://dotenv-run.app\\"); 27 | console.log(meta()); 28 | })(); 29 | " 30 | `; 31 | 32 | exports[`Usage with esbuild > should replace environment variables using esbuild plugin and a custom define 1`] = ` 33 | "\\"use strict\\"; 34 | (() => { 35 | // test/util.js 36 | function meta() { 37 | return \\"https://dotenv-run.define\\"; 38 | } 39 | 40 | // test/app.js 41 | console.log(\\"https://dotenv-run.define\\"); 42 | console.log(meta()); 43 | })(); 44 | " 45 | `; 46 | -------------------------------------------------------------------------------- /packages/esbuild/test/app.js: -------------------------------------------------------------------------------- 1 | import { meta } from './util.js'; 2 | 3 | console.log(process.env.MY_API_BASE); 4 | console.log(meta()); -------------------------------------------------------------------------------- /packages/esbuild/test/index.test.ts: -------------------------------------------------------------------------------- 1 | import { build } from "esbuild"; 2 | import { describe, expect, it } from "vitest"; 3 | import { dotenvRun } from "../src/"; 4 | import { env } from "@dotenv-run/core"; 5 | 6 | describe("Usage with esbuild", () => { 7 | it("should replace environment variables using esbuild plugin", async () => { 8 | const results = await build({ 9 | write: false, 10 | bundle: true, 11 | entryPoints: [`test/app.js`], 12 | plugins: [ 13 | dotenvRun({ 14 | prefix: "MY_", 15 | verbose: false, 16 | files: [".env"], 17 | }), 18 | ], 19 | }); 20 | 21 | expect(results.outputFiles.at(0)?.text).toMatchSnapshot(); 22 | }); 23 | 24 | 25 | it("should replace environment variables using esbuild plugin and a custom define", async () => { 26 | const results = await build({ 27 | write: false, 28 | bundle: true, 29 | entryPoints: [`test/app.js`], 30 | define: { 31 | "process.env.MY_API_BASE": '"https://dotenv-run.define"', 32 | "import.meta.env.MY_API_BASE": '"https://dotenv-run.define"', 33 | }, 34 | plugins: [ 35 | dotenvRun({ 36 | prefix: "MY_", 37 | verbose: false, 38 | files: [".env"], 39 | }), 40 | ], 41 | }); 42 | 43 | expect(results.outputFiles.at(0)?.text).toMatchSnapshot(); 44 | }); 45 | 46 | it("should replace environment variables using define option", async () => { 47 | const { full } = env({ 48 | prefix: "MY_", 49 | verbose: false, 50 | files: [".env"], 51 | }); 52 | 53 | const results = await build({ 54 | bundle: true, 55 | write: false, 56 | entryPoints: [`test/app.js`], 57 | define: full, 58 | }); 59 | 60 | expect(results.outputFiles.at(0)?.text.trim()).toMatchSnapshot(); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /packages/esbuild/test/util.js: -------------------------------------------------------------------------------- 1 | export function meta() { 2 | return import.meta.env.MY_API_BASE; 3 | } -------------------------------------------------------------------------------- /packages/esbuild/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "moduleResolution": "node", 6 | "module": "ES2022", 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strictPropertyInitialization": false, 10 | "esModuleInterop": true, 11 | "strictNullChecks": false, 12 | "pretty": true, 13 | "sourceMap": true, 14 | "declaration": true, 15 | "skipLibCheck": true 16 | }, 17 | "exclude": ["node_modules"], 18 | "compileOnSave": false, 19 | "buildOnSave": false 20 | } 21 | -------------------------------------------------------------------------------- /packages/jest-angular/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/jest-angular 2 | 3 | ## 0.2.0 4 | 5 | ### Minor Changes 6 | 7 | - 8f83f0c: feat: add compatibility with Angular 19 8 | -------------------------------------------------------------------------------- /packages/jest-angular/README.md: -------------------------------------------------------------------------------- 1 | ## Install 2 | 3 | The package requires `jest-preset-angular@14` to be installed as a peer dependency. 4 | 5 | ```sh 6 | npm install --save-dev @dotenv-run/jest-angular 7 | ``` 8 | 9 | ## Usage 10 | 11 | Add the following to your `jest.config.js`, more information can be found in the [jest-preset-angular](https://thymikee.github.io/jest-preset-angular/docs/guides/esm-support/). 12 | 13 | ESM support is required for Jest to understand `import.meta.env` notation. 14 | 15 | ```js 16 | const jestConfig = { 17 | // Required for ESM support 18 | preset: "jest-preset-angular/presets/defaults-esm", 19 | setupFilesAfterEnv: ["/setup-jest.ts"], 20 | testMatch: ["/src/app/**/*.(spec|jest).ts"], 21 | moduleNameMapper: { 22 | "^rxjs(/operators$)?$": 23 | "/node_modules/rxjs/dist/bundles/rxjs.umd.js", 24 | tslib: "/node_modules/tslib/tslib.es6.mjs", 25 | }, 26 | 27 | // @dotenv-run/jest-angular transformer 28 | transform: { 29 | "^.+\\.(ts)$": [ 30 | "@dotenv-run/jest-angular", 31 | { 32 | useESM: true, 33 | stringifyContentPathRegex: "\\.(html|svg)$", 34 | }, 35 | ], 36 | }, 37 | }; 38 | 39 | export default jestConfig; 40 | ``` 41 | 42 | Add the following to your `setup-jest.ts` file. 43 | 44 | ```ts 45 | // Required for ESM support 46 | import "jest-preset-angular/setup-jest.mjs"; 47 | 48 | // Load environment variables for Jest 49 | import { env } from "@dotenv-run/core"; 50 | env({ root: "../../..", files: [".env", ".env.app"] }); 51 | ``` 52 | 53 | Run your tests with `jest`. More information can be found in the [Jest documentation](https://jestjs.io/docs/ecmascript-modules). 54 | 55 | ```sh 56 | NODE_OPTIONS=--experimental-vm-modules npx jest 57 | ``` 58 | 59 | or 60 | 61 | ```sh 62 | node --experimental-vm-modules /path/to/node_modules/jest/bin/jest.js 63 | ``` 64 | 65 | If you're using Nx 66 | 67 | ```sh 68 | NODE_OPTIONS=--experimental-vm-modules nx test 69 | ``` 70 | 71 | ```sh 72 | node --experimental-vm-modules /path/to/node_modules/nx/bin/nx.js test 73 | ``` 74 | -------------------------------------------------------------------------------- /packages/jest-angular/index.mjs: -------------------------------------------------------------------------------- 1 | import { NgJestTransformer } from "jest-preset-angular/build/ng-jest-transformer.js"; 2 | export default { 3 | createTransformer: (tsJestConfig) => { 4 | const ngT = new NgJestTransformer(tsJestConfig); 5 | return { 6 | process: (src, filename, config, options) => { 7 | if (/.ts$/.test(filename)) { 8 | src = ` 9 | import.meta.env = process.env; 10 | ${src} 11 | `; 12 | } 13 | return ngT.process(src, filename, config, options); 14 | }, 15 | }; 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /packages/jest-angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/jest-angular", 3 | "version": "0.2.0", 4 | "description": "Run Jest with Angular CLI environment variables", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "sideEffects": true, 7 | "files": [ 8 | "index.mjs", 9 | "README.md" 10 | ], 11 | "exports": { 12 | ".": { 13 | "import": "./index.mjs", 14 | "require": "./index.mjs" 15 | } 16 | }, 17 | "keywords": [ 18 | "dotenv", 19 | "run", 20 | "cli" 21 | ], 22 | "devDependencies": { 23 | "jest-preset-angular": "^14.0.0" 24 | }, 25 | "peerDependencies": { 26 | "jest-preset-angular": "^14.0.0" 27 | }, 28 | "author": "Chihab Otmani ", 29 | "license": "ISC" 30 | } 31 | -------------------------------------------------------------------------------- /packages/jest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/jest", 3 | "version": "0.1.0", 4 | "description": "Run Jest with import.meta.env", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "main": "src/jest-env.mjs", 7 | "module": "src/jest-env.mjs", 8 | "files": [ 9 | "src", 10 | "README.md" 11 | ], 12 | "keywords": [ 13 | "dotenv", 14 | "run" 15 | ], 16 | "author": "Chihab Otmani ", 17 | "license": "ISC" 18 | } 19 | -------------------------------------------------------------------------------- /packages/jest/src/jest-env.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | createTransformer: () => { 3 | return { 4 | process: (src, filename) => { 5 | if (/.ts$/.test(filename)) { 6 | src = ` 7 | import.meta.env = process.env; 8 | ${src} 9 | `; 10 | } 11 | return { code: src }; 12 | }, 13 | }; 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /packages/load/.env: -------------------------------------------------------------------------------- 1 | API_USERS=$API_BASE/api/v1/users 2 | API_AUTH=$API_BASE/api/v1/auth -------------------------------------------------------------------------------- /packages/load/.env.dev: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-run.dev -------------------------------------------------------------------------------- /packages/load/.env.prod: -------------------------------------------------------------------------------- 1 | API_BASE=https://dotenv-run.app -------------------------------------------------------------------------------- /packages/load/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/load 2 | 3 | ## 1.3.6 4 | 5 | ### Patch Changes 6 | 7 | - chore: use pnpm workspace protocol for dependencies 8 | - Updated dependencies 9 | - @dotenv-run/core@1.3.6 10 | 11 | ## 1.3.4 12 | 13 | ### Patch Changes 14 | 15 | - docs: updates packages' README files 16 | - Updated dependencies 17 | - @dotenv-run/core@1.3.4 18 | 19 | ## 1.3.3 20 | 21 | ### Patch Changes 22 | 23 | - fix(cli): fix unsecure mode alias 24 | - Updated dependencies 25 | - @dotenv-run/core@1.3.3 26 | 27 | ## 1.3.2 28 | 29 | ### Patch Changes 30 | 31 | - feat(angular): add unsecure mode option 32 | - Updated dependencies 33 | - @dotenv-run/core@1.3.2 34 | 35 | ## 1.3.1 36 | 37 | ### Patch Changes 38 | 39 | - feat: add secure mode to debug info 40 | - Updated dependencies 41 | - @dotenv-run/core@1.3.1 42 | 43 | ## 1.3.0 44 | 45 | ### Minor Changes 46 | 47 | - refactor and docs initialization 48 | 49 | ### Patch Changes 50 | 51 | - Updated dependencies 52 | - @dotenv-run/core@1.3.0 53 | 54 | ## 1.2.3 55 | 56 | ### Patch Changes 57 | 58 | - feat(core): support sub-module level turbo.json 59 | - Updated dependencies 60 | - @dotenv-run/core@1.2.3 61 | 62 | ## 1.2.2 63 | 64 | ### Patch Changes 65 | 66 | - fix(core): filter out undefined env values 67 | - Updated dependencies 68 | - @dotenv-run/core@1.2.2 69 | 70 | ## 1.2.1 71 | 72 | ### Patch Changes 73 | 74 | - refactor(esbuild): usde esbuild define option 75 | - Updated dependencies 76 | - @dotenv-run/core@1.2.1 77 | 78 | ## 1.2.0 79 | 80 | ### Minor Changes 81 | 82 | - f63ecac: feat: add esbuild plugin 83 | 84 | ### Patch Changes 85 | 86 | - Updated dependencies [f63ecac] 87 | - @dotenv-run/core@1.2.0 88 | 89 | ## 1.1.0 90 | 91 | ### Minor Changes 92 | 93 | - af82054: feat: add cjs format and doc 94 | 95 | ### Patch Changes 96 | 97 | - Updated dependencies [af82054] 98 | - @dotenv-run/core@1.1.0 99 | -------------------------------------------------------------------------------- /packages/load/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/load", 3 | "version": "1.3.6", 4 | "description": "Preload your scripts with dotenv variables", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "main": "dist/index.js", 7 | "types": "dist/index.d.ts", 8 | "scripts": { 9 | "dev": "tsc -w", 10 | "test": "vitest", 11 | "build": "tsc" 12 | }, 13 | "files": [ 14 | "dist", 15 | "README.md" 16 | ], 17 | "keywords": [ 18 | "dotenv", 19 | "run", 20 | "cli" 21 | ], 22 | "author": "Chihab Otmani ", 23 | "license": "ISC", 24 | "dependencies": { 25 | "@dotenv-run/core": "workspace:^1.3.6" 26 | }, 27 | "devDependencies": { 28 | "@types/node": "^16.18.112" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/load/src/index.ts: -------------------------------------------------------------------------------- 1 | import { env, findRootPath } from "@dotenv-run/core"; 2 | env({ 3 | environment: process.env.NODE_ENV, 4 | cwd: process.cwd(), 5 | root: findRootPath(), 6 | files: [".env"] 7 | }); 8 | env(); 9 | -------------------------------------------------------------------------------- /packages/load/test/load.test.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from "child_process"; 2 | import { describe, it, expect } from "vitest"; 3 | 4 | describe("dotenv-run should give the expected output", () => { 5 | it("preload dev", () => { 6 | const actual = execSync( 7 | "NODE_ENV=dev node -r ./dist/index.js ./test/server.js", 8 | { 9 | encoding: "utf8", 10 | } 11 | ); 12 | expect(actual).toContain("https://dotenv-run.dev/"); 13 | }); 14 | 15 | it("preload prod", () => { 16 | const actual = execSync( 17 | "NODE_ENV=prod node -r ./dist/index.js ./test/server.js", 18 | { 19 | encoding: "utf8", 20 | } 21 | ); 22 | expect(actual).toContain("https://dotenv-run.app/"); 23 | }); 24 | 25 | it("NODE_OPTIONS prod", () => { 26 | const actual = execSync( 27 | "NODE_ENV=prod NODE_OPTIONS='-r ./dist/index.js' node ./test/server.js", 28 | { 29 | encoding: "utf8", 30 | } 31 | ); 32 | expect(actual).toContain("https://dotenv-run.app/"); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/load/test/server.js: -------------------------------------------------------------------------------- 1 | console.log(process.env.API_USERS) -------------------------------------------------------------------------------- /packages/load/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "moduleResolution": "node", 6 | "module": "CommonJS", 7 | "strict": true, 8 | "allowSyntheticDefaultImports": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "strictPropertyInitialization": false, 11 | "strictNullChecks": false, 12 | "pretty": true, 13 | "sourceMap": true, 14 | "declaration": true, 15 | "skipLibCheck": true 16 | }, 17 | "exclude": ["node_modules"], 18 | "compileOnSave": false, 19 | "buildOnSave": false 20 | } 21 | -------------------------------------------------------------------------------- /packages/rollup/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/rollup 2 | 3 | ## 1.3.6 4 | 5 | ### Patch Changes 6 | 7 | - chore: use pnpm workspace protocol for dependencies 8 | - Updated dependencies 9 | - @dotenv-run/core@1.3.6 10 | 11 | ## 1.3.4 12 | 13 | ### Patch Changes 14 | 15 | - docs: updates packages' README files 16 | - Updated dependencies 17 | - @dotenv-run/core@1.3.4 18 | 19 | ## 1.3.3 20 | 21 | ### Patch Changes 22 | 23 | - fix(cli): fix unsecure mode alias 24 | - Updated dependencies 25 | - @dotenv-run/core@1.3.3 26 | 27 | ## 1.3.2 28 | 29 | ### Patch Changes 30 | 31 | - feat(angular): add unsecure mode option 32 | - Updated dependencies 33 | - @dotenv-run/core@1.3.2 34 | 35 | ## 1.3.1 36 | 37 | ### Patch Changes 38 | 39 | - feat: add secure mode to debug info 40 | - Updated dependencies 41 | - @dotenv-run/core@1.3.1 42 | 43 | ## 1.3.0 44 | 45 | ### Minor Changes 46 | 47 | - refactor and docs initialization 48 | 49 | ### Patch Changes 50 | 51 | - Updated dependencies 52 | - @dotenv-run/core@1.3.0 53 | 54 | ## 1.2.3 55 | 56 | ### Patch Changes 57 | 58 | - feat(core): support sub-module level turbo.json 59 | - Updated dependencies 60 | - @dotenv-run/core@1.2.3 61 | 62 | ## 1.2.2 63 | 64 | ### Patch Changes 65 | 66 | - fix(core): filter out undefined env values 67 | - Updated dependencies 68 | - @dotenv-run/core@1.2.2 69 | 70 | ## 1.2.1 71 | 72 | ### Patch Changes 73 | 74 | - refactor(esbuild): usde esbuild define option 75 | - Updated dependencies 76 | - @dotenv-run/core@1.2.1 77 | 78 | ## 1.2.0 79 | 80 | ### Minor Changes 81 | 82 | - f63ecac: feat: add esbuild plugin 83 | 84 | ### Patch Changes 85 | 86 | - Updated dependencies [f63ecac] 87 | - @dotenv-run/core@1.2.0 88 | 89 | ## 1.1.1 90 | 91 | ### Patch Changes 92 | 93 | - cea8c35: fix(rollup): upgrade rollup peerdep 94 | 95 | ## 1.1.0 96 | 97 | ### Minor Changes 98 | 99 | - af82054: feat: add cjs format and doc 100 | 101 | ### Patch Changes 102 | 103 | - Updated dependencies [af82054] 104 | - @dotenv-run/core@1.1.0 105 | 106 | ## 1.0.1 107 | 108 | ### Patch Changes 109 | 110 | - 429d699: refactor(webpack): export dotenv results 111 | 112 | ## 1.0.0 113 | 114 | ### Major Changes 115 | 116 | - feat: add bundler plugins 117 | 118 | ### Patch Changes 119 | 120 | - Updated dependencies 121 | - @dotenv-run/core@1.0.0 122 | -------------------------------------------------------------------------------- /packages/rollup/README.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/rollup 2 | 3 | - ✅ Load environment variables from the command line `API_BASE=/v1/ rollup` 4 | - ✅ Load environment variables from `.env` files 5 | - ✅ Expand environment variables `API_URL=$API_BASE/users` 6 | - ✅ Define environment variables for a specific environment (e.g. `.env.production`) 7 | - ✅ Load priorities of `.env.*` files (e.g. `.env.production` > `.env`) 8 | - ✅ Hierarchical cascading configuration in monorepo projects ([Nx](https://nx.dev), [Turbo](https://turborepo.com/), etc.) 9 | `apps/next-app/.env` > `apps/.env` > `.env` 10 | 11 | ## Install 12 | 13 | ```sh 14 | npm add @dotenv-run/rollup --save-dev 15 | ``` 16 | 17 | ## Usage 18 | 19 | Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin: 20 | 21 | ```js 22 | import env from "@dotenv-run/rollup"; 23 | 24 | export default { 25 | input: "src/index.js", 26 | output: { 27 | file: "dist/index.js", 28 | }, 29 | plugins: [env({ prefix: "API", verbose: true, root: "../../.." })], 30 | }; 31 | ``` 32 | 33 | Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api). 34 | -------------------------------------------------------------------------------- /packages/rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/rollup", 3 | "version": "1.3.6", 4 | "description": "Run your scripts with dotenv variables", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "main": "dist/index.js", 7 | "types": "dist/index.d.ts", 8 | "type": "module", 9 | "scripts": { 10 | "dev": "tsc -w", 11 | "build": "tsc" 12 | }, 13 | "files": [ 14 | "dist", 15 | "README.md" 16 | ], 17 | "keywords": [ 18 | "dotenv", 19 | "run", 20 | "cli" 21 | ], 22 | "author": "Chihab Otmani ", 23 | "license": "ISC", 24 | "dependencies": { 25 | "@dotenv-run/core": "workspace:^1.3.6", 26 | "@rollup/plugin-replace": "^5.0.7" 27 | }, 28 | "peerDependencies": { 29 | "rollup": "^3.0.0" 30 | }, 31 | "devDependencies": { 32 | "@types/node": "^16.18.112", 33 | "rollup": "^3.29.5" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/rollup/src/index.ts: -------------------------------------------------------------------------------- 1 | import { type DotenvRunOptions, env } from "@dotenv-run/core"; 2 | import replace from "@rollup/plugin-replace"; 3 | import { Plugin } from "rollup"; 4 | 5 | const dotenvRun = (options: DotenvRunOptions): Plugin => { 6 | const { full } = env(options); 7 | return { 8 | name: "dotenv-run", 9 | ...replace({ 10 | preventAssignment: true, 11 | values: full, 12 | }), 13 | }; 14 | } 15 | 16 | export { dotenvRun, DotenvRunOptions }; 17 | export default dotenvRun; 18 | -------------------------------------------------------------------------------- /packages/rollup/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "moduleResolution": "node", 6 | "module": "ES2022", 7 | "strict": true, 8 | "allowSyntheticDefaultImports": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "strictPropertyInitialization": false, 11 | "strictNullChecks": false, 12 | "pretty": true, 13 | "sourceMap": true, 14 | "declaration": true, 15 | "skipLibCheck": true 16 | }, 17 | "exclude": ["node_modules"], 18 | "compileOnSave": false, 19 | "buildOnSave": false 20 | } 21 | -------------------------------------------------------------------------------- /packages/rspack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/rspack", 3 | "version": "1.0.0", 4 | "description": "Run your scripts with dotenv variables", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "main": "dist/cjs/index.js", 7 | "module": "dist/esm/index.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "dev": "tsc -w", 11 | "build": "concurrently npm:build:*", 12 | "build:esm": "tsc --module esnext --outDir dist/esm", 13 | "build:cjs": "tsc --module commonjs --outDir dist/cjs", 14 | "build:types": "tsc --emitDeclarationOnly --declaration --declarationMap --module esnext --outDir dist" 15 | }, 16 | "files": [ 17 | "dist", 18 | "README.md" 19 | ], 20 | "keywords": [ 21 | "dotenv", 22 | "run", 23 | "cli" 24 | ], 25 | "author": "Chihab Otmani ", 26 | "license": "ISC", 27 | "dependencies": { 28 | "@dotenv-run/core": "workspace:^1.3.5" 29 | }, 30 | "peerDependencies": { 31 | "@rspack/core": "^1.0.0" 32 | }, 33 | "devDependencies": { 34 | "@types/node": "^16.18.101", 35 | "@rspack/core": "^1.0.4" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/rspack/src/index.ts: -------------------------------------------------------------------------------- 1 | import { type DotenvRunOptions, type Dict, env } from "@dotenv-run/core"; 2 | import type { RspackPluginInstance, Compiler } from "@rspack/core"; 3 | import { DefinePlugin } from "@rspack/core"; 4 | 5 | class DotenvRunPlugin implements RspackPluginInstance { 6 | public raw: Dict = {}; 7 | public full: Dict = {}; 8 | public stringified: Dict = {}; 9 | 10 | constructor(options: DotenvRunOptions, private ssr = false) { 11 | const { full, stringified, raw } = env(options); 12 | this.raw = raw; 13 | this.full = full; 14 | this.stringified = stringified; 15 | } 16 | 17 | apply(compiler: Compiler) { 18 | const definePlugin = new DefinePlugin( 19 | this.ssr 20 | ? { ...this.full } 21 | : { 22 | "process.env": this.stringified, 23 | "import.meta.env": this.stringified, 24 | "import.meta.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV), 25 | } 26 | ); 27 | definePlugin.apply(compiler); 28 | } 29 | } 30 | 31 | export { DotenvRunOptions, DotenvRunPlugin }; 32 | 33 | export default DotenvRunPlugin; 34 | -------------------------------------------------------------------------------- /packages/rspack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "moduleResolution": "node", 6 | "module": "ES2022", 7 | "strict": true, 8 | "allowSyntheticDefaultImports": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "strictPropertyInitialization": false, 11 | "strictNullChecks": false, 12 | "pretty": true, 13 | "sourceMap": true, 14 | "declaration": true, 15 | "skipLibCheck": true 16 | }, 17 | "exclude": ["node_modules"], 18 | "compileOnSave": false, 19 | "buildOnSave": false 20 | } 21 | -------------------------------------------------------------------------------- /packages/vite/README.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/vite 2 | 3 | - ✅ Load environment variables from the command line `API_BASE=/v1/ vite` 4 | - ✅ Load environment variables from `.env` files 5 | - ✅ Expand environment variables `API_URL=$API_BASE/users` 6 | - ✅ Define environment variables for a specific environment (e.g. `.env.production`) 7 | - ✅ Load priorities of `.env.*` files (e.g. `.env.production` > `.env`) 8 | - ✅ Hierarchical cascading configuration in monorepo projects ([Nx](https://nx.dev), [Turbo](https://turborepo.com/), etc.) 9 | `apps/next-app/.env` > `apps/.env` > `.env` 10 | 11 | ## Install 12 | 13 | ```sh 14 | npm add @dotenv-run/vite --save-dev 15 | ``` 16 | 17 | ## Usage 18 | 19 | Create a `vite.config.js` [configuration file](https://vite.dev/config) and import the plugin: 20 | 21 | ```js 22 | import env from "@dotenv-run/vite"; 23 | 24 | export default { 25 | envPrefix: 'MY_PREFIX_', 26 | envDir: './my-env-directory', 27 | plugins: [env()], 28 | }; 29 | ``` 30 | 31 | Then call `vite` or `vite build` either via the [CLI](https://vite.dev/guide/cli.html). 32 | 33 | The available options are similar to those supported by [`@dotenv-run/core`](https://www.npmjs.com/package/@dotenv-run/core), but this plugin seamlessly integrates with Vite by automatically deriving the root, prefix, and environment values from its standard configuration, ensuring a more cohesive experience. For more details, refer to the API section. 34 | -------------------------------------------------------------------------------- /packages/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/vite", 3 | "version": "1.0.0", 4 | "description": "Run your scripts with dotenv variables", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "main": "dist/index.js", 7 | "types": "dist/index.d.ts", 8 | "type": "module", 9 | "scripts": { 10 | "dev": "tsc -w", 11 | "build": "tsc" 12 | }, 13 | "files": [ 14 | "dist", 15 | "README.md" 16 | ], 17 | "keywords": [ 18 | "dotenv", 19 | "run", 20 | "cli", 21 | "vite", 22 | "vite-plugin" 23 | ], 24 | "author": "Iacopo Ciao ", 25 | "license": "ISC", 26 | "dependencies": { 27 | "@dotenv-run/core": "workspace:^1.3.6", 28 | "@rollup/plugin-replace": "^5.0.7", 29 | "lodash-es": "^4.17.21", 30 | "vite": "^6.2.0" 31 | }, 32 | "devDependencies": { 33 | "@types/lodash-es": "^4.17.12", 34 | "@types/node": "^16.18.112" 35 | } 36 | } -------------------------------------------------------------------------------- /packages/vite/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_PREFIX = 'VITE_'; 2 | 3 | export const DEFAULT_ENV_FILES = [ 4 | /** vault file */ `.env.vault`, 5 | /** default file */ `.env`, 6 | ]; 7 | -------------------------------------------------------------------------------- /packages/vite/src/index.ts: -------------------------------------------------------------------------------- 1 | import { env as loadEnv } from "@dotenv-run/core"; 2 | import { Plugin } from "vite"; 3 | import { viteEnvPrefixToPrefix } from "./mapper.js"; 4 | import { sanitizeOptions, ViteDotenvRunOptions } from "./options.js"; 5 | import replace from "@rollup/plugin-replace"; 6 | import { DEFAULT_ENV_FILES } from "./constants.js"; 7 | 8 | /** 9 | * Vite plugin to load environment variables from .env files using `@dotenv-run/core`. 10 | * 11 | * This plugin seamlessly integrates with Vite by automatically deriving the root, 12 | * prefix and environment options from Vite's `envDir`, `envPrefix` and `mode`, 13 | * ensuring a more cohesive experience. 14 | * 15 | * @param {ViteDotenvRunOptions} [options] - Options for configuring the plugin. 16 | * See {@link ViteDotenvRunOptions} for more details. 17 | * 18 | * @returns {Plugin} Vite plugin object that enhances the Vite configuration. 19 | * 20 | * @example 21 | * // Usage in a Vite config file 22 | * import dotenvRun from 'vite-plugin-dotenv-run'; 23 | * 24 | * export default { 25 | * envDir: '../..', 26 | * envPrefix: ['VITE_', 'CUSTOM_'], 27 | * plugins: [ 28 | * dotenvRun(), 29 | * ], 30 | * }; 31 | */ 32 | const dotenvRun = (options?: ViteDotenvRunOptions): Plugin => { 33 | options = sanitizeOptions(options); 34 | const files = options?.files ?? DEFAULT_ENV_FILES; 35 | 36 | return { 37 | name: "vite-plugin-dotenv-run", 38 | config: (config, configEnv) => { 39 | const prefix = viteEnvPrefixToPrefix(config.envPrefix); 40 | 41 | const { full } = loadEnv({ 42 | files, 43 | prefix, 44 | root: config.envDir, 45 | environment: configEnv.mode, 46 | ...options, 47 | }); 48 | 49 | return { 50 | ...config, 51 | ...replace({ 52 | preventAssignment: true, 53 | values: full, 54 | }), 55 | }; 56 | }, 57 | }; 58 | }; 59 | 60 | export { dotenvRun, ViteDotenvRunOptions }; 61 | export default dotenvRun; 62 | -------------------------------------------------------------------------------- /packages/vite/src/mapper.ts: -------------------------------------------------------------------------------- 1 | import { 2 | castArray, 3 | escapeRegExp, 4 | first, 5 | isEmpty, 6 | isNil, 7 | negate, 8 | } from "lodash-es"; 9 | import { DEFAULT_PREFIX } from "./constants.js"; 10 | 11 | /** 12 | * Converts a Vite `envPrefix` configuration value into a usable prefix or RegExp for @dotenv-run/core. 13 | * 14 | * @param {string | string[] | undefined} prefixes - The prefix or list of prefixes to filter environment variables. 15 | * @returns {string | RegExp} - A single prefix as a string if only one is provided, or a RegExp if multiple prefixes are given. 16 | * 17 | * @throws {Error} If an empty string (`''`) is included in the prefixes, as this could expose all environment variables. 18 | * 19 | * @example 20 | * viteEnvPrefixToPrefix("VITE_") // Returns: "VITE_" 21 | * viteEnvPrefixToPrefix(["VITE_", "CUSTOM_"]) // Returns: /^VITE_|CUSTOM_/ 22 | * viteEnvPrefixToPrefix(undefined) // Returns: DEFAULT_PREFIX 23 | * 24 | * @see {@link https://vite.dev/config/shared-options.html#envprefix Vite Documentation on envPrefix} 25 | * 26 | * @security 27 | * The `envPrefix` option should **never** be set to an empty string (`''`), 28 | * as this will expose **all** environment variables, potentially leaking sensitive information. 29 | * Vite has a built-in safeguard that throws an error when detecting `''` as a prefix. 30 | * 31 | * If you need to expose an unprefixed environment variable, use the `define` option instead: 32 | * 33 | * ``` 34 | * define: { 35 | * "process.env.MY_VAR": JSON.stringify(process.env.MY_VAR) 36 | * } 37 | * ``` 38 | */ 39 | export const viteEnvPrefixToPrefix = ( 40 | prefixes: string | string[] | undefined 41 | ): string | RegExp => { 42 | prefixes = castArray(prefixes).filter(negate(isNil)); 43 | 44 | if (isEmpty(prefixes)) { 45 | return DEFAULT_PREFIX; 46 | } 47 | 48 | if (prefixes.includes("")) { 49 | throw new Error( 50 | `envPrefix option contains value '', which could lead unexpected exposure of sensitive information.` 51 | ); 52 | } 53 | 54 | if (prefixes.length === 1) { 55 | return first(prefixes); 56 | } 57 | 58 | return new RegExp(`^(${prefixes.map(escapeRegExp).join("|")})`); 59 | }; 60 | -------------------------------------------------------------------------------- /packages/vite/src/options.ts: -------------------------------------------------------------------------------- 1 | import type { DotenvRunOptions } from "@dotenv-run/core"; 2 | import { pick } from "lodash-es"; 3 | 4 | /** 5 | * Options for configuring the @dotenv-run/vite plugin. 6 | * 7 | * @interface ViteDotenvRunOptions 8 | * @extends {Pick} 9 | * 10 | * @property {DotenvConfigOptions} [dotenv] - Options for configuring dotenv. 11 | * @property {string[]} [files] - Environment files to load. Defaults to `['.env.vault', '.env']`. 12 | * @property {boolean} [unsecure] - Display environment variables in debug output. 13 | * @property {boolean} [nodeEnv] - Node environment. 14 | * @property {boolean} [verbose] - Print verbose output. 15 | * @property {Dict} [builtIn] - Built-in environment variables. 16 | * @property {boolean} [runtime] - Whether to use runtime variables. 17 | * @property {string} [global] - Global variable name. 18 | */ 19 | export type ViteDotenvRunOptions = Pick; 20 | 21 | export const sanitizeOptions = (options?: T): ViteDotenvRunOptions | undefined => { 22 | return pick(options, 'verbose', 'unsecure', 'builtIn', 'global', 'nodeEnv', 'runtime', 'dotenv', 'files'); 23 | } -------------------------------------------------------------------------------- /packages/vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "moduleResolution": "node", 6 | "module": "ES2022", 7 | "strict": true, 8 | "allowSyntheticDefaultImports": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "strictPropertyInitialization": false, 11 | "strictNullChecks": false, 12 | "pretty": true, 13 | "sourceMap": true, 14 | "declaration": true, 15 | "skipLibCheck": true 16 | }, 17 | "exclude": ["node_modules"], 18 | "compileOnSave": false, 19 | "buildOnSave": false 20 | } 21 | -------------------------------------------------------------------------------- /packages/webpack/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/webpack 2 | 3 | ## 1.5.0 4 | 5 | ### Minor Changes 6 | 7 | - 8f83f0c: feat: add compatibility with Angular 19 8 | 9 | ## 1.4.1 10 | 11 | ### Patch Changes 12 | 13 | - chore: use pnpm workspace protocol for dependencies 14 | - Updated dependencies 15 | - @dotenv-run/core@1.3.6 16 | 17 | ## 1.4.0 18 | 19 | ### Minor Changes 20 | 21 | - bump up webpack and esbuild versions 22 | 23 | ## 1.3.4 24 | 25 | ### Patch Changes 26 | 27 | - docs: updates packages' README files 28 | - Updated dependencies 29 | - @dotenv-run/core@1.3.4 30 | 31 | ## 1.3.3 32 | 33 | ### Patch Changes 34 | 35 | - fix(cli): fix unsecure mode alias 36 | - Updated dependencies 37 | - @dotenv-run/core@1.3.3 38 | 39 | ## 1.3.2 40 | 41 | ### Patch Changes 42 | 43 | - feat(angular): add unsecure mode option 44 | - Updated dependencies 45 | - @dotenv-run/core@1.3.2 46 | 47 | ## 1.3.1 48 | 49 | ### Patch Changes 50 | 51 | - feat: add secure mode to debug info 52 | - Updated dependencies 53 | - @dotenv-run/core@1.3.1 54 | 55 | ## 1.3.0 56 | 57 | ### Minor Changes 58 | 59 | - refactor and docs initialization 60 | 61 | ### Patch Changes 62 | 63 | - Updated dependencies 64 | - @dotenv-run/core@1.3.0 65 | 66 | ## 1.2.3 67 | 68 | ### Patch Changes 69 | 70 | - feat(core): support sub-module level turbo.json 71 | - Updated dependencies 72 | - @dotenv-run/core@1.2.3 73 | 74 | ## 1.2.2 75 | 76 | ### Patch Changes 77 | 78 | - fix(core): filter out undefined env values 79 | - Updated dependencies 80 | - @dotenv-run/core@1.2.2 81 | 82 | ## 1.2.1 83 | 84 | ### Patch Changes 85 | 86 | - refactor(esbuild): usde esbuild define option 87 | - Updated dependencies 88 | - @dotenv-run/core@1.2.1 89 | 90 | ## 1.2.0 91 | 92 | ### Minor Changes 93 | 94 | - f63ecac: feat: add esbuild plugin 95 | 96 | ### Patch Changes 97 | 98 | - Updated dependencies [f63ecac] 99 | - @dotenv-run/core@1.2.0 100 | 101 | ## 1.1.0 102 | 103 | ### Minor Changes 104 | 105 | - af82054: feat: add cjs format and doc 106 | 107 | ### Patch Changes 108 | 109 | - Updated dependencies [af82054] 110 | - @dotenv-run/core@1.1.0 111 | 112 | ## 1.0.1 113 | 114 | ### Patch Changes 115 | 116 | - 429d699: refactor(webpack): export dotenv results 117 | 118 | ## 1.0.0 119 | 120 | ### Major Changes 121 | 122 | - feat: add bundler plugins 123 | 124 | ### Patch Changes 125 | 126 | - Updated dependencies 127 | - @dotenv-run/core@1.0.0 128 | -------------------------------------------------------------------------------- /packages/webpack/README.md: -------------------------------------------------------------------------------- 1 | # @dotenv-run/webpack 2 | 3 | - ✅ Load environment variables from the command line `API_BASE=/v1/ webpack` 4 | - ✅ Load environment variables from `.env` files 5 | - ✅ Expand environment variables `API_URL=$API_BASE/users` 6 | - ✅ Define environment variables for a specific environment (e.g. `.env.production`) 7 | - ✅ Load priorities of `.env.*` files (e.g. `.env.production` > `.env`) 8 | - ✅ Hierarchical cascading configuration in monorepo projects ([Nx](https://nx.dev), [Turbo](https://turborepo.com/), etc.) 9 | `apps/next-app/.env` > `apps/.env` > `.env` 10 | 11 | ## Install 12 | 13 | ```console 14 | npm add @dotenv-run/webpack --save-dev 15 | ``` 16 | 17 | ## Usage 18 | 19 | Create a `webpack.config.js` [configuration file](https://www.webpackjs.org/guide/en/#configuration-files) and import the plugin: 20 | 21 | ```js 22 | import { DotenvRunPlugin } from "@dotenv-run/webpack"; 23 | import path from "path"; 24 | 25 | const __dirname = path.resolve(); 26 | 27 | export default { 28 | entry: "./src/index.js", 29 | output: { 30 | filename: "main.js", 31 | path: path.resolve(__dirname, "dist"), 32 | }, 33 | plugins: [ 34 | new DotenvRunPlugin( 35 | { prefix: "API", verbose: true, root: "../../.." }, 36 | __dirname 37 | ), 38 | ], 39 | }; 40 | ``` 41 | -------------------------------------------------------------------------------- /packages/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dotenv-run/webpack", 3 | "version": "1.5.0", 4 | "description": "Run your scripts with dotenv variables", 5 | "homepage": "https://github.com/chihab/dotenv-run", 6 | "main": "dist/cjs/index.js", 7 | "module": "dist/esm/index.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "dev": "tsc -w", 11 | "build": "concurrently npm:build:*", 12 | "build:esm": "tsc --module esnext --outDir dist/esm", 13 | "build:cjs": "tsc --module commonjs --outDir dist/cjs", 14 | "build:types": "tsc --emitDeclarationOnly --declaration --declarationMap --module esnext --outDir dist" 15 | }, 16 | "files": [ 17 | "dist", 18 | "README.md" 19 | ], 20 | "keywords": [ 21 | "dotenv", 22 | "run", 23 | "cli" 24 | ], 25 | "author": "Chihab Otmani ", 26 | "license": "ISC", 27 | "dependencies": { 28 | "@dotenv-run/core": "workspace:^1.3.6" 29 | }, 30 | "peerDependencies": { 31 | "webpack": "^5.0.0" 32 | }, 33 | "devDependencies": { 34 | "@types/node": "^16.18.112", 35 | "webpack": "5.96.1" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/webpack/src/index.ts: -------------------------------------------------------------------------------- 1 | import { type DotenvRunOptions, type Dict, env } from "@dotenv-run/core"; 2 | import type { WebpackPluginInstance, Compiler } from "webpack"; 3 | import { DefinePlugin } from "webpack"; 4 | 5 | class DotenvRunPlugin implements WebpackPluginInstance { 6 | public raw: Dict = {}; 7 | public full: Dict = {}; 8 | public stringified: Dict = {}; 9 | 10 | constructor(options: DotenvRunOptions, private ssr = false) { 11 | const { full, stringified, raw } = env(options); 12 | this.raw = raw; 13 | this.full = full; 14 | this.stringified = stringified; 15 | } 16 | 17 | apply(compiler: Compiler) { 18 | const definePlugin = new DefinePlugin( 19 | this.ssr 20 | ? { ...this.full } 21 | : { 22 | "process.env": this.stringified, 23 | "import.meta.env": this.stringified, 24 | "import.meta.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV), 25 | } 26 | ); 27 | definePlugin.apply(compiler); 28 | } 29 | } 30 | 31 | export { DotenvRunOptions, DotenvRunPlugin }; 32 | 33 | export default DotenvRunPlugin; 34 | -------------------------------------------------------------------------------- /packages/webpack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "moduleResolution": "node", 6 | "module": "ES2022", 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strictPropertyInitialization": false, 10 | "strictNullChecks": false, 11 | "pretty": true, 12 | "sourceMap": true, 13 | "declaration": true, 14 | "skipLibCheck": true 15 | }, 16 | "exclude": ["node_modules"], 17 | "compileOnSave": false, 18 | "buildOnSave": false 19 | } 20 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "examples/nx-workspace-old" 3 | - "examples/nx-workspace-old/**/*" 4 | - "packages/*" 5 | - "docs" 6 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turborepo.com/schema.json", 3 | "pipeline": { 4 | "build": { 5 | "dependsOn": [ 6 | "^build" 7 | ], 8 | "outputs": [ 9 | "dist" 10 | ] 11 | }, 12 | "test": { 13 | "dependsOn": [ 14 | "^test" 15 | ] 16 | }, 17 | "dev": { 18 | "dependsOn": [ 19 | "^dev" 20 | ] 21 | } 22 | } 23 | } 24 | --------------------------------------------------------------------------------