@dbml/connector 5.6.0-alpha.1 → 6.0.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/.babelrc +13 -0
- package/dist/connectors/bigquery/index.js +291 -0
- package/dist/connectors/connector.js +28 -0
- package/dist/connectors/mssql/index.js +486 -0
- package/dist/connectors/mysql/index.js +454 -0
- package/dist/connectors/oracle/constraints.js +112 -0
- package/dist/connectors/oracle/index.js +68 -0
- package/dist/connectors/oracle/indexes.js +65 -0
- package/dist/connectors/oracle/refs.js +67 -0
- package/dist/connectors/oracle/tables.js +280 -0
- package/dist/connectors/oracle/utils.js +27 -0
- package/dist/connectors/postgres/index.js +517 -0
- package/dist/connectors/snowflake/index.js +311 -0
- package/dist/connectors/types.js +2 -0
- package/dist/index.js +38 -3739
- package/dist/utils/credential-loader.js +58 -0
- package/dist/utils/helpers.js +61 -0
- package/dist/utils/parseSchema.js +59 -0
- package/eslint.config.ts +1 -2
- package/jest.config.ts +18 -0
- package/package.json +25 -8
- package/src/connectors/mysql/index.ts +1 -1
- package/dist/index.mjs +0 -10359
- package/vite.config.ts +0 -53
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadCredentialFromFile = loadCredentialFromFile;
|
|
4
|
+
exports.parseBigQueryCredential = parseBigQueryCredential;
|
|
5
|
+
const promises_1 = require("fs/promises");
|
|
6
|
+
async function loadCredentialFromFile(filename) {
|
|
7
|
+
try {
|
|
8
|
+
const data = await (0, promises_1.readFile)(filename, { encoding: 'utf8' });
|
|
9
|
+
return data;
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
if (error.name === 'TypeError' || error.name === 'Error') {
|
|
13
|
+
throw new Error(`Load credential error: ${error.message}`);
|
|
14
|
+
}
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function parseBigQueryCredential(credentialString) {
|
|
19
|
+
try {
|
|
20
|
+
const credentialJson = JSON.parse(credentialString);
|
|
21
|
+
const { project_id: projectId, client_email: clientEmail, private_key: privateKey, datasets, } = credentialJson;
|
|
22
|
+
// valid datasets: ['dataset_1', 'dataset_2']
|
|
23
|
+
const parsedDatasets = !Array.isArray(datasets)
|
|
24
|
+
? []
|
|
25
|
+
: datasets.filter((dataset) => typeof dataset === 'string');
|
|
26
|
+
const parsedCredentials = {
|
|
27
|
+
datasets: parsedDatasets,
|
|
28
|
+
};
|
|
29
|
+
// Validate and add projectId if provided
|
|
30
|
+
if (projectId !== undefined) {
|
|
31
|
+
if (typeof projectId !== 'string' || !projectId || !projectId.trim()) {
|
|
32
|
+
throw new Error('project_id must be a non-empty string when provided');
|
|
33
|
+
}
|
|
34
|
+
parsedCredentials.projectId = projectId;
|
|
35
|
+
}
|
|
36
|
+
// Validate and add credentials if provided
|
|
37
|
+
// Note: If one credential field is provided, both must be provided
|
|
38
|
+
if (clientEmail !== undefined || privateKey !== undefined) {
|
|
39
|
+
if (!clientEmail || typeof clientEmail !== 'string' || !clientEmail.trim()) {
|
|
40
|
+
throw new Error('client_email must be a non-empty string when credentials are provided');
|
|
41
|
+
}
|
|
42
|
+
if (!privateKey || typeof privateKey !== 'string' || !privateKey.trim()) {
|
|
43
|
+
throw new Error('private_key must be a non-empty string when credentials are provided');
|
|
44
|
+
}
|
|
45
|
+
parsedCredentials.credentials = {
|
|
46
|
+
clientEmail,
|
|
47
|
+
privateKey,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return parsedCredentials;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (error instanceof SyntaxError) {
|
|
54
|
+
throw new Error('Credentials must be in JSON format');
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getIntersection = getIntersection;
|
|
4
|
+
exports.getTableSchemaKey = getTableSchemaKey;
|
|
5
|
+
exports.mergeTables = mergeTables;
|
|
6
|
+
exports.mergeFieldDictionary = mergeFieldDictionary;
|
|
7
|
+
exports.mergeIndexDictionary = mergeIndexDictionary;
|
|
8
|
+
exports.mergeTableConstraintDictionary = mergeTableConstraintDictionary;
|
|
9
|
+
exports.mergeCheckConstraintDictionary = mergeCheckConstraintDictionary;
|
|
10
|
+
function getIntersection(firstList, secondList) {
|
|
11
|
+
return firstList.filter((item) => secondList.includes(item));
|
|
12
|
+
}
|
|
13
|
+
function getTableSchemaKey(schemaName, tableName) {
|
|
14
|
+
if (!tableName || !tableName.trim()) {
|
|
15
|
+
throw new Error('Table name must be a non-empty string');
|
|
16
|
+
}
|
|
17
|
+
return schemaName ? `${schemaName}.${tableName}` : `${tableName}`;
|
|
18
|
+
}
|
|
19
|
+
function mergeTables(firstTableList, secondTable) {
|
|
20
|
+
return firstTableList.concat(secondTable);
|
|
21
|
+
}
|
|
22
|
+
function mergeFieldDictionary(firstDict, secondDict) {
|
|
23
|
+
const result = { ...firstDict };
|
|
24
|
+
Object.keys(secondDict).forEach((key) => {
|
|
25
|
+
if (!result[key]) {
|
|
26
|
+
result[key] = [];
|
|
27
|
+
}
|
|
28
|
+
result[key] = result[key].concat(secondDict[key]);
|
|
29
|
+
});
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
function mergeIndexDictionary(firstDict, secondDict) {
|
|
33
|
+
const result = { ...firstDict };
|
|
34
|
+
Object.keys(secondDict).forEach((key) => {
|
|
35
|
+
if (!result[key]) {
|
|
36
|
+
result[key] = [];
|
|
37
|
+
}
|
|
38
|
+
result[key] = result[key].concat(secondDict[key]);
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
function mergeTableConstraintDictionary(firstDict, secondDict) {
|
|
43
|
+
const result = { ...firstDict };
|
|
44
|
+
Object.keys(secondDict).forEach((key) => {
|
|
45
|
+
if (!result[key]) {
|
|
46
|
+
result[key] = {};
|
|
47
|
+
}
|
|
48
|
+
result[key] = secondDict[key];
|
|
49
|
+
});
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
function mergeCheckConstraintDictionary(firstDict, secondDict) {
|
|
53
|
+
const result = { ...firstDict };
|
|
54
|
+
Object.keys(secondDict).forEach((key) => {
|
|
55
|
+
if (!result[key]) {
|
|
56
|
+
result[key] = [];
|
|
57
|
+
}
|
|
58
|
+
result[key] = result[key].concat(secondDict[key]);
|
|
59
|
+
});
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildSchemaQuery = exports.parseConnectionString = exports.parseJdbcSchema = exports.parseSchema = void 0;
|
|
4
|
+
// You cannot use the "=" inside database's schema name. It will be treated as a delimiter.
|
|
5
|
+
const SCHEMAS_DELIMITER = 'schemas=';
|
|
6
|
+
const haveSchemas = (str) => {
|
|
7
|
+
return str.toLowerCase().includes(SCHEMAS_DELIMITER);
|
|
8
|
+
};
|
|
9
|
+
const getSchemasPart = (str) => {
|
|
10
|
+
return str ? str.toLowerCase().split(SCHEMAS_DELIMITER)[1] : '';
|
|
11
|
+
};
|
|
12
|
+
const noSchemaResult = (connectionString) => ({
|
|
13
|
+
connectionString,
|
|
14
|
+
schemas: [],
|
|
15
|
+
});
|
|
16
|
+
// Inputs: schemas string -> Output: schema array string[]
|
|
17
|
+
// schema1, schema2 -> ['schema1', 'schema2']
|
|
18
|
+
// schema3,schema4 -> ['schema3", 'schema4']
|
|
19
|
+
// "schema5,gg", "schema6", schema7 -> ['schema5,gg', 'schema6', 'schema7']
|
|
20
|
+
// schema8 -> ['schema8']
|
|
21
|
+
const parseSchema = (schemas) => {
|
|
22
|
+
if (!schemas)
|
|
23
|
+
return [];
|
|
24
|
+
const schemasWithDoubleQuotes = schemas.split(/,(?=(?:[^"]*(?:"[^"]*")*)*$)/).map((s) => s.trim());
|
|
25
|
+
return schemasWithDoubleQuotes.map((s) => s.replace(/"/g, ''));
|
|
26
|
+
};
|
|
27
|
+
exports.parseSchema = parseSchema;
|
|
28
|
+
const parseOdbcSchema = (connectionString) => {
|
|
29
|
+
const connectionParts = connectionString.split(';');
|
|
30
|
+
const schemasPart = connectionParts.find((part) => haveSchemas(part));
|
|
31
|
+
return {
|
|
32
|
+
connectionString: connectionParts.filter((part) => !haveSchemas(part)).join(';'),
|
|
33
|
+
schemas: (0, exports.parseSchema)(getSchemasPart(schemasPart)),
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const parseJdbcSchema = (connectionString) => {
|
|
37
|
+
const connectionParts = connectionString.split('?');
|
|
38
|
+
const connectionArgs = connectionParts[1].split('&');
|
|
39
|
+
const schemasPart = connectionArgs.find((part) => haveSchemas(part));
|
|
40
|
+
return {
|
|
41
|
+
connectionString: connectionParts[0],
|
|
42
|
+
schemas: (0, exports.parseSchema)(getSchemasPart(schemasPart)),
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
exports.parseJdbcSchema = parseJdbcSchema;
|
|
46
|
+
const parseConnectionString = (connectionString, connectionStringType) => {
|
|
47
|
+
if (!haveSchemas(connectionString))
|
|
48
|
+
return noSchemaResult(connectionString);
|
|
49
|
+
return connectionStringType === 'jdbc'
|
|
50
|
+
? (0, exports.parseJdbcSchema)(connectionString)
|
|
51
|
+
: parseOdbcSchema(connectionString);
|
|
52
|
+
};
|
|
53
|
+
exports.parseConnectionString = parseConnectionString;
|
|
54
|
+
const buildSchemaQuery = (columnName, schemas, prefix = 'AND') => {
|
|
55
|
+
if (schemas.length === 0)
|
|
56
|
+
return '';
|
|
57
|
+
return `${prefix} ${columnName} IN (${schemas.map((schema) => `'${schema}'`).join(', ')})`;
|
|
58
|
+
};
|
|
59
|
+
exports.buildSchemaQuery = buildSchemaQuery;
|
package/eslint.config.ts
CHANGED
|
@@ -19,7 +19,7 @@ export default defineConfig(
|
|
|
19
19
|
'node_modules/*',
|
|
20
20
|
'dist/*',
|
|
21
21
|
'eslint.config.ts',
|
|
22
|
-
'
|
|
22
|
+
'jest.config.ts',
|
|
23
23
|
'**/*.test.ts',
|
|
24
24
|
'__tests__/**/*',
|
|
25
25
|
],
|
|
@@ -32,7 +32,6 @@ export default defineConfig(
|
|
|
32
32
|
sourceType: 'module',
|
|
33
33
|
ecmaVersion: 2020,
|
|
34
34
|
project: './tsconfig.json',
|
|
35
|
-
tsconfigRootDir: import.meta.dirname,
|
|
36
35
|
},
|
|
37
36
|
},
|
|
38
37
|
plugins: {
|
package/jest.config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Config } from 'jest';
|
|
2
|
+
|
|
3
|
+
const config: Config = {
|
|
4
|
+
testMatch: ["**/?(*.)+(spec|test).?([mc])[jt]s?(x)"],
|
|
5
|
+
preset: 'ts-jest',
|
|
6
|
+
testEnvironment: 'node',
|
|
7
|
+
transform: {
|
|
8
|
+
'^.+\\.[tj]sx?$': 'babel-jest',
|
|
9
|
+
},
|
|
10
|
+
moduleNameMapper: {
|
|
11
|
+
'\\.(css|less|scss)$': 'identity-obj-proxy',
|
|
12
|
+
},
|
|
13
|
+
collectCoverage: true,
|
|
14
|
+
coverageReporters: ['json', 'json-summary', 'html', 'text'],
|
|
15
|
+
coverageDirectory: 'coverage',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default config;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@dbml/connector",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "6.0.0",
|
|
5
5
|
"description": "This package was created to fetch the schema JSON from many kind of databases.",
|
|
6
6
|
"author": "huy.phung.sw@gmail.com",
|
|
7
7
|
"license": "MIT",
|
|
@@ -10,25 +10,42 @@
|
|
|
10
10
|
"main": "dist/index.js",
|
|
11
11
|
"types": "dist/index.d.ts",
|
|
12
12
|
"devDependencies": {
|
|
13
|
+
"@babel/core": "^7.21.4",
|
|
14
|
+
"@babel/node": "^7.20.7",
|
|
15
|
+
"@babel/plugin-transform-runtime": "^7.21.4",
|
|
16
|
+
"@babel/preset-env": "^7.21.4",
|
|
17
|
+
"@babel/preset-typescript": "^7.24.7",
|
|
18
|
+
"@babel/runtime": "^7.21.0",
|
|
19
|
+
"@stylistic/eslint-plugin": "^5.5.0",
|
|
20
|
+
"@types/jest": "^29.5.12",
|
|
13
21
|
"@types/lodash": "^4.17.16",
|
|
14
22
|
"@types/mssql": "^9.1.5",
|
|
15
23
|
"@types/node": "^22.2.0",
|
|
16
24
|
"@types/oracledb": "^6.10.0",
|
|
17
25
|
"@types/pg": "^8.11.6",
|
|
18
|
-
"
|
|
26
|
+
"@typescript-eslint/eslint-plugin": "^8.46.3",
|
|
27
|
+
"@typescript-eslint/parser": "^8.46.3",
|
|
28
|
+
"babel-jest": "^29.5.0",
|
|
29
|
+
"eslint": "^9.39.1",
|
|
30
|
+
"jest": "^29.7.0",
|
|
31
|
+
"ts-jest": "^29.2.4",
|
|
32
|
+
"ts-node": "^10.9.2",
|
|
33
|
+
"typescript": "^5.9.3",
|
|
34
|
+
"typescript-eslint": "^8.46.3"
|
|
19
35
|
},
|
|
20
36
|
"scripts": {
|
|
21
|
-
"build": "
|
|
22
|
-
"dev": "vite build --watch",
|
|
37
|
+
"build": "tsc",
|
|
23
38
|
"start": "node dist/index.js",
|
|
24
|
-
"test
|
|
25
|
-
"
|
|
26
|
-
"coverage": "vitest --coverage",
|
|
39
|
+
"test": "jest --coverage=false",
|
|
40
|
+
"coverage": "jest --coverage",
|
|
27
41
|
"lint": "eslint .",
|
|
28
42
|
"lint:fix": "eslint --fix ."
|
|
29
43
|
},
|
|
30
44
|
"dependencies": {
|
|
31
45
|
"@google-cloud/bigquery": "^7.9.0",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^8.46.3",
|
|
47
|
+
"@typescript-eslint/parser": "^8.46.3",
|
|
48
|
+
"eslint": "^9.39.1",
|
|
32
49
|
"lodash": "^4.17.21",
|
|
33
50
|
"mssql": "^11.0.1",
|
|
34
51
|
"mysql2": "^3.11.0",
|
|
@@ -39,5 +56,5 @@
|
|
|
39
56
|
"engines": {
|
|
40
57
|
"node": ">=18"
|
|
41
58
|
},
|
|
42
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "75a218687814d8b1c538b26908745e0d0ee8b35a"
|
|
43
60
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createConnection, Connection } from 'mysql2/promise';
|
|
2
|
-
import { flatten } from 'lodash
|
|
2
|
+
import { flatten } from 'lodash';
|
|
3
3
|
import {
|
|
4
4
|
CheckConstraintDictionary, DefaultInfo, DatabaseSchema, DefaultType, Field, IndexColumn, FieldsDictionary, Table, Enum, IndexesDictionary, TableConstraintsDictionary, Index, Ref,
|
|
5
5
|
} from '../types';
|