Skip to content

Commit b07f58e

Browse files
authored
Visualizer - Handle envs import (#42)
* add env selector for the visualizer * add env option in drizzle lab cli * rework env loader
1 parent fce9454 commit b07f58e

23 files changed

+176
-130
lines changed

apps/cli/README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ Usage:
1111
Flags:
1212
-c, --config string Path to drizzle config file
1313
--debug Enable log output (default: false)
14-
--save-dir string Directory to save the visualizer data (default: ".drizzle-lab")
15-
--project-id string A unique identifier for the current visualized project. It is used as filename to save the visualizer state.
14+
--save-dir string Directory to save the visualizer data (default: ".drizzle")
15+
--project-id string A unique identifier for the current visualized project. It is used as filename to save the visualizer state. (default: "visualizer")
1616
--ts-config string Path to tsconfig.json. It is used to resolve TypeScript paths aliases. (default: "./tsconfig.json")
1717
-p, --port number Port to run visualizer on (default: 64738)
18+
-e, --env-path string Path to a .env file
1819

1920
Global flags:
2021
-h, --help help for visualizer

apps/cli/build.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ await bundle.write(config.output);
4343
await bundle.close();
4444

4545
// Add banner to dist/cli.js
46-
const banner = `#!/usr/bin/env node\n`;
46+
const banner = "#!/usr/bin/env node\n";
4747
const cliFilePath = "dist/cli.js";
4848
const originalContent = await fs.readFile(cliFilePath, "utf-8");
4949
await fs.writeFile(cliFilePath, banner + originalContent);

apps/cli/cli.ts

+19-8
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { spawnSync } from "node:child_process";
33

44
import {
55
DRIZZLE_LAB_ENV_KEY,
6+
getEnv,
67
importDrizzleConfig,
7-
DRIZZLE_LAB_TS_CONFIG_PATH,
88
} from "@drizzle-lab/api/config/node";
99
import { command, string, run, boolean, number } from "@drizzle-team/brocli";
1010
import chalk from "chalk";
@@ -17,23 +17,27 @@ const tsConfig = string()
1717
.desc(
1818
"Path to tsconfig.json. It is used to resolve TypeScript paths aliases.",
1919
)
20-
.default(DRIZZLE_LAB_TS_CONFIG_PATH);
20+
.default(getEnv().DRIZZLE_LAB_TS_CONFIG_PATH);
21+
const envPath = string()
22+
.desc("Path to a .env file. It is used to load environment variables.")
23+
.alias("e");
2124

2225
const visualizer = command({
2326
name: "visualizer",
2427
options: {
2528
config: optionConfig,
2629
debug,
27-
["save-dir"]: string()
30+
"save-dir": string()
2831
.desc("Directory to save the visualizer data")
2932
.default(".drizzle"),
30-
["project-id"]: string()
33+
"project-id": string()
3134
.desc(
3235
"A unique identifier for the current visualized project. It is used as filename to save the visualizer state.",
3336
)
3437
.default("visualizer"),
35-
["ts-config"]: tsConfig,
38+
"ts-config": tsConfig,
3639
port: number().desc("Port to run visualizer on").default(64738).alias("p"),
40+
"env-path": envPath,
3741
},
3842
async transform(options) {
3943
const DRIZZLE_LAB_CWD = process.cwd();
@@ -46,6 +50,7 @@ const visualizer = command({
4650
[DRIZZLE_LAB_ENV_KEY.PROJECT_ID]: options["project-id"],
4751
[DRIZZLE_LAB_ENV_KEY.CWD]: DRIZZLE_LAB_CWD,
4852
[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH]: options["ts-config"],
53+
[DRIZZLE_LAB_ENV_KEY.ENV_FILE_PATH]: options["env-path"],
4954
} as const;
5055

5156
process.env = {
@@ -87,7 +92,7 @@ const visualizer = command({
8792
? spawnSync("vite", ["--host"], {
8893
stdio: "inherit",
8994
})
90-
: spawnSync(process.execPath, [`visualizer/server/index.mjs`], {
95+
: spawnSync(process.execPath, ["visualizer/server/index.mjs"], {
9196
stdio: "inherit",
9297
cwd: import.meta.dirname,
9398
env: {
@@ -104,11 +109,14 @@ const snapshot = command({
104109
options: {
105110
config: optionConfig,
106111
debug,
107-
["ts-config"]: tsConfig,
112+
"ts-config": tsConfig,
113+
"env-path": envPath,
108114
},
109115
transform: async (options) => {
110116
process.env[DRIZZLE_LAB_ENV_KEY.DEBUG] = String(options.debug);
111117
process.env[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH] = options["ts-config"];
118+
process.env[DRIZZLE_LAB_ENV_KEY.ENV_FILE_PATH] = options["env-path"];
119+
112120
const config = await importDrizzleConfig(options.config);
113121

114122
if (options.debug) {
@@ -165,11 +173,14 @@ const sql = command({
165173
options: {
166174
config: optionConfig,
167175
debug,
168-
["ts-config"]: tsConfig,
176+
"ts-config": tsConfig,
177+
"env-path": envPath,
169178
},
170179
transform: async (options) => {
171180
process.env[DRIZZLE_LAB_ENV_KEY.DEBUG] = String(options.debug);
172181
process.env[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH] = options["ts-config"];
182+
process.env[DRIZZLE_LAB_ENV_KEY.ENV_FILE_PATH] = options["env-path"];
183+
173184
const config = await importDrizzleConfig(options.config);
174185

175186
if (options.debug) {

apps/cli/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "drizzle-lab",
3-
"version": "0.9.0",
3+
"version": "0.10.0",
44
"description": "Drizzle Lab CLI",
55
"sideEffects": false,
66
"type": "module",

apps/cli/visualizer/entry.server.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import { PassThrough } from "node:stream";
88

9-
import { DRIZZLE_LAB_DEBUG } from "@drizzle-lab/api/config/node";
9+
import { getEnv } from "@drizzle-lab/api/config/node";
1010
import type { AppLoadContext, EntryContext } from "@remix-run/node";
1111
import { createReadableStreamFromReadable } from "@remix-run/node";
1212
import { RemixServer } from "@remix-run/react";
@@ -29,11 +29,11 @@ if (!global.__server) {
2929
// eslint-disable-next-line no-console
3030
console.log(
3131
`\n${chalk.green(
32-
`Drizzle Visualizer`,
32+
"Drizzle Visualizer",
3333
)} is up and running on ${chalk.blue(`http://127.0.0.1:${info.port}`)}\n`,
3434
);
3535
},
36-
defaultLogger: DRIZZLE_LAB_DEBUG,
36+
defaultLogger: getEnv().DRIZZLE_LAB_DEBUG,
3737
});
3838
}
3939

apps/cli/visualizer/routes/_index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path from "node:path";
44
import {
55
importDrizzleConfig,
66
DRIZZLE_LAB_ENV_KEY,
7-
DRIZZLE_LAB_DEBUG,
7+
getEnv,
88
} from "@drizzle-lab/api/config/node";
99
import {
1010
DrizzleVisualizer,
@@ -61,7 +61,7 @@ export async function loader() {
6161
await fs.readFile(saveFilePath, "utf-8"),
6262
) as NodePosition[];
6363
} catch (e) {
64-
if (DRIZZLE_LAB_DEBUG) {
64+
if (getEnv().DRIZZLE_LAB_DEBUG) {
6565
console.warn(
6666
`Using default nodes positions. Reason is: ${
6767
e instanceof Error ? e.message : "unknown"

package-lock.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/api/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ They are all optional.
162162
| `DRIZZLE_LAB_SAVE_DIR` | Directory to save output | `./drizzle` |
163163
| `DRIZZLE_LAB_PROJECT_ID` | Project ID to identify the project in json output | `drizzle-lab` |
164164
| `TS_CONFIG_PATH` | Path to tsconfig.json | `./tsconfig.json` |
165+
| `DRIZZLE_LAB_ENV_FILE_PATH` | Path to env file | `undefined` |
165166

166167
## License
167168

packages/api/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@drizzle-lab/api",
3-
"version": "0.28.0",
3+
"version": "0.29.0",
44
"description": "Drizzle Lab API - Fork of Drizzle Kit API",
55
"type": "module",
66
"license": "MIT",
@@ -198,6 +198,7 @@
198198
},
199199
"dependencies": {
200200
"chalk": "^5.3.0",
201+
"dotenv": "^16.4.5",
201202
"glob": "^11.0.0",
202203
"jiti": "^2.4.0",
203204
"zod": "^3.23.8"

packages/api/src/config/env.node.ts

+14-15
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,19 @@ export const DRIZZLE_LAB_ENV_KEY = {
55
SAVE_DIR: "DRIZZLE_LAB_SAVE_DIR",
66
PROJECT_ID: "DRIZZLE_LAB_PROJECT_ID",
77
TS_CONFIG_PATH: "TS_CONFIG_PATH",
8+
ENV_FILE_PATH: "DRIZZLE_LAB_ENV_FILE_PATH",
89
} as const;
910

10-
export const DRIZZLE_LAB_DEBUG =
11-
process.env[DRIZZLE_LAB_ENV_KEY.DEBUG] === "true";
12-
13-
export const DRIZZLE_LAB_CWD = process.env[DRIZZLE_LAB_ENV_KEY.CWD]
14-
? `${process.env[DRIZZLE_LAB_ENV_KEY.CWD]}/`
15-
: "";
16-
17-
export const DRIZZLE_LAB_CONFIG_PATH =
18-
process.env[DRIZZLE_LAB_ENV_KEY.CONFIG_PATH];
19-
20-
export const DRIZZLE_LAB_PROJECT_ID =
21-
process.env[DRIZZLE_LAB_ENV_KEY.PROJECT_ID];
22-
23-
export const DRIZZLE_LAB_TS_CONFIG_PATH =
24-
process.env[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH] || "./tsconfig.json";
11+
export function getEnv() {
12+
return {
13+
DRIZZLE_LAB_DEBUG: process.env[DRIZZLE_LAB_ENV_KEY.DEBUG] === "true",
14+
DRIZZLE_LAB_CWD: process.env[DRIZZLE_LAB_ENV_KEY.CWD]
15+
? `${process.env[DRIZZLE_LAB_ENV_KEY.CWD]}/`
16+
: "",
17+
DRIZZLE_LAB_CONFIG_PATH: process.env[DRIZZLE_LAB_ENV_KEY.CONFIG_PATH],
18+
DRIZZLE_LAB_PROJECT_ID: process.env[DRIZZLE_LAB_ENV_KEY.PROJECT_ID],
19+
DRIZZLE_LAB_TS_CONFIG_PATH:
20+
process.env[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH] || "./tsconfig.json",
21+
DRIZZLE_LAB_ENV_FILE_PATH: process.env[DRIZZLE_LAB_ENV_KEY.ENV_FILE_PATH],
22+
};
23+
}

packages/api/src/config/loader.node.ts

+8-12
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ import Path from "node:path";
33

44
import { glob } from "glob";
55

6-
import {
7-
DRIZZLE_LAB_CWD,
8-
DRIZZLE_LAB_DEBUG,
9-
DRIZZLE_LAB_PROJECT_ID,
10-
} from "./env.node.ts";
6+
import { getEnv } from "./env.node.ts";
117
import { configCommonSchema } from "./schema.ts";
128
import { importModule } from "../internal/import-module.node.ts";
139
import { withStyle } from "../internal/style";
@@ -22,10 +18,10 @@ export type PartialConfig = Partial<Config>;
2218
*/
2319
export async function importDrizzleConfig(configPath?: string) {
2420
const defaultTsConfigExists = fs.existsSync(
25-
Path.resolve(Path.join(DRIZZLE_LAB_CWD, "drizzle.config.ts")),
21+
Path.resolve(Path.join(getEnv().DRIZZLE_LAB_CWD, "drizzle.config.ts")),
2622
);
2723
const defaultJsConfigExists = fs.existsSync(
28-
Path.resolve(Path.join(DRIZZLE_LAB_CWD, "drizzle.config.js")),
24+
Path.resolve(Path.join(getEnv().DRIZZLE_LAB_CWD, "drizzle.config.js")),
2925
);
3026

3127
const defaultConfigPath = defaultTsConfigExists
@@ -34,7 +30,7 @@ export async function importDrizzleConfig(configPath?: string) {
3430
? "drizzle.config.js"
3531
: "drizzle.config.json";
3632

37-
if (DRIZZLE_LAB_DEBUG && !configPath) {
33+
if (getEnv().DRIZZLE_LAB_DEBUG && !configPath) {
3834
console.info(
3935
withStyle.info(
4036
`No config path provided, using default '${defaultConfigPath}'`,
@@ -43,15 +39,15 @@ export async function importDrizzleConfig(configPath?: string) {
4339
}
4440

4541
const path = Path.resolve(
46-
Path.join(DRIZZLE_LAB_CWD, configPath ?? defaultConfigPath),
42+
Path.join(getEnv().DRIZZLE_LAB_CWD, configPath ?? defaultConfigPath),
4743
);
4844

4945
if (!fs.existsSync(path)) {
5046
console.error(withStyle.error(`${path} file does not exist`));
5147
throw new Error();
5248
}
5349

54-
if (DRIZZLE_LAB_DEBUG) {
50+
if (getEnv().DRIZZLE_LAB_DEBUG) {
5551
console.info(withStyle.info(`Reading config file '${path}'`));
5652
}
5753

@@ -69,13 +65,13 @@ export async function importDrizzleConfig(configPath?: string) {
6965
return {
7066
...config.data,
7167
schema: prepareFilenames(config.data.schema),
72-
projectId: config.data.lab.projectId || DRIZZLE_LAB_PROJECT_ID,
68+
projectId: config.data.lab.projectId || getEnv().DRIZZLE_LAB_PROJECT_ID,
7369
};
7470
}
7571

7672
const prepareFilenames = (paths: string[]) => {
7773
const matches = paths.reduce((matches, cur) => {
78-
const globMatches = glob.sync(`${DRIZZLE_LAB_CWD}${cur}`);
74+
const globMatches = glob.sync(`${getEnv().DRIZZLE_LAB_CWD}${cur}`);
7975

8076
globMatches.forEach((it) => {
8177
const fileName = fs.lstatSync(it).isDirectory() ? null : Path.resolve(it);

packages/api/src/internal/import-module.node.ts

+11-10
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@ import path from "node:path";
33
import { pathToFileURL } from "node:url";
44

55
import chalk from "chalk";
6+
import { config } from "dotenv";
67
import { createJiti } from "jiti";
78

8-
import {
9-
DRIZZLE_LAB_CWD,
10-
DRIZZLE_LAB_DEBUG,
11-
DRIZZLE_LAB_TS_CONFIG_PATH,
12-
} from "../config/env.node.ts";
9+
import { getEnv } from "../config/env.node.ts";
1310

1411
const jiti = createJiti(import.meta.url, {
15-
alias: loadTsConfigPathsAlias(DRIZZLE_LAB_CWD),
12+
alias: loadTsConfigPathsAlias(getEnv().DRIZZLE_LAB_CWD),
1613
moduleCache: false,
1714
});
1815

@@ -24,11 +21,15 @@ let warned = false;
2421
* @node-only - This function is not supported in the browser.
2522
*/
2623
export async function importModule(path: string) {
27-
if (DRIZZLE_LAB_DEBUG) {
24+
if (getEnv().DRIZZLE_LAB_DEBUG) {
2825
console.log("[importModule] Importing module", path);
2926
}
3027

3128
try {
29+
if (getEnv().DRIZZLE_LAB_ENV_FILE_PATH) {
30+
config({ path: getEnv().DRIZZLE_LAB_ENV_FILE_PATH });
31+
}
32+
3233
let module = await jiti.import<{ default: { default?: any } }>(
3334
pathToFileURL(path).href,
3435
);
@@ -52,7 +53,7 @@ export async function importModule(path: string) {
5253

5354
return module;
5455
} catch (e) {
55-
if (DRIZZLE_LAB_DEBUG) {
56+
if (getEnv().DRIZZLE_LAB_DEBUG) {
5657
console.error(
5758
"[importModule] Failed to import module",
5859
path,
@@ -65,7 +66,7 @@ export async function importModule(path: string) {
6566

6667
function loadTsConfigPathsAlias(cwd: string) {
6768
try {
68-
const tsconfigPath = path.resolve(cwd, DRIZZLE_LAB_TS_CONFIG_PATH);
69+
const tsconfigPath = path.resolve(cwd, getEnv().DRIZZLE_LAB_TS_CONFIG_PATH);
6970
let rawImport = fs.readFileSync(tsconfigPath, "utf8");
7071
// Remove single-line comments
7172
rawImport = rawImport.replace(/\/\/.*$/gm, "");
@@ -86,7 +87,7 @@ function loadTsConfigPathsAlias(cwd: string) {
8687
return acc;
8788
}, {});
8889

89-
if (DRIZZLE_LAB_DEBUG) {
90+
if (getEnv().DRIZZLE_LAB_DEBUG) {
9091
console.log("[tsconfig] Loading tsConfig path", tsconfigPath);
9192
console.log("[tsconfig] Loaded tsConfig", rawImport);
9293
console.log("[tsconfig] TS alias", alias);

vscode-extension/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to the "drizzle-orm" extension will be documented in this fi
44

55
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
66

7+
## [0.9.0]
8+
9+
- Upgrade to the latest drizzle-lab visualizer
10+
- Support loading env files in the visualizer
11+
712
## [0.8.0]
813

914
- New visualizer UI

0 commit comments

Comments
 (0)