drizzle-docs-generator 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.ja.md +59 -15
  2. package/README.md +55 -11
  3. package/dist/adapter/types.d.ts +40 -0
  4. package/dist/adapter/types.d.ts.map +1 -0
  5. package/dist/adapter/v0-adapter.d.ts +73 -0
  6. package/dist/adapter/v0-adapter.d.ts.map +1 -0
  7. package/dist/adapter/v0-adapter.js +136 -0
  8. package/dist/adapter/v0-adapter.js.map +1 -0
  9. package/dist/adapter/v1-adapter.d.ts +40 -0
  10. package/dist/adapter/v1-adapter.d.ts.map +1 -0
  11. package/dist/adapter/v1-adapter.js +83 -0
  12. package/dist/adapter/v1-adapter.js.map +1 -0
  13. package/dist/cli/index.js +194 -71
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/integration-test-utils.d.ts +19 -0
  16. package/dist/cli/integration-test-utils.d.ts.map +1 -0
  17. package/dist/formatter/dbml-builder.d.ts +29 -0
  18. package/dist/formatter/dbml-builder.d.ts.map +1 -0
  19. package/dist/formatter/dbml-builder.js +39 -0
  20. package/dist/formatter/dbml-builder.js.map +1 -0
  21. package/dist/formatter/dbml.d.ts +81 -0
  22. package/dist/formatter/dbml.d.ts.map +1 -0
  23. package/dist/formatter/dbml.js +163 -0
  24. package/dist/formatter/dbml.js.map +1 -0
  25. package/dist/formatter/markdown.d.ts +126 -0
  26. package/dist/formatter/markdown.d.ts.map +1 -0
  27. package/dist/formatter/markdown.js +235 -0
  28. package/dist/formatter/markdown.js.map +1 -0
  29. package/dist/formatter/mermaid.d.ts +102 -0
  30. package/dist/formatter/mermaid.d.ts.map +1 -0
  31. package/dist/formatter/mermaid.js +177 -0
  32. package/dist/formatter/mermaid.js.map +1 -0
  33. package/dist/formatter/types.d.ts +37 -0
  34. package/dist/formatter/types.d.ts.map +1 -0
  35. package/dist/generator/common.d.ts +115 -208
  36. package/dist/generator/common.d.ts.map +1 -1
  37. package/dist/generator/common.js +260 -479
  38. package/dist/generator/common.js.map +1 -1
  39. package/dist/generator/mysql.js +3 -3
  40. package/dist/generator/pg.d.ts +8 -7
  41. package/dist/generator/pg.d.ts.map +1 -1
  42. package/dist/generator/pg.js +29 -31
  43. package/dist/generator/pg.js.map +1 -1
  44. package/dist/generator/sqlite.js +3 -3
  45. package/dist/index.d.ts +15 -4
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +22 -18
  48. package/dist/index.js.map +1 -1
  49. package/dist/test-utils/cli-runner.d.ts +4 -1
  50. package/dist/test-utils/cli-runner.d.ts.map +1 -1
  51. package/dist/test-utils/dbml-validator.d.ts +29 -0
  52. package/dist/test-utils/dbml-validator.d.ts.map +1 -1
  53. package/dist/types.d.ts +128 -16
  54. package/dist/types.d.ts.map +1 -1
  55. package/package.json +3 -2
  56. package/dist/generator/index.d.ts +0 -15
  57. package/dist/generator/index.d.ts.map +0 -1
  58. package/dist/parser/index.d.ts +0 -5
  59. package/dist/parser/index.d.ts.map +0 -1
  60. package/dist/test-utils/index.d.ts +0 -7
  61. package/dist/test-utils/index.d.ts.map +0 -1
package/README.ja.md CHANGED
@@ -5,13 +5,14 @@
5
5
 
6
6
  Drizzle ORM スキーマから DBML を生成する CLI。JSDoc コメントを Note 句として出力できる。
7
7
 
8
- **✨ 機能:**
8
+ **機能:**
9
9
 
10
- - 📁 **ディレクトリインポート対応**: ディレクトリ内のすべてのスキーマファイルを自動インポート
11
- - 🔄 **拡張子不要**: 拡張子なしのインポートに対応 (例: `import { users } from './users'`)
12
- - 📝 **JSDoc コメント**: 自動的に DBML の Note 句に変換
13
- - 🔗 **リレーション対応**: `relations()` または `defineRelations()` から参照を生成
14
- - 👀 **Watch モード**: ファイル変更時に自動再生成
10
+ - **ディレクトリインポート対応**: ディレクトリ内のすべてのスキーマファイルを自動インポート
11
+ - **拡張子不要**: 拡張子なしのインポートに対応 (例: `import { users } from './users'`)
12
+ - **JSDoc コメント**: 自動的に DBML の Note 句に変換
13
+ - **リレーション対応**: `relations()` または `defineRelations()` から参照を生成
14
+ - **Watch モード**: ファイル変更時に自動再生成
15
+ - **複数の出力形式**: DBML (デフォルト) および ER 図付き Markdown
15
16
 
16
17
  [English README](./README.md)
17
18
 
@@ -25,6 +26,8 @@ pnpm add -g drizzle-docs-generator
25
26
 
26
27
  ## 使い方
27
28
 
29
+ ### DBML 出力 (デフォルト)
30
+
28
31
  ```bash
29
32
  # 基本 - 単一ファイル
30
33
  drizzle-docs generate ./src/db/schema.ts -d postgresql
@@ -42,14 +45,39 @@ drizzle-docs generate ./src/db/schema.ts -d postgresql -r
42
45
  drizzle-docs generate ./src/db/schema.ts -d postgresql -w
43
46
  ```
44
47
 
