diff --git a/packages/db/.gitignore b/packages/db/.gitignore new file mode 100644 index 000000000..67608bcee --- /dev/null +++ b/packages/db/.gitignore @@ -0,0 +1,2 @@ +dbml.svg +schema.dbml diff --git a/packages/db/dbml.ts b/packages/db/dbml.ts new file mode 100644 index 000000000..71b6c291e --- /dev/null +++ b/packages/db/dbml.ts @@ -0,0 +1,8 @@ +import { pgGenerate } from "drizzle-dbml-generator"; + +import * as schema from "./src/schema/index.js"; + +const out = "./schema.dbml"; +const relational = false; + +pgGenerate({ schema, out, relational }); diff --git a/packages/db/eslint.config.js b/packages/db/eslint.config.js index 7a7cc9475..3754c3be5 100644 --- a/packages/db/eslint.config.js +++ b/packages/db/eslint.config.js @@ -6,7 +6,7 @@ import baseConfig, { /** @type {import('typescript-eslint').Config} */ export default [ { - ignores: ["dist/**"], + ignores: ["dist/**", "dbml.ts"], }, ...baseConfig, ...requireJsSuffix, diff --git a/packages/db/package.json b/packages/db/package.json index f7dffb099..534cad401 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -35,6 +35,7 @@ "with-env": "dotenv -e ../../.env --", "migrate": "pnpm with-env tsx ./migrate.ts", "generate": "pnpm with-env drizzle-kit generate", + "generate:erd": "pnpm tsx dbml.ts && pnpm dbml-renderer -i schema.dbml -o erd.svg", "rest": "pnpm with-env psql $POSTGRES_URL -c \"DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public;\"" }, "dependencies": { @@ -49,9 +50,11 @@ "@ctrlplane/eslint-config": "workspace:*", "@ctrlplane/prettier-config": "workspace:*", "@ctrlplane/tsconfig": "workspace:*", + "@softwaretechnik/dbml-renderer": "^1.0.30", "@types/node": "catalog:node22", "@types/pg": "^8.11.6", "dotenv-cli": "^7.4.2", + "drizzle-dbml-generator": "^0.9.0", "drizzle-kit": "^0.24.2", "eslint": "catalog:", "prettier": "catalog:", diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json index 6c7fd999e..a96ede4ae 100644 --- a/packages/db/tsconfig.json +++ b/packages/db/tsconfig.json @@ -5,5 +5,5 @@ "baseUrl": "." }, "include": ["src", "../api/src/utils", "migrate.ts"], - "exclude": ["node_modules"] + "exclude": ["node_modules", "dbml.ts"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 385ee9619..23699c33e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1025,6 +1025,9 @@ importers: '@ctrlplane/tsconfig': specifier: workspace:* version: link:../../tooling/typescript + '@softwaretechnik/dbml-renderer': + specifier: ^1.0.30 + version: 1.0.30 '@types/node': specifier: catalog:node22 version: 22.7.4 @@ -1034,6 +1037,9 @@ importers: dotenv-cli: specifier: ^7.4.2 version: 7.4.2 + drizzle-dbml-generator: + specifier: ^0.9.0 + version: 0.9.0(drizzle-orm@0.33.0(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.10)(pg@8.13.0)(react@18.3.1)) drizzle-kit: specifier: ^0.24.2 version: 0.24.2 @@ -1370,7 +1376,7 @@ importers: version: 1.13.4(eslint@9.11.1(jiti@1.21.6)) eslint-plugin-import: specifier: ^2.29.1 - version: 2.30.0(eslint@9.11.1(jiti@1.21.6)) + version: 2.30.0(@typescript-eslint/parser@8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2))(eslint@9.11.1(jiti@1.21.6)) eslint-plugin-jsx-a11y: specifier: ^6.9.0 version: 6.10.0(eslint@9.11.1(jiti@1.21.6)) @@ -1468,6 +1474,9 @@ packages: '@actions/http-client@2.2.3': resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==} + '@aduh95/viz.js@3.4.0': + resolution: {integrity: sha512-KI2nVf9JdwWCXqK6RVf+9/096G7VWN4Z84mnynlyZKao2xQENW8WNEjLmvdlxS5X8PNWXFC1zqwm7tveOXw/4A==} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -4541,6 +4550,10 @@ packages: '@shikijs/vscode-textmate@9.2.2': resolution: {integrity: sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg==} + '@softwaretechnik/dbml-renderer@1.0.30': + resolution: {integrity: sha512-cGSeiZg5/IsW76mfKXAV39hveGnOOosLJLyIbFi/EcbUz/wqBlnPYnAgF/0d5lW+4AtzoBSMA8SNHkDMxCu/5Q==} + hasBin: true + '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} @@ -6112,6 +6125,11 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} + drizzle-dbml-generator@0.9.0: + resolution: {integrity: sha512-R/INfHUJNtxUkanSng8suh6er3snYKzMLFCeshqMMtGbrzo1+ulOY6qyrWXkY1d5jLuFwydySUD6bIZSyr0aSg==} + peerDependencies: + drizzle-orm: '>=0.32.0' + drizzle-kit@0.24.2: resolution: {integrity: sha512-nXOaTSFiuIaTMhS8WJC2d4EBeIcN9OSt2A2cyFbQYBAZbi7lRsVGJNqDpEwPqYfJz38yxbY/UtbvBBahBfnExQ==} hasBin: true @@ -10204,6 +10222,8 @@ snapshots: tunnel: 0.0.6 undici: 5.28.4 + '@aduh95/viz.js@3.4.0': {} + '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': @@ -13722,6 +13742,12 @@ snapshots: '@shikijs/vscode-textmate@9.2.2': {} + '@softwaretechnik/dbml-renderer@1.0.30': + dependencies: + '@aduh95/viz.js': 3.4.0 + yargs: 17.7.2 + zod: 3.23.8 + '@swc/counter@0.1.3': {} '@swc/helpers@0.5.13': @@ -15504,6 +15530,10 @@ snapshots: dotenv@16.4.5: {} + drizzle-dbml-generator@0.9.0(drizzle-orm@0.33.0(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.10)(pg@8.13.0)(react@18.3.1)): + dependencies: + drizzle-orm: 0.33.0(@opentelemetry/api@1.9.0)(@types/pg@8.11.10)(@types/react@18.3.10)(pg@8.13.0)(react@18.3.1) + drizzle-kit@0.24.2: dependencies: '@drizzle-team/brocli': 0.10.1 @@ -15827,16 +15857,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(eslint-import-resolver-node@0.3.9)(eslint@9.11.1(jiti@1.21.6)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint@9.11.1(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: + '@typescript-eslint/parser': 8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2) eslint: 9.11.1(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.30.0(eslint@9.11.1(jiti@1.21.6)): + eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2))(eslint@9.11.1(jiti@1.21.6)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -15847,7 +15878,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.11.1(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(eslint-import-resolver-node@0.3.9)(eslint@9.11.1(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint@9.11.1(jiti@1.21.6)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -15857,6 +15888,8 @@ snapshots: object.values: 1.2.0 semver: 6.3.1 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack