drizzle-docs-generator 0.1.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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +89 -0
  3. package/README.md +89 -0
  4. package/dist/cli/index.d.ts +8 -0
  5. package/dist/cli/index.d.ts.map +1 -0
  6. package/dist/cli/index.js +69 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/generator/common.d.ts +393 -0
  9. package/dist/generator/common.d.ts.map +1 -0
  10. package/dist/generator/common.js +699 -0
  11. package/dist/generator/common.js.map +1 -0
  12. package/dist/generator/index.d.ts +15 -0
  13. package/dist/generator/index.d.ts.map +1 -0
  14. package/dist/generator/mysql.d.ts +36 -0
  15. package/dist/generator/mysql.d.ts.map +1 -0
  16. package/dist/generator/mysql.js +16 -0
  17. package/dist/generator/mysql.js.map +1 -0
  18. package/dist/generator/pg.d.ts +48 -0
  19. package/dist/generator/pg.d.ts.map +1 -0
  20. package/dist/generator/pg.js +52 -0
  21. package/dist/generator/pg.js.map +1 -0
  22. package/dist/generator/sqlite.d.ts +36 -0
  23. package/dist/generator/sqlite.d.ts.map +1 -0
  24. package/dist/generator/sqlite.js +16 -0
  25. package/dist/generator/sqlite.js.map +1 -0
  26. package/dist/index.d.ts +13 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +21 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/parser/comments.d.ts +31 -0
  31. package/dist/parser/comments.d.ts.map +1 -0
  32. package/dist/parser/comments.js +113 -0
  33. package/dist/parser/comments.js.map +1 -0
  34. package/dist/parser/index.d.ts +5 -0
  35. package/dist/parser/index.d.ts.map +1 -0
  36. package/dist/parser/relations.d.ts +34 -0
  37. package/dist/parser/relations.d.ts.map +1 -0
  38. package/dist/parser/relations.js +111 -0
  39. package/dist/parser/relations.js.map +1 -0
  40. package/dist/test-utils/cli-runner.d.ts +35 -0
  41. package/dist/test-utils/cli-runner.d.ts.map +1 -0
  42. package/dist/test-utils/dbml-validator.d.ts +70 -0
  43. package/dist/test-utils/dbml-validator.d.ts.map +1 -0
  44. package/dist/test-utils/index.d.ts +7 -0
  45. package/dist/test-utils/index.d.ts.map +1 -0
  46. package/dist/types.d.ts +53 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/package.json +69 -0