48
+ ### Markdown 出力
49
+
50
+ ```bash
51
+ # Markdown 出力 (ER 図付き複数ファイル)
52
+ drizzle-docs generate ./src/db/schema.ts -d postgresql -f markdown -o ./docs
53
+
54
+ # Markdown 出力 (単一ファイル)
55
+ drizzle-docs generate ./src/db/schema.ts -d postgresql -f markdown --single-file -o schema.md
56
+
57
+ # ER 図なしの Markdown
58
+ drizzle-docs generate ./src/db/schema.ts -d postgresql -f markdown --no-er-diagram -o ./docs
59
+ ```
60
+
45
61
  ### オプション
46
62
 
47
- | オプション | 説明 |
48
- | ------------------------- | -------------------------------------------------- |
49
- | `-o, --output <file>` | 出力ファイルパス |
50
- | `-d, --dialect <dialect>` | DB 種別: `postgresql` (default), `mysql`, `sqlite` |
51
- | `-r, --relational` | relations() 定義からリファレンスを生成 |
52
- | `-w, --watch` | ファイル変更時に自動再生成 |
63
+ | オプション | 説明 |
64
+ | ------------------------- | ----------------------------------------------------- |
65
+ | `-o, --output <path>` | 出力ファイルまたはディレクトリパス |
66
+ | `-d, --dialect <dialect>` | DB 種別: `postgresql` (デフォルト), `mysql`, `sqlite` |
67
+ | `-f, --format <format>` | 出力形式: `dbml` (デフォルト), `markdown` |
68
+ | `-w, --watch` | ファイル変更時に自動再生成 |
69
+ | `--single-file` | Markdown を単一ファイルで出力 (markdown のみ) |
70
+ | `--no-er-diagram` | ER 図を Markdown 出力から除外 |
71
+ | `--force` | 確認なしで既存ファイルを上書き |
72
+
73
+ ### リレーション検出
74
+
75
+ リレーションはスキーマから**自動検出**されます:
76
+
77
+ - **v1 API** (`defineRelations()`): スキーマオブジェクトから実行時に検出
78
+ - **v0 API** (`relations()`): ソースファイルを解析して検出
79
+
80
+ 設定不要 - リレーション定義があれば使用し、なければ外部キー制約にフォールバックします。
53
81
 
54
82
  ## 例
55
83
 
@@ -63,7 +91,7 @@ export const users = pgTable("users", {
63
91
  });
64
92
  ```
65
93
 
66
-
94
+ ### DBML 出力
67
95
 
68
96
  ```dbml
