easy-postgresql 0.0.1
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/LICENSE +21 -0
- package/README.md +45 -0
- package/SECURITY.md +15 -0
- package/database/procedure.ts +129 -0
- package/database/query.ts +78 -0
- package/database/sql_types.d.ts +52 -0
- package/database/sql_types.ts +90 -0
- package/database/table.ts +378 -0
- package/database.ts +26 -0
- package/dist/database/procedure.d.ts +26 -0
- package/dist/database/procedure.js +107 -0
- package/dist/database/procedure.js.map +1 -0
- package/dist/database/query.d.ts +13 -0
- package/dist/database/query.js +79 -0
- package/dist/database/query.js.map +1 -0
- package/dist/database/sql_types.d.ts +48 -0
- package/dist/database/sql_types.js +50 -0
- package/dist/database/sql_types.js.map +1 -0
- package/dist/database/table.d.ts +54 -0
- package/dist/database/table.js +308 -0
- package/dist/database/table.js.map +1 -0
- package/dist/database.d.ts +24 -0
- package/dist/database.js +28 -0
- package/dist/database.js.map +1 -0
- package/dist/operations/config.d.ts +22 -0
- package/dist/operations/config.js +30 -0
- package/dist/operations/config.js.map +1 -0
- package/dist/operations/connect_to_server.d.ts +28 -0
- package/dist/operations/connect_to_server.js +108 -0
- package/dist/operations/connect_to_server.js.map +1 -0
- package/dist/operations/data_types.d.ts +6 -0
- package/dist/operations/data_types.js +120 -0
- package/dist/operations/data_types.js.map +1 -0
- package/dist/operations/get_pieces.d.ts +29 -0
- package/dist/operations/get_pieces.js +56 -0
- package/dist/operations/get_pieces.js.map +1 -0
- package/dist/operations/log.d.ts +12 -0
- package/dist/operations/log.js +27 -0
- package/dist/operations/log.js.map +1 -0
- package/dist/operations/procedure_execute.d.ts +18 -0
- package/dist/operations/procedure_execute.js +53 -0
- package/dist/operations/procedure_execute.js.map +1 -0
- package/operations/config.ts +28 -0
- package/operations/connect_to_server.ts +111 -0
- package/operations/data_types.ts +129 -0
- package/operations/get_pieces.ts +63 -0
- package/operations/log.ts +27 -0
- package/operations/procedure_execute.ts +58 -0
- package/package.json +55 -0
- package/simple/advanced-test.js +631 -0
- package/simple/config.simple.js +9 -0
- package/simple/config.simple.ts +9 -0
- package/simple/test.js +398 -0
- package/simple/test.ts +392 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class is used to create an object of any data type.
|
|
3
|
+
*/
|
|
4
|
+
class Any {
|
|
5
|
+
value: any;
|
|
6
|
+
|
|
7
|
+
constructor(value: any) {
|
|
8
|
+
this.value = value;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This function is used to check if the value is null.
|
|
14
|
+
*
|
|
15
|
+
* @param value - The data to be checked
|
|
16
|
+
* @returns boolean - Returns true if the value is null, false otherwise
|
|
17
|
+
*/
|
|
18
|
+
const isNull = (value: any): boolean => value === null;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* This object contains functions to convert values to specific data types.
|
|
22
|
+
*/
|
|
23
|
+
const types = {
|
|
24
|
+
/**
|
|
25
|
+
* Converts a value to a string.
|
|
26
|
+
* @param value - The value to be converted
|
|
27
|
+
* @returns string | null - The converted string value or null
|
|
28
|
+
*/
|
|
29
|
+
string: (value: any): string | null => {
|
|
30
|
+
return isNull(value) ? null : String(value);
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Converts a value to a number.
|
|
35
|
+
* @param value - The value to be converted
|
|
36
|
+
* @returns number | null - The converted number value or null
|
|
37
|
+
*/
|
|
38
|
+
number: (value: any): number | null => {
|
|
39
|
+
return isNull(value) ? null : Number(value);
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Converts a value to a boolean.
|
|
44
|
+
* @param value - The value to be converted
|
|
45
|
+
* @returns boolean | null - The converted boolean value or null
|
|
46
|
+
*/
|
|
47
|
+
boolean: (value: any): boolean | null => {
|
|
48
|
+
return isNull(value) ? null : Boolean(value);
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Converts a value to a Date.
|
|
53
|
+
* @param value - The value to be converted
|
|
54
|
+
* @returns Date | null - The converted Date value or null
|
|
55
|
+
*/
|
|
56
|
+
date: (value: any): Date | null => {
|
|
57
|
+
return isNull(value) ? null : new Date(value);
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Converts a value to a Buffer.
|
|
62
|
+
* @param value - The value to be converted
|
|
63
|
+
* @returns Buffer | null - The converted Buffer value or null
|
|
64
|
+
*/
|
|
65
|
+
buffer: (value: any): Buffer | null => {
|
|
66
|
+
return isNull(value) ? null : Buffer.from(String(value));
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Converts a value to an Array.
|
|
71
|
+
* @param value - The value to be converted
|
|
72
|
+
* @returns any[] | null - The converted Array value or null
|
|
73
|
+
*/
|
|
74
|
+
array: (value: any): any[] | null => {
|
|
75
|
+
return isNull(value) ? null : Array.isArray(value) ? value : [value];
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Wraps a value in an Any object.
|
|
80
|
+
* @param value - The value to be wrapped
|
|
81
|
+
* @returns Any | null - The wrapped value or null
|
|
82
|
+
*/
|
|
83
|
+
any: (value: any): Any | null => {
|
|
84
|
+
return isNull(value) ? null : new Any(value);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
type TypeConverter = (value: any) => any;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* This object contains the data types of PostgreSQL and their corresponding JavaScript data type converters.
|
|
92
|
+
*/
|
|
93
|
+
export const sqlTypes: Record<string, TypeConverter> = {
|
|
94
|
+
"char": types.string,
|
|
95
|
+
"character": types.string,
|
|
96
|
+
"varchar": types.string,
|
|
97
|
+
"character varying": types.string,
|
|
98
|
+
"text": types.string,
|
|
99
|
+
"bytea": types.buffer,
|
|
100
|
+
"bool": types.boolean,
|
|
101
|
+
"boolean": types.boolean,
|
|
102
|
+
"int2": types.number,
|
|
103
|
+
"smallint": types.number,
|
|
104
|
+
"int4": types.number,
|
|
105
|
+
"integer": types.number,
|
|
106
|
+
"int8": types.number,
|
|
107
|
+
"bigint": types.number,
|
|
108
|
+
"decimal": types.number,
|
|
109
|
+
"numeric": types.number,
|
|
110
|
+
"float4": types.number,
|
|
111
|
+
"real": types.number,
|
|
112
|
+
"float8": types.number,
|
|
113
|
+
"double precision": types.number,
|
|
114
|
+
"money": types.number,
|
|
115
|
+
"timestamp": types.date,
|
|
116
|
+
"timestamptz": types.date,
|
|
117
|
+
"timestamp without time zone": types.date,
|
|
118
|
+
"timestamp with time zone": types.date,
|
|
119
|
+
"date": types.date,
|
|
120
|
+
"time": types.string,
|
|
121
|
+
"timetz": types.string,
|
|
122
|
+
"time without time zone": types.string,
|
|
123
|
+
"time with time zone": types.string,
|
|
124
|
+
"uuid": types.string,
|
|
125
|
+
"xml": types.string,
|
|
126
|
+
"json": types.any,
|
|
127
|
+
"jsonb": types.any,
|
|
128
|
+
"ARRAY": types.array,
|
|
129
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface ParameterizedPieces {
|
|
2
|
+
condition: string;
|
|
3
|
+
inputs: any[];
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface InsertPieces {
|
|
7
|
+
columns: string;
|
|
8
|
+
values: string;
|
|
9
|
+
inputs: any[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Converts an object into a parameterized WHERE/SET condition string.
|
|
14
|
+
* Generates $1, $2... positional placeholders to prevent SQL injection.
|
|
15
|
+
*
|
|
16
|
+
* @param data - The key/value pairs to parameterize
|
|
17
|
+
* @param startIndex - Starting positional index for parameters (default: 0, meaning first param is $1)
|
|
18
|
+
* @returns Parameterized condition and ordered input values array
|
|
19
|
+
*/
|
|
20
|
+
export const getConditionPieces = (data: Record<string, any> = {}, startIndex: number = 0): ParameterizedPieces => {
|
|
21
|
+
const keys = Object.keys(data).filter(key => isValidIdentifier(key));
|
|
22
|
+
const condition = keys.map((key, i) => `${key} = $${startIndex + i + 1}`).join(' AND ');
|
|
23
|
+
const inputs: any[] = keys.map(key => sanitizeValue(data[key]));
|
|
24
|
+
return { condition, inputs };
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Converts an object into a parameterized INSERT fragment.
|
|
29
|
+
*
|
|
30
|
+
* @param data - The key/value pairs to insert
|
|
31
|
+
* @returns Column names, positional placeholders ($1, $2...), and ordered input values
|
|
32
|
+
*/
|
|
33
|
+
export const getInsertPieces = (data: Record<string, any> = {}): InsertPieces => {
|
|
34
|
+
const keys = Object.keys(data).filter(key => isValidIdentifier(key));
|
|
35
|
+
const columns = keys.join(', ');
|
|
36
|
+
const values = keys.map((_, i) => `$${i + 1}`).join(', ');
|
|
37
|
+
const inputs: any[] = keys.map(key => sanitizeValue(data[key]));
|
|
38
|
+
return { columns, values, inputs };
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Validates that a SQL identifier (table/column name) contains only safe characters.
|
|
43
|
+
*/
|
|
44
|
+
export const isValidIdentifier = (name: string): boolean => {
|
|
45
|
+
return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Sanitizes a value for use as a SQL parameter.
|
|
50
|
+
* Converts undefined/NaN to null, booleans to true/false, bigint to string.
|
|
51
|
+
*/
|
|
52
|
+
function sanitizeValue(value: any): any {
|
|
53
|
+
if (value === undefined || value === null || (typeof value === 'number' && isNaN(value))) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (typeof value === 'boolean') {
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
if (typeof value === 'bigint') {
|
|
60
|
+
return value.toString();
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import 'colors';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This function is used to display logs in the console.
|
|
5
|
+
*
|
|
6
|
+
* @param title - The title of the log.
|
|
7
|
+
* @param alt - The alternative title of the log.
|
|
8
|
+
* @param description - The description of the log.
|
|
9
|
+
* @param file - The file of the log.
|
|
10
|
+
*/
|
|
11
|
+
function Log(title: string | null, alt: string | null, description: string | null, file: string | null = null): void {
|
|
12
|
+
title = title ? (title.length > 20 ? title.substring(0, 20) + '...' : title) : null;
|
|
13
|
+
alt = alt ? (alt.length > 20 ? alt.substring(0, 20) + '...' : alt) : null;
|
|
14
|
+
description = description ? (description.length > 50 ? description.substring(0, 50) + '...' : description) : null;
|
|
15
|
+
file = file ? (file.length > 20 ? file.substring(0, 20) + '...' : file) : null;
|
|
16
|
+
|
|
17
|
+
let time = (new Date().toLocaleTimeString()).gray;
|
|
18
|
+
title = title ? ('[' + title.trim() + ']').cyan.bold as any as string : null;
|
|
19
|
+
alt = alt ? ('(' + alt.trim() + ')').magenta : null;
|
|
20
|
+
description = description ? description.trim().green : null;
|
|
21
|
+
file = file ? ('[' + file.trim() + ']').gray : 'easy-postgresql'.gray;
|
|
22
|
+
|
|
23
|
+
const data = [time, title, alt, description, file].filter(f => f !== null && f !== undefined);
|
|
24
|
+
console.log(data.join(' '));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const log = Log;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getPool } from './connect_to_server';
|
|
2
|
+
import { config } from './config';
|
|
3
|
+
import { log } from './log';
|
|
4
|
+
|
|
5
|
+
interface ProcedureResult {
|
|
6
|
+
status: number;
|
|
7
|
+
message: string;
|
|
8
|
+
data: any[] | any | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ProcedureReference {
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function pgTypeOf(value: any): string {
|
|
16
|
+
if (value === null || value === undefined) return 'text';
|
|
17
|
+
if (typeof value === 'number') return Number.isInteger(value) ? 'integer' : 'float8';
|
|
18
|
+
if (typeof value === 'boolean') return 'boolean';
|
|
19
|
+
if (value instanceof Date) return 'timestamp';
|
|
20
|
+
if (Buffer.isBuffer(value)) return 'bytea';
|
|
21
|
+
return 'text';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Executes a stored procedure/function in the database.
|
|
26
|
+
*
|
|
27
|
+
* @param procedureName - The name of the stored procedure/function
|
|
28
|
+
* @param reference - The input parameters for the procedure
|
|
29
|
+
* @param useRecordsets - If true, wraps rows in array; otherwise returns rows directly
|
|
30
|
+
* @returns Promise<ProcedureResult>
|
|
31
|
+
*/
|
|
32
|
+
export const executeProcedure = async (
|
|
33
|
+
procedureName: string,
|
|
34
|
+
reference: ProcedureReference = {},
|
|
35
|
+
useRecordsets: boolean = false
|
|
36
|
+
): Promise<ProcedureResult> => {
|
|
37
|
+
try {
|
|
38
|
+
const keys = Object.keys(reference);
|
|
39
|
+
const values = keys.map(k => reference[k]);
|
|
40
|
+
const params = keys.map((_, i) => `$${i + 1}::${pgTypeOf(values[i])}`).join(', ');
|
|
41
|
+
const queryText = `SELECT * FROM ${procedureName}(${params})`;
|
|
42
|
+
|
|
43
|
+
const pool = getPool();
|
|
44
|
+
const client = await pool.connect();
|
|
45
|
+
try {
|
|
46
|
+
const result = await client.query(queryText, values);
|
|
47
|
+
const data = useRecordsets ? [result.rows] : result.rows;
|
|
48
|
+
return { status: 200, message: 'Success', data };
|
|
49
|
+
} finally {
|
|
50
|
+
client.release();
|
|
51
|
+
}
|
|
52
|
+
} catch (err) {
|
|
53
|
+
if (config.get.logingMode()) {
|
|
54
|
+
log('Procedure', procedureName, err instanceof Error ? err.message : String(err));
|
|
55
|
+
}
|
|
56
|
+
return { status: 500, message: 'Error', data: null };
|
|
57
|
+
}
|
|
58
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "easy-postgresql",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "This is a simple and easy to use postgresql library for node.js",
|
|
5
|
+
"main": "dist/database.js",
|
|
6
|
+
"types": "dist/database.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/database.d.ts",
|
|
10
|
+
"default": "./dist/database.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"start": "node dist/simple/server.js",
|
|
15
|
+
"dev": "nodemon dist/simple/server.js",
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"watch": "tsc -w",
|
|
18
|
+
"test-ts": "ts-node simple/test.ts",
|
|
19
|
+
"test-js": "node simple/test.js",
|
|
20
|
+
"test": "npm run test-ts && npm run test-js",
|
|
21
|
+
"update": "update-modules"
|
|
22
|
+
},
|
|
23
|
+
"author": {
|
|
24
|
+
"name": "cihatksm",
|
|
25
|
+
"email": "me@cihatksm.com"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/cihatksm/easy-postgresql.git"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"cihatksm",
|
|
34
|
+
"cihatksm.com",
|
|
35
|
+
"sql",
|
|
36
|
+
"easy",
|
|
37
|
+
"easypostgresql",
|
|
38
|
+
"easy-postgresql",
|
|
39
|
+
"postgresql",
|
|
40
|
+
"node-postgresql",
|
|
41
|
+
"database"
|
|
42
|
+
],
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"colors": "^1.4.0",
|
|
45
|
+
"pg": "^8.16.0",
|
|
46
|
+
"update-modules": "^0.3.3"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/pg": "^8.16.0",
|
|
50
|
+
"@types/node": "^26.1.1",
|
|
51
|
+
"nodemon": "^3.1.14",
|
|
52
|
+
"ts-node": "^10.9.2",
|
|
53
|
+
"typescript": "^7.0.2"
|
|
54
|
+
}
|
|
55
|
+
}
|