dimond-db 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.
@@ -0,0 +1,133 @@
1
+ import { ValidationError } from '../errors/DatabaseError.js';
2
+
3
+ /**
4
+ * Validates a document before insertion or update
5
+ * @param {*} doc - The document to validate
6
+ * @throws {ValidationError} If validation fails
7
+ */
8
+ export function validateDocument(doc) {
9
+ if (doc === null || doc === undefined) {
10
+ throw new ValidationError('Document cannot be null or undefined');
11
+ }
12
+
13
+ if (typeof doc !== 'object') {
14
+ throw new ValidationError('Document must be an object');
15
+ }
16
+
17
+ if (Array.isArray(doc)) {
18
+ throw new ValidationError('Document cannot be an array');
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Validates an array of documents
24
+ * @param {Array} docs - The documents to validate
25
+ * @throws {ValidationError} If validation fails
26
+ */
27
+ export function validateDocuments(docs) {
28
+ if (!Array.isArray(docs)) {
29
+ throw new ValidationError('Documents must be an array');
30
+ }
31
+
32
+ if (docs.length === 0) {
33
+ throw new ValidationError('Documents array cannot be empty');
34
+ }
35
+
36
+ docs.forEach((doc, index) => {
37
+ try {
38
+ validateDocument(doc);
39
+ } catch (error) {
40
+ throw new ValidationError(`Document at index ${index}: ${error.message}`);
41
+ }
42
+ });
43
+ }
44
+
45
+ /**
46
+ * Validates a query filter object
47
+ * @param {Object} filter - The filter to validate
48
+ * @throws {ValidationError} If validation fails
49
+ */
50
+ export function validateFilter(filter) {
51
+ if (filter === null || filter === undefined) {
52
+ return; // Empty filter is valid (matches all)
53
+ }
54
+
55
+ if (typeof filter !== 'object') {
56
+ throw new ValidationError('Filter must be an object');
57
+ }
58
+
59
+ if (Array.isArray(filter)) {
60
+ throw new ValidationError('Filter cannot be an array');
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Validates an update operation object
66
+ * @param {Object} update - The update operation to validate
67
+ * @throws {ValidationError} If validation fails
68
+ */
69
+ export function validateUpdate(update) {
70
+ if (update === null || update === undefined) {
71
+ throw new ValidationError('Update cannot be null or undefined');
72
+ }
73
+
74
+ if (typeof update !== 'object') {
75
+ throw new ValidationError('Update must be an object');
76
+ }
77
+
78
+ if (Array.isArray(update)) {
79
+ throw new ValidationError('Update cannot be an array');
80
+ }
81
+
82
+ if (Object.keys(update).length === 0) {
83
+ throw new ValidationError('Update cannot be empty');
84
+ }
85
+
86
+ // Check if all top-level keys are valid operators
87
+ const validOperators = ['$set', '$unset', '$inc', '$push'];
88
+ const keys = Object.keys(update);
89
+
90
+ const hasOperators = keys.some(key => key.startsWith('$'));
91
+ const hasNonOperators = keys.some(key => !key.startsWith('$'));
92
+
93
+ if (hasOperators && hasNonOperators) {
94
+ throw new ValidationError('Update cannot mix operators and direct field assignments');
95
+ }
96
+
97
+ if (hasOperators) {
98
+ const invalidOperators = keys.filter(key => !validOperators.includes(key));
99
+ if (invalidOperators.length > 0) {
100
+ throw new ValidationError(`Invalid update operators: ${invalidOperators.join(', ')}`);
101
+ }
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Validates a collection name
107
+ * @param {string} name - The collection name to validate
108
+ * @throws {ValidationError} If validation fails
109
+ */
110
+ export function validateCollectionName(name) {
111
+ if (typeof name !== 'string') {
112
+ throw new ValidationError('Collection name must be a string');
113
+ }
114
+
115
+ if (name.length === 0) {
116
+ throw new ValidationError('Collection name cannot be empty');
117
+ }
118
+
119
+ if (name.length > 64) {
120
+ throw new ValidationError('Collection name cannot exceed 64 characters');
121
+ }
122
+
123
+ // Check for invalid characters
124
+ const invalidChars = /[\\/:*?"<>|]/;
125
+ if (invalidChars.test(name)) {
126
+ throw new ValidationError('Collection name contains invalid characters');
127
+ }
128
+
129
+ // Prevent reserved names
130
+ if (name.startsWith('system.')) {
131
+ throw new ValidationError('Collection name cannot start with "system."');
132
+ }
133
+ }