69
97
  Table users {
@@ -74,6 +102,23 @@ Table users {
74
102
  }
75
103
  ```
76
104
 
105
+ ### Markdown 出力
106
+
107
+ ```markdown
108
+ # users
109
+
110
+ ユーザーテーブル
111
+
112
+ ## Columns
113
+
114
+ | Name | Type | Nullable | Default | Comment |
115
+ | ---- | ------ | -------- | ------- | ---------- |
116
+ | id | serial | No | | ユーザーID |
117
+ | name | text | No | | ユーザー名 |
118
+ ```
119
+
120
+ 詳細なサンプル出力は [examples/](./examples/) を参照してください。
121
+
77
122
  ## API
78
123
 
79
124
  ```typescript
@@ -82,8 +127,7 @@ import * as schema from "./schema";
82
127
 
83
128
  const dbml = pgGenerate({
84
129
  schema,
85
- source: "./schema.ts",
86
- relational: false,
130
+ source: "./schema.ts", // JSDoc コメントと v0 relations() 検出用
87
131
  out: "./output.dbml", // optional
88
132
  });
89
133
  ```
package/README.md CHANGED
@@ -5,13 +5,14 @@
5
5
 
6
6
  CLI tool to generate DBML from Drizzle ORM schemas. Extracts JSDoc comments and outputs them as Note clauses.
7
7
 
8
- **✨ Features:**
8
+ **Features:**
9
9
 
10
- - 📁 **Directory Import Support**: Import all schema files from a directory
11
- - 🔄 **No File Extension Required**: Works with extensionless imports (e.g., `import { users } from './users'`)
12
- - 📝 **JSDoc Comments**: Automatically extracts and converts to DBML Notes
13
- - 🔗 **Relations Support**: Generate refs from `relations()` or `defineRelations()`
14
- - 👀 **Watch Mode**: Auto-regenerate on file changes
10
+ - **Directory Import Support**: Import all schema files from a directory
11
+ - **No File Extension Required**: Works with extensionless imports (e.g., `import { users } from './users'`)
12
+ - **JSDoc Comments**: Automatically extracts and converts to DBML Notes
13
+ - **Relations Support**: Generate refs from `relations()` or `defineRelations()`
14
+ - **Watch Mode**: Auto-regenerate on file changes
15
+ - **Multiple Output Formats**: DBML (default) and Markdown with ER diagrams
15
16
 
16
17
  [日本語版READMEはこちら](./README.ja.md)
17
18
 
@@ -25,6 +26,8 @@ pnpm add -g drizzle-docs-generator
25
26
 
26
27
  ## Usage
27
28
 
29
+ ### DBML Output (Default)
30
+
28
31
  ```bash
29
32
  # Basic - single file
30
33
  drizzle-docs generate ./src/db/schema.ts -d postgresql
@@ -42,14 +45,39 @@ drizzle-docs generate ./src/db/schema.ts -d postgresql -r
42
45
  drizzle-docs generate ./src/db/schema.ts -d postgresql -w
43
46
  ```
44
47
 
48
+ ### Markdown Output
49
+
50
+ ```bash
51
+ # Markdown output (multiple files with ER diagram)
52
+ drizzle-docs generate ./src/db/schema.ts -d postgresql -f markdown -o ./docs
53
+
54
+ # Markdown output (single file)
55
+ drizzle-docs generate ./src/db/schema.ts -d postgresql -f markdown --single-file -o schema.md
56
+
57
+ # Markdown without ER diagram
58
+ drizzle-docs generate ./src/db/schema.ts -d postgresql -f markdown --no-er-diagram -o ./docs
59
+ ```
60
+
45
61
  ### Options
46
62
 
47
63
  | Option | Description |
48
64
  | ------------------------- | --------------------------------------------------- |
49
- | `-o, --output <file>` | Output file path |
65
+ | `-o, --output <path>` | Output file or directory path |
50
66
  | `-d, --dialect <dialect>` | Database: `postgresql` (default), `mysql`, `sqlite` |
51
- | `-r, --relational` | Generate refs from relations() definitions |
67
+ | `-f, --format <format>` | Output format: `dbml` (default), `markdown` |
52
68
  | `-w, --watch` | Regenerate on file changes |
69
+ | `--single-file` | Output Markdown as a single file (markdown only) |
70
+ | `--no-er-diagram` | Exclude ER diagram from Markdown output |
71
+ | `--force` | Overwrite existing files without confirmation |
72
+
73
+ ### Relation Detection
74
+
75
+ Relations are **automatically detected** from your schema:
76
+
77
+ - **v1 API** (`defineRelations()`): Detected from schema objects at runtime
78
+ - **v0 API** (`relations()`): Detected by parsing source files
79
+
80
+ No configuration needed - the tool will use relation definitions when present, or fall back to foreign key constraints.
53
81
 
54
82
  ## Example
55
83
 
@@ -63,7 +91,7 @@ export const users = pgTable("users", {
63
91
  });
64
92
  ```
65
93
 
66
-
94
+ ### DBML Output
67
95
 
68
96
  ```dbml
69
97
  Table users {
@@ -74,6 +102,23 @@ Table users {
74
102
  }
75
103
  ```
76
104
 
105
+ ### Markdown Output
106
+
107
+ ```markdown
108
+ # users
109
+
110
+ Users table
111
+
112
+ ## Columns
113
+
114
+ | Name | Type | Nullable | Default | Comment |
115
+ | ---- | ------ | -------- | ------- | --------- |
116
+ | id | serial | No | | User ID |
117
+ | name | text | No | | User name |
118
+ ```
119
+
120
+ See [examples/](./examples/) for more detailed output samples.
121
+
77
122
  ## API
78
123
 
79
124
  ```typescript
@@ -82,8 +127,7 @@ import * as schema from "./schema";
82
127
 
83
128
  const dbml = pgGenerate({
84
129
  schema,
85
- source: "./schema.ts",
86
- relational: false,
130
+ source: "./schema.ts", // for JSDoc comments and v0 relations() detection
87
131
  out: "./output.dbml", // optional
88
132
  });
89
133
  ```
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Unified relation representation for both v0 (relations()) and v1 (defineRelations())
3
+ *
4
+ * This interface provides a common format for relation information extracted
5
+ * from either API version, enabling consistent processing downstream.
6
+ */
7
+ export interface UnifiedRelation {
8
+ /** Source table name (database name, not TypeScript variable) */
9
+ sourceTable: string;
10
+ /** Source column names (database names) */
11
+ sourceColumns: string[];
12
+ /** Target table name (database name) */
13
+ targetTable: string;
14
+ /** Target column names (database names) */
15
+ targetColumns: string[];
16
+ /** Type of relation */
17
+ relationType: "one-to-one" | "one-to-many" | "many-to-one";
18
+ /** Optional onDelete action (e.g., CASCADE, SET NULL) */
19
+ onDelete?: string;
20
+ /** Optional onUpdate action (e.g., CASCADE, SET NULL) */
21
+ onUpdate?: string;
22
+ }
23
+ /**
24
+ * Adapter interface for extracting relations from different Drizzle ORM APIs
25
+ *
26
+ * Implementations handle the specifics of v0 relations() and v1 defineRelations()
27
+ * APIs, converting them to a unified representation.
28
+ */
29
+ export interface RelationAdapter {
30
+ /**
31
+ * Extract relations from the schema
32
+ *
33
+ * Processes the schema to identify and extract all relations, converting
34
+ * them to the unified format.
35
+ *
36
+ * @returns Array of unified relations
37
+ */
38
+ extract(): UnifiedRelation[];
39
+ }
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapter/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,uBAAuB;IACvB,YAAY,EAAE,YAAY,GAAG,aAAa,GAAG,aAAa,CAAC;IAC3D,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,OAAO,IAAI,eAAe,EAAE,CAAC;CAC9B"}
@@ -0,0 +1,73 @@
1
+ import { SchemaRelations } from '../parser/relations';
2
+ import { RelationAdapter, UnifiedRelation } from './types';
3
+ /**
4
+ * Adapter for extracting relations from v0 relations() API
5
+ *
6
+ * Handles the legacy relations() format by parsing relation definitions
7
+ * from the TypeScript source using the schema parser.
8
+ */
9
+ export declare class V0RelationAdapter implements RelationAdapter {
10
+ private schema;
11
+ private parsedRelations;
12
+ private tableNameMapping;
13
+ private columnNameMappings;
14
+ /**
15
+ * Create a new V0RelationAdapter
16
+ *
17
+ * @param schema - The Drizzle schema object containing tables
18
+ * @param parsedRelations - Parsed relation information from TypeScript source
19
+ */
20
+ constructor(schema: Record<string, unknown>, parsedRelations: SchemaRelations | undefined);
21
+ /**
22
+ * Extract relations from v0 relations() definitions
23
+ *
24
+ * Processes parsed relation information to extract foreign key relationships,
25
+ * determining relation types (one-to-one vs many-to-one) based on bidirectional
26
+ * analysis.
27
+ *
28
+ * @returns Array of unified relations
29
+ */
30
+ extract(): UnifiedRelation[];
31
+ /**
32
+ * Build a mapping from variable names to table names
33
+ *
34
+ * @returns Map of variable names to database table names
35
+ */
36
+ private buildTableNameMapping;
37
+ /**
38
+ * Check if a value is a Drizzle table
39
+ *
40
+ * @param value - The value to check
41
+ * @returns True if value is a table
42
+ */
43
+ private isTable;
44
+ /**
45
+ * Get column name mapping for a table
46
+ *
47
+ * @param tableVarName - The variable name of the table
48
+ * @returns Map of property names to database column names
49
+ */
50
+ private getColumnNameMapping;
51
+ /**
52
+ * Check if there's a reverse one() relation (B->A when we have A->B)
53
+ *
54
+ * Used to detect one-to-one relationships by checking if both tables
55
+ * have one() relations pointing to each other.
56
+ *
57
+ * @param sourceTable - The source table variable name
58
+ * @param targetTable - The target table variable name
59
+ * @param sourceFields - The source table's field names
60
+ * @param targetReferences - The target table's reference column names
61
+ * @returns True if a reverse one() relation exists
62
+ */
63
+ private hasReverseOneRelation;
64
+ /**
65
+ * Helper to check if two arrays are equal
66
+ *
67
+ * @param a - First array
68
+ * @param b - Second array
69
+ * @returns True if arrays have same length and same elements in order
70
+ */
71
+ private arraysEqual;
72
+ }
73
+ //# sourceMappingURL=v0-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v0-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/v0-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEhE;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IACvD,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,kBAAkB,CAAmC;IAE7D;;;;;OAKG;gBACS,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,EAAE,eAAe,GAAG,SAAS;IAOzF;;;;;;;;OAQG;IACH,OAAO,IAAI,eAAe,EAAE;IAmE5B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IAIf;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAoB5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,qBAAqB;IAoC7B;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;CAIpB"}
@@ -0,0 +1,136 @@
1
+ import { getTableName as g, is as c, getTableColumns as h } from "drizzle-orm";
2
+ import { PgTable as b } from "drizzle-orm/pg-core";
3
+ import { MySqlTable as T } from "drizzle-orm/mysql-core";
4
+ import { SQLiteTable as M } from "drizzle-orm/sqlite-core";
5
+ class $ {
6
+ schema;
7
+ parsedRelations;
8
+ tableNameMapping;
9
+ columnNameMappings;
10
+ /**
11
+ * Create a new V0RelationAdapter
12
+ *
13
+ * @param schema - The Drizzle schema object containing tables
14
+ * @param parsedRelations - Parsed relation information from TypeScript source
15
+ */
16
+ constructor(t, s) {
17
+ this.schema = t, this.parsedRelations = s, this.tableNameMapping = this.buildTableNameMapping(), this.columnNameMappings = /* @__PURE__ */ new Map();
18
+ }
19
+ /**
20
+ * Extract relations from v0 relations() definitions
21
+ *
22
+ * Processes parsed relation information to extract foreign key relationships,
23
+ * determining relation types (one-to-one vs many-to-one) based on bidirectional
24
+ * analysis.
25
+ *
26
+ * @returns Array of unified relations
27
+ */
28
+ extract() {
29
+ if (!this.parsedRelations || this.parsedRelations.relations.length === 0)
30
+ return [];
31
+ const t = [], s = /* @__PURE__ */ new Set();
32
+ for (const e of this.parsedRelations.relations) {
33
+ if (e.type !== "one" || e.fields.length === 0 || e.references.length === 0)
34
+ continue;
35
+ const a = this.tableNameMapping.get(e.sourceTable), n = this.tableNameMapping.get(e.targetTable);
36
+ if (!a || !n)
37
+ continue;
38
+ const o = this.getColumnNameMapping(e.sourceTable), r = this.getColumnNameMapping(e.targetTable), l = e.fields.map(
39
+ (i) => o.get(i) || i
40
+ ), p = e.references.map((i) => r.get(i) || i), m = `${a}.${l.join(",")}-${n}.${p.join(",")}`, u = `${n}.${p.join(",")}-${a}.${l.join(",")}`;
41
+ if (s.has(m) || s.has(u))
42
+ continue;
43
+ s.add(m);
44
+ const f = this.hasReverseOneRelation(
45
+ e.sourceTable,
46
+ e.targetTable,
47
+ e.fields,
48
+ e.references
49
+ );
50
+ t.push({
51
+ sourceTable: a,
52
+ sourceColumns: l,
53
+ targetTable: n,
54
+ targetColumns: p,
55
+ relationType: f ? "one-to-one" : "many-to-one"
56
+ });
57
+ }
58
+ return t;
59
+ }
60
+ /**
61
+ * Build a mapping from variable names to table names
62
+ *
63
+ * @returns Map of variable names to database table names
64
+ */
65
+ buildTableNameMapping() {
66
+ const t = /* @__PURE__ */ new Map();
67
+ for (const [s, e] of Object.entries(this.schema))
68
+ if (this.isTable(e)) {
69
+ const a = g(e);
70
+ t.set(s, a);
71
+ }
72
+ return t;
73
+ }
74
+ /**
75
+ * Check if a value is a Drizzle table
76
+ *
77
+ * @param value - The value to check
78
+ * @returns True if value is a table
79
+ */
80
+ isTable(t) {
81
+ return c(t, b) || c(t, T) || c(t, M);
82
+ }
83
+ /**
84
+ * Get column name mapping for a table
85
+ *
86
+ * @param tableVarName - The variable name of the table
87
+ * @returns Map of property names to database column names
88
+ */
89
+ getColumnNameMapping(t) {
90
+ if (this.columnNameMappings.has(t))
91
+ return this.columnNameMappings.get(t);
92
+ const s = /* @__PURE__ */ new Map(), e = this.schema[t];
93
+ if (e && this.isTable(e)) {
94
+ const a = h(e);
95
+ for (const [n, o] of Object.entries(a))
96
+ s.set(n, o.name);
97
+ }
98
+ return this.columnNameMappings.set(t, s), s;
99
+ }
100
+ /**
101
+ * Check if there's a reverse one() relation (B->A when we have A->B)
102
+ *
103
+ * Used to detect one-to-one relationships by checking if both tables
104
+ * have one() relations pointing to each other.
105
+ *
106
+ * @param sourceTable - The source table variable name
107
+ * @param targetTable - The target table variable name
108
+ * @param sourceFields - The source table's field names
109
+ * @param targetReferences - The target table's reference column names
110
+ * @returns True if a reverse one() relation exists
111
+ */
112
+ hasReverseOneRelation(t, s, e, a) {
113
+ if (!this.parsedRelations) return !1;
114
+ for (const n of this.parsedRelations.relations)
115
+ if (n.type === "one" && n.sourceTable === s && n.targetTable === t && n.fields.length > 0 && n.references.length > 0) {
116
+ const o = n.fields, r = n.references;
117
+ if (this.arraysEqual(o, a) && this.arraysEqual(r, e))
118
+ return !0;
119
+ }
120
+ return !1;
121
+ }
122
+ /**
123
+ * Helper to check if two arrays are equal
124
+ *
125
+ * @param a - First array
126
+ * @param b - Second array
127
+ * @returns True if arrays have same length and same elements in order
128
+ */
129
+ arraysEqual(t, s) {
130
+ return t.length !== s.length ? !1 : t.every((e, a) => e === s[a]);
131
+ }
132
+ }
133
+ export {
134
+ $ as V0RelationAdapter
135
+ };
136
+ //# sourceMappingURL=v0-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v0-adapter.js","sources":["../../src/adapter/v0-adapter.ts"],"sourcesContent":["import { type Table, getTableColumns, getTableName, is } from \"drizzle-orm\";\nimport { PgTable } from \"drizzle-orm/pg-core\";\nimport { MySqlTable } from \"drizzle-orm/mysql-core\";\nimport { SQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport type { SchemaRelations } from \"../parser/relations\";\nimport type { RelationAdapter, UnifiedRelation } from \"./types\";\n\n/**\n * Adapter for extracting relations from v0 relations() API\n *\n * Handles the legacy relations() format by parsing relation definitions\n * from the TypeScript source using the schema parser.\n */\nexport class V0RelationAdapter implements RelationAdapter {\n private schema: Record<string, unknown>;\n private parsedRelations: SchemaRelations | undefined;\n private tableNameMapping: Map<string, string>;\n private columnNameMappings: Map<string, Map<string, string>>;\n\n /**\n * Create a new V0RelationAdapter\n *\n * @param schema - The Drizzle schema object containing tables\n * @param parsedRelations - Parsed relation information from TypeScript source\n */\n constructor(schema: Record<string, unknown>, parsedRelations: SchemaRelations | undefined) {\n this.schema = schema;\n this.parsedRelations = parsedRelations;\n this.tableNameMapping = this.buildTableNameMapping();\n this.columnNameMappings = new Map();\n }\n\n /**\n * Extract relations from v0 relations() definitions\n *\n * Processes parsed relation information to extract foreign key relationships,\n * determining relation types (one-to-one vs many-to-one) based on bidirectional\n * analysis.\n *\n * @returns Array of unified relations\n */\n extract(): UnifiedRelation[] {\n if (!this.parsedRelations || this.parsedRelations.relations.length === 0) {\n return [];\n }\n\n const relations: UnifiedRelation[] = [];\n const processedRefs = new Set<string>();\n\n for (const parsedRelation of this.parsedRelations.relations) {\n // Only process one() relations with fields and references\n // many() relations are typically the inverse and don't have field info\n if (parsedRelation.type !== \"one\") {\n continue;\n }\n\n if (parsedRelation.fields.length === 0 || parsedRelation.references.length === 0) {\n continue;\n }\n\n // Map variable names to actual table names\n const fromTableName = this.tableNameMapping.get(parsedRelation.sourceTable);\n const toTableName = this.tableNameMapping.get(parsedRelation.targetTable);\n\n if (!fromTableName || !toTableName) {\n continue;\n }\n\n // Get column name mappings (TypeScript property names -> database column names)\n const fromColumnMapping = this.getColumnNameMapping(parsedRelation.sourceTable);\n const toColumnMapping = this.getColumnNameMapping(parsedRelation.targetTable);\n\n // Map TypeScript field names to database column names\n const fromColumns = parsedRelation.fields.map(\n (field) => fromColumnMapping.get(field) || field,\n );\n const toColumns = parsedRelation.references.map((ref) => toColumnMapping.get(ref) || ref);\n\n // Create a unique key to avoid duplicate refs (bidirectional)\n const refKey = `${fromTableName}.${fromColumns.join(\",\")}-${toTableName}.${toColumns.join(\",\")}`;\n const reverseRefKey = `${toTableName}.${toColumns.join(\",\")}-${fromTableName}.${fromColumns.join(\",\")}`;\n\n if (processedRefs.has(refKey) || processedRefs.has(reverseRefKey)) {\n continue;\n }\n processedRefs.add(refKey);\n\n // Check if this is a one-to-one relationship (bidirectional one())\n const isOneToOne = this.hasReverseOneRelation(\n parsedRelation.sourceTable,\n parsedRelation.targetTable,\n parsedRelation.fields,\n parsedRelation.references,\n );\n\n // Create UnifiedRelation\n relations.push({\n sourceTable: fromTableName,\n sourceColumns: fromColumns,\n targetTable: toTableName,\n targetColumns: toColumns,\n relationType: isOneToOne ? \"one-to-one\" : \"many-to-one\",\n });\n }\n\n return relations;\n }\n\n /**\n * Build a mapping from variable names to table names\n *\n * @returns Map of variable names to database table names\n */\n private buildTableNameMapping(): Map<string, string> {\n const mapping = new Map<string, string>();\n for (const [varName, value] of Object.entries(this.schema)) {\n if (this.isTable(value)) {\n const tableName = getTableName(value as Table);\n mapping.set(varName, tableName);\n }\n }\n return mapping;\n }\n\n /**\n * Check if a value is a Drizzle table\n *\n * @param value - The value to check\n * @returns True if value is a table\n */\n private isTable(value: unknown): boolean {\n return is(value, PgTable) || is(value, MySqlTable) || is(value, SQLiteTable);\n }\n\n /**\n * Get column name mapping for a table\n *\n * @param tableVarName - The variable name of the table\n * @returns Map of property names to database column names\n */\n private getColumnNameMapping(tableVarName: string): Map<string, string> {\n // Check cache first\n if (this.columnNameMappings.has(tableVarName)) {\n return this.columnNameMappings.get(tableVarName)!;\n }\n\n const mapping = new Map<string, string>();\n const table = this.schema[tableVarName];\n if (table && this.isTable(table)) {\n const columns = getTableColumns(table as Table);\n for (const [propName, column] of Object.entries(columns)) {\n mapping.set(propName, column.name);\n }\n }\n\n // Cache the mapping\n this.columnNameMappings.set(tableVarName, mapping);\n return mapping;\n }\n\n /**\n * Check if there's a reverse one() relation (B->A when we have A->B)\n *\n * Used to detect one-to-one relationships by checking if both tables\n * have one() relations pointing to each other.\n *\n * @param sourceTable - The source table variable name\n * @param targetTable - The target table variable name\n * @param sourceFields - The source table's field names\n * @param targetReferences - The target table's reference column names\n * @returns True if a reverse one() relation exists\n */\n private hasReverseOneRelation(\n sourceTable: string,\n targetTable: string,\n sourceFields: string[],\n targetReferences: string[],\n ): boolean {\n if (!this.parsedRelations) return false;\n\n // Look for a one() relation from targetTable to sourceTable\n for (const relation of this.parsedRelations.relations) {\n if (\n relation.type === \"one\" &&\n relation.sourceTable === targetTable &&\n relation.targetTable === sourceTable &&\n relation.fields.length > 0 &&\n relation.references.length > 0\n ) {\n // Check if the fields/references are the reverse of each other\n // A->B: fields=[A.col], references=[B.col]\n // B->A: fields=[B.col], references=[A.col]\n const reverseFields = relation.fields;\n const reverseReferences = relation.references;\n\n // The reverse relation's fields should match our references\n // and the reverse relation's references should match our fields\n if (\n this.arraysEqual(reverseFields, targetReferences) &&\n this.arraysEqual(reverseReferences, sourceFields)\n ) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Helper to check if two arrays are equal\n *\n * @param a - First array\n * @param b - Second array\n * @returns True if arrays have same length and same elements in order\n */\n private arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n return a.every((val, i) => val === b[i]);\n }\n}\n"],"names":["V0RelationAdapter","schema","parsedRelations","relations","processedRefs","parsedRelation","fromTableName","toTableName","fromColumnMapping","toColumnMapping","fromColumns","field","toColumns","ref","refKey","reverseRefKey","isOneToOne","mapping","varName","value","tableName","getTableName","is","PgTable","MySqlTable","SQLiteTable","tableVarName","table","columns","getTableColumns","propName","column","sourceTable","targetTable","sourceFields","targetReferences","relation","reverseFields","reverseReferences","a","b","val","i"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { TableRelationalConfig } from 'drizzle-orm/relations';
2
+ import { RelationAdapter, UnifiedRelation } from './types';
3
+ /**
4
+ * Adapter for extracting relations from v1 defineRelations() API
5
+ *
6
+ * Handles the modern v1 defineRelations() format using official Drizzle types
7
+ * (TableRelationalConfig, AnyRelation, One).
8
+ */
9
+ export declare class V1RelationAdapter implements RelationAdapter {
10
+ private entries;
11
+ /**
12
+ * Create a new V1RelationAdapter
13
+ *
14
+ * @param entries - Array of v1 relation entries from defineRelations()
15
+ */
16
+ constructor(entries: TableRelationalConfig[]);
17
+ /**
18
+ * Extract relations from v1 defineRelations() entries
19
+ *
20
+ * Processes One relations to extract foreign key information and generates
21
+ * relation definitions. Detects one-to-one relationships with bidirectional checks.
22
+ *
23
+ * @returns Array of unified relations
24
+ */
25
+ extract(): UnifiedRelation[];
26
+ /**
27
+ * Check if there's a reverse One relation in v1 entries
28
+ *
29
+ * Detects one-to-one relationships by checking if the target table
30
+ * has a matching One relation pointing back to the source table.
31
+ *
32
+ * @param fromTableName - The table to search for reverse relation
33
+ * @param toTableName - The expected target table of the reverse relation
34
+ * @param fromColumns - The expected source columns of the reverse relation
35
+ * @param toColumns - The expected target columns of the reverse relation
36
+ * @returns True if a matching reverse One relation exists
37
+ */
38
+ private hasReverseOneRelation;
39
+ }
40
+ //# sourceMappingURL=v1-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/v1-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEhE;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IACvD,OAAO,CAAC,OAAO,CAA0B;IAEzC;;;;OAIG;gBACS,OAAO,EAAE,qBAAqB,EAAE;IAI5C;;;;;;;OAOG;IACH,OAAO,IAAI,eAAe,EAAE;IA4D5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,qBAAqB;CAsC9B"}
@@ -0,0 +1,83 @@
1
+ import { getTableName as m, is as h, One as T } from "drizzle-orm";
2
+ class v {
3
+ entries;
4
+ /**
5
+ * Create a new V1RelationAdapter
6
+ *
7
+ * @param entries - Array of v1 relation entries from defineRelations()
8
+ */
9
+ constructor(s) {
10
+ this.entries = s;
11
+ }
12
+ /**
13
+ * Extract relations from v1 defineRelations() entries
14
+ *
15
+ * Processes One relations to extract foreign key information and generates
16
+ * relation definitions. Detects one-to-one relationships with bidirectional checks.
17
+ *
18
+ * @returns Array of unified relations
19
+ */
20
+ extract() {
21
+ const s = [], i = /* @__PURE__ */ new Set();
22
+ for (const c of this.entries) {
23
+ const o = m(c.table);
24
+ for (const a of Object.values(c.relations)) {
25
+ if (!h(a, T) || a.isReversed)
26
+ continue;
27
+ const n = a, e = n.sourceColumns.map((g) => g.name), l = n.targetColumns.map((g) => g.name);
28
+ if (e.length === 0 || l.length === 0)
29
+ continue;
30
+ const r = m(n.targetTable), u = `${o}.${e.join(",")}->${r}.${l.join(",")}`, t = `${r}.${l.join(",")}->${o}.${e.join(",")}`;
31
+ if (i.has(u) || i.has(t))
32
+ continue;
33
+ i.add(u);
34
+ const f = this.hasReverseOneRelation(
35
+ r,
36
+ o,
37
+ l,
38
+ e
39
+ );
40
+ s.push({
41
+ sourceTable: o,
42
+ sourceColumns: e,
43
+ targetTable: r,
44
+ targetColumns: l,
45
+ relationType: f ? "one-to-one" : "many-to-one"
46
+ });
47
+ }
48
+ }
49
+ return s;
50
+ }
51
+ /**
52
+ * Check if there's a reverse One relation in v1 entries
53
+ *
54
+ * Detects one-to-one relationships by checking if the target table
55
+ * has a matching One relation pointing back to the source table.
56
+ *
57
+ * @param fromTableName - The table to search for reverse relation
58
+ * @param toTableName - The expected target table of the reverse relation
59
+ * @param fromColumns - The expected source columns of the reverse relation
60
+ * @param toColumns - The expected target columns of the reverse relation
61
+ * @returns True if a matching reverse One relation exists
62
+ */
63
+ hasReverseOneRelation(s, i, c, o) {
64
+ const a = this.entries.find((n) => m(n.table) === s);
65
+ if (!a)
66
+ return !1;
67
+ for (const n of Object.values(a.relations)) {
68
+ if (!h(n, T))
69
+ continue;
70
+ const e = n;
71
+ if (m(e.targetTable) !== i)
72
+ continue;
73
+ const r = e.sourceColumns.map((t) => t.name), u = e.targetColumns.map((t) => t.name);
74
+ if (r.length === c.length && u.length === o.length && r.every((t, f) => t === c[f]) && u.every((t, f) => t === o[f]))
75
+ return !0;
76
+ }
77
+ return !1;
78
+ }
79
+ }
80
+ export {
81
+ v as V1RelationAdapter
82
+ };
83
+ //# sourceMappingURL=v1-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1-adapter.js","sources":["../../src/adapter/v1-adapter.ts"],"sourcesContent":["import { type Table, getTableName, is, One } from \"drizzle-orm\";\nimport type { AnyRelation, TableRelationalConfig } from \"drizzle-orm/relations\";\nimport type { RelationAdapter, UnifiedRelation } from \"./types\";\n\n/**\n * Adapter for extracting relations from v1 defineRelations() API\n *\n * Handles the modern v1 defineRelations() format using official Drizzle types\n * (TableRelationalConfig, AnyRelation, One).\n */\nexport class V1RelationAdapter implements RelationAdapter {\n private entries: TableRelationalConfig[];\n\n /**\n * Create a new V1RelationAdapter\n *\n * @param entries - Array of v1 relation entries from defineRelations()\n */\n constructor(entries: TableRelationalConfig[]) {\n this.entries = entries;\n }\n\n /**\n * Extract relations from v1 defineRelations() entries\n *\n * Processes One relations to extract foreign key information and generates\n * relation definitions. Detects one-to-one relationships with bidirectional checks.\n *\n * @returns Array of unified relations\n */\n extract(): UnifiedRelation[] {\n const relations: UnifiedRelation[] = [];\n const processedRefs = new Set<string>();\n\n for (const entry of this.entries) {\n const sourceTableName = getTableName(entry.table as Table);\n\n for (const relation of Object.values(entry.relations)) {\n // Only process One relations as they define the FK direction\n // Many relations are the inverse and don't add new information\n if (!is(relation, One)) {\n continue;\n }\n\n // Skip reversed relations (they are auto-generated inverse relations)\n if ((relation as AnyRelation).isReversed) {\n continue;\n }\n\n // Get source and target column names (using official Relation properties)\n const rel = relation as AnyRelation;\n const sourceColumns = rel.sourceColumns.map((col) => col.name);\n const targetColumns = rel.targetColumns.map((col) => col.name);\n\n if (sourceColumns.length === 0 || targetColumns.length === 0) {\n continue;\n }\n\n const targetTableName = getTableName(rel.targetTable as Table);\n\n // Create a unique key to avoid duplicate refs\n const refKey = `${sourceTableName}.${sourceColumns.join(\",\")}->${targetTableName}.${targetColumns.join(\",\")}`;\n const reverseRefKey = `${targetTableName}.${targetColumns.join(\",\")}->${sourceTableName}.${sourceColumns.join(\",\")}`;\n\n if (processedRefs.has(refKey) || processedRefs.has(reverseRefKey)) {\n continue;\n }\n processedRefs.add(refKey);\n\n // Check if there's a reverse one() relation (indicating one-to-one)\n const isOneToOne = this.hasReverseOneRelation(\n targetTableName,\n sourceTableName,\n targetColumns,\n sourceColumns,\n );\n\n relations.push({\n sourceTable: sourceTableName,\n sourceColumns,\n targetTable: targetTableName,\n targetColumns,\n relationType: isOneToOne ? \"one-to-one\" : \"many-to-one\",\n });\n }\n }\n\n return relations;\n }\n\n /**\n * Check if there's a reverse One relation in v1 entries\n *\n * Detects one-to-one relationships by checking if the target table\n * has a matching One relation pointing back to the source table.\n *\n * @param fromTableName - The table to search for reverse relation\n * @param toTableName - The expected target table of the reverse relation\n * @param fromColumns - The expected source columns of the reverse relation\n * @param toColumns - The expected target columns of the reverse relation\n * @returns True if a matching reverse One relation exists\n */\n private hasReverseOneRelation(\n fromTableName: string,\n toTableName: string,\n fromColumns: string[],\n toColumns: string[],\n ): boolean {\n const fromEntry = this.entries.find((e) => getTableName(e.table as Table) === fromTableName);\n if (!fromEntry) {\n return false;\n }\n\n for (const relation of Object.values(fromEntry.relations)) {\n if (!is(relation, One)) {\n continue;\n }\n\n const rel = relation as AnyRelation;\n const relTargetName = getTableName(rel.targetTable as Table);\n if (relTargetName !== toTableName) {\n continue;\n }\n\n const relSourceCols = rel.sourceColumns.map((col) => col.name);\n const relTargetCols = rel.targetColumns.map((col) => col.name);\n\n // Check if columns match in reverse\n if (\n relSourceCols.length === fromColumns.length &&\n relTargetCols.length === toColumns.length &&\n relSourceCols.every((col, i) => col === fromColumns[i]) &&\n relTargetCols.every((col, i) => col === toColumns[i])\n ) {\n return true;\n }\n }\n\n return false;\n }\n}\n"],"names":["V1RelationAdapter","entries","relations","processedRefs","entry","sourceTableName","getTableName","relation","is","One","rel","sourceColumns","col","targetColumns","targetTableName","refKey","reverseRefKey","isOneToOne","fromTableName","toTableName","fromColumns","toColumns","fromEntry","e","relSourceCols","relTargetCols","i"],"mappings":";AAUO,MAAMA,EAA6C;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOR,YAAYC,GAAkC;AAC5C,SAAK,UAAUA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,UAA6B;AAC3B,UAAMC,IAA+B,CAAA,GAC/BC,wBAAoB,IAAA;AAE1B,eAAWC,KAAS,KAAK,SAAS;AAChC,YAAMC,IAAkBC,EAAaF,EAAM,KAAc;AAEzD,iBAAWG,KAAY,OAAO,OAAOH,EAAM,SAAS,GAAG;AAQrD,YALI,CAACI,EAAGD,GAAUE,CAAG,KAKhBF,EAAyB;AAC5B;AAIF,cAAMG,IAAMH,GACNI,IAAgBD,EAAI,cAAc,IAAI,CAACE,MAAQA,EAAI,IAAI,GACvDC,IAAgBH,EAAI,cAAc,IAAI,CAACE,MAAQA,EAAI,IAAI;AAE7D,YAAID,EAAc,WAAW,KAAKE,EAAc,WAAW;AACzD;AAGF,cAAMC,IAAkBR,EAAaI,EAAI,WAAoB,GAGvDK,IAAS,GAAGV,CAAe,IAAIM,EAAc,KAAK,GAAG,CAAC,KAAKG,CAAe,IAAID,EAAc,KAAK,GAAG,CAAC,IACrGG,IAAgB,GAAGF,CAAe,IAAID,EAAc,KAAK,GAAG,CAAC,KAAKR,CAAe,IAAIM,EAAc,KAAK,GAAG,CAAC;AAElH,YAAIR,EAAc,IAAIY,CAAM,KAAKZ,EAAc,IAAIa,CAAa;AAC9D;AAEF,QAAAb,EAAc,IAAIY,CAAM;AAGxB,cAAME,IAAa,KAAK;AAAA,UACtBH;AAAA,UACAT;AAAA,UACAQ;AAAA,UACAF;AAAA,QAAA;AAGF,QAAAT,EAAU,KAAK;AAAA,UACb,aAAaG;AAAA,UACb,eAAAM;AAAA,UACA,aAAaG;AAAA,UACb,eAAAD;AAAA,UACA,cAAcI,IAAa,eAAe;AAAA,QAAA,CAC3C;AAAA,MACH;AAAA,IACF;AAEA,WAAOf;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcQ,sBACNgB,GACAC,GACAC,GACAC,GACS;AACT,UAAMC,IAAY,KAAK,QAAQ,KAAK,CAACC,MAAMjB,EAAaiB,EAAE,KAAc,MAAML,CAAa;AAC3F,QAAI,CAACI;AACH,aAAO;AAGT,eAAWf,KAAY,OAAO,OAAOe,EAAU,SAAS,GAAG;AACzD,UAAI,CAACd,EAAGD,GAAUE,CAAG;AACnB;AAGF,YAAMC,IAAMH;AAEZ,UADsBD,EAAaI,EAAI,WAAoB,MACrCS;AACpB;AAGF,YAAMK,IAAgBd,EAAI,cAAc,IAAI,CAACE,MAAQA,EAAI,IAAI,GACvDa,IAAgBf,EAAI,cAAc,IAAI,CAACE,MAAQA,EAAI,IAAI;AAG7D,UACEY,EAAc,WAAWJ,EAAY,UACrCK,EAAc,WAAWJ,EAAU,UACnCG,EAAc,MAAM,CAACZ,GAAKc,MAAMd,MAAQQ,EAAYM,CAAC,CAAC,KACtDD,EAAc,MAAM,CAACb,GAAKc,MAAMd,MAAQS,EAAUK,CAAC,CAAC;AAEpD,eAAO;AAAA,IAEX;AAEA,WAAO;AAAA,EACT;AACF;"}