dbdocs 0.12.2 → 0.13.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.
package/README.md CHANGED
@@ -36,6 +36,7 @@ USAGE
36
36
  * [`dbdocs password`](#dbdocs-password)
37
37
  * [`dbdocs remove [PROJECT_NAME]`](#dbdocs-remove-project_name)
38
38
  * [`dbdocs rename`](#dbdocs-rename)
39
+ * [`dbdocs set`](#dbdocs-set)
39
40
  * [`dbdocs token`](#dbdocs-token)
40
41
  * [`dbdocs validate [FILEPATH]`](#dbdocs-validate-filepath)
41
42
 
@@ -184,6 +185,25 @@ DESCRIPTION
184
185
  change your username and your default organization name
185
186
  ```
186
187
 
188
+ ## `dbdocs set`
189
+
190
+ Set the Web URL and API URL of dbdocs self-hosted server
191
+
192
+ ```bash
193
+ USAGE
194
+ $ dbdocs set --webUrl <value> --apiUrl <value>
195
+
196
+ FLAGS
197
+ --apiUrl=<value> (required) Self-hosted api url
198
+ --webUrl=<value> (required) Self-hosted web url
199
+
200
+ DESCRIPTION
201
+ Set the Web URL and API URL of dbdocs self-hosted server
202
+
203
+ EXAMPLES
204
+ $ dbdocs set --webUrl http://webserver.dev --apiUrl http://apiserver.dev
205
+ ```
206
+
187
207
  ## `dbdocs token`
188
208
 
189
209
  generate or revoke your authentication token
@@ -1 +1 @@
1
- {"version":"0.12.2","commands":{"build":{"id":"build","description":"build docs","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{"project":{"name":"project","type":"option","description":"project name","multiple":false},"public":{"name":"public","type":"boolean","description":"anyone with the URL can access","helpGroup":"sharing","allowNo":false,"exclusive":["private","password"]},"private":{"name":"private","type":"boolean","description":"only invited people can access","helpGroup":"sharing","allowNo":false,"exclusive":["public","password"]},"password":{"name":"password","type":"option","char":"p","description":"anyone with the URL + password can access","helpGroup":"sharing","multiple":false,"exclusive":["public","private"]}},"args":[{"name":"filepath","description":"dbml file path"}]},"db2dbml":{"id":"db2dbml","description":"Generate DBML directly from a database","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"examples":"Postgres:\n $ db2dbml postgres 'postgresql://user:password@localhost:5432/dbname?schemas=schema1,schema2'\nMySQL:\n $ db2dbml mysql 'mysql://user:password@localhost:3306/dbname'\nMSSQL:\n $ db2dbml mssql 'Server=localhost,1433;Database=master;User Id=sa;Password=your_password;Encrypt=true;TrustServerCertificate=true;Schemas=schema1,schema2;'\nSnowflake:\n $ db2dbml snowflake 'SERVER=<account_identifier>.<region>;UID=<your_username>;PWD=<your_password>;DATABASE=<your_database>;WAREHOUSE=<your_warehouse>;ROLE=<your_role>;SCHEMAS=schema1,schema2;'\nBigQuery:\n $ db2dbml bigquery /path_to_json_credential.json\n \n Note: Your JSON credential file must contain:\n {\n \"project_id\": \"your-project-id\",\n \"client_email\": \"your-client-email\",\n \"private_key\": \"your-private-key\",\n \"datasets\": [\"dataset_1\", \"dataset_2\", ...]\n }\n If \"datasets\" key is not provided or is empty, it will fetch all datasets.","flags":{"outFile":{"name":"outFile","type":"option","char":"o","description":"output file path","helpValue":"/path-to-your-file","multiple":false}},"args":[{"name":"database-type","description":"your database type (postgres, mysql, mssql, snowflake, bigquery)","required":true},{"name":"connection-string","description":"your database connection string (See below examples for more details)","required":true}]},"login":{"id":"login","description":"login to dbdocs\nlogin with your dbdocs credentials\n","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[]},"logout":{"id":"logout","description":"logout\nclears local login credentials\n","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[]},"ls":{"id":"ls","description":"list projects","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[]},"password":{"id":"password","description":"set password for your project or remove password","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{"project":{"name":"project","type":"option","char":"p","description":"project name","helpValue":"project name","multiple":false},"set":{"name":"set","type":"option","char":"s","description":"password for your project","helpValue":"password","multiple":false},"remove":{"name":"remove","type":"boolean","char":"r","description":"remove password from your project","allowNo":false}},"args":[]},"remove":{"id":"remove","description":"remove project","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"project_name","description":"name of the project which you want to remove"}]},"rename":{"id":"rename","description":"change your username","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[]},"token":{"id":"token","description":"generate or revoke your authentication token","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{"generate":{"name":"generate","type":"boolean","char":"g","description":"generate authentication token","allowNo":false},"revoke":{"name":"revoke","type":"boolean","char":"r","description":"revoke authentication token","allowNo":false}},"args":[]},"validate":{"id":"validate","description":"validate docs content","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"filepath","description":"dbml file path"}]}}}
1
+ {"version":"0.13.0","commands":{"build":{"id":"build","description":"build docs","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{"project":{"name":"project","type":"option","description":"project name","multiple":false},"public":{"name":"public","type":"boolean","description":"anyone with the URL can access","helpGroup":"sharing","allowNo":false,"exclusive":["private","password"]},"private":{"name":"private","type":"boolean","description":"only invited people can access","helpGroup":"sharing","allowNo":false,"exclusive":["public","password"]},"password":{"name":"password","type":"option","char":"p","description":"anyone with the URL + password can access","helpGroup":"sharing","multiple":false,"exclusive":["public","private"]}},"args":[{"name":"filepath","description":"dbml file path"}]},"db2dbml":{"id":"db2dbml","description":"Generate DBML directly from a database","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"examples":"Postgres:\n $ db2dbml postgres 'postgresql://user:password@localhost:5432/dbname?schemas=schema1,schema2'\nMySQL:\n $ db2dbml mysql 'mysql://user:password@localhost:3306/dbname'\nMSSQL:\n $ db2dbml mssql 'Server=localhost,1433;Database=master;User Id=sa;Password=your_password;Encrypt=true;TrustServerCertificate=true;Schemas=schema1,schema2;'\nSnowflake:\n $ db2dbml snowflake 'SERVER=<account_identifier>.<region>;UID=<your_username>;PWD=<your_password>;DATABASE=<your_database>;WAREHOUSE=<your_warehouse>;ROLE=<your_role>;SCHEMAS=schema1,schema2;'\nBigQuery:\n $ db2dbml bigquery /path_to_json_credential.json\n \n Note: Your JSON credential file must contain:\n {\n \"project_id\": \"your-project-id\",\n \"client_email\": \"your-client-email\",\n \"private_key\": \"your-private-key\",\n \"datasets\": [\"dataset_1\", \"dataset_2\", ...]\n }\n If \"datasets\" key is not provided or is empty, it will fetch all datasets.","flags":{"outFile":{"name":"outFile","type":"option","char":"o","description":"output file path","helpValue":"/path-to-your-file","multiple":false}},"args":[{"name":"database-type","description":"your database type (postgres, mysql, mssql, snowflake, bigquery)","required":true},{"name":"connection-string","description":"your database connection string (See below examples for more details)","required":true}]},"login":{"id":"login","description":"login to dbdocs\nlogin with your dbdocs credentials\n","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[]},"logout":{"id":"logout","description":"logout\nclears local login credentials\n","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[]},"ls":{"id":"ls","description":"list projects","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[]},"password":{"id":"password","description":"set password for your project or remove password","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{"project":{"name":"project","type":"option","char":"p","description":"project name","helpValue":"project name","multiple":false},"set":{"name":"set","type":"option","char":"s","description":"password for your project","helpValue":"password","multiple":false},"remove":{"name":"remove","type":"boolean","char":"r","description":"remove password from your project","allowNo":false}},"args":[]},"remove":{"id":"remove","description":"remove project","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"project_name","description":"name of the project which you want to remove"}]},"rename":{"id":"rename","description":"change your username","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[]},"set":{"id":"set","description":"Set the Web URL and API URL of dbdocs self-hosted server","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"examples":"$ dbdocs set --webUrl http://webserver.dev --apiUrl http://apiserver.dev","flags":{"webUrl":{"name":"webUrl","type":"option","description":"Self-hosted web url","required":true,"multiple":false},"apiUrl":{"name":"apiUrl","type":"option","description":"Self-hosted api url","required":true,"multiple":false}},"args":[]},"token":{"id":"token","description":"generate or revoke your authentication token","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{"generate":{"name":"generate","type":"boolean","char":"g","description":"generate authentication token","allowNo":false},"revoke":{"name":"revoke","type":"boolean","char":"r","description":"revoke authentication token","allowNo":false}},"args":[]},"validate":{"id":"validate","description":"validate docs content","strict":true,"pluginName":"dbdocs","pluginAlias":"dbdocs","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"filepath","description":"dbml file path"}]}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbdocs",
3
- "version": "0.12.2",
3
+ "version": "0.13.0",
4
4
  "author": "@holistics",
5
5
  "bin": {
6
6
  "dbdocs": "./bin/run"
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@dbml/connector": "3.8.1",
13
- "@dbml/core": "3.8.1",
13
+ "@dbml/core": "3.9.0",
14
14
  "@oclif/core": "1.12.1",
15
15
  "@oclif/plugin-help": "5.1.12",
16
16
  "axios": "^1.7.4",
@@ -120,6 +120,7 @@ class BuildCommand extends Command {
120
120
  if (err.response) {
121
121
  const { error } = err.response.data;
122
122
  if (error.name === 'SyntaxError') {
123
+ // eslint-disable-next-line max-len
123
124
  message = `You have syntax error(s) in ${path.basename(filepath)} line ${error.location.start.line} column ${error.location.start.column}. ${error.message}`;
124
125
  } else if (error.name === 'AccessDenied') {
125
126
  message = error.message;
@@ -0,0 +1,80 @@
1
+ const { Command, Flags } = require('@oclif/core');
2
+ const ora = require('ora');
3
+ const netrc = require('netrc-parser').default;
4
+ const { HOST_CONFIG_STATUS } = require('../utils/constants');
5
+ const { tryParseHttpUrl } = require('../validators/url');
6
+
7
+ class SetCommand extends Command {
8
+ async run () {
9
+ const spinner = ora({});
10
+ try {
11
+ const { flags } = await this.parse(SetCommand);
12
+
13
+ const { webUrl, apiUrl } = flags;
14
+
15
+ const parseAPIUrlResult = tryParseHttpUrl(apiUrl);
16
+ if (!parseAPIUrlResult.isSuccess) {
17
+ spinner.fail(`API URL parse error: ${parseAPIUrlResult.data}`);
18
+ return;
19
+ }
20
+
21
+ const parseWebUrlResult = tryParseHttpUrl(webUrl);
22
+ if (!parseWebUrlResult.isSuccess) {
23
+ spinner.fail(`Web URL parse error: ${parseWebUrlResult.data}`);
24
+ return;
25
+ }
26
+
27
+ // load netrc config
28
+ await netrc.load();
29
+
30
+ spinner.text = 'Saving your configurations';
31
+ spinner.start();
32
+
33
+ // make all hosts are inactive
34
+ Object.keys(netrc.machines).forEach((host) => {
35
+ if (netrc.machines[host].webUrl) {
36
+ netrc.machines[host].status = HOST_CONFIG_STATUS.inactive;
37
+ }
38
+ });
39
+
40
+ const parsedAPIUrl = parseAPIUrlResult.data;
41
+ const parsedWebUrl = parseWebUrlResult.data;
42
+
43
+ if (!netrc.machines[parsedAPIUrl]) {
44
+ netrc.machines[parsedAPIUrl] = {};
45
+ }
46
+
47
+ netrc.machines[parsedAPIUrl].webUrl = parsedWebUrl;
48
+ netrc.machines[parsedAPIUrl].status = HOST_CONFIG_STATUS.active;
49
+
50
+ await netrc.save();
51
+
52
+ spinner.succeed('Your configuration has been saved.');
53
+ } catch (error) {
54
+ if (spinner.isSpinning) {
55
+ spinner.fail();
56
+ }
57
+
58
+ this.error(error.message);
59
+ }
60
+ }
61
+ }
62
+
63
+ SetCommand.description = 'Set the Web URL and API URL of dbdocs self-hosted server';
64
+
65
+ SetCommand.flags = {
66
+ webUrl: Flags.string({
67
+ description: 'Self-hosted web url',
68
+ required: true,
69
+ }),
70
+ apiUrl: Flags.string({
71
+ description: 'Self-hosted api url',
72
+ required: true,
73
+ }),
74
+ };
75
+
76
+ SetCommand.examples = [
77
+ '$ dbdocs set --webUrl http://webserver.dev --apiUrl http://apiserver.dev',
78
+ ].join('\n');
79
+
80
+ module.exports = SetCommand;
@@ -1,3 +1,23 @@
1
+ /* eslint-disable no-restricted-syntax */
2
+ /* eslint-disable guard-for-in */
3
+ const netrc = require('netrc-parser').default;
4
+ const { HOST_CONFIG_STATUS } = require('../../utils/constants');
5
+
6
+ // eslint-disable-next-line func-names
1
7
  module.exports = async function () {
8
+ // eslint-disable-next-line global-require
2
9
  require('dotenv').config();
3
- }
10
+
11
+ // Check netrc config
12
+ await netrc.load();
13
+
14
+ const machines = Object.keys(netrc.machines).map((key) => ({ apiUrl: key, ...netrc.machines[key] }));
15
+
16
+ const matchedMachine = machines.find((machine) => machine.apiUrl && machine.webUrl && machine.status === HOST_CONFIG_STATUS.active);
17
+
18
+ if (!matchedMachine) return;
19
+
20
+ // Override env
21
+ process.env.DBDOCS_HOST = matchedMachine.webUrl;
22
+ process.env.DBDOCS_API_HOST = matchedMachine.apiUrl;
23
+ };
@@ -38,6 +38,11 @@ const WINDOW_FILE_PATH_REGEX = /^[a-zA-Z]:[\\/](?:[^<>:"/\\|?*\n\r]+[\\/])*[^<>:
38
38
  */
39
39
  const UNIX_FILE_PATH_REGEX = /^(\/|\.\/|~\/|\.\.\/)([^<>:"|?*\n\r]*\/?)*[^<>:"|?*\n\r]*$/;
40
40
 
41
+ const HOST_CONFIG_STATUS = {
42
+ active: 'active',
43
+ inactive: 'inactive',
44
+ };
45
+
41
46
  module.exports = {
42
47
  PROJECT_GENERAL_ACCESS_TYPE,
43
48
  PROJECT_SHARING_TEXT,
@@ -46,4 +51,5 @@ module.exports = {
46
51
  SUPPORTED_DATABASE_CONNECTORS,
47
52
  WINDOW_FILE_PATH_REGEX,
48
53
  UNIX_FILE_PATH_REGEX,
54
+ HOST_CONFIG_STATUS,
49
55
  };
@@ -0,0 +1,22 @@
1
+ const { URL } = require('url');
2
+
3
+ function tryParseHttpUrl (url) {
4
+ try {
5
+ const parsedUrl = new URL(url);
6
+
7
+ if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
8
+ return { isSuccess: false, data: 'URL protocol must be HTTP or HTTPS' };
9
+ }
10
+
11
+ // Remove trailing slash from the origin.
12
+ const sanitizedOrigin = parsedUrl.origin.replace(/\/$/, '');
13
+
14
+ return { isSuccess: true, data: sanitizedOrigin };
15
+ } catch (error) {
16
+ return { isSuccess: false, data: 'Invalid URL format' };
17
+ }
18
+ }
19
+
20
+ module.exports = {
21
+ tryParseHttpUrl,
22
+ };