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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/SECURITY.md +15 -0
  4. package/database/procedure.ts +129 -0
  5. package/database/query.ts +78 -0
  6. package/database/sql_types.d.ts +52 -0
  7. package/database/sql_types.ts +90 -0
  8. package/database/table.ts +378 -0
  9. package/database.ts +26 -0
  10. package/dist/database/procedure.d.ts +26 -0
  11. package/dist/database/procedure.js +107 -0
  12. package/dist/database/procedure.js.map +1 -0
  13. package/dist/database/query.d.ts +13 -0
  14. package/dist/database/query.js +79 -0
  15. package/dist/database/query.js.map +1 -0
  16. package/dist/database/sql_types.d.ts +48 -0
  17. package/dist/database/sql_types.js +50 -0
  18. package/dist/database/sql_types.js.map +1 -0
  19. package/dist/database/table.d.ts +54 -0
  20. package/dist/database/table.js +308 -0
  21. package/dist/database/table.js.map +1 -0
  22. package/dist/database.d.ts +24 -0
  23. package/dist/database.js +28 -0
  24. package/dist/database.js.map +1 -0
  25. package/dist/operations/config.d.ts +22 -0
  26. package/dist/operations/config.js +30 -0
  27. package/dist/operations/config.js.map +1 -0
  28. package/dist/operations/connect_to_server.d.ts +28 -0
  29. package/dist/operations/connect_to_server.js +108 -0
  30. package/dist/operations/connect_to_server.js.map +1 -0
  31. package/dist/operations/data_types.d.ts +6 -0
  32. package/dist/operations/data_types.js +120 -0
  33. package/dist/operations/data_types.js.map +1 -0
  34. package/dist/operations/get_pieces.d.ts +29 -0
  35. package/dist/operations/get_pieces.js +56 -0
  36. package/dist/operations/get_pieces.js.map +1 -0
  37. package/dist/operations/log.d.ts +12 -0
  38. package/dist/operations/log.js +27 -0
  39. package/dist/operations/log.js.map +1 -0
  40. package/dist/operations/procedure_execute.d.ts +18 -0
  41. package/dist/operations/procedure_execute.js +53 -0
  42. package/dist/operations/procedure_execute.js.map +1 -0
  43. package/operations/config.ts +28 -0
  44. package/operations/connect_to_server.ts +111 -0
  45. package/operations/data_types.ts +129 -0
  46. package/operations/get_pieces.ts +63 -0
  47. package/operations/log.ts +27 -0
  48. package/operations/procedure_execute.ts +58 -0
  49. package/package.json +55 -0
  50. package/simple/advanced-test.js +631 -0
  51. package/simple/config.simple.js +9 -0
  52. package/simple/config.simple.ts +9 -0
  53. package/simple/test.js +398 -0
  54. package/simple/test.ts +392 -0
  55. 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
+ }