@@ -0,0 +1,5 @@
1
+ export { extractComments } from './comments';
2
+ export type { SchemaComments, TableComment, ColumnComment } from './comments';
3
+ export { extractRelations } from './relations';
4
+ export type { ParsedRelation, SchemaRelations } from './relations';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Parsed relation from relations() definition
3
+ */
4
+ export interface ParsedRelation {
5
+ /** Name of the source table (the first argument of relations()) */
6
+ sourceTable: string;
7
+ /** Name of the target table (the first argument of one()/many()) */
8
+ targetTable: string;
9
+ /** Relation type: "one" or "many" */
10
+ type: "one" | "many";
11
+ /** Source column names (from fields array) */
12
+ fields: string[];
13
+ /** Target column names (from references array) */
14
+ references: string[];
15
+ }
16
+ /**
17
+ * All extracted relations from a schema file
18
+ */
19
+ export interface SchemaRelations {
20
+ relations: ParsedRelation[];
21
+ }
22
+ /**
23
+ * Extract relations from a Drizzle schema source file or directory using AST parsing
24
+ *
25
+ * Parses TypeScript source files and extracts:
26
+ * - relations() function calls
27
+ * - one() and many() relation definitions within them
28
+ * - fields and references arrays for generating DBML Refs
29
+ *
30
+ * @param sourcePath - Path to the TypeScript schema file or directory
31
+ * @returns Extracted relations
32
+ */
33
+ export declare function extractRelations(sourcePath: string): SchemaRelations;
34
+ //# sourceMappingURL=relations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/parser/relations.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kDAAkD;IAClD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B;AA+BD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAapE"}
@@ -0,0 +1,111 @@
1
+ import * as r from "typescript";
2
+ import { readFileSync as h, statSync as A, readdirSync as b } from "node:fs";
3
+ import { join as F } from "node:path";
4
+ function d(e) {
5
+ const s = A(e);
6
+ if (s.isFile())
7
+ return e.endsWith(".ts") ? [e] : [];
8
+ if (s.isDirectory()) {
9
+ const n = [], i = b(e, { withFileTypes: !0 });
10
+ for (const t of i) {
11
+ const o = F(e, t.name);
12
+ t.isDirectory() ? n.push(...d(o)) : t.isFile() && t.name.endsWith(".ts") && !t.name.endsWith(".test.ts") && n.push(o);
13
+ }
14
+ return n;
15
+ }
16
+ return [];
17
+ }
18
+ function S(e) {
19
+ const s = { relations: [] }, n = d(e);
20
+ for (const i of n) {
21
+ const t = h(i, "utf-8"), o = r.createSourceFile(i, t, r.ScriptTarget.Latest, !0);
22
+ x(o, o, s);
23
+ }
24
+ return s;
25
+ }
26
+ function x(e, s, n) {
27
+ if (r.isVariableStatement(e)) {
28
+ for (const i of e.declarationList.declarations)
29
+ if (i.initializer && r.isCallExpression(i.initializer)) {
30
+ const t = p(i.initializer);
31
+ t && n.relations.push(...t);
32
+ }
33
+ }
34
+ if (r.isExportAssignment(e) && r.isCallExpression(e.expression)) {
35
+ const i = p(e.expression);
36
+ i && n.relations.push(...i);
37
+ }
38
+ r.forEachChild(e, (i) => x(i, s, n));
39
+ }
40
+ function p(e, s) {
41
+ if (y(e) !== "relations")
42
+ return;
43
+ const i = e.arguments[0];
44
+ if (!i)
45
+ return;
46
+ const t = g(i);
47
+ if (!t)
48
+ return;
49
+ const o = e.arguments[1];
50
+ if (!(!o || !r.isArrowFunction(o)))
51
+ return v(t, o);
52
+ }
53
+ function v(e, s, n) {
54
+ const i = [];
55
+ let t = s.body;
56
+ if (r.isParenthesizedExpression(t) && (t = t.expression), !r.isObjectLiteralExpression(t))
57
+ return i;
58
+ for (const o of t.properties)
59
+ if (r.isPropertyAssignment(o) && r.isCallExpression(o.initializer)) {
60
+ const f = z(e, o.initializer);
61
+ f && i.push(f);
62
+ }
63
+ return i;
64
+ }
65
+ function z(e, s, n) {
66
+ const i = y(s);
67
+ if (i !== "one" && i !== "many")
68
+ return;
69
+ const t = s.arguments[0];
70
+ if (!t)
71
+ return;
72
+ const o = g(t);
73
+ if (!o)
74
+ return;
75
+ const f = s.arguments[1];
76
+ let c = [], l = [];
77
+ if (f && r.isObjectLiteralExpression(f)) {
78
+ for (const a of f.properties)
79
+ if (r.isPropertyAssignment(a) && r.isIdentifier(a.name)) {
80
+ const u = a.name.text;
81
+ u === "fields" && r.isArrayLiteralExpression(a.initializer) ? c = m(a.initializer) : u === "references" && r.isArrayLiteralExpression(a.initializer) && (l = m(a.initializer));
82
+ }
83
+ }
84
+ return {
85
+ sourceTable: e,
86
+ targetTable: o,
87
+ type: i,
88
+ fields: c,
89
+ references: l
90
+ };
91
+ }
92
+ function m(e) {
93
+ const s = [];
94
+ for (const n of e.elements)
95
+ r.isPropertyAccessExpression(n) ? s.push(n.name.text) : r.isIdentifier(n) && s.push(n.text);
96
+ return s;
97
+ }
98
+ function y(e) {
99
+ if (r.isIdentifier(e.expression))
100
+ return e.expression.text;
101
+ if (r.isPropertyAccessExpression(e.expression))
102
+ return e.expression.name.text;
103
+ }
104
+ function g(e) {
105
+ if (r.isIdentifier(e))
106
+ return e.text;
107
+ }
108
+ export {
109
+ S as extractRelations
110
+ };
111
+ //# sourceMappingURL=relations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.js","sources":["../../src/parser/relations.ts"],"sourcesContent":["import * as ts from \"typescript\";\nimport { readFileSync, statSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Parsed relation from relations() definition\n */\nexport interface ParsedRelation {\n /** Name of the source table (the first argument of relations()) */\n sourceTable: string;\n /** Name of the target table (the first argument of one()/many()) */\n targetTable: string;\n /** Relation type: \"one\" or \"many\" */\n type: \"one\" | \"many\";\n /** Source column names (from fields array) */\n fields: string[];\n /** Target column names (from references array) */\n references: string[];\n}\n\n/**\n * All extracted relations from a schema file\n */\nexport interface SchemaRelations {\n relations: ParsedRelation[];\n}\n\n/**\n * Get all TypeScript files from a path (file or directory)\n */\nfunction getTypeScriptFiles(sourcePath: string): string[] {\n const stat = statSync(sourcePath);\n\n if (stat.isFile()) {\n return sourcePath.endsWith(\".ts\") ? [sourcePath] : [];\n }\n\n if (stat.isDirectory()) {\n const files: string[] = [];\n const entries = readdirSync(sourcePath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(sourcePath, entry.name);\n if (entry.isDirectory()) {\n files.push(...getTypeScriptFiles(fullPath));\n } else if (entry.isFile() && entry.name.endsWith(\".ts\") && !entry.name.endsWith(\".test.ts\")) {\n files.push(fullPath);\n }\n }\n\n return files;\n }\n\n return [];\n}\n\n/**\n * Extract relations from a Drizzle schema source file or directory using AST parsing\n *\n * Parses TypeScript source files and extracts:\n * - relations() function calls\n * - one() and many() relation definitions within them\n * - fields and references arrays for generating DBML Refs\n *\n * @param sourcePath - Path to the TypeScript schema file or directory\n * @returns Extracted relations\n */\nexport function extractRelations(sourcePath: string): SchemaRelations {\n const result: SchemaRelations = { relations: [] };\n const files = getTypeScriptFiles(sourcePath);\n\n for (const filePath of files) {\n const sourceCode = readFileSync(filePath, \"utf-8\");\n const sourceFile = ts.createSourceFile(filePath, sourceCode, ts.ScriptTarget.Latest, true);\n\n // Visit all nodes to find relations() calls\n visitNode(sourceFile, sourceFile, result);\n }\n\n return result;\n}\n\n/**\n * Recursively visit AST nodes to find relations() definitions\n */\nfunction visitNode(node: ts.Node, sourceFile: ts.SourceFile, result: SchemaRelations): void {\n // Look for variable declarations that define relations\n if (ts.isVariableStatement(node)) {\n for (const declaration of node.declarationList.declarations) {\n if (declaration.initializer && ts.isCallExpression(declaration.initializer)) {\n const parsedRelations = parseRelationsDefinition(declaration.initializer, sourceFile);\n if (parsedRelations) {\n result.relations.push(...parsedRelations);\n }\n }\n }\n }\n\n // Also check for direct call expressions (e.g., export const x = relations(...))\n if (ts.isExportAssignment(node) && ts.isCallExpression(node.expression)) {\n const parsedRelations = parseRelationsDefinition(node.expression, sourceFile);\n if (parsedRelations) {\n result.relations.push(...parsedRelations);\n }\n }\n\n ts.forEachChild(node, (child) => visitNode(child, sourceFile, result));\n}\n\n/**\n * Parse a relations() call expression\n *\n * Example:\n * relations(posts, ({ one }) => ({\n * author: one(users, {\n * fields: [posts.authorId],\n * references: [users.id],\n * }),\n * }))\n */\nfunction parseRelationsDefinition(\n callExpr: ts.CallExpression,\n sourceFile: ts.SourceFile,\n): ParsedRelation[] | undefined {\n const funcName = getCallExpressionName(callExpr);\n\n if (funcName !== \"relations\") {\n return undefined;\n }\n\n // Get source table from first argument\n const sourceTableArg = callExpr.arguments[0];\n if (!sourceTableArg) {\n return undefined;\n }\n const sourceTable = extractIdentifierName(sourceTableArg);\n if (!sourceTable) {\n return undefined;\n }\n\n // Get the callback function (second argument)\n const callbackArg = callExpr.arguments[1];\n if (!callbackArg || !ts.isArrowFunction(callbackArg)) {\n return undefined;\n }\n\n // Parse the callback body for one()/many() calls\n return parseRelationsCallback(sourceTable, callbackArg, sourceFile);\n}\n\n/**\n * Parse the callback function inside relations()\n */\nfunction parseRelationsCallback(\n sourceTable: string,\n callback: ts.ArrowFunction,\n sourceFile: ts.SourceFile,\n): ParsedRelation[] {\n const relations: ParsedRelation[] = [];\n\n // The callback body should be an object literal or parenthesized expression containing object literal\n let body = callback.body;\n\n // Unwrap parenthesized expression: ({ ... })\n if (ts.isParenthesizedExpression(body)) {\n body = body.expression;\n }\n\n if (!ts.isObjectLiteralExpression(body)) {\n return relations;\n }\n\n // Iterate over object properties to find one()/many() calls\n for (const property of body.properties) {\n if (ts.isPropertyAssignment(property) && ts.isCallExpression(property.initializer)) {\n const relation = parseRelationCall(sourceTable, property.initializer, sourceFile);\n if (relation) {\n relations.push(relation);\n }\n }\n }\n\n return relations;\n}\n\n/**\n * Parse a one() or many() call expression\n */\nfunction parseRelationCall(\n sourceTable: string,\n callExpr: ts.CallExpression,\n _sourceFile: ts.SourceFile,\n): ParsedRelation | undefined {\n const funcName = getCallExpressionName(callExpr);\n\n if (funcName !== \"one\" && funcName !== \"many\") {\n return undefined;\n }\n\n // Get target table from first argument\n const targetTableArg = callExpr.arguments[0];\n if (!targetTableArg) {\n return undefined;\n }\n const targetTable = extractIdentifierName(targetTableArg);\n if (!targetTable) {\n return undefined;\n }\n\n // For many(), there might not be a config object (no fields/references)\n // In that case, the relation is only useful if there's a corresponding one() on the other side\n const configArg = callExpr.arguments[1];\n\n let fields: string[] = [];\n let references: string[] = [];\n\n if (configArg && ts.isObjectLiteralExpression(configArg)) {\n // Parse fields and references from config object\n for (const property of configArg.properties) {\n if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name)) {\n const propName = property.name.text;\n\n if (propName === \"fields\" && ts.isArrayLiteralExpression(property.initializer)) {\n fields = extractColumnNames(property.initializer);\n } else if (propName === \"references\" && ts.isArrayLiteralExpression(property.initializer)) {\n references = extractColumnNames(property.initializer);\n }\n }\n }\n }\n\n return {\n sourceTable,\n targetTable,\n type: funcName,\n fields,\n references,\n };\n}\n\n/**\n * Extract column names from an array literal like [posts.authorId, posts.title]\n */\nfunction extractColumnNames(arrayLiteral: ts.ArrayLiteralExpression): string[] {\n const names: string[] = [];\n\n for (const element of arrayLiteral.elements) {\n // Handle property access like: posts.authorId\n if (ts.isPropertyAccessExpression(element)) {\n names.push(element.name.text);\n }\n // Handle identifier (less common)\n else if (ts.isIdentifier(element)) {\n names.push(element.text);\n }\n }\n\n return names;\n}\n\n/**\n * Get the function name from a call expression\n */\nfunction getCallExpressionName(callExpr: ts.CallExpression): string | undefined {\n if (ts.isIdentifier(callExpr.expression)) {\n return callExpr.expression.text;\n }\n if (ts.isPropertyAccessExpression(callExpr.expression)) {\n return callExpr.expression.name.text;\n }\n return undefined;\n}\n\n/**\n * Extract identifier name from an expression\n */\nfunction extractIdentifierName(expr: ts.Expression): string | undefined {\n if (ts.isIdentifier(expr)) {\n return expr.text;\n }\n return undefined;\n}\n"],"names":["getTypeScriptFiles","sourcePath","stat","statSync","files","entries","readdirSync","entry","fullPath","join","extractRelations","result","filePath","sourceCode","readFileSync","sourceFile","ts","visitNode","node","declaration","parsedRelations","parseRelationsDefinition","child","callExpr","getCallExpressionName","sourceTableArg","sourceTable","extractIdentifierName","callbackArg","parseRelationsCallback","callback","relations","body","property","relation","parseRelationCall","_sourceFile","funcName","targetTableArg","targetTable","configArg","fields","references","propName","extractColumnNames","arrayLiteral","names","element","expr"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * CLI runner utility for integration tests
3
+ *
4
+ * Provides functions to execute the CLI and capture output
5
+ */
6
+ export interface CliResult {
7
+ stdout: string;
8
+ stderr: string;
9
+ exitCode: number;
10
+ }
11
+ /**
12
+ * Run the CLI with the given arguments
13
+ *
14
+ * @param args - CLI arguments (e.g., ["generate", "schema.ts", "-d", "postgresql"])
15
+ * @param options - Optional configuration
16
+ * @returns Promise resolving to CLI output and exit code
17
+ */
18
+ export declare function runCli(args: string[], options?: {
19
+ cwd?: string;
20
+ timeout?: number;
21
+ }): Promise<CliResult>;
22
+ /**
23
+ * Run the CLI generate command with common options
24
+ *
25
+ * @param schemaPath - Path to the schema file
26
+ * @param dialect - Database dialect
27
+ * @param options - Additional CLI options
28
+ * @returns Promise resolving to CLI output and exit code
29
+ */
30
+ export declare function runGenerate(schemaPath: string, dialect: "postgresql" | "mysql" | "sqlite", options?: {
31
+ output?: string;
32
+ relational?: boolean;
33
+ cwd?: string;
34
+ }): Promise<CliResult>;
35
+ //# sourceMappingURL=cli-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-runner.d.ts","sourceRoot":"","sources":["../../src/test-utils/cli-runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,OAAO,CAAC,SAAS,CAAC,CA0CpB;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,GAAG,OAAO,GAAG,QAAQ,EAC1C,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACT,GACL,OAAO,CAAC,SAAS,CAAC,CAYpB"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * DBML validation utilities for integration tests
3
+ *
4
+ * Provides functions to validate DBML output structure
5
+ */
6
+ /**
7
+ * Validate that the DBML output contains expected table definitions
8
+ *
9
+ * @param dbml - DBML output string
10
+ * @param tableNames - Expected table names
11
+ * @param quoteChar - Quote character used for identifiers (" for PG/SQLite, ` for MySQL)
12
+ * @returns true if all tables are present
13
+ */
14
+ export declare function hasAllTables(dbml: string, tableNames: string[], quoteChar?: '"' | "`"): boolean;
15
+ /**
16
+ * Validate that the DBML output contains expected columns in a table
17
+ *
18
+ * @param dbml - DBML output string
19
+ * @param tableName - Table name to check
20
+ * @param columnNames - Expected column names
21
+ * @param quoteChar - Quote character used for identifiers
22
+ * @returns true if all columns are present
23
+ */
24
+ export declare function hasAllColumns(dbml: string, tableName: string, columnNames: string[], quoteChar?: '"' | "`"): boolean;
25
+ /**
26
+ * Check if DBML contains a reference (foreign key relationship)
27
+ *
28
+ * @param dbml - DBML output string
29
+ * @param fromTable - Source table name
30
+ * @param fromColumn - Source column name
31
+ * @param toTable - Target table name
32
+ * @param toColumn - Target column name
33
+ * @param quoteChar - Quote character used for identifiers
34
+ * @returns true if the reference exists
35
+ */
36
+ export declare function hasReference(dbml: string, fromTable: string, fromColumn: string, toTable: string, toColumn: string, quoteChar?: '"' | "`"): boolean;
37
+ /**
38
+ * Check if DBML contains indexes section for a table
39
+ *
40
+ * @param dbml - DBML output string
41
+ * @param tableName - Table name to check
42
+ * @param quoteChar - Quote character used for identifiers
43
+ * @returns true if indexes section exists
44
+ */
45
+ export declare function hasIndexes(dbml: string, tableName: string, quoteChar?: '"' | "`"): boolean;
46
+ /**
47
+ * Check if DBML contains a Note clause for a table
48
+ *
49
+ * @param dbml - DBML output string
50
+ * @param tableName - Table name to check
51
+ * @param noteText - Expected note text (partial match)
52
+ * @param quoteChar - Quote character used for identifiers
53
+ * @returns true if the note exists
54
+ */
55
+ export declare function hasTableNote(dbml: string, tableName: string, noteText: string, quoteChar?: '"' | "`"): boolean;
56
+ /**
57
+ * Count the number of tables in DBML output
58
+ *
59
+ * @param dbml - DBML output string
60
+ * @returns Number of tables
61
+ */
62
+ export declare function countTables(dbml: string): number;
63
+ /**
64
+ * Count the number of Ref statements in DBML output
65
+ *
66
+ * @param dbml - DBML output string
67
+ * @returns Number of references
68
+ */
69
+ export declare function countRefs(dbml: string): number;
70
+ //# sourceMappingURL=dbml-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dbml-validator.d.ts","sourceRoot":"","sources":["../../src/test-utils/dbml-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAAE,EACpB,SAAS,GAAE,GAAG,GAAG,GAAS,GACzB,OAAO,CAET;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,GAAE,GAAG,GAAG,GAAS,GACzB,OAAO,CAqBT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,GAAG,GAAG,GAAS,GACzB,OAAO,CAOT;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,GAAG,GAAG,GAAS,GAAG,OAAO,CAqB/F;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,GAAG,GAAG,GAAS,GACzB,OAAO,CAqBT;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG9C"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Test utilities for integration testing
3
+ */
4
+ export { runCli, runGenerate } from './cli-runner.js';
5
+ export type { CliResult } from './cli-runner.js';
6
+ export { hasAllTables, hasAllColumns, hasReference, hasIndexes, hasTableNote, countTables, countRefs, } from './dbml-validator.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test-utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,SAAS,GACV,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { AnyColumn, Table } from 'drizzle-orm';
2
+ import { SchemaComments } from './parser/comments';
3
+ export type { AnyColumn, Table };
4
+ /**
5
+ * Options for DBML generation
6
+ */
7
+ export interface GenerateOptions<TSchema extends Record<string, unknown>> {
8
+ /** The Drizzle schema object containing tables and optionally relations */
9
+ schema: TSchema;
10
+ /** Output file path. If provided, DBML will be written to this file */
11
+ out?: string;
12
+ /** If true, uses relations() definitions instead of foreign keys for references */
13
+ relational?: boolean;
14
+ /**
15
+ * Path to the source schema file or directory for extracting JSDoc comments and relations.
16
+ * If a directory is provided, all .ts files will be processed recursively.
17
+ * Comments will be extracted and included as DBML Note clauses.
18
+ */
19
+ source?: string;
20
+ /**
21
+ * Pre-extracted comments to use for DBML Note clauses.
22
+ * Alternative to source - use this if you've already extracted comments.
23
+ */
24
+ comments?: SchemaComments;
25
+ }
26
+ /**
27
+ * Supported relation types in DBML
28
+ */
29
+ export type RelationType = "one-to-one" | "one-to-many" | "many-to-one";
30
+ /**
31
+ * Internal representation of a reference/relationship
32
+ */
33
+ export interface GeneratedRef {
34
+ fromTable: string;
35
+ fromColumns: string[];
36
+ toTable: string;
37
+ toColumns: string[];
38
+ type: "<" | ">" | "-";
39
+ onDelete?: string;
40
+ onUpdate?: string;
41
+ }
42
+ /**
43
+ * Column constraint attributes for DBML output
44
+ */
45
+ export interface ColumnAttributes {
46
+ primaryKey?: boolean;
47
+ notNull?: boolean;
48
+ unique?: boolean;
49
+ increment?: boolean;
50
+ default?: string;
51
+ note?: string;
52
+ }
53
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAEjC;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACtE,2EAA2E;IAC3E,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,aAAa,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "drizzle-docs-generator",
3
+ "version": "0.1.0",
4
+ "description": "A CLI tool that generates DBML files from Drizzle ORM schema definitions.",
5
+ "keywords": [
6
+ "cli",
7
+ "database",
8
+ "dbml",
9
+ "documentation",
10
+ "drizzle",
11
+ "drizzle-orm",
12
+ "schema",
13
+ "typescript"
14
+ ],
15
+ "homepage": "https://github.com/rikeda71/drizzle-docs-generator#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/rikeda71/drizzle-docs-generator/issues"
18
+ },
19
+ "license": "MIT",
20
+ "author": "rikeda71",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/rikeda71/drizzle-docs-generator.git"
24
+ },
25
+ "bin": {
26
+ "drizzle-docs": "dist/cli/index.js"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "LICENSE",
31
+ "README.md"
32
+ ],
33
+ "type": "module",
34
+ "main": "dist/index.js",
35
+ "types": "dist/index.d.ts",
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "dependencies": {
40
+ "commander": "^14.0.2",
41
+ "drizzle-orm": "1.0.0-beta.10-42c284e"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^24.10.7",
45
+ "oxfmt": "^0.23.0",
46
+ "oxlint": "^1.38.0",
47
+ "typescript": "^5.9.3",
48
+ "vite": "^7.3.1",
49
+ "vite-plugin-dts": "^4.5.4",
50
+ "vitest": "^4.0.16"
51
+ },
52
+ "peerDependencies": {
53
+ "drizzle-orm": ">=0.44.0 || >=1.0.0-beta.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=24"
57
+ },
58
+ "scripts": {
59
+ "build": "vite build",
60
+ "dev": "vite build --watch",
61
+ "test": "vitest",
62
+ "test:run": "vitest run",
63
+ "test:integration": "vitest run --config vitest.integration.config.ts",
64
+ "lint": "oxlint",
65
+ "format": "oxfmt --write",
66
+ "format:check": "oxfmt --check",
67
+ "typecheck": "tsc --noEmit"
68
+ }
69
+ }