fakebase-studio 1.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/README.md +85 -0
- package/bin/fakebase.js +92 -0
- package/package.json +44 -0
- package/server/dist/db.d.ts +18 -0
- package/server/dist/db.d.ts.map +1 -0
- package/server/dist/db.js +83 -0
- package/server/dist/db.js.map +1 -0
- package/server/dist/index.d.ts +2 -0
- package/server/dist/index.d.ts.map +1 -0
- package/server/dist/index.js +62 -0
- package/server/dist/index.js.map +1 -0
- package/server/dist/routes/connect.d.ts +6 -0
- package/server/dist/routes/connect.d.ts.map +1 -0
- package/server/dist/routes/connect.js +40 -0
- package/server/dist/routes/connect.js.map +1 -0
- package/server/dist/routes/connections.d.ts +3 -0
- package/server/dist/routes/connections.d.ts.map +1 -0
- package/server/dist/routes/connections.js +106 -0
- package/server/dist/routes/connections.js.map +1 -0
- package/server/dist/routes/index.d.ts +6 -0
- package/server/dist/routes/index.d.ts.map +1 -0
- package/server/dist/routes/index.js +16 -0
- package/server/dist/routes/index.js.map +1 -0
- package/server/dist/routes/indexes.d.ts +6 -0
- package/server/dist/routes/indexes.d.ts.map +1 -0
- package/server/dist/routes/indexes.js +38 -0
- package/server/dist/routes/indexes.js.map +1 -0
- package/server/dist/routes/schema.d.ts +6 -0
- package/server/dist/routes/schema.d.ts.map +1 -0
- package/server/dist/routes/schema.js +41 -0
- package/server/dist/routes/schema.js.map +1 -0
- package/server/dist/routes/tables.d.ts +6 -0
- package/server/dist/routes/tables.d.ts.map +1 -0
- package/server/dist/routes/tables.js +121 -0
- package/server/dist/routes/tables.js.map +1 -0
- package/server/dist/services/connections.service.d.ts +31 -0
- package/server/dist/services/connections.service.d.ts.map +1 -0
- package/server/dist/services/connections.service.js +125 -0
- package/server/dist/services/connections.service.js.map +1 -0
- package/server/dist/services/indexes.service.d.ts +8 -0
- package/server/dist/services/indexes.service.d.ts.map +1 -0
- package/server/dist/services/indexes.service.js +54 -0
- package/server/dist/services/indexes.service.js.map +1 -0
- package/server/dist/services/schema.service.d.ts +7 -0
- package/server/dist/services/schema.service.d.ts.map +1 -0
- package/server/dist/services/schema.service.js +165 -0
- package/server/dist/services/schema.service.js.map +1 -0
- package/server/dist/types/api.d.ts +36 -0
- package/server/dist/types/api.d.ts.map +1 -0
- package/server/dist/types/api.js +5 -0
- package/server/dist/types/api.js.map +1 -0
- package/server/dist/types/database.d.ts +29 -0
- package/server/dist/types/database.d.ts.map +1 -0
- package/server/dist/types/database.js +5 -0
- package/server/dist/types/database.js.map +1 -0
- package/server/dist/utils/errors.d.ts +15 -0
- package/server/dist/utils/errors.d.ts.map +1 -0
- package/server/dist/utils/errors.js +63 -0
- package/server/dist/utils/errors.js.map +1 -0
- package/ui/dist/assets/index-D3BM4q8p.js +70 -0
- package/ui/dist/assets/index-DvydtHdZ.css +1 -0
- package/ui/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/ui/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/ui/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/ui/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/ui/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/ui/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/ui/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/ui/dist/index.html +14 -0
- package/ui/dist/vite.svg +1 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get all tables from the database
|
|
3
|
+
*/
|
|
4
|
+
async function getTables(pool) {
|
|
5
|
+
const query = `
|
|
6
|
+
SELECT
|
|
7
|
+
table_name as name,
|
|
8
|
+
table_schema as schema
|
|
9
|
+
FROM information_schema.tables
|
|
10
|
+
WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
|
|
11
|
+
AND table_type = 'BASE TABLE'
|
|
12
|
+
ORDER BY table_schema, table_name;
|
|
13
|
+
`;
|
|
14
|
+
const result = await pool.query(query);
|
|
15
|
+
return result.rows;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get all columns for a specific table
|
|
19
|
+
*/
|
|
20
|
+
async function getColumns(pool, schema, tableName) {
|
|
21
|
+
const query = `
|
|
22
|
+
SELECT
|
|
23
|
+
column_name as name,
|
|
24
|
+
data_type as type,
|
|
25
|
+
is_nullable = 'YES' as nullable,
|
|
26
|
+
column_default as "defaultValue"
|
|
27
|
+
FROM information_schema.columns
|
|
28
|
+
WHERE table_schema = $1 AND table_name = $2
|
|
29
|
+
ORDER BY ordinal_position;
|
|
30
|
+
`;
|
|
31
|
+
const result = await pool.query(query, [schema, tableName]);
|
|
32
|
+
return result.rows.map((row) => ({
|
|
33
|
+
name: row.name,
|
|
34
|
+
type: row.type,
|
|
35
|
+
nullable: row.nullable,
|
|
36
|
+
isPrimaryKey: false, // Will be set later
|
|
37
|
+
defaultValue: row.defaultValue,
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get primary keys for all tables
|
|
42
|
+
*/
|
|
43
|
+
async function getPrimaryKeys(pool) {
|
|
44
|
+
const query = `
|
|
45
|
+
SELECT
|
|
46
|
+
tc.table_schema,
|
|
47
|
+
tc.table_name,
|
|
48
|
+
kcu.column_name
|
|
49
|
+
FROM information_schema.table_constraints tc
|
|
50
|
+
JOIN information_schema.key_column_usage kcu
|
|
51
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
52
|
+
AND tc.table_schema = kcu.table_schema
|
|
53
|
+
WHERE tc.constraint_type = 'PRIMARY KEY'
|
|
54
|
+
ORDER BY tc.table_schema, tc.table_name, kcu.ordinal_position;
|
|
55
|
+
`;
|
|
56
|
+
const result = await pool.query(query);
|
|
57
|
+
const primaryKeys = new Map();
|
|
58
|
+
for (const row of result.rows) {
|
|
59
|
+
const key = `${row.table_schema}.${row.table_name}`;
|
|
60
|
+
if (!primaryKeys.has(key)) {
|
|
61
|
+
primaryKeys.set(key, new Set());
|
|
62
|
+
}
|
|
63
|
+
primaryKeys.get(key).add(row.column_name);
|
|
64
|
+
}
|
|
65
|
+
return primaryKeys;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get all foreign keys (relationships) between tables
|
|
69
|
+
*/
|
|
70
|
+
async function getForeignKeys(pool) {
|
|
71
|
+
const query = `
|
|
72
|
+
SELECT
|
|
73
|
+
kcu.table_schema as from_schema,
|
|
74
|
+
kcu.table_name as from_table,
|
|
75
|
+
kcu.column_name as from_column,
|
|
76
|
+
ccu.table_schema as to_schema,
|
|
77
|
+
ccu.table_name as to_table,
|
|
78
|
+
ccu.column_name as to_column,
|
|
79
|
+
kcu.constraint_name
|
|
80
|
+
FROM information_schema.table_constraints tc
|
|
81
|
+
JOIN information_schema.key_column_usage kcu
|
|
82
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
83
|
+
AND tc.table_schema = kcu.table_schema
|
|
84
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
85
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
86
|
+
AND ccu.table_schema = tc.table_schema
|
|
87
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
88
|
+
AND tc.table_schema NOT IN ('pg_catalog', 'information_schema')
|
|
89
|
+
ORDER BY kcu.table_schema, kcu.table_name, kcu.ordinal_position;
|
|
90
|
+
`;
|
|
91
|
+
try {
|
|
92
|
+
const result = await pool.query(query);
|
|
93
|
+
return result.rows.map((row) => ({
|
|
94
|
+
fromTable: `${row.from_schema}.${row.from_table}`,
|
|
95
|
+
fromColumn: row.from_column,
|
|
96
|
+
toTable: `${row.to_schema}.${row.to_table}`,
|
|
97
|
+
toColumn: row.to_column,
|
|
98
|
+
constraintName: row.constraint_name,
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
// Return empty array if foreign keys can't be fetched
|
|
103
|
+
// This allows the rest of the schema to still be returned
|
|
104
|
+
console.warn("Could not fetch foreign keys:", error);
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get complete schema data including tables, columns, and relationships
|
|
110
|
+
*/
|
|
111
|
+
export async function getSchemaData(pool) {
|
|
112
|
+
// Get all tables
|
|
113
|
+
const tablesData = await getTables(pool);
|
|
114
|
+
// Get primary keys for all tables
|
|
115
|
+
const primaryKeysMap = await getPrimaryKeys(pool);
|
|
116
|
+
// Get all foreign keys
|
|
117
|
+
const foreignKeys = await getForeignKeys(pool);
|
|
118
|
+
// Create a map of foreign keys by table.column for quick lookup
|
|
119
|
+
const foreignKeysMap = new Map();
|
|
120
|
+
for (const fk of foreignKeys) {
|
|
121
|
+
const key = `${fk.fromTable}.${fk.fromColumn}`;
|
|
122
|
+
foreignKeysMap.set(key, fk);
|
|
123
|
+
}
|
|
124
|
+
// Get columns for each table and build complete table objects
|
|
125
|
+
const tables = await Promise.all(tablesData.map(async (tableData) => {
|
|
126
|
+
try {
|
|
127
|
+
const columns = await getColumns(pool, tableData.schema, tableData.name);
|
|
128
|
+
const tableKey = `${tableData.schema}.${tableData.name}`;
|
|
129
|
+
const primaryKeys = Array.from(primaryKeysMap.get(tableKey) || []);
|
|
130
|
+
// Mark primary key columns
|
|
131
|
+
columns.forEach((col) => {
|
|
132
|
+
col.isPrimaryKey = primaryKeys.includes(col.name);
|
|
133
|
+
});
|
|
134
|
+
// Add foreign key references to columns
|
|
135
|
+
columns.forEach((col) => {
|
|
136
|
+
const fkKey = `${tableData.schema}.${tableData.name}.${col.name}`;
|
|
137
|
+
const fk = foreignKeysMap.get(fkKey);
|
|
138
|
+
if (fk) {
|
|
139
|
+
col.foreignKey = fk;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
name: tableData.name,
|
|
144
|
+
schema: tableData.schema,
|
|
145
|
+
columns,
|
|
146
|
+
primaryKeys,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
// Return table with empty columns if we can't fetch them
|
|
151
|
+
console.warn(`Could not fetch columns for ${tableData.schema}.${tableData.name}:`, error);
|
|
152
|
+
return {
|
|
153
|
+
name: tableData.name,
|
|
154
|
+
schema: tableData.schema,
|
|
155
|
+
columns: [],
|
|
156
|
+
primaryKeys: [],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}));
|
|
160
|
+
return {
|
|
161
|
+
tables,
|
|
162
|
+
foreignKeys,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=schema.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.service.js","sourceRoot":"","sources":["../../services/schema.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API request/response types
|
|
3
|
+
*/
|
|
4
|
+
export interface ConnectionRequest {
|
|
5
|
+
connectionString: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ApiResponse<T = unknown> {
|
|
8
|
+
success: boolean;
|
|
9
|
+
data?: T;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ConnectionResponse {
|
|
13
|
+
databaseName: string;
|
|
14
|
+
}
|
|
15
|
+
export type { SchemaData, Table, Column, ForeignKey } from "./database.js";
|
|
16
|
+
/** Index list item for the Indexes page */
|
|
17
|
+
export interface IndexListItem {
|
|
18
|
+
schema: string;
|
|
19
|
+
table: string;
|
|
20
|
+
indexName: string;
|
|
21
|
+
/** Columns covered by this index */
|
|
22
|
+
columns: string[];
|
|
23
|
+
/** Index size in bytes */
|
|
24
|
+
sizeBytes: number;
|
|
25
|
+
/** Number of index scans */
|
|
26
|
+
indexScans: number;
|
|
27
|
+
isUnique: boolean;
|
|
28
|
+
isPrimary: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Response for /api/indexes/list */
|
|
31
|
+
export interface IndexesListData {
|
|
32
|
+
indexes: IndexListItem[];
|
|
33
|
+
/** Unique schemas found (convenience for UI dropdown) */
|
|
34
|
+
schemas: string[];
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../types/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB;AAGD,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAM3E,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,yDAAyD;IACzD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../types/api.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database schema types for schema introspection
|
|
3
|
+
*/
|
|
4
|
+
export interface Column {
|
|
5
|
+
name: string;
|
|
6
|
+
type: string;
|
|
7
|
+
nullable: boolean;
|
|
8
|
+
isPrimaryKey: boolean;
|
|
9
|
+
foreignKey?: ForeignKey;
|
|
10
|
+
defaultValue?: string | null;
|
|
11
|
+
}
|
|
12
|
+
export interface ForeignKey {
|
|
13
|
+
fromTable: string;
|
|
14
|
+
fromColumn: string;
|
|
15
|
+
toTable: string;
|
|
16
|
+
toColumn: string;
|
|
17
|
+
constraintName: string;
|
|
18
|
+
}
|
|
19
|
+
export interface Table {
|
|
20
|
+
name: string;
|
|
21
|
+
schema: string;
|
|
22
|
+
columns: Column[];
|
|
23
|
+
primaryKeys: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface SchemaData {
|
|
26
|
+
tables: Table[];
|
|
27
|
+
foreignKeys: ForeignKey[];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../types/database.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../types/database.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FastifyReply } from "fastify";
|
|
2
|
+
/**
|
|
3
|
+
* Convert an error into a user-friendly message for API responses.
|
|
4
|
+
* Handles common PostgreSQL error patterns.
|
|
5
|
+
*/
|
|
6
|
+
export declare function toPublicErrorMessage(error: unknown): string;
|
|
7
|
+
/**
|
|
8
|
+
* Send an error response with consistent format.
|
|
9
|
+
*/
|
|
10
|
+
export declare function sendError(reply: FastifyReply, statusCode: number, error: unknown): void;
|
|
11
|
+
/**
|
|
12
|
+
* Send a success response with consistent format.
|
|
13
|
+
*/
|
|
14
|
+
export declare function sendSuccess<T>(reply: FastifyReply, data?: T): void;
|
|
15
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAiD3D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAMvF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAKlE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert an error into a user-friendly message for API responses.
|
|
3
|
+
* Handles common PostgreSQL error patterns.
|
|
4
|
+
*/
|
|
5
|
+
export function toPublicErrorMessage(error) {
|
|
6
|
+
if (!(error instanceof Error)) {
|
|
7
|
+
return String(error);
|
|
8
|
+
}
|
|
9
|
+
const message = error.message;
|
|
10
|
+
const errorAny = error;
|
|
11
|
+
// Handle common pg errors with user-friendly messages
|
|
12
|
+
if (message.includes("ENOTFOUND") || message.includes("getaddrinfo")) {
|
|
13
|
+
// Try to extract hostname from error
|
|
14
|
+
let hostname = errorAny.hostname || "unknown host";
|
|
15
|
+
if (hostname === "unknown host") {
|
|
16
|
+
const hostnameMatch = message.match(/([a-zA-Z0-9.-]+\.(supabase\.co|com|net|org|io))/);
|
|
17
|
+
if (hostnameMatch) {
|
|
18
|
+
hostname = hostnameMatch[1];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Check if it's a Supabase connection
|
|
22
|
+
if (hostname.includes("supabase.co")) {
|
|
23
|
+
return `Cannot resolve Supabase hostname: ${hostname}. Please verify:\n1. Your Supabase project is active (not paused)\n2. The connection string is correct\n3. The hostname format matches: [project-ref].supabase.co (without 'db.' prefix)`;
|
|
24
|
+
}
|
|
25
|
+
return `Cannot resolve hostname: ${hostname}. Please check your connection string and ensure the database server is accessible.`;
|
|
26
|
+
}
|
|
27
|
+
if (message.includes("password authentication failed")) {
|
|
28
|
+
return "Authentication failed. Please check your username and password.";
|
|
29
|
+
}
|
|
30
|
+
if (message.includes("connection refused") || message.includes("ECONNREFUSED")) {
|
|
31
|
+
return "Connection refused. Please check if the database server is running and the port is correct.";
|
|
32
|
+
}
|
|
33
|
+
if (message.includes("timeout") || message.includes("ETIMEDOUT")) {
|
|
34
|
+
return "Connection timeout. Please check your network connection and firewall settings.";
|
|
35
|
+
}
|
|
36
|
+
if (message.includes("does not exist") || (message.includes("database") && message.includes("does not exist"))) {
|
|
37
|
+
return `Database error: ${message}`;
|
|
38
|
+
}
|
|
39
|
+
if (message.includes("permission") || message.includes("access")) {
|
|
40
|
+
return `Database access denied: ${message}. Please check user permissions.`;
|
|
41
|
+
}
|
|
42
|
+
return message;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Send an error response with consistent format.
|
|
46
|
+
*/
|
|
47
|
+
export function sendError(reply, statusCode, error) {
|
|
48
|
+
const message = toPublicErrorMessage(error);
|
|
49
|
+
reply.status(statusCode).send({
|
|
50
|
+
success: false,
|
|
51
|
+
error: message,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Send a success response with consistent format.
|
|
56
|
+
*/
|
|
57
|
+
export function sendSuccess(reply, data) {
|
|
58
|
+
reply.send({
|
|
59
|
+
success: true,
|
|
60
|
+
data,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../utils/errors.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAA2C,CAAC;IAE7D,sDAAsD;IACtD,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACrE,qCAAqC;QACrC,IAAI,QAAQ,GAAI,QAAQ,CAAC,QAAmB,IAAI,cAAc,CAAC;QAC/D,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;YAChC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CACjC,iDAAiD,CAClD,CAAC;YACF,IAAI,aAAa,EAAE,CAAC;gBAClB,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACrC,OAAO,qCAAqC,QAAQ,0LAA0L,CAAC;QACjP,CAAC;QACD,OAAO,4BAA4B,QAAQ,qFAAqF,CAAC;IACnI,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,CAAC;QACvD,OAAO,iEAAiE,CAAC;IAC3E,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/E,OAAO,6FAA6F,CAAC;IACvG,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACjE,OAAO,iFAAiF,CAAC;IAC3F,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;QAC/G,OAAO,mBAAmB,OAAO,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjE,OAAO,2BAA2B,OAAO,kCAAkC,CAAC;IAC9E,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,KAAmB,EAAE,UAAkB,EAAE,KAAc;IAC/E,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC5C,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC5B,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,OAAO;KACf,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAI,KAAmB,EAAE,IAAQ;IAC1D,KAAK,CAAC,IAAI,CAAC;QACT,OAAO,EAAE,IAAI;QACb,IAAI;KACL,CAAC,CAAC;AACL,CAAC"}
|