@dataramen/cli 0.0.9 → 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.
Files changed (44) hide show
  1. package/dist/README.md +67 -0
  2. package/dist/code/api/chat/router.js +55 -0
  3. package/dist/code/api/dataSources/router.js +147 -0
  4. package/dist/code/api/dataSources/types.js +2 -0
  5. package/dist/code/api/dataSources/validators.js +22 -0
  6. package/dist/code/api/project/router.js +100 -0
  7. package/dist/code/api/queries/router.js +122 -0
  8. package/dist/code/api/runner/router.js +22 -0
  9. package/dist/code/api/status/router.js +17 -0
  10. package/dist/code/api/teams/router.js +35 -0
  11. package/dist/code/api/userSettings/router.js +54 -0
  12. package/dist/code/api/users/router.js +91 -0
  13. package/dist/code/api/workbooks/router.js +123 -0
  14. package/dist/code/api/workbooks/types.js +2 -0
  15. package/dist/code/env.js +25 -0
  16. package/dist/code/index.js +86 -0
  17. package/dist/code/proxy.js +8 -8
  18. package/dist/code/repository/db.js +58 -0
  19. package/dist/code/repository/tables/databaseInspection.js +40 -0
  20. package/dist/code/repository/tables/datasource.js +86 -0
  21. package/dist/code/repository/tables/query.js +50 -0
  22. package/dist/code/repository/tables/teams.js +48 -0
  23. package/dist/code/repository/tables/userSettings.js +39 -0
  24. package/dist/code/repository/tables/users.js +42 -0
  25. package/dist/code/repository/tables/workbook.js +43 -0
  26. package/dist/code/services/connectorManager/index.js +38 -0
  27. package/dist/code/services/connectorManager/types.js +2 -0
  28. package/dist/code/services/files/index.js +44 -0
  29. package/dist/code/services/mysqlConnector/index.js +180 -0
  30. package/dist/code/services/oauthClient/oauth2Client.js +10 -0
  31. package/dist/code/services/openai/index.js +20 -0
  32. package/dist/code/services/openai/types.js +2 -0
  33. package/dist/code/services/pgConnector/index.js +220 -0
  34. package/dist/code/services/userSqlPromptRunner/index.js +207 -0
  35. package/dist/code/types/connectors.js +2 -0
  36. package/dist/code/utils/createRouter.js +10 -0
  37. package/dist/code/utils/httpError.js +13 -0
  38. package/dist/code/utils/prompts.js +11 -0
  39. package/dist/code/utils/queryUtils.js +18 -0
  40. package/dist/code/utils/rawSql.js +32 -0
  41. package/dist/code/utils/request.js +35 -0
  42. package/dist/code/utils/token.js +8 -0
  43. package/dist/package.json +1 -1
  44. package/package.json +21 -1
package/dist/README.md CHANGED
@@ -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,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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
+ });
@@ -0,0 +1,54 @@
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 httpError_1 = require("../../utils/httpError");
6
+ const token_1 = require("../../utils/token");
7
+ const db_1 = require("../../repository/db");
8
+ function sanitizeFeSettings(settings) {
9
+ const newSettings = db_1.UserSettingsRepository.create(settings);
10
+ if (settings.openAiToken) {
11
+ newSettings.openAiToken = (0, token_1.sanitizeOpenAIToken)(settings.openAiToken);
12
+ }
13
+ return newSettings;
14
+ }
15
+ exports.default = (0, createRouter_1.createRouter)((instance) => {
16
+ // get user settings by user id
17
+ instance.get("/", async (req) => {
18
+ const userId = (0, request_1.getRequestUserId)(req);
19
+ let settings = await db_1.UserSettingsRepository.findOneBy({
20
+ user: {
21
+ id: userId,
22
+ }
23
+ });
24
+ if (!settings) {
25
+ // create default settings if not found
26
+ settings = await db_1.UserSettingsRepository.save(db_1.UserSettingsRepository.create({
27
+ user: {
28
+ id: userId,
29
+ },
30
+ model: "gpt-4o",
31
+ }));
32
+ }
33
+ return {
34
+ data: sanitizeFeSettings(settings),
35
+ };
36
+ });
37
+ // update user settings
38
+ instance.patch("/", async (req) => {
39
+ const { settings } = (0, request_1.getRequestPayload)(req);
40
+ if (!settings.id) {
41
+ throw new httpError_1.HttpError(400, "Settings id is required!");
42
+ }
43
+ const result = await db_1.UserSettingsRepository.update(settings.id, settings);
44
+ if (!result.affected) {
45
+ throw new httpError_1.HttpError(404, "You do not own these settings!");
46
+ }
47
+ const updatedSettings = await db_1.UserSettingsRepository.findOneBy({
48
+ id: settings.id,
49
+ });
50
+ return {
51
+ data: updatedSettings,
52
+ };
53
+ });
54
+ });