@dataramen/cli 0.0.8 → 0.0.10
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 +67 -0
- package/dist/README.md +67 -0
- package/dist/code/api/chat/router.js +55 -0
- package/dist/code/api/dataSources/router.js +147 -0
- package/dist/code/api/dataSources/types.js +2 -0
- package/dist/code/api/dataSources/validators.js +22 -0
- package/dist/code/api/project/router.js +100 -0
- package/dist/code/api/queries/router.js +122 -0
- package/dist/code/api/runner/router.js +22 -0
- package/dist/code/api/status/router.js +17 -0
- package/dist/code/api/teams/router.js +35 -0
- package/dist/code/api/userSettings/router.js +54 -0
- package/dist/code/api/users/router.js +91 -0
- package/dist/code/api/workbooks/router.js +123 -0
- package/dist/code/api/workbooks/types.js +2 -0
- package/dist/code/env.js +25 -0
- package/dist/code/index.js +86 -0
- package/dist/code/proxy.js +8 -8
- package/dist/code/repository/db.js +58 -0
- package/dist/code/repository/tables/databaseInspection.js +40 -0
- package/dist/code/repository/tables/datasource.js +86 -0
- package/dist/code/repository/tables/query.js +50 -0
- package/dist/code/repository/tables/teams.js +48 -0
- package/dist/code/repository/tables/userSettings.js +39 -0
- package/dist/code/repository/tables/users.js +42 -0
- package/dist/code/repository/tables/workbook.js +43 -0
- package/dist/code/services/connectorManager/index.js +38 -0
- package/dist/code/services/connectorManager/types.js +2 -0
- package/dist/code/services/files/index.js +44 -0
- package/dist/code/services/mysqlConnector/index.js +180 -0
- package/dist/code/services/oauthClient/oauth2Client.js +10 -0
- package/dist/code/services/openai/index.js +20 -0
- package/dist/code/services/openai/types.js +2 -0
- package/dist/code/services/pgConnector/index.js +220 -0
- package/dist/code/services/userSqlPromptRunner/index.js +207 -0
- package/dist/code/types/connectors.js +2 -0
- package/dist/code/utils/createRouter.js +10 -0
- package/dist/code/utils/httpError.js +13 -0
- package/dist/code/utils/prompts.js +11 -0
- package/dist/code/utils/queryUtils.js +18 -0
- package/dist/code/utils/rawSql.js +32 -0
- package/dist/code/utils/request.js +35 -0
- package/dist/code/utils/token.js +8 -0
- package/dist/package.json +1 -1
- package/package.json +21 -1
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# 🍜 Data Ramen CLI
|
|
2
|
+
|
|
3
|
+
**Your cozy corner for exploring and working with SQL databases — no query writing required (unless you want to).**
|
|
4
|
+
|
|
5
|
+
Data Ramen CLI lets you launch a powerful, local database exploration app that connects effortlessly to MySQL and PostgreSQL databases. Browse schemas, follow relationships, insert data, and even write raw SQL — all from your browser.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🔌 **Connect to PostgreSQL & MySQL**
|
|
10
|
+
Securely plug in your credentials — you're ready to explore.
|
|
11
|
+
|
|
12
|
+
- 🧭 **Visual Schema Explorer**
|
|
13
|
+
Instantly browse tables, columns, types, primary/foreign keys, and relationships.
|
|
14
|
+
|
|
15
|
+
- 🧙 **No-SQL Querying**
|
|
16
|
+
Filter, sort, join, and summarize data using a beautiful, intuitive interface.
|
|
17
|
+
|
|
18
|
+
- 🔗 **Follow Relationships Easily**
|
|
19
|
+
Click to expand related records like nested tables.
|
|
20
|
+
|
|
21
|
+
- ✏️ **Insert & Update Visually**
|
|
22
|
+
Add or modify rows with a visual editor — no SQL errors.
|
|
23
|
+
|
|
24
|
+
- 💾 **Save Queries**
|
|
25
|
+
Save your favorite views for quick access later.
|
|
26
|
+
|
|
27
|
+
- ⌨️ **Raw SQL Mode Available**
|
|
28
|
+
Prefer typing? Drop into SQL mode anytime and run your own queries.
|
|
29
|
+
|
|
30
|
+
## 🛠️ Installation
|
|
31
|
+
|
|
32
|
+
### 1. Install Node.js
|
|
33
|
+
|
|
34
|
+
Data Ramen requires Node.js **v22 or above**.
|
|
35
|
+
👉 [Download Node.js](https://nodejs.org/)
|
|
36
|
+
|
|
37
|
+
### 2. Install Data Ramen CLI
|
|
38
|
+
|
|
39
|
+
Open your terminal and run:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm i -g @dataramen/cli
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 🖥️ Usage
|
|
46
|
+
|
|
47
|
+
### Start the Local Server
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
dataramen start
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Open the App
|
|
54
|
+
|
|
55
|
+
Go to https://app.dataramen.xyz in your browser. Your local server will connect automatically.
|
|
56
|
+
|
|
57
|
+
## 🔧 Additional CLI Commands
|
|
58
|
+
|
|
59
|
+
| Command | Description |
|
|
60
|
+
| ----------------- | --------------------------------- |
|
|
61
|
+
| `dataramen start` | Start the local Data Ramen server |
|
|
62
|
+
| `dataramen stop` | Stop the local server |
|
|
63
|
+
| `dataramen logs` | Show logs from the running server |
|
|
64
|
+
|
|
65
|
+
## ❤️ Made with love by [Oleksandr Demian](https://github.com/OleksandrDemian)
|
|
66
|
+
|
|
67
|
+
Visit [dataramen.xyz](https://dataramen.xyz) for more info.
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# 🍜 Data Ramen CLI
|
|
2
|
+
|
|
3
|
+
**Your cozy corner for exploring and working with SQL databases — no query writing required (unless you want to).**
|
|
4
|
+
|
|
5
|
+
Data Ramen CLI lets you launch a powerful, local database exploration app that connects effortlessly to MySQL and PostgreSQL databases. Browse schemas, follow relationships, insert data, and even write raw SQL — all from your browser.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🔌 **Connect to PostgreSQL & MySQL**
|
|
10
|
+
Securely plug in your credentials — you're ready to explore.
|
|
11
|
+
|
|
12
|
+
- 🧭 **Visual Schema Explorer**
|
|
13
|
+
Instantly browse tables, columns, types, primary/foreign keys, and relationships.
|
|
14
|
+
|
|
15
|
+
- 🧙 **No-SQL Querying**
|
|
16
|
+
Filter, sort, join, and summarize data using a beautiful, intuitive interface.
|
|
17
|
+
|
|
18
|
+
- 🔗 **Follow Relationships Easily**
|
|
19
|
+
Click to expand related records like nested tables.
|
|
20
|
+
|
|
21
|
+
- ✏️ **Insert & Update Visually**
|
|
22
|
+
Add or modify rows with a visual editor — no SQL errors.
|
|
23
|
+
|
|
24
|
+
- 💾 **Save Queries**
|
|
25
|
+
Save your favorite views for quick access later.
|
|
26
|
+
|
|
27
|
+
- ⌨️ **Raw SQL Mode Available**
|
|
28
|
+
Prefer typing? Drop into SQL mode anytime and run your own queries.
|
|
29
|
+
|
|
30
|
+
## 🛠️ Installation
|
|
31
|
+
|
|
32
|
+
### 1. Install Node.js
|
|
33
|
+
|
|
34
|
+
Data Ramen requires Node.js **v22 or above**.
|
|
35
|
+
👉 [Download Node.js](https://nodejs.org/)
|
|
36
|
+
|
|
37
|
+
### 2. Install Data Ramen CLI
|
|
38
|
+
|
|
39
|
+
Open your terminal and run:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm i -g @dataramen/cli
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 🖥️ Usage
|
|
46
|
+
|
|
47
|
+
### Start the Local Server
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
dataramen start
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Open the App
|
|
54
|
+
|
|
55
|
+
Go to https://app.dataramen.xyz in your browser. Your local server will connect automatically.
|
|
56
|
+
|
|
57
|
+
## 🔧 Additional CLI Commands
|
|
58
|
+
|
|
59
|
+
| Command | Description |
|
|
60
|
+
| ----------------- | --------------------------------- |
|
|
61
|
+
| `dataramen start` | Start the local Data Ramen server |
|
|
62
|
+
| `dataramen stop` | Stop the local server |
|
|
63
|
+
| `dataramen logs` | Show logs from the running server |
|
|
64
|
+
|
|
65
|
+
## ❤️ Made with love by [Oleksandr Demian](https://github.com/OleksandrDemian)
|
|
66
|
+
|
|
67
|
+
Visit [dataramen.xyz](https://dataramen.xyz) for more info.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const createRouter_1 = require("../../utils/createRouter");
|
|
4
|
+
const httpError_1 = require("../../utils/httpError");
|
|
5
|
+
const prompts_1 = require("../../utils/prompts");
|
|
6
|
+
const db_1 = require("../../repository/db");
|
|
7
|
+
async function getDbString(datastoreId) {
|
|
8
|
+
const inspections = await db_1.DatabaseInspectionRepository.findBy({
|
|
9
|
+
datasource: {
|
|
10
|
+
id: datastoreId,
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
return (0, prompts_1.buildDbString)(inspections);
|
|
14
|
+
}
|
|
15
|
+
async function getAiCallInfo(userId) {
|
|
16
|
+
const userSettings = await db_1.UserSettingsRepository.findOneBy({
|
|
17
|
+
id: userId,
|
|
18
|
+
});
|
|
19
|
+
const openAiToken = userSettings?.openAiToken;
|
|
20
|
+
if (!openAiToken) {
|
|
21
|
+
throw new httpError_1.HttpError(400, "API key not found. Please set API key in settings");
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
model: userSettings?.model || "gpt-4o",
|
|
25
|
+
token: openAiToken,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
exports.default = (0, createRouter_1.createRouter)((instance) => {
|
|
29
|
+
// workbook chat
|
|
30
|
+
instance.post("/workbook", async (request) => {
|
|
31
|
+
// const userId = getRequestUserId(request);
|
|
32
|
+
// const { messages, id } = getRequestPayload<{ messages: TOpenAiMessage[]; id: string; }>(request);
|
|
33
|
+
// const workbook = await Workbook.findByPk(id);
|
|
34
|
+
// if (!workbook) {
|
|
35
|
+
// throw new Error("Workbook not found");
|
|
36
|
+
// }
|
|
37
|
+
// const { model, token } = await getAiCallInfo(userId);
|
|
38
|
+
// const dbString = await getDbString(workbook.getDataValue("dataSourceId"));
|
|
39
|
+
// const { choices } = await executePrompt({
|
|
40
|
+
// openaiApiKey: token,
|
|
41
|
+
// temperature: 0.5,
|
|
42
|
+
// messages: [
|
|
43
|
+
// {
|
|
44
|
+
// role: "system",
|
|
45
|
+
// content: `You are a database administrator and your role is to assist the user while writing queries. This is the database schema:\n${dbString}.\n\nThe current workbook is:\n${workbook.getDataValue("text")}`,
|
|
46
|
+
// },
|
|
47
|
+
// ...messages
|
|
48
|
+
// ],
|
|
49
|
+
// model,
|
|
50
|
+
// });
|
|
51
|
+
return {
|
|
52
|
+
data: "", //choices[0].message,
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const createRouter_1 = require("../../utils/createRouter");
|
|
4
|
+
const request_1 = require("../../utils/request");
|
|
5
|
+
const validators_1 = require("./validators");
|
|
6
|
+
const httpError_1 = require("../../utils/httpError");
|
|
7
|
+
const connectorManager_1 = require("../../services/connectorManager");
|
|
8
|
+
const db_1 = require("../../repository/db");
|
|
9
|
+
exports.default = (0, createRouter_1.createRouter)((instance) => {
|
|
10
|
+
// get datasource by id
|
|
11
|
+
instance.get("/:id", async (request) => {
|
|
12
|
+
const { id } = (0, request_1.getRequestParams)(request);
|
|
13
|
+
const dataSource = await db_1.DataSourceRepository.findOne({
|
|
14
|
+
where: {
|
|
15
|
+
id,
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
if (!dataSource) {
|
|
19
|
+
throw new httpError_1.HttpError(404, "Data source not found");
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
data: dataSource,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
instance.get("/", async (request) => {
|
|
26
|
+
const { teamId } = (0, request_1.getRequestQuery)(request);
|
|
27
|
+
const dataSources = await db_1.DataSourceRepository.find({
|
|
28
|
+
where: {
|
|
29
|
+
team: {
|
|
30
|
+
id: teamId,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
order: {
|
|
34
|
+
createdAt: "DESC",
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
data: dataSources,
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
// create data source
|
|
42
|
+
instance.post("/", async (request, reply) => {
|
|
43
|
+
const { teamId, ownerId, ...proto } = (0, request_1.getRequestPayload)(request, validators_1.validateCreateDataSource);
|
|
44
|
+
const dataSource = db_1.DataSourceRepository.create({
|
|
45
|
+
...proto,
|
|
46
|
+
team: {
|
|
47
|
+
id: teamId,
|
|
48
|
+
},
|
|
49
|
+
owner: {
|
|
50
|
+
id: ownerId,
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const connection = await (0, connectorManager_1.getDynamicConnection)(dataSource, request);
|
|
54
|
+
try {
|
|
55
|
+
await connection.checkConnection();
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
throw new httpError_1.HttpError(400, "Cannot connect to the database, please check datasource configuration");
|
|
59
|
+
}
|
|
60
|
+
const createdDataSource = await db_1.DataSourceRepository.save(dataSource);
|
|
61
|
+
return {
|
|
62
|
+
data: createdDataSource,
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
// update datasource
|
|
66
|
+
instance.put("/:id", async (request, reply) => {
|
|
67
|
+
const { id } = (0, request_1.getRequestParams)(request);
|
|
68
|
+
const payload = (0, request_1.getRequestPayload)(request);
|
|
69
|
+
const dataSource = await db_1.DataSourceRepository.findOneBy({
|
|
70
|
+
id,
|
|
71
|
+
});
|
|
72
|
+
if (!dataSource) {
|
|
73
|
+
throw new httpError_1.HttpError(404, "Data source not found");
|
|
74
|
+
}
|
|
75
|
+
const updated = db_1.DataSourceRepository.merge(dataSource, payload);
|
|
76
|
+
await db_1.DataSourceRepository.save(updated);
|
|
77
|
+
return {
|
|
78
|
+
data: updated,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
// remove datasource
|
|
82
|
+
instance.delete("/:id", async (request, reply) => {
|
|
83
|
+
return db_1.AppDataSource.transaction(async () => {
|
|
84
|
+
const { id } = (0, request_1.getRequestParams)(request);
|
|
85
|
+
await Promise.all([
|
|
86
|
+
db_1.DatabaseInspectionRepository.delete({
|
|
87
|
+
datasource: {
|
|
88
|
+
id,
|
|
89
|
+
}
|
|
90
|
+
}),
|
|
91
|
+
db_1.QueriesRepository.delete({
|
|
92
|
+
dataSource: {
|
|
93
|
+
id,
|
|
94
|
+
},
|
|
95
|
+
}),
|
|
96
|
+
]);
|
|
97
|
+
await db_1.DataSourceRepository.delete({
|
|
98
|
+
id,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
// inspect datasource
|
|
103
|
+
instance.post("/:id/inspect", async (request, reply) => {
|
|
104
|
+
const { id } = (0, request_1.getRequestParams)(request);
|
|
105
|
+
const dataSource = await db_1.DataSourceRepository.findOneBy({
|
|
106
|
+
id,
|
|
107
|
+
});
|
|
108
|
+
if (!dataSource) {
|
|
109
|
+
throw new Error("Data source not found");
|
|
110
|
+
}
|
|
111
|
+
dataSource.status = "INSPECTING";
|
|
112
|
+
await db_1.DataSourceRepository.save(dataSource);
|
|
113
|
+
const connection = await (0, connectorManager_1.getDynamicConnection)(dataSource, request);
|
|
114
|
+
// inspect dataSource
|
|
115
|
+
const inspection = await connection.inspectSchema();
|
|
116
|
+
// destroy previous inspections
|
|
117
|
+
await db_1.DatabaseInspectionRepository.delete({
|
|
118
|
+
datasource: {
|
|
119
|
+
id,
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
await db_1.DatabaseInspectionRepository.insert(inspection.sort().map((i) => db_1.DatabaseInspectionRepository.create({
|
|
123
|
+
tableName: i.tableName,
|
|
124
|
+
columns: i.columns,
|
|
125
|
+
datasource: {
|
|
126
|
+
id,
|
|
127
|
+
},
|
|
128
|
+
})));
|
|
129
|
+
// update datasource last inspected
|
|
130
|
+
dataSource.status = "READY";
|
|
131
|
+
dataSource.lastInspected = new Date();
|
|
132
|
+
await db_1.DataSourceRepository.save(dataSource);
|
|
133
|
+
});
|
|
134
|
+
instance.get("/:id/inspections", async (request, reply) => {
|
|
135
|
+
const { id } = (0, request_1.getRequestParams)(request);
|
|
136
|
+
const inspections = await db_1.DatabaseInspectionRepository.find({
|
|
137
|
+
where: {
|
|
138
|
+
datasource: {
|
|
139
|
+
id,
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
data: inspections,
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateCreateDataSource = void 0;
|
|
4
|
+
const httpError_1 = require("../../utils/httpError");
|
|
5
|
+
const validateCreateDataSource = (dataSource) => {
|
|
6
|
+
if (!dataSource.dbUrl) {
|
|
7
|
+
throw new httpError_1.HttpError(400, "url is required");
|
|
8
|
+
}
|
|
9
|
+
if (!dataSource.dbUser) {
|
|
10
|
+
throw new httpError_1.HttpError(400, "user is required");
|
|
11
|
+
}
|
|
12
|
+
if (!dataSource.dbType) {
|
|
13
|
+
throw new httpError_1.HttpError(400, "type is required");
|
|
14
|
+
}
|
|
15
|
+
if (!dataSource.name) {
|
|
16
|
+
throw new httpError_1.HttpError(400, "name is required");
|
|
17
|
+
}
|
|
18
|
+
if (!dataSource.dbDatabase) {
|
|
19
|
+
throw new httpError_1.HttpError(400, "database is required");
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
exports.validateCreateDataSource = validateCreateDataSource;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const createRouter_1 = require("../../utils/createRouter");
|
|
4
|
+
const request_1 = require("../../utils/request");
|
|
5
|
+
const db_1 = require("../../repository/db");
|
|
6
|
+
const typeorm_1 = require("typeorm");
|
|
7
|
+
exports.default = (0, createRouter_1.createRouter)((instance) => {
|
|
8
|
+
instance.get("/team/:teamId/files", async (request, reply) => {
|
|
9
|
+
const { teamId } = (0, request_1.getRequestParams)(request);
|
|
10
|
+
const query = {
|
|
11
|
+
where: {
|
|
12
|
+
team: {
|
|
13
|
+
id: teamId,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
order: {
|
|
17
|
+
name: 'ASC',
|
|
18
|
+
},
|
|
19
|
+
select: {
|
|
20
|
+
id: true,
|
|
21
|
+
name: true,
|
|
22
|
+
updatedAt: true,
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const [dataSources = [], workbooks = [], queries = []] = await Promise.all([
|
|
26
|
+
db_1.DataSourceRepository.find(query),
|
|
27
|
+
db_1.WorkbookRepository.find({
|
|
28
|
+
...query,
|
|
29
|
+
where: {
|
|
30
|
+
...query.where,
|
|
31
|
+
isTrash: false,
|
|
32
|
+
}
|
|
33
|
+
}),
|
|
34
|
+
db_1.QueriesRepository.find({
|
|
35
|
+
...query,
|
|
36
|
+
where: {
|
|
37
|
+
...query.where,
|
|
38
|
+
isTrash: false,
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
]);
|
|
42
|
+
return {
|
|
43
|
+
data: [
|
|
44
|
+
...dataSources.map((d) => ({ ...d, type: "dataSource" })),
|
|
45
|
+
...workbooks.map((w) => ({ ...w, type: "workbook" })),
|
|
46
|
+
...queries.map((w) => ({ ...w, type: "query" })),
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
instance.get("/team/:teamId/trash", async (request) => {
|
|
51
|
+
const { teamId } = (0, request_1.getRequestParams)(request);
|
|
52
|
+
const workbooks = await db_1.AppDataSource.query(`
|
|
53
|
+
select id, name, updatedAt
|
|
54
|
+
from workbooks
|
|
55
|
+
where teamId = '${teamId}' AND (isTrash = true OR isTrash IS NULL)
|
|
56
|
+
order by name asc
|
|
57
|
+
limit 100;
|
|
58
|
+
`);
|
|
59
|
+
return {
|
|
60
|
+
data: workbooks,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
instance.get("/team/:teamId/tables", async (request) => {
|
|
64
|
+
const { teamId } = (0, request_1.getRequestParams)(request);
|
|
65
|
+
const { search, size } = (0, request_1.getRequestQuery)(request);
|
|
66
|
+
const tables = await db_1.DatabaseInspectionRepository.find({
|
|
67
|
+
where: {
|
|
68
|
+
tableName: (0, typeorm_1.Like)(`%${search}%`),
|
|
69
|
+
datasource: {
|
|
70
|
+
team: {
|
|
71
|
+
id: teamId,
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
relations: {
|
|
76
|
+
datasource: true,
|
|
77
|
+
},
|
|
78
|
+
select: {
|
|
79
|
+
id: true,
|
|
80
|
+
tableName: true,
|
|
81
|
+
datasource: {
|
|
82
|
+
name: true,
|
|
83
|
+
id: true,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
order: {
|
|
87
|
+
tableName: "ASC",
|
|
88
|
+
},
|
|
89
|
+
take: parseInt(size) || 20,
|
|
90
|
+
});
|
|
91
|
+
return {
|
|
92
|
+
data: tables.map(t => ({
|
|
93
|
+
name: t.tableName,
|
|
94
|
+
id: t.id,
|
|
95
|
+
dataSourceName: t.datasource?.name || '--',
|
|
96
|
+
dataSourceId: t.datasource?.id || '--',
|
|
97
|
+
})),
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const createRouter_1 = require("../../utils/createRouter");
|
|
4
|
+
const request_1 = require("../../utils/request");
|
|
5
|
+
const queryUtils_1 = require("../../utils/queryUtils");
|
|
6
|
+
const httpError_1 = require("../../utils/httpError");
|
|
7
|
+
const db_1 = require("../../repository/db");
|
|
8
|
+
const typeorm_1 = require("typeorm");
|
|
9
|
+
exports.default = (0, createRouter_1.createRouter)((instance) => {
|
|
10
|
+
instance.get("/", async (request) => {
|
|
11
|
+
const { dataSourceId, teamId, limit, orderBy, name } = (0, request_1.getRequestQuery)(request);
|
|
12
|
+
if (!dataSourceId && !teamId) {
|
|
13
|
+
throw new httpError_1.HttpError(400, "Either dsId or teamId is required");
|
|
14
|
+
}
|
|
15
|
+
const where = {
|
|
16
|
+
isTrash: false,
|
|
17
|
+
};
|
|
18
|
+
if (dataSourceId) {
|
|
19
|
+
where.dataSource = {
|
|
20
|
+
id: dataSourceId,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (teamId) {
|
|
24
|
+
where.team = {
|
|
25
|
+
id: teamId,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (name) {
|
|
29
|
+
where.name = (0, typeorm_1.Like)(`%${name}%`);
|
|
30
|
+
}
|
|
31
|
+
const queries = await db_1.QueriesRepository.find({
|
|
32
|
+
where,
|
|
33
|
+
take: limit,
|
|
34
|
+
order: (0, queryUtils_1.parseOrderQueryParam)(orderBy, {
|
|
35
|
+
createdAt: "DESC",
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
data: queries,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
instance.get("/:id", async (request) => {
|
|
43
|
+
const { id } = (0, request_1.getRequestParams)(request);
|
|
44
|
+
const query = await db_1.QueriesRepository.findOne({
|
|
45
|
+
where: {
|
|
46
|
+
id,
|
|
47
|
+
},
|
|
48
|
+
select: {
|
|
49
|
+
dataSource: {
|
|
50
|
+
id: true,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
relations: {
|
|
54
|
+
dataSource: true,
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
if (!query) {
|
|
58
|
+
return {
|
|
59
|
+
status: 404,
|
|
60
|
+
data: "Query not found",
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
data: query,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
instance.post("/", async (request) => {
|
|
68
|
+
const payload = (0, request_1.getRequestPayload)(request);
|
|
69
|
+
const dataSource = await db_1.DataSourceRepository.findOne({
|
|
70
|
+
where: {
|
|
71
|
+
id: payload.dataSourceId,
|
|
72
|
+
},
|
|
73
|
+
relations: {
|
|
74
|
+
team: true,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
const query = await db_1.QueriesRepository.save(db_1.QueriesRepository.create({
|
|
78
|
+
name: payload.name,
|
|
79
|
+
isTrash: false,
|
|
80
|
+
opts: payload.opts,
|
|
81
|
+
team: {
|
|
82
|
+
id: dataSource?.team.id,
|
|
83
|
+
},
|
|
84
|
+
dataSource: {
|
|
85
|
+
id: payload.dataSourceId,
|
|
86
|
+
}
|
|
87
|
+
}));
|
|
88
|
+
return {
|
|
89
|
+
data: query,
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
// update workbook
|
|
93
|
+
instance.patch("/:id", async (request) => {
|
|
94
|
+
const { id } = (0, request_1.getRequestParams)(request);
|
|
95
|
+
const payload = (0, request_1.getRequestPayload)(request);
|
|
96
|
+
const result = await db_1.QueriesRepository.update(id, payload);
|
|
97
|
+
if (!result.affected) {
|
|
98
|
+
throw new httpError_1.HttpError(404, "Workbook not found");
|
|
99
|
+
}
|
|
100
|
+
const query = await db_1.QueriesRepository.findOneBy({
|
|
101
|
+
id,
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
data: query,
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
// delete query
|
|
108
|
+
instance.delete("/:id", async (request) => {
|
|
109
|
+
return db_1.AppDataSource.transaction(async () => {
|
|
110
|
+
const { id } = (0, request_1.getRequestParams)(request);
|
|
111
|
+
const result = await db_1.QueriesRepository.delete({
|
|
112
|
+
id
|
|
113
|
+
});
|
|
114
|
+
if (!result.affected) {
|
|
115
|
+
return {
|
|
116
|
+
status: 404,
|
|
117
|
+
data: "Workbook not found",
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const createRouter_1 = require("../../utils/createRouter");
|
|
4
|
+
const request_1 = require("../../utils/request");
|
|
5
|
+
const userSqlPromptRunner_1 = require("../../services/userSqlPromptRunner");
|
|
6
|
+
exports.default = (0, createRouter_1.createRouter)((instance) => {
|
|
7
|
+
// run sql
|
|
8
|
+
instance.post("/sql", async (request) => {
|
|
9
|
+
const payload = (0, request_1.getRequestPayload)(request);
|
|
10
|
+
const result = await (0, userSqlPromptRunner_1.runUserSqlQuery)(request, payload);
|
|
11
|
+
return {
|
|
12
|
+
data: result,
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
instance.post("/raw", async (request) => {
|
|
16
|
+
const payload = (0, request_1.getRequestPayload)(request);
|
|
17
|
+
const result = await (0, userSqlPromptRunner_1.runRawSqlQuery)(request, payload);
|
|
18
|
+
return {
|
|
19
|
+
data: result,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const createRouter_1 = require("../../utils/createRouter");
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
exports.default = (0, createRouter_1.createRouter)((instance) => {
|
|
6
|
+
instance.get("/", async (request, reply) => {
|
|
7
|
+
return {
|
|
8
|
+
data: {
|
|
9
|
+
active: true,
|
|
10
|
+
version: process.env.SERVER_VERSION,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
instance.get("/logs", async () => {
|
|
15
|
+
(0, node_child_process_1.spawn)(`echo "${process.env.SERVER_VERSION}"`);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const createRouter_1 = require("../../utils/createRouter");
|
|
4
|
+
const request_1 = require("../../utils/request");
|
|
5
|
+
const db_1 = require("../../repository/db");
|
|
6
|
+
exports.default = (0, createRouter_1.createRouter)((instance) => {
|
|
7
|
+
instance.get("/", async (request, reply) => {
|
|
8
|
+
const userId = (0, request_1.getRequestUserId)(request);
|
|
9
|
+
const teams = await db_1.TeamRepository.find({
|
|
10
|
+
where: {
|
|
11
|
+
users: {
|
|
12
|
+
id: userId,
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
data: teams,
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
// post
|
|
21
|
+
instance.post("/", async (request, reply) => {
|
|
22
|
+
return db_1.AppDataSource.transaction(async () => {
|
|
23
|
+
const userId = (0, request_1.getRequestUserId)(request);
|
|
24
|
+
const teamPayload = (0, request_1.getRequestPayload)(request);
|
|
25
|
+
const user = db_1.UserRepository.create();
|
|
26
|
+
user.id = userId;
|
|
27
|
+
const team = db_1.TeamRepository.create(teamPayload);
|
|
28
|
+
team.users = [user];
|
|
29
|
+
await db_1.TeamRepository.save(team);
|
|
30
|
+
return {
|
|
31
|
+
data: team,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|