Skip to content

Commit

Permalink
Visualizer - Handle envs import (#42)
Browse files Browse the repository at this point in the history
* add env selector for the visualizer
* add env option in drizzle lab cli
* rework env loader
  • Loading branch information
rphlmr authored Nov 28, 2024
1 parent fce9454 commit b07f58e
Show file tree
Hide file tree
Showing 23 changed files with 176 additions and 130 deletions.
5 changes: 3 additions & 2 deletions apps/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ Usage:
Flags:
-c, --config string Path to drizzle config file
--debug Enable log output (default: false)
--save-dir string Directory to save the visualizer data (default: ".drizzle-lab")
--project-id string A unique identifier for the current visualized project. It is used as filename to save the visualizer state.
--save-dir string Directory to save the visualizer data (default: ".drizzle")
--project-id string A unique identifier for the current visualized project. It is used as filename to save the visualizer state. (default: "visualizer")
--ts-config string Path to tsconfig.json. It is used to resolve TypeScript paths aliases. (default: "./tsconfig.json")
-p, --port number Port to run visualizer on (default: 64738)
-e, --env-path string Path to a .env file

Global flags:
-h, --help help for visualizer
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ await bundle.write(config.output);
await bundle.close();

// Add banner to dist/cli.js
const banner = `#!/usr/bin/env node\n`;
const banner = "#!/usr/bin/env node\n";
const cliFilePath = "dist/cli.js";
const originalContent = await fs.readFile(cliFilePath, "utf-8");
await fs.writeFile(cliFilePath, banner + originalContent);
Expand Down
27 changes: 19 additions & 8 deletions apps/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { spawnSync } from "node:child_process";

import {
DRIZZLE_LAB_ENV_KEY,
getEnv,
importDrizzleConfig,
DRIZZLE_LAB_TS_CONFIG_PATH,
} from "@drizzle-lab/api/config/node";
import { command, string, run, boolean, number } from "@drizzle-team/brocli";
import chalk from "chalk";
Expand All @@ -17,23 +17,27 @@ const tsConfig = string()
.desc(
"Path to tsconfig.json. It is used to resolve TypeScript paths aliases.",
)
.default(DRIZZLE_LAB_TS_CONFIG_PATH);
.default(getEnv().DRIZZLE_LAB_TS_CONFIG_PATH);
const envPath = string()
.desc("Path to a .env file. It is used to load environment variables.")
.alias("e");

const visualizer = command({
name: "visualizer",
options: {
config: optionConfig,
debug,
["save-dir"]: string()
"save-dir": string()
.desc("Directory to save the visualizer data")
.default(".drizzle"),
["project-id"]: string()
"project-id": string()
.desc(
"A unique identifier for the current visualized project. It is used as filename to save the visualizer state.",
)
.default("visualizer"),
["ts-config"]: tsConfig,
"ts-config": tsConfig,
port: number().desc("Port to run visualizer on").default(64738).alias("p"),
"env-path": envPath,
},
async transform(options) {
const DRIZZLE_LAB_CWD = process.cwd();
Expand All @@ -46,6 +50,7 @@ const visualizer = command({
[DRIZZLE_LAB_ENV_KEY.PROJECT_ID]: options["project-id"],
[DRIZZLE_LAB_ENV_KEY.CWD]: DRIZZLE_LAB_CWD,
[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH]: options["ts-config"],
[DRIZZLE_LAB_ENV_KEY.ENV_FILE_PATH]: options["env-path"],
} as const;

process.env = {
Expand Down Expand Up @@ -87,7 +92,7 @@ const visualizer = command({
? spawnSync("vite", ["--host"], {
stdio: "inherit",
})
: spawnSync(process.execPath, [`visualizer/server/index.mjs`], {
: spawnSync(process.execPath, ["visualizer/server/index.mjs"], {
stdio: "inherit",
cwd: import.meta.dirname,
env: {
Expand All @@ -104,11 +109,14 @@ const snapshot = command({
options: {
config: optionConfig,
debug,
["ts-config"]: tsConfig,
"ts-config": tsConfig,
"env-path": envPath,
},
transform: async (options) => {
process.env[DRIZZLE_LAB_ENV_KEY.DEBUG] = String(options.debug);
process.env[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH] = options["ts-config"];
process.env[DRIZZLE_LAB_ENV_KEY.ENV_FILE_PATH] = options["env-path"];

const config = await importDrizzleConfig(options.config);

if (options.debug) {
Expand Down Expand Up @@ -165,11 +173,14 @@ const sql = command({
options: {
config: optionConfig,
debug,
["ts-config"]: tsConfig,
"ts-config": tsConfig,
"env-path": envPath,
},
transform: async (options) => {
process.env[DRIZZLE_LAB_ENV_KEY.DEBUG] = String(options.debug);
process.env[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH] = options["ts-config"];
process.env[DRIZZLE_LAB_ENV_KEY.ENV_FILE_PATH] = options["env-path"];

const config = await importDrizzleConfig(options.config);

if (options.debug) {
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drizzle-lab",
"version": "0.9.0",
"version": "0.10.0",
"description": "Drizzle Lab CLI",
"sideEffects": false,
"type": "module",
Expand Down
6 changes: 3 additions & 3 deletions apps/cli/visualizer/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { PassThrough } from "node:stream";

import { DRIZZLE_LAB_DEBUG } from "@drizzle-lab/api/config/node";
import { getEnv } from "@drizzle-lab/api/config/node";
import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
Expand All @@ -29,11 +29,11 @@ if (!global.__server) {
// eslint-disable-next-line no-console
console.log(
`\n${chalk.green(
`Drizzle Visualizer`,
"Drizzle Visualizer",
)} is up and running on ${chalk.blue(`http://127.0.0.1:${info.port}`)}\n`,
);
},
defaultLogger: DRIZZLE_LAB_DEBUG,
defaultLogger: getEnv().DRIZZLE_LAB_DEBUG,
});
}

Expand Down
4 changes: 2 additions & 2 deletions apps/cli/visualizer/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import path from "node:path";
import {
importDrizzleConfig,
DRIZZLE_LAB_ENV_KEY,
DRIZZLE_LAB_DEBUG,
getEnv,
} from "@drizzle-lab/api/config/node";
import {
DrizzleVisualizer,
Expand Down Expand Up @@ -61,7 +61,7 @@ export async function loader() {
await fs.readFile(saveFilePath, "utf-8"),
) as NodePosition[];
} catch (e) {
if (DRIZZLE_LAB_DEBUG) {
if (getEnv().DRIZZLE_LAB_DEBUG) {
console.warn(
`Using default nodes positions. Reason is: ${
e instanceof Error ? e.message : "unknown"
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ They are all optional.
| `DRIZZLE_LAB_SAVE_DIR` | Directory to save output | `./drizzle` |
| `DRIZZLE_LAB_PROJECT_ID` | Project ID to identify the project in json output | `drizzle-lab` |
| `TS_CONFIG_PATH` | Path to tsconfig.json | `./tsconfig.json` |
| `DRIZZLE_LAB_ENV_FILE_PATH` | Path to env file | `undefined` |

## License

Expand Down
3 changes: 2 additions & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@drizzle-lab/api",
"version": "0.28.0",
"version": "0.29.0",
"description": "Drizzle Lab API - Fork of Drizzle Kit API",
"type": "module",
"license": "MIT",
Expand Down Expand Up @@ -198,6 +198,7 @@
},
"dependencies": {
"chalk": "^5.3.0",
"dotenv": "^16.4.5",
"glob": "^11.0.0",
"jiti": "^2.4.0",
"zod": "^3.23.8"
Expand Down
29 changes: 14 additions & 15 deletions packages/api/src/config/env.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ export const DRIZZLE_LAB_ENV_KEY = {
SAVE_DIR: "DRIZZLE_LAB_SAVE_DIR",
PROJECT_ID: "DRIZZLE_LAB_PROJECT_ID",
TS_CONFIG_PATH: "TS_CONFIG_PATH",
ENV_FILE_PATH: "DRIZZLE_LAB_ENV_FILE_PATH",
} as const;

export const DRIZZLE_LAB_DEBUG =
process.env[DRIZZLE_LAB_ENV_KEY.DEBUG] === "true";

export const DRIZZLE_LAB_CWD = process.env[DRIZZLE_LAB_ENV_KEY.CWD]
? `${process.env[DRIZZLE_LAB_ENV_KEY.CWD]}/`
: "";

export const DRIZZLE_LAB_CONFIG_PATH =
process.env[DRIZZLE_LAB_ENV_KEY.CONFIG_PATH];

export const DRIZZLE_LAB_PROJECT_ID =
process.env[DRIZZLE_LAB_ENV_KEY.PROJECT_ID];

export const DRIZZLE_LAB_TS_CONFIG_PATH =
process.env[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH] || "./tsconfig.json";
export function getEnv() {
return {
DRIZZLE_LAB_DEBUG: process.env[DRIZZLE_LAB_ENV_KEY.DEBUG] === "true",
DRIZZLE_LAB_CWD: process.env[DRIZZLE_LAB_ENV_KEY.CWD]
? `${process.env[DRIZZLE_LAB_ENV_KEY.CWD]}/`
: "",
DRIZZLE_LAB_CONFIG_PATH: process.env[DRIZZLE_LAB_ENV_KEY.CONFIG_PATH],
DRIZZLE_LAB_PROJECT_ID: process.env[DRIZZLE_LAB_ENV_KEY.PROJECT_ID],
DRIZZLE_LAB_TS_CONFIG_PATH:
process.env[DRIZZLE_LAB_ENV_KEY.TS_CONFIG_PATH] || "./tsconfig.json",
DRIZZLE_LAB_ENV_FILE_PATH: process.env[DRIZZLE_LAB_ENV_KEY.ENV_FILE_PATH],
};
}
20 changes: 8 additions & 12 deletions packages/api/src/config/loader.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ import Path from "node:path";

import { glob } from "glob";

import {
DRIZZLE_LAB_CWD,
DRIZZLE_LAB_DEBUG,
DRIZZLE_LAB_PROJECT_ID,
} from "./env.node.ts";
import { getEnv } from "./env.node.ts";
import { configCommonSchema } from "./schema.ts";
import { importModule } from "../internal/import-module.node.ts";
import { withStyle } from "../internal/style";
Expand All @@ -22,10 +18,10 @@ export type PartialConfig = Partial<Config>;
*/
export async function importDrizzleConfig(configPath?: string) {
const defaultTsConfigExists = fs.existsSync(
Path.resolve(Path.join(DRIZZLE_LAB_CWD, "drizzle.config.ts")),
Path.resolve(Path.join(getEnv().DRIZZLE_LAB_CWD, "drizzle.config.ts")),
);
const defaultJsConfigExists = fs.existsSync(
Path.resolve(Path.join(DRIZZLE_LAB_CWD, "drizzle.config.js")),
Path.resolve(Path.join(getEnv().DRIZZLE_LAB_CWD, "drizzle.config.js")),
);

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

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

const path = Path.resolve(
Path.join(DRIZZLE_LAB_CWD, configPath ?? defaultConfigPath),
Path.join(getEnv().DRIZZLE_LAB_CWD, configPath ?? defaultConfigPath),
);

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

if (DRIZZLE_LAB_DEBUG) {
if (getEnv().DRIZZLE_LAB_DEBUG) {
console.info(withStyle.info(`Reading config file '${path}'`));
}

Expand All @@ -69,13 +65,13 @@ export async function importDrizzleConfig(configPath?: string) {
return {
...config.data,
schema: prepareFilenames(config.data.schema),
projectId: config.data.lab.projectId || DRIZZLE_LAB_PROJECT_ID,
projectId: config.data.lab.projectId || getEnv().DRIZZLE_LAB_PROJECT_ID,
};
}

const prepareFilenames = (paths: string[]) => {
const matches = paths.reduce((matches, cur) => {
const globMatches = glob.sync(`${DRIZZLE_LAB_CWD}${cur}`);
const globMatches = glob.sync(`${getEnv().DRIZZLE_LAB_CWD}${cur}`);

globMatches.forEach((it) => {
const fileName = fs.lstatSync(it).isDirectory() ? null : Path.resolve(it);
Expand Down
21 changes: 11 additions & 10 deletions packages/api/src/internal/import-module.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ import path from "node:path";
import { pathToFileURL } from "node:url";

import chalk from "chalk";
import { config } from "dotenv";
import { createJiti } from "jiti";

import {
DRIZZLE_LAB_CWD,
DRIZZLE_LAB_DEBUG,
DRIZZLE_LAB_TS_CONFIG_PATH,
} from "../config/env.node.ts";
import { getEnv } from "../config/env.node.ts";

const jiti = createJiti(import.meta.url, {
alias: loadTsConfigPathsAlias(DRIZZLE_LAB_CWD),
alias: loadTsConfigPathsAlias(getEnv().DRIZZLE_LAB_CWD),
moduleCache: false,
});

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

try {
if (getEnv().DRIZZLE_LAB_ENV_FILE_PATH) {
config({ path: getEnv().DRIZZLE_LAB_ENV_FILE_PATH });
}

let module = await jiti.import<{ default: { default?: any } }>(
pathToFileURL(path).href,
);
Expand All @@ -52,7 +53,7 @@ export async function importModule(path: string) {

return module;
} catch (e) {
if (DRIZZLE_LAB_DEBUG) {
if (getEnv().DRIZZLE_LAB_DEBUG) {
console.error(
"[importModule] Failed to import module",
path,
Expand All @@ -65,7 +66,7 @@ export async function importModule(path: string) {

function loadTsConfigPathsAlias(cwd: string) {
try {
const tsconfigPath = path.resolve(cwd, DRIZZLE_LAB_TS_CONFIG_PATH);
const tsconfigPath = path.resolve(cwd, getEnv().DRIZZLE_LAB_TS_CONFIG_PATH);
let rawImport = fs.readFileSync(tsconfigPath, "utf8");
// Remove single-line comments
rawImport = rawImport.replace(/\/\/.*$/gm, "");
Expand All @@ -86,7 +87,7 @@ function loadTsConfigPathsAlias(cwd: string) {
return acc;
}, {});

if (DRIZZLE_LAB_DEBUG) {
if (getEnv().DRIZZLE_LAB_DEBUG) {
console.log("[tsconfig] Loading tsConfig path", tsconfigPath);
console.log("[tsconfig] Loaded tsConfig", rawImport);
console.log("[tsconfig] TS alias", alias);
Expand Down
5 changes: 5 additions & 0 deletions vscode-extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to the "drizzle-orm" extension will be documented in this fi

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

## [0.9.0]

- Upgrade to the latest drizzle-lab visualizer
- Support loading env files in the visualizer

## [0.8.0]

- New visualizer UI
Expand Down
Loading

0 comments on commit b07f58e

Please sign in to comment.