drizzle-docs-generator 0.7.0 → 0.7.2
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.
- package/dist/adapter/v0-adapter.js +69 -135
- package/dist/adapter/v0-adapter.js.map +1 -1
- package/dist/adapter/v1-adapter.js +46 -82
- package/dist/adapter/v1-adapter.js.map +1 -1
- package/dist/cli/index.js +167 -228
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/resolve-schema-exports.js +11 -7
- package/dist/cli/resolve-schema-exports.js.map +1 -1
- package/dist/formatter/dbml-builder.js +21 -38
- package/dist/formatter/dbml-builder.js.map +1 -1
- package/dist/formatter/dbml.d.ts +8 -0
- package/dist/formatter/dbml.d.ts.map +1 -1
- package/dist/formatter/dbml.js +100 -164
- package/dist/formatter/dbml.js.map +1 -1
- package/dist/formatter/markdown.js +150 -237
- package/dist/formatter/markdown.js.map +1 -1
- package/dist/formatter/mermaid.js +136 -209
- package/dist/formatter/mermaid.js.map +1 -1
- package/dist/generator/common.js +271 -479
- package/dist/generator/common.js.map +1 -1
- package/dist/generator/mysql.js +12 -14
- package/dist/generator/mysql.js.map +1 -1
- package/dist/generator/pg.js +33 -48
- package/dist/generator/pg.js.map +1 -1
- package/dist/generator/sqlite.js +12 -14
- package/dist/generator/sqlite.js.map +1 -1
- package/dist/index.js +10 -25
- package/dist/parser/comments.js +91 -109
- package/dist/parser/comments.js.map +1 -1
- package/dist/parser/relations.js +85 -102
- package/dist/parser/relations.js.map +1 -1
- package/package.json +4 -4
- package/dist/index.js.map +0 -1
|
@@ -1,136 +1,70 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PgTable as
|
|
3
|
-
import { MySqlTable as
|
|
4
|
-
import { SQLiteTable as
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
|
1
|
+
import { getTableColumns as e, getTableName as t, is as n } from "drizzle-orm";
|
|
2
|
+
import { PgTable as r } from "drizzle-orm/pg-core";
|
|
3
|
+
import { MySqlTable as i } from "drizzle-orm/mysql-core";
|
|
4
|
+
import { SQLiteTable as a } from "drizzle-orm/sqlite-core";
|
|
5
|
+
//#region src/adapter/v0-adapter.ts
|
|
6
|
+
var o = class {
|
|
7
|
+
schema;
|
|
8
|
+
parsedRelations;
|
|
9
|
+
tableNameMapping;
|
|
10
|
+
columnNameMappings;
|
|
11
|
+
constructor(e, t) {
|
|
12
|
+
this.schema = e, this.parsedRelations = t, this.tableNameMapping = this.buildTableNameMapping(), this.columnNameMappings = /* @__PURE__ */ new Map();
|
|
13
|
+
}
|
|
14
|
+
extract() {
|
|
15
|
+
if (!this.parsedRelations || this.parsedRelations.relations.length === 0) return [];
|
|
16
|
+
let e = [], t = /* @__PURE__ */ new Set();
|
|
17
|
+
for (let n of this.parsedRelations.relations) {
|
|
18
|
+
if (n.type !== "one" || n.fields.length === 0 || n.references.length === 0) continue;
|
|
19
|
+
let r = this.tableNameMapping.get(n.sourceTable), i = this.tableNameMapping.get(n.targetTable);
|
|
20
|
+
if (!r || !i) continue;
|
|
21
|
+
let a = this.getColumnNameMapping(n.sourceTable), o = this.getColumnNameMapping(n.targetTable), s = n.fields.map((e) => a.get(e) || e), c = n.references.map((e) => o.get(e) || e), l = `${r}.${s.join(",")}-${i}.${c.join(",")}`, u = `${i}.${c.join(",")}-${r}.${s.join(",")}`;
|
|
22
|
+
if (t.has(l) || t.has(u)) continue;
|
|
23
|
+
t.add(l);
|
|
24
|
+
let d = this.hasReverseOneRelation(n.sourceTable, n.targetTable, n.fields, n.references);
|
|
25
|
+
e.push({
|
|
26
|
+
sourceTable: r,
|
|
27
|
+
sourceColumns: s,
|
|
28
|
+
targetTable: i,
|
|
29
|
+
targetColumns: c,
|
|
30
|
+
relationType: d ? "one-to-one" : "many-to-one"
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return e;
|
|
34
|
+
}
|
|
35
|
+
buildTableNameMapping() {
|
|
36
|
+
let e = /* @__PURE__ */ new Map();
|
|
37
|
+
for (let [n, r] of Object.entries(this.schema)) if (this.isTable(r)) {
|
|
38
|
+
let i = t(r);
|
|
39
|
+
e.set(n, i);
|
|
40
|
+
}
|
|
41
|
+
return e;
|
|
42
|
+
}
|
|
43
|
+
isTable(e) {
|
|
44
|
+
return n(e, r) || n(e, i) || n(e, a);
|
|
45
|
+
}
|
|
46
|
+
getColumnNameMapping(t) {
|
|
47
|
+
if (this.columnNameMappings.has(t)) return this.columnNameMappings.get(t);
|
|
48
|
+
let n = /* @__PURE__ */ new Map(), r = this.schema[t];
|
|
49
|
+
if (r && this.isTable(r)) {
|
|
50
|
+
let t = e(r);
|
|
51
|
+
for (let [e, r] of Object.entries(t)) n.set(e, r.name);
|
|
52
|
+
}
|
|
53
|
+
return this.columnNameMappings.set(t, n), n;
|
|
54
|
+
}
|
|
55
|
+
hasReverseOneRelation(e, t, n, r) {
|
|
56
|
+
if (!this.parsedRelations) return !1;
|
|
57
|
+
for (let i of this.parsedRelations.relations) if (i.type === "one" && i.sourceTable === t && i.targetTable === e && i.fields.length > 0 && i.references.length > 0) {
|
|
58
|
+
let e = i.fields, t = i.references;
|
|
59
|
+
if (this.arraysEqual(e, r) && this.arraysEqual(t, n)) return !0;
|
|
60
|
+
}
|
|
61
|
+
return !1;
|
|
62
|
+
}
|
|
63
|
+
arraysEqual(e, t) {
|
|
64
|
+
return e.length === t.length ? e.every((e, n) => e === t[n]) : !1;
|
|
65
|
+
}
|
|
135
66
|
};
|
|
136
|
-
//#
|
|
67
|
+
//#endregion
|
|
68
|
+
export { o as V0RelationAdapter };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=v0-adapter.js.map
|
|
@@ -1 +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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"}
|
|
1
|
+
{"version":3,"file":"v0-adapter.js","names":[],"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"],"mappings":"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"}
|
|
@@ -1,83 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
1
|
+
import { One as e, getTableName as t, is as n } from "drizzle-orm";
|
|
2
|
+
//#region src/adapter/v1-adapter.ts
|
|
3
|
+
var r = class {
|
|
4
|
+
entries;
|
|
5
|
+
constructor(e) {
|
|
6
|
+
this.entries = e;
|
|
7
|
+
}
|
|
8
|
+
extract() {
|
|
9
|
+
let r = [], i = /* @__PURE__ */ new Set();
|
|
10
|
+
for (let a of this.entries) {
|
|
11
|
+
let o = t(a.table);
|
|
12
|
+
for (let s of Object.values(a.relations)) {
|
|
13
|
+
if (!n(s, e) || s.isReversed) continue;
|
|
14
|
+
let a = s, c = a.sourceColumns.map((e) => e.name), l = a.targetColumns.map((e) => e.name);
|
|
15
|
+
if (c.length === 0 || l.length === 0) continue;
|
|
16
|
+
let u = t(a.targetTable), d = `${o}.${c.join(",")}->${u}.${l.join(",")}`, f = `${u}.${l.join(",")}->${o}.${c.join(",")}`;
|
|
17
|
+
if (i.has(d) || i.has(f)) continue;
|
|
18
|
+
i.add(d);
|
|
19
|
+
let p = this.hasReverseOneRelation(u, o, l, c);
|
|
20
|
+
r.push({
|
|
21
|
+
sourceTable: o,
|
|
22
|
+
sourceColumns: c,
|
|
23
|
+
targetTable: u,
|
|
24
|
+
targetColumns: l,
|
|
25
|
+
relationType: p ? "one-to-one" : "many-to-one"
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return r;
|
|
30
|
+
}
|
|
31
|
+
hasReverseOneRelation(r, i, a, o) {
|
|
32
|
+
let s = this.entries.find((e) => t(e.table) === r);
|
|
33
|
+
if (!s) return !1;
|
|
34
|
+
for (let r of Object.values(s.relations)) {
|
|
35
|
+
if (!n(r, e)) continue;
|
|
36
|
+
let s = r;
|
|
37
|
+
if (t(s.targetTable) !== i) continue;
|
|
38
|
+
let c = s.sourceColumns.map((e) => e.name), l = s.targetColumns.map((e) => e.name);
|
|
39
|
+
if (c.length === a.length && l.length === o.length && c.every((e, t) => e === a[t]) && l.every((e, t) => e === o[t])) return !0;
|
|
40
|
+
}
|
|
41
|
+
return !1;
|
|
42
|
+
}
|
|
82
43
|
};
|
|
83
|
-
//#
|
|
44
|
+
//#endregion
|
|
45
|
+
export { r as V1RelationAdapter };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=v1-adapter.js.map
|
|
@@ -1 +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"],"
|
|
1
|
+
{"version":3,"file":"v1-adapter.js","names":[],"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"],"mappings":";;AAUA,IAAa,IAAb,MAA0D;CACxD;CAOA,YAAY,GAAkC;AAC5C,OAAK,UAAU;;CAWjB,UAA6B;EAC3B,IAAM,IAA+B,EAAE,EACjC,oBAAgB,IAAI,KAAa;AAEvC,OAAK,IAAM,KAAS,KAAK,SAAS;GAChC,IAAM,IAAkB,EAAa,EAAM,MAAe;AAE1D,QAAK,IAAM,KAAY,OAAO,OAAO,EAAM,UAAU,EAAE;AAQrD,QALI,CAAC,EAAG,GAAU,EAAI,IAKjB,EAAyB,WAC5B;IAIF,IAAM,IAAM,GACN,IAAgB,EAAI,cAAc,KAAK,MAAQ,EAAI,KAAK,EACxD,IAAgB,EAAI,cAAc,KAAK,MAAQ,EAAI,KAAK;AAE9D,QAAI,EAAc,WAAW,KAAK,EAAc,WAAW,EACzD;IAGF,IAAM,IAAkB,EAAa,EAAI,YAAqB,EAGxD,IAAS,GAAG,EAAgB,GAAG,EAAc,KAAK,IAAI,CAAC,IAAI,EAAgB,GAAG,EAAc,KAAK,IAAI,IACrG,IAAgB,GAAG,EAAgB,GAAG,EAAc,KAAK,IAAI,CAAC,IAAI,EAAgB,GAAG,EAAc,KAAK,IAAI;AAElH,QAAI,EAAc,IAAI,EAAO,IAAI,EAAc,IAAI,EAAc,CAC/D;AAEF,MAAc,IAAI,EAAO;IAGzB,IAAM,IAAa,KAAK,sBACtB,GACA,GACA,GACA,EACD;AAED,MAAU,KAAK;KACb,aAAa;KACb;KACA,aAAa;KACb;KACA,cAAc,IAAa,eAAe;KAC3C,CAAC;;;AAIN,SAAO;;CAeT,sBACE,GACA,GACA,GACA,GACS;EACT,IAAM,IAAY,KAAK,QAAQ,MAAM,MAAM,EAAa,EAAE,MAAe,KAAK,EAAc;AAC5F,MAAI,CAAC,EACH,QAAO;AAGT,OAAK,IAAM,KAAY,OAAO,OAAO,EAAU,UAAU,EAAE;AACzD,OAAI,CAAC,EAAG,GAAU,EAAI,CACpB;GAGF,IAAM,IAAM;AAEZ,OADsB,EAAa,EAAI,YAAqB,KACtC,EACpB;GAGF,IAAM,IAAgB,EAAI,cAAc,KAAK,MAAQ,EAAI,KAAK,EACxD,IAAgB,EAAI,cAAc,KAAK,MAAQ,EAAI,KAAK;AAG9D,OACE,EAAc,WAAW,EAAY,UACrC,EAAc,WAAW,EAAU,UACnC,EAAc,OAAO,GAAK,MAAM,MAAQ,EAAY,GAAG,IACvD,EAAc,OAAO,GAAK,MAAM,MAAQ,EAAU,GAAG,CAErD,QAAO;;AAIX,SAAO"}
|