diff --git a/docs/docs/introduction.md b/docs/docs/introduction.md index 75b53de38e7a..ccec5a235aca 100644 --- a/docs/docs/introduction.md +++ b/docs/docs/introduction.md @@ -51,7 +51,7 @@ That said, there are some references you should consider reading at some point i Especially if you want to become an advanced user. For example, [Services](services.md) are fundamental to Redwood. It's worth getting to know them inside and out. -And if you're not writing [tests](testing.md) and [stories](storybook.md), you're not using Redwood to its full potential. +And if you're not writing [tests](testing.md) and [stories](storybook/about.md), you're not using Redwood to its full potential. > **We realize that the content doesn't always match the organization** > diff --git a/packages/api-server/tsconfig.json b/packages/api-server/tsconfig.json index 1d359338047d..23c1f8cc762b 100644 --- a/packages/api-server/tsconfig.json +++ b/packages/api-server/tsconfig.json @@ -11,7 +11,8 @@ { "path": "../internal" }, { "path": "../project-config" }, { "path": "../adapters/fastify/web" }, - { "path": "../web-server" } + { "path": "../web-server" }, + { "path": "../realtime" } ], "exclude": [ "dist", diff --git a/packages/cli-helpers/build.ts b/packages/cli-helpers/build.ts index 833546fa0de5..378f269c2ca0 100644 --- a/packages/cli-helpers/build.ts +++ b/packages/cli-helpers/build.ts @@ -6,8 +6,6 @@ import { build, defaultBuildOptions } from '@redwoodjs/framework-tools' await build({ buildOptions: { ...defaultBuildOptions, - bundle: true, - entryPoints: ['./src/index.ts'], format: 'esm', packages: 'external', }, @@ -17,8 +15,6 @@ await build({ await build({ buildOptions: { ...defaultBuildOptions, - bundle: true, - entryPoints: ['./src/index.ts'], outdir: 'dist/cjs', packages: 'external', }, diff --git a/packages/cli-helpers/package.json b/packages/cli-helpers/package.json index aa12469eae4b..87c2fd5bf615 100644 --- a/packages/cli-helpers/package.json +++ b/packages/cli-helpers/package.json @@ -9,9 +9,21 @@ "license": "MIT", "type": "module", "exports": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "default": "./dist/cjs/index.js" + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "default": "./dist/cjs/index.js" + }, + "./loadEnvFiles": { + "types": "./dist/lib/loadEnvFiles.d.ts", + "import": "./dist/lib/loadEnvFiles.js", + "default": "./dist/cjs/lib/loadEnvFiles.js" + }, + "./dist/lib/loadEnvFiles.js": { + "types": "./dist/lib/loadEnvFiles.d.ts", + "import": "./dist/lib/loadEnvFiles.js", + "default": "./dist/cjs/lib/loadEnvFiles.js" + } }, "types": "./dist/index.d.ts", "files": [ @@ -33,6 +45,7 @@ "@redwoodjs/telemetry": "workspace:*", "chalk": "4.1.2", "dotenv": "16.4.5", + "dotenv-defaults": "5.0.2", "execa": "5.1.1", "listr2": "6.6.1", "lodash": "4.17.21", @@ -44,6 +57,7 @@ }, "devDependencies": { "@redwoodjs/framework-tools": "workspace:*", + "@types/dotenv-defaults": "^2.0.4", "@types/lodash": "4.17.5", "@types/pascalcase": "1.0.3", "@types/yargs": "17.0.32", diff --git a/packages/cli-helpers/src/lib/loadEnvFiles.ts b/packages/cli-helpers/src/lib/loadEnvFiles.ts new file mode 100644 index 000000000000..95f70afd8d39 --- /dev/null +++ b/packages/cli-helpers/src/lib/loadEnvFiles.ts @@ -0,0 +1,71 @@ +import fs from 'node:fs' +import path from 'node:path' + +import { config as dotenvConfig } from 'dotenv' +import { config as dotenvDefaultsConfig } from 'dotenv-defaults' +import { hideBin, Parser } from 'yargs/helpers' + +import { getPaths } from '@redwoodjs/project-config' + +export function loadEnvFiles() { + if (process.env.REDWOOD_ENV_FILES_LOADED) { + return + } + + const { base } = getPaths() + + loadDefaultEnvFiles(base) + loadNodeEnvDerivedEnvFile(base) + + const { loadEnvFiles } = Parser.default(hideBin(process.argv), { + array: ['load-env-files'], + default: { + loadEnvFiles: [], + }, + }) + + if (loadEnvFiles.length > 0) { + loadUserSpecifiedEnvFiles(base, loadEnvFiles) + } + + process.env.REDWOOD_ENV_FILES_LOADED = 'true' +} + +export function loadDefaultEnvFiles(cwd: string) { + dotenvDefaultsConfig({ + path: path.join(cwd, '.env'), + defaults: path.join(cwd, '.env.defaults'), + // @ts-expect-error - Old typings. @types/dotenv-defaults depends on dotenv + // v8. dotenv-defaults uses dotenv v14 + multiline: true, + }) +} + +export function loadNodeEnvDerivedEnvFile(cwd: string) { + if (!process.env.NODE_ENV) { + return + } + + const nodeEnvDerivedEnvFilePath = path.join( + cwd, + `.env.${process.env.NODE_ENV}`, + ) + if (!fs.existsSync(nodeEnvDerivedEnvFilePath)) { + return + } + + dotenvConfig({ path: nodeEnvDerivedEnvFilePath, override: true }) +} + +export function loadUserSpecifiedEnvFiles(cwd: string, loadEnvFiles: string[]) { + for (const suffix of loadEnvFiles) { + const envPath = path.join(cwd, `.env.${suffix}`) + if (!fs.existsSync(envPath)) { + throw new Error( + `Couldn't find an .env file at '${envPath}' as specified by '--load-env-files'`, + ) + } + + dotenvConfig({ path: envPath, override: true }) + } +} diff --git a/packages/cli-helpers/tsconfig.build.json b/packages/cli-helpers/tsconfig.build.json index 6945be2c984c..fd72ed0a99c9 100644 --- a/packages/cli-helpers/tsconfig.build.json +++ b/packages/cli-helpers/tsconfig.build.json @@ -3,7 +3,6 @@ "compilerOptions": { "moduleResolution": "NodeNext", "module": "NodeNext", - "baseUrl": ".", "rootDir": "src", "outDir": "dist", }, diff --git a/packages/cli-packages/dataMigrate/src/bin.ts b/packages/cli-packages/dataMigrate/src/bin.ts index ff0539416a2e..7c74e3f03c9b 100644 --- a/packages/cli-packages/dataMigrate/src/bin.ts +++ b/packages/cli-packages/dataMigrate/src/bin.ts @@ -1,6 +1,5 @@ import path from 'path' -// @ts-expect-error not sure; other packages use this and don't provide the types import { config } from 'dotenv-defaults' import { hideBin } from 'yargs/helpers' import yargs from 'yargs/yargs' @@ -14,6 +13,8 @@ if (!process.env.REDWOOD_ENV_FILES_LOADED) { config({ path: path.join(getPaths().base, '.env'), defaults: path.join(getPaths().base, '.env.defaults'), + // @ts-expect-error - Old typings. @types/dotenv-defaults depends on dotenv + // v8. dotenv-defaults uses dotenv v14 multiline: true, }) diff --git a/packages/internal/src/routes.ts b/packages/internal/src/routes.ts index 18ad7991ad1f..bfc37b329ea2 100644 --- a/packages/internal/src/routes.ts +++ b/packages/internal/src/routes.ts @@ -4,7 +4,7 @@ import chalk from 'chalk' import { getPaths, getRouteHookForPage } from '@redwoodjs/project-config' import { getRouteRegexAndParams } from '@redwoodjs/router' -import { getProject } from '@redwoodjs/structure/dist/index' +import { getProject } from '@redwoodjs/structure/dist/index.js' import type { RWRoute } from '@redwoodjs/structure/dist/model/RWRoute' export interface RouteInformation { diff --git a/packages/structure/src/model/RWEnvHelper.ts b/packages/structure/src/model/RWEnvHelper.ts index b52fb532153a..f97f114127ea 100644 --- a/packages/structure/src/model/RWEnvHelper.ts +++ b/packages/structure/src/model/RWEnvHelper.ts @@ -88,7 +88,7 @@ export class RWEnvHelper extends BaseNode { if (!existsSync(file)) { return undefined } - return dotenv.parse(readFileSync(file)) + return dotenv.parse(readFileSync(file, 'utf-8')) } @lazy() get env_available_to_api() { diff --git a/packages/vite/src/runFeServer.ts b/packages/vite/src/runFeServer.ts index 8d04a319bf04..691ce4bb3eb0 100644 --- a/packages/vite/src/runFeServer.ts +++ b/packages/vite/src/runFeServer.ts @@ -9,7 +9,6 @@ import path from 'node:path' import url from 'node:url' import { createServerAdapter } from '@whatwg-node/server' -// @ts-expect-error We will remove dotenv-defaults from this package anyway import { config as loadDotEnv } from 'dotenv-defaults' import express from 'express' import type { HTTPMethod } from 'find-my-way' @@ -45,6 +44,8 @@ import { convertExpressHeaders, getFullUrl } from './utils.js' loadDotEnv({ path: path.join(getPaths().base, '.env'), defaults: path.join(getPaths().base, '.env.defaults'), + // @ts-expect-error - Old typings. @types/dotenv-defaults depends on dotenv + // v8. dotenv-defaults uses dotenv v14 multiline: true, }) // ------------------------------------------------ diff --git a/yarn.lock b/yarn.lock index c270869cb88d..a8f0dd7c3438 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7872,11 +7872,13 @@ __metadata: "@redwoodjs/framework-tools": "workspace:*" "@redwoodjs/project-config": "workspace:*" "@redwoodjs/telemetry": "workspace:*" + "@types/dotenv-defaults": "npm:^2.0.4" "@types/lodash": "npm:4.17.5" "@types/pascalcase": "npm:1.0.3" "@types/yargs": "npm:17.0.32" chalk: "npm:4.1.2" dotenv: "npm:16.4.5" + dotenv-defaults: "npm:5.0.2" execa: "npm:5.1.1" listr2: "npm:6.6.1" lodash: "npm:4.17.21" @@ -10786,6 +10788,16 @@ __metadata: languageName: node linkType: hard +"@types/dotenv-defaults@npm:^2.0.4": + version: 2.0.4 + resolution: "@types/dotenv-defaults@npm:2.0.4" + dependencies: + "@types/node": "npm:*" + dotenv: "npm:^8.2.0" + checksum: 10c0/7d7ebdd696318d5f9a510d1d0b5fa262e240a377056d6ce7ed8984fb222d472732bf27f8d16726879531706030f1aa0879e65e711dbda17ad4d0be138d9d118b + languageName: node + linkType: hard + "@types/ejs@npm:^3.1.1": version: 3.1.2 resolution: "@types/ejs@npm:3.1.2"