diff --git a/bearer.yml b/bearer.yml index ed6de0124..3b7e95509 100644 --- a/bearer.yml +++ b/bearer.yml @@ -31,4 +31,5 @@ scan: - packages/dbml-cli/__tests__/** - packages/dbml-cli/jestHelpers.ts - packages/dbml-core/__tests__/** - - packages/dbml-parser/__tests__/** \ No newline at end of file + - packages/dbml-parser/__tests__/** + - dbml-homepage/docs/** \ No newline at end of file diff --git a/dbml-homepage/configs/sidebars.ts b/dbml-homepage/configs/sidebars.ts index c0b333dc6..91ac958a8 100644 --- a/dbml-homepage/configs/sidebars.ts +++ b/dbml-homepage/configs/sidebars.ts @@ -12,7 +12,29 @@ import { SidebarsConfig } from '@docusaurus/plugin-content-docs'; Create as many sidebars as you want. */ const SidebarConfigs: SidebarsConfig = { - docs: ['home', 'docs', 'cli', 'js-module'], + docs: [ + 'home', + 'docs', + 'cli', + { + type: 'category', + label: 'JS Module', + collapsed: false, + collapsible: true, + items: [ + { + id: 'js-module/core', + type: 'doc', + label: '@dbml/core', + }, + { + id: 'js-module/connector', + type: 'doc', + label: '@dbml/connector', + }, + ], + }, + ], }; export default SidebarConfigs; diff --git a/dbml-homepage/docs/cli.md b/dbml-homepage/docs/cli.md index 83d48b0db..431521b31 100644 --- a/dbml-homepage/docs/cli.md +++ b/dbml-homepage/docs/cli.md @@ -18,11 +18,8 @@ Before you begin, ensure you have met the following requirements: ## Installation -```bash +```bash npm2yarn npm install -g @dbml/cli - -# or if you're using yarn -yarn global add @dbml/cli ``` ## Convert a DBML file to SQL diff --git a/dbml-homepage/docs/docs.md b/dbml-homepage/docs/docs.md index 2f3888240..6aabf6875 100644 --- a/dbml-homepage/docs/docs.md +++ b/dbml-homepage/docs/docs.md @@ -39,18 +39,18 @@ outlines the full syntax documentations of DBML. ```text Table users { - id integer - username varchar - role varchar - created_at timestamp + id integer + username varchar + role varchar + created_at timestamp } Table posts { - id integer [primary key] - title varchar - body text [note: 'Content of the post'] - user_id integer - created_at timestamp + id integer [primary key] + title varchar + body text [note: 'Content of the post'] + user_id integer + created_at timestamp } Ref: posts.user_id > users.id // many-to-one @@ -62,8 +62,8 @@ You can give overall description of the project. ```text Project project_name { - database_type: 'PostgreSQL' - Note: 'Description of the project' + database_type: 'PostgreSQL' + Note: 'Description of the project' } ``` @@ -75,7 +75,7 @@ For example, the following code will define a new schema `core` along with a tab ```text Table core.user { - ... + ... } ``` @@ -88,12 +88,12 @@ By default, any **table**, **relationship**, or **enum** definition that omits ` ```text // table belonged to default "public" schema Table table_name { - column_name column_type [column_settings] + column_name column_type [column_settings] } // table belonged to a schema Table schema_name.table_name { - column_name column_type [column_settings] + column_name column_type [column_settings] } ``` @@ -113,7 +113,7 @@ You can alias the table, and use them in the references later on. ```text Table very_long_user_table as U { - ... + ... } Ref: U.id < posts.user_id @@ -125,10 +125,10 @@ You can add notes to the table, and refer to them in the visual plane. ```text Table users { - id integer - status varchar [note: 'status'] + id integer + status varchar [note: 'status'] - Note: 'Stores user data' + Note: 'Stores user data' } ``` @@ -144,8 +144,8 @@ Example, ```text Table users [headercolor: #3498DB] { - id integer [primary key] - username varchar(255) [not null, unique] + id integer [primary key] + username varchar(255) [not null, unique] } ``` @@ -157,9 +157,9 @@ Each column can take have optional settings, defined in square brackets like: ```text Table buildings { - ... - address varchar(255) [unique, not null, note: 'to include unit number'] - id integer [ pk, unique, default: 123, note: 'Number' ] + ... + address varchar(255) [unique, not null, note: 'to include unit number'] + id integer [ pk, unique, default: 123, note: 'Number' ] } ``` @@ -187,13 +187,13 @@ Example, ```text Table users { - id integer [primary key] - username varchar(255) [not null, unique] - full_name varchar(255) [not null] - gender varchar(1) [not null] - source varchar(255) [default: 'direct'] - created_at timestamp [default: `now()`] - rating integer [default: 10] + id integer [primary key] + username varchar(255) [not null, unique] + full_name varchar(255) [not null] + gender varchar(1) [not null] + source varchar(255) [default: 'direct'] + created_at timestamp [default: `now()`] + rating integer [default: 10] } ``` @@ -203,21 +203,21 @@ Indexes allow users to quickly locate and access the data. Users can define sing ```text Table bookings { - id integer - country varchar - booking_date date - created_at timestamp - - indexes { - (id, country) [pk] // composite primary key - created_at [name: 'created_at_index', note: 'Date'] - booking_date - (country, booking_date) [unique] - booking_date [type: hash] - (`id*2`) - (`id*3`,`getdate()`) - (`id*3`,id) - } + id integer + country varchar + booking_date date + created_at timestamp + + indexes { + (id, country) [pk] // composite primary key + created_at [name: 'created_at_index', note: 'Date'] + booking_date + (country, booking_date) [unique] + booking_date [type: hash] + (`id*2`) + (`id*3`,`getdate()`) + (`id*3`,id) + } } ``` @@ -241,13 +241,13 @@ Relationships are used to define foreign key constraints between tables across s ```text Table posts { - id integer [primary key] - user_id integer [ref: > users.id] // many-to-one + id integer [primary key] + user_id integer [ref: > users.id] // many-to-one } // or this Table users { - id integer [ref: < posts.user_id, ref: < reviews.user_id] // one to many + id integer [ref: < posts.user_id, ref: < reviews.user_id] // one to many } // The space after '<' is optional @@ -263,18 +263,18 @@ There are 4 types of relationships: one-to-one, one-to-many, many-to-one and man In DBML, there are 3 syntaxes to define relationships: ```text -//Long form +// Long form Ref name_optional { - schema1.table1.column1 < schema2.table2.column2 + schema1.table1.column1 < schema2.table2.column2 } -//Short form: +// Short form: Ref name_optional: schema1.table1.column1 < schema2.table2.column2 // Inline form Table schema2.table2 { - id integer - column2 integer [ref: > schema1.table1.column1] + id integer + column2 integer [ref: > schema1.table1.column1] } ``` @@ -290,12 +290,12 @@ Ref: merchant_periods.(merchant_id, country_code) > merchants.(id, country_code) ```text Table core.users { - id integer [pk] + id integer [pk] } Table blogging.posts { - id integer [pk] - user_id integer [ref: > core.users.id] + id integer [pk] + user_id integer [ref: > core.users.id] } // or this @@ -331,21 +331,21 @@ When hovering over the column in the canvas, the enum values will be displayed. ```text // enum belonged to default "public" schema enum job_status { - created [note: 'Waiting to be processed'] - running - done - failure + created [note: 'Waiting to be processed'] + running + done + failure } // enum belonged to a schema enum v2.job_status { - ... + ... } Table jobs { - id integer - status job_status - status_v2 v2.job_status + id integer + status job_status + status_v2 v2.job_status } ``` @@ -355,10 +355,10 @@ If your enum values contain spaces or other special characters you can use doubl ```text enum grade { - "A+" - "A" - "A-" - "Not Yet Set" + "A+" + "A" + "A-" + "Not Yet Set" } ``` @@ -368,14 +368,14 @@ Note allows users to give description for a particular DBML element. ```text Table users { - id int [pk] - name varchar + id int [pk] + name varchar - Note: 'This is a note of this table' - // or - Note { - 'This is a note of this table' - } + Note: 'This is a note of this table' + // or + Note { + 'This is a note of this table' + } } ``` @@ -385,16 +385,16 @@ Note's value is a string. If your note spans over multiple lines, you can use [m ```text Project DBML { - Note: ''' - # DBML - Database Markup Language - DBML (database markup language) is a simple, readable DSL language designed to define database structures. + Note: ''' + # DBML - Database Markup Language + DBML (database markup language) is a simple, readable DSL language designed to define database structures. - ## Benefits + ## Benefits - * It is simple, flexible and highly human-readable - * It is database agnostic, focusing on the essential database structure definition without worrying about the detailed syntaxes of each database - * Comes with a free, simple database visualiser at [dbdiagram.io](http://dbdiagram.io) - ''' + * It is simple, flexible and highly human-readable + * It is database agnostic, focusing on the essential database structure definition without worrying about the detailed syntaxes of each database + * Comes with a free, simple database visualiser at [dbdiagram.io](http://dbdiagram.io) + ''' } ``` @@ -402,10 +402,10 @@ Project DBML { ```text Table users { - id int [pk] - name varchar + id int [pk] + name varchar - Note: 'Stores user data' + Note: 'Stores user data' } ``` @@ -421,13 +421,13 @@ Example, ```text Table orders { - status varchar [ - note: ''' - 💸 1 = processing, - ✔️ 2 = shipped, - ❌ 3 = cancelled, - 😔 4 = refunded - '''] + status varchar [ + note: ''' + 💸 1 = processing, + ✔️ 2 = shipped, + ❌ 3 = cancelled, + 😔 4 = refunded + '''] } ``` @@ -435,11 +435,11 @@ Table orders { ```text TableGroup e-commerce [note: 'Contains tables that are related to e-commerce system'] { - merchants - countries + merchants + countries - // or - Note: 'Contains tables that are related to e-commerce system' + // or + Note: 'Contains tables that are related to e-commerce system' } ``` @@ -451,17 +451,17 @@ Example, ```text Table jobs { - ... + ... } Note single_line_note { - 'This is a single line note' + 'This is a single line note' } Note multiple_lines_note { ''' - This is a multiple lines note - This string can spans over multiple lines. + This is a multiple lines note + This string can spans over multiple lines. ''' } ``` @@ -472,15 +472,15 @@ Note multiple_lines_note { ```text TableGroup tablegroup_name { // tablegroup is case-insensitive. - table1 - table2 - table3 + table1 + table2 + table3 } -//example +// example TableGroup e-commerce1 { - merchants - countries + merchants + countries } ``` @@ -490,11 +490,11 @@ Table groupings can be annotated with notes that describe their meaning and purp ```text TableGroup e-commerce [note: 'Contains tables that are related to e-commerce system'] { - merchants - countries + merchants + countries - // or - Note: 'Contains tables that are related to e-commerce system' + // or + Note: 'Contains tables that are related to e-commerce system' } ``` @@ -504,8 +504,8 @@ Multiline string will be defined between triple single quote `'''` ```text Note: ''' - This is a block string - This string can spans over multiple lines. + This is a block string + This string can spans over multiple lines. ''' ``` @@ -517,8 +517,8 @@ Note: ''' - The number of spaces you use to indent a block string will be the minimum number of leading spaces among all lines. The parser will automatically remove the number of indentation spaces in the final output. The result of the above example will be: ```text - This is a block string - This string can spans over multiple lines. + This is a block string + This string can spans over multiple lines. ``` ## Comments @@ -541,9 +541,9 @@ Example, ```text /* - This is a - Multi-lines - comment + This is a + Multi-lines + comment */ ``` diff --git a/dbml-homepage/docs/home.md b/dbml-homepage/docs/home.md index 9b7939a3c..876726e1d 100644 --- a/dbml-homepage/docs/home.md +++ b/dbml-homepage/docs/home.md @@ -92,7 +92,7 @@ DBML comes with: 1. A free database visualiser at [dbdiagram.io](https://dbdiagram.io) 2. A free database documentation builder at [dbdocs.io](https://dbdocs.io) 3. A command-line tool to help to convert SQL to DBML files and vice versa. -4. An [open-source JS library](/js-module) (NPM package) for you to programmatically convert between DBML and SQL DDL. +4. An [open-source JS library](/js-module/core) (NPM package) for you to programmatically convert between DBML and SQL DDL. ### dbdiagram diff --git a/dbml-homepage/docs/js-module/connector.md b/dbml-homepage/docs/js-module/connector.md new file mode 100644 index 000000000..03419e4e9 --- /dev/null +++ b/dbml-homepage/docs/js-module/connector.md @@ -0,0 +1,56 @@ +--- +title: '@dbml/connector' +--- + +[![NPM](https://img.shields.io/npm/v/@dbml/connector)](https://www.npmjs.com/package/@dbml/connector) + +This package is responsible for connecting to a database on your local environment and fetch its schema information. + +## Supported Databases + +- PostgreSQL +- MySQL +- MSSQL + +## Prerequisites + +- **Nodejs** version 18.0.0 or higher. + +## Installation + +```bash npm2yarn +npm install @dbml/connector +``` + +## APIs + +### connector + +```javascript +const { connector } = require('@dbml/connector'); +``` + +#### `connector.fetchSchemaJson(connection, format)` + +- **Arguments:** + - `{string} connection` + - `{'postgres'|'mssql'|'mysql'} format` + +- **Returns:** + - `{DatabaseSchema} schemaJson` + +- **Usage:** +Generate `DatabaseSchema` object directly from a database. + +```javascript +const { connector } = require('@dbml/connector'); + +const connection = 'postgresql://dbml_user:dbml_pass@localhost:5432/schema'; +const format = 'postgres'; + +const schemaJson = await connector.fetchSchemaJson(connection, format); +``` + +:::info +The type definition of `DatabaseSchema` object can be found [here](https://github.com/holistics/dbml/blob/a4dcb110f1d79f5d95b0d3db4b919914439e039d/packages/dbml-connector/src/connectors/types.ts#L89). +::: diff --git a/dbml-homepage/docs/js-module.md b/dbml-homepage/docs/js-module/core.md similarity index 62% rename from dbml-homepage/docs/js-module.md rename to dbml-homepage/docs/js-module/core.md index 1f05f219a..1ef8077e5 100644 --- a/dbml-homepage/docs/js-module.md +++ b/dbml-homepage/docs/js-module/core.md @@ -1,42 +1,31 @@ --- -title: JS Module +title: '@dbml/core' --- -# JS Module - -## Prerequisites - -Before you begin, ensure you have met the following requirements: - -- **Node.js**: From `@dbml/core@3.7.1`, you need to have Node.js version 18.0.0 or higher installed. - -## core - [![NPM](https://img.shields.io/npm/v/@dbml/core)](https://www.npmjs.com/package/@dbml/core) -A core package that is responsible for parsing and converting between different formats +This is a core package that is responsible for parsing and converting between different formats: * Parse DBML and SQL to `Database` object * Export SQL and DBML from `Database` object * Convert DBML to SQL and SQL to DBML +* Generate DBML from `DatabaseSchema` object -### Installation +## Installation -```bash +```bash npm2yarn npm install @dbml/core -# or -yarn add @dbml/core ``` -### API +## APIs -#### importer +### importer ```javascript const { importer } = require('@dbml/core'); ``` -##### importer.import( str, format ) +#### `importer.import(str, format)` * **Arguments:** * ```{string} str``` @@ -48,7 +37,9 @@ const { importer } = require('@dbml/core'); * **Usage:** Generate DBML from SQL. -Note: The `postgresLegacy` and `mysqlLegacy` options import PostgreSQL/MySQL to dbml using the old parsers. It's quicker but less accurate. +:::note +The `postgresLegacy` and `mysqlLegacy` options import PostgreSQL/MySQL to dbml using the old parsers. It's quicker but less accurate. +::: ```javascript const fs = require('fs'); @@ -59,40 +50,42 @@ const postgreSQL = fs.readFileSync('./schema.sql', 'utf-8'); // generate DBML from PostgreSQL script const dbml = importer.import(postgreSQL, 'postgres'); - ``` -##### importer.generateDbml( connection, format ) +#### `importer.generateDbml(schemaJson)` * **Arguments:** - * ```{string} connection``` - * ```{'postgres'|'mssql'|'mysql'} format``` + * ```{DatabaseSchema} schemaJson``` * **Returns:** - * ```{Promise} DBML``` + * ```{string} DBML``` * **Usage:** -Generate DBML from your database. +Generate DBML from a `DatabaseSchema` object. + +The following example use the [@dbml/connector](./connector.md) to get the `DatabaseSchema` object. ```javascript const { importer } = require('@dbml/core'); +const { connector } = require('@dbml/connector'); -// Your database connection string +// Use the dbml connector to get the DatabaseSchema object const connection = 'postgresql://dbml_user:dbml_pass@localhost:5432/schema'; +const format = 'postgres'; -importer.generateDbml(connection, 'postgres') - .then((dbml) => console.log(dbml)) - .catch((error) => console.log(error)); +const schemaJson = await connector.fetchSchemaJson(connection, format); +// Generate DBML from the DatabaseSchema object +const dbml = importer.generateDbml(schemaJson); ``` -#### exporter +### exporter ```javascript const { exporter } = require('@dbml/core'); ``` -##### exporter.export( str, format ) +#### `exporter.export(str, format)` * **Arguments:** * ```{string} str``` @@ -115,13 +108,15 @@ const dbml = fs.readFileSync('./schema.dbml', 'utf-8'); const mysql = exporter.export(dbml, 'mysql'); ``` -#### Class: Parser +### Parser ```javascript const { Parser } = require('@dbml/core'); + +const parser = new Parser(); ``` -##### Parser.parse( str, format ) +#### `parser.parse(str, format)` * **Arguments:** * ```{string} str``` @@ -132,28 +127,34 @@ const { Parser } = require('@dbml/core'); * **Usage:** Parse specified format to ```Database``` object -Note: The `postgresLegacy` and `mysqlLegacy` options import PostgreSQL/MySQL to dbml using the old parsers. It's quicker but less accurate. +:::note + +* The `postgresLegacy` and `mysqlLegacy` options import PostgreSQL/MySQL to dbml using the old parsers. It's quicker but less accurate. -Note: The `dbmlv2` option parse dbml using the new parser. It's quicker and more robust to errors/more user-friendly error messages. +* The `dbmlv2` option parse dbml using the new parser. It's quicker and more robust to errors/more user-friendly error messages. + +::: ```javascript const fs = require('fs'); const { Parser } = require('@dbml/core'); +const parser = new Parser(); + // get DBML file content const dbml = fs.readFileSync('./schema.dbml', 'utf-8'); // parse DBML to Database object -const database = (new Parser()).parse(dbml, 'dbml'); +const database = parser.parse(dbml, 'dbml'); ``` -#### Class: ModelExporter +### ModelExporter ```javascript const { ModelExporter } = require('@dbml/core'); ``` -##### ModelExporter.export( model, format, isNormalized = true ) +#### `ModelExporter.export(model, format, isNormalized)` * **Arguments:** * ```{model} Database``` @@ -166,13 +167,14 @@ const { ModelExporter } = require('@dbml/core'); Export ```Database``` object to specified format ```javascript -const { ModelExporter } = require('@dbml/core'); +const { ModelExporter, Parser } = require('@dbml/core'); // get DBML file content const dbml = fs.readFileSync('./schema.dbml', 'utf-8'); // parse DBML to Database object -const database = (new Parser()).parse(dbml, 'dbml'); +const parser = new Parser(); +const database = parser.parse(dbml, 'dbml'); // Export Database object to PostgreSQL const postgreSQL = ModelExporter.export(database, 'postgres', false); diff --git a/dbml-homepage/docusaurus.config.ts b/dbml-homepage/docusaurus.config.ts index 6679dca23..46c5b46f1 100644 --- a/dbml-homepage/docusaurus.config.ts +++ b/dbml-homepage/docusaurus.config.ts @@ -1,4 +1,5 @@ import type * as Preset from '@docusaurus/preset-classic'; +import npm2yarn from '@docusaurus/remark-plugin-npm2yarn'; import type { Config } from '@docusaurus/types'; import { themes as prismThemes } from 'prism-react-renderer'; import NavbarConfigs from './configs/navbar'; @@ -28,8 +29,11 @@ const config: Config = { { docs: { sidebarPath: './configs/sidebars.ts', - breadcrumbs: false, + breadcrumbs: true, routeBasePath: '/', + remarkPlugins: [ + [npm2yarn, { sync: true }] + ], }, blog: false, theme: { @@ -50,7 +54,11 @@ const config: Config = { // prefer system preferences respectPrefersColorScheme: true, }, - + // https://docusaurus.io/docs/markdown-features/toc#table-of-contents-heading-level + tableOfContents: { + minHeadingLevel: 2, + maxHeadingLevel: 5, + }, } satisfies Preset.ThemeConfig, plugins: [ 'docusaurus-plugin-sass', diff --git a/dbml-homepage/package.json b/dbml-homepage/package.json index 4c9145d48..4197aaa3d 100644 --- a/dbml-homepage/package.json +++ b/dbml-homepage/package.json @@ -18,6 +18,7 @@ "@docusaurus/core": "^3.3.2", "@docusaurus/plugin-google-gtag": "^3.3.2", "@docusaurus/preset-classic": "^3.3.2", + "@docusaurus/remark-plugin-npm2yarn": "^3.5.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "docusaurus-lunr-search": "^3.3.2", diff --git a/dbml-homepage/yarn.lock b/dbml-homepage/yarn.lock index e6d447279..090c382a7 100644 --- a/dbml-homepage/yarn.lock +++ b/dbml-homepage/yarn.lock @@ -1800,6 +1800,17 @@ "@docusaurus/theme-search-algolia" "3.3.2" "@docusaurus/types" "3.3.2" +"@docusaurus/remark-plugin-npm2yarn@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@docusaurus/remark-plugin-npm2yarn/-/remark-plugin-npm2yarn-3.5.2.tgz#892a63a9b53475d7c59957bd67277656dcd91079" + integrity sha512-EAD7R/skPuhW3lWZyDhRuFs3m2EGaR008tuoe6SrFre7PifoxmSCwXk8Nb4VtVRKnnbn4IgHyqq+ma47gGmKwg== + dependencies: + mdast-util-mdx "^3.0.0" + npm-to-yarn "^2.2.1" + tslib "^2.6.0" + unified "^11.0.3" + unist-util-visit "^5.0.0" + "@docusaurus/theme-classic@3.3.2": version "3.3.2" resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.3.2.tgz#44489580e034a6f5b877ec8bfd1203e226b4a4ab" @@ -6640,6 +6651,11 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-to-yarn@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/npm-to-yarn/-/npm-to-yarn-2.2.1.tgz#048843a6630621daffc6a239dfc89698b8abf7e8" + integrity sha512-O/j/ROyX0KGLG7O6Ieut/seQ0oiTpHF2tXAcFbpdTLQFiaNtkyTXXocM1fwpaa60dg1qpWj0nHlbNhx6qwuENQ== + nprogress@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1"