inibase 1.0.0-rc.123 → 1.0.0-rc.125
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 +93 -9
- package/dist/file.js +2 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +10 -13
- package/dist/utils.server.js +14 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,40 +106,124 @@ interface {
|
|
|
106
106
|
<summary>Schema</summary>
|
|
107
107
|
<blockquote>
|
|
108
108
|
|
|
109
|
+
<details>
|
|
110
|
+
<summary>Types</summary>
|
|
111
|
+
<blockquote>
|
|
112
|
+
|
|
109
113
|
```ts
|
|
110
|
-
interface {
|
|
114
|
+
interface Field {
|
|
111
115
|
id: number; // stored as a Number but displayed as a hashed ID
|
|
112
116
|
key: string;
|
|
113
117
|
required?: boolean;
|
|
114
|
-
unique?: boolean;
|
|
115
|
-
|
|
118
|
+
unique?: boolean | string; // boolean for simple uniqueness, string for grouped uniqueness
|
|
119
|
+
regex?: RegExp; // Regular expression for custom validation
|
|
120
|
+
type:
|
|
121
|
+
| "string"
|
|
122
|
+
| "number"
|
|
123
|
+
| "boolean"
|
|
124
|
+
| "date"
|
|
125
|
+
| "email"
|
|
126
|
+
| "url"
|
|
127
|
+
| "password"
|
|
128
|
+
| "html"
|
|
129
|
+
| "ip"
|
|
130
|
+
| "json"
|
|
131
|
+
| "id";
|
|
116
132
|
}
|
|
117
|
-
|
|
133
|
+
|
|
134
|
+
interface TableField {
|
|
118
135
|
id: number;
|
|
119
136
|
key: string;
|
|
120
137
|
required?: boolean;
|
|
138
|
+
unique?: boolean | string; // Supports uniqueness constraints
|
|
121
139
|
type: "table";
|
|
122
140
|
table: string;
|
|
123
141
|
}
|
|
124
|
-
|
|
142
|
+
|
|
143
|
+
interface ArrayField {
|
|
125
144
|
id: number;
|
|
126
145
|
key: string;
|
|
127
146
|
required?: boolean;
|
|
147
|
+
unique?: boolean | string; // Supports uniqueness constraints
|
|
128
148
|
type: "array";
|
|
129
|
-
children: string|string[];
|
|
149
|
+
children: string | string[]; // Can be a single type or an array of types
|
|
130
150
|
}
|
|
131
|
-
|
|
151
|
+
|
|
152
|
+
interface ObjectOrArrayOfObjectsField {
|
|
132
153
|
id: number;
|
|
133
154
|
key: string;
|
|
134
155
|
required?: boolean;
|
|
156
|
+
unique?: boolean | string; // Supports uniqueness constraints
|
|
157
|
+
regex?: RegExp; // For validation of object-level keys
|
|
135
158
|
type: "object" | "array";
|
|
136
|
-
children: Schema;
|
|
159
|
+
children: Schema; // Nested schema for objects or arrays
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
</blockquote>
|
|
164
|
+
</details>
|
|
165
|
+
|
|
166
|
+
<details>
|
|
167
|
+
<summary>Unique</summary>
|
|
168
|
+
<blockquote>
|
|
169
|
+
|
|
170
|
+
The `unique` property ensures that the values of a specific column or a group of columns are unique within a table. This property can be either a boolean or a string.
|
|
171
|
+
- **Boolean**: Setting `unique: true` ensures that the values in the column are unique across all rows.
|
|
172
|
+
- **String**: By setting a string value, you can group columns to enforce a combined uniqueness constraint. This is useful when you need to ensure that a combination of values across multiple fields is unique.
|
|
173
|
+
|
|
174
|
+
<details>
|
|
175
|
+
<summary>Examples</summary>
|
|
176
|
+
<blockquote>
|
|
177
|
+
|
|
178
|
+
<details>
|
|
179
|
+
<summary>Unique Column</summary>
|
|
180
|
+
<blockquote>
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
{
|
|
184
|
+
key: "email",
|
|
185
|
+
type: "string",
|
|
186
|
+
required: true,
|
|
187
|
+
unique: true, // Ensures all email values are unique
|
|
137
188
|
}
|
|
138
189
|
```
|
|
139
190
|
|
|
140
191
|
</blockquote>
|
|
141
192
|
</details>
|
|
142
193
|
|
|
194
|
+
<details>
|
|
195
|
+
<summary>Group of Unique Columns</summary>
|
|
196
|
+
<blockquote>
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
[
|
|
200
|
+
{
|
|
201
|
+
key: "firstName",
|
|
202
|
+
type: "string",
|
|
203
|
+
required: true,
|
|
204
|
+
unique: "nameGroup", // Part of "nameGroup" uniqueness
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
key: "lastName",
|
|
208
|
+
type: "string",
|
|
209
|
+
required: true,
|
|
210
|
+
unique: "nameGroup", // Part of "nameGroup" uniqueness
|
|
211
|
+
},
|
|
212
|
+
]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
</blockquote>
|
|
216
|
+
</details>
|
|
217
|
+
|
|
218
|
+
</blockquote>
|
|
219
|
+
</details>
|
|
220
|
+
|
|
221
|
+
</blockquote>
|
|
222
|
+
</details>
|
|
223
|
+
|
|
224
|
+
</blockquote>
|
|
225
|
+
</details>
|
|
226
|
+
|
|
143
227
|
<details>
|
|
144
228
|
<summary>Create Table</summary>
|
|
145
229
|
<blockquote>
|
|
@@ -357,7 +441,7 @@ const product = await db.post("product", productTableData);
|
|
|
357
441
|
</blockquote>
|
|
358
442
|
</details>
|
|
359
443
|
|
|
360
|
-
<details>
|
|
444
|
+
<details open>
|
|
361
445
|
<summary>Methods</summary>
|
|
362
446
|
<blockquote>
|
|
363
447
|
|
package/dist/file.js
CHANGED
|
@@ -399,7 +399,7 @@ export const append = async (filePath, data) => {
|
|
|
399
399
|
}
|
|
400
400
|
else {
|
|
401
401
|
const escapedFileTempPath = escapeShellPath(fileTempPath);
|
|
402
|
-
await exec(`echo
|
|
402
|
+
await exec(`echo '${(Array.isArray(data) ? data.join("\n") : data)
|
|
403
403
|
.toString()
|
|
404
404
|
.replace(/'/g, "\\'")}' | gzip - >> ${escapedFileTempPath}`);
|
|
405
405
|
}
|
|
@@ -542,7 +542,7 @@ export const search = async (filePath, operator, comparedAtValue, logicalOperato
|
|
|
542
542
|
// Increment the line count for each line.
|
|
543
543
|
linesCount++;
|
|
544
544
|
// Search only in provided linesNumbers
|
|
545
|
-
if (searchIn && (!searchIn.has(linesCount) || searchIn.has(-linesCount)))
|
|
545
|
+
if (searchIn?.size && (!searchIn.has(linesCount) || searchIn.has(-linesCount)))
|
|
546
546
|
continue;
|
|
547
547
|
// Decode the line for comparison.
|
|
548
548
|
const decodedLine = decode(line, fieldType, fieldChildrenType, secretKey);
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -381,13 +381,13 @@ export default class Inibase {
|
|
|
381
381
|
if (!Array.isArray(value))
|
|
382
382
|
value = [value];
|
|
383
383
|
if (Utils.isArrayOfObjects(fieldChildrenType))
|
|
384
|
-
return this.
|
|
384
|
+
return this.formatData(value, fieldChildrenType);
|
|
385
385
|
if (!value.length)
|
|
386
386
|
return null;
|
|
387
387
|
return value.map((_value) => this.formatField(_value, fieldChildrenType));
|
|
388
388
|
case "object":
|
|
389
389
|
if (Utils.isArrayOfObjects(fieldChildrenType))
|
|
390
|
-
return this.
|
|
390
|
+
return this.formatData(value, fieldChildrenType, _formatOnlyAvailiableKeys);
|
|
391
391
|
break;
|
|
392
392
|
case "table":
|
|
393
393
|
if (Utils.isObject(value)) {
|
|
@@ -438,24 +438,24 @@ export default class Inibase {
|
|
|
438
438
|
for await (const [columnID, values] of valueObject.columnsValues) {
|
|
439
439
|
index++;
|
|
440
440
|
const field = flattenSchema.find(({ id }) => id === columnID);
|
|
441
|
-
const [searchResult, totalLines] = await File.search(join(tablePath, `${field.key}${this.getFileExtension(tableName)}`), "[]", values, undefined, valueObject.exclude, field.type, field.children, 1, undefined, false, this.salt);
|
|
441
|
+
const [searchResult, totalLines] = await File.search(join(tablePath, `${field.key}${this.getFileExtension(tableName)}`), "[]", Array.from(values), undefined, valueObject.exclude, field.type, field.children, 1, undefined, false, this.salt);
|
|
442
442
|
if (searchResult && totalLines > 0) {
|
|
443
443
|
if (index === valueObject.columnsValues.size)
|
|
444
444
|
throw this.createError("FIELD_UNIQUE", [
|
|
445
445
|
field.key,
|
|
446
|
-
Array.
|
|
446
|
+
Array.from(values).join(", "),
|
|
447
447
|
]);
|
|
448
448
|
}
|
|
449
449
|
else
|
|
450
|
-
|
|
450
|
+
return;
|
|
451
451
|
}
|
|
452
452
|
}
|
|
453
453
|
this.uniqueMap = new Map();
|
|
454
454
|
}
|
|
455
|
-
|
|
455
|
+
formatData(data, schema, formatOnlyAvailiableKeys) {
|
|
456
456
|
const clonedData = JSON.parse(JSON.stringify(data));
|
|
457
457
|
if (Utils.isArrayOfObjects(clonedData))
|
|
458
|
-
return clonedData.map((singleData) => this.
|
|
458
|
+
return clonedData.map((singleData) => this.formatData(singleData, schema, formatOnlyAvailiableKeys));
|
|
459
459
|
if (Utils.isObject(clonedData)) {
|
|
460
460
|
const RETURN = {};
|
|
461
461
|
for (const field of schema) {
|
|
@@ -471,9 +471,6 @@ export default class Inibase {
|
|
|
471
471
|
}
|
|
472
472
|
return [];
|
|
473
473
|
}
|
|
474
|
-
formatData(tableName, data, formatOnlyAvailiableKeys) {
|
|
475
|
-
data = this._formatData(data, this.tablesMap.get(tableName).schema, formatOnlyAvailiableKeys);
|
|
476
|
-
}
|
|
477
474
|
getDefaultValue(field) {
|
|
478
475
|
if (Array.isArray(field.type))
|
|
479
476
|
return this.getDefaultValue({
|
|
@@ -1192,7 +1189,7 @@ export default class Inibase {
|
|
|
1192
1189
|
data.createdAt = Date.now();
|
|
1193
1190
|
data.updatedAt = undefined;
|
|
1194
1191
|
}
|
|
1195
|
-
this.formatData(tableName,
|
|
1192
|
+
data = this.formatData(data, this.tablesMap.get(tableName).schema, true);
|
|
1196
1193
|
const pathesContents = this.joinPathesContents(tableName, this.tablesMap.get(tableName).config.prepend
|
|
1197
1194
|
? Array.isArray(data)
|
|
1198
1195
|
? data.toReversed()
|
|
@@ -1245,7 +1242,7 @@ export default class Inibase {
|
|
|
1245
1242
|
return this.put(tableName, data, data.id, options, returnUpdatedData || undefined);
|
|
1246
1243
|
}
|
|
1247
1244
|
await this.validateData(tableName, data, true);
|
|
1248
|
-
this.formatData(
|
|
1245
|
+
data = this.formatData(data, this.tablesMap.get(tableName).schema, true);
|
|
1249
1246
|
const pathesContents = this.joinPathesContents(tableName, {
|
|
1250
1247
|
...(({ id, ...restOfData }) => restOfData)(data),
|
|
1251
1248
|
updatedAt: Date.now(),
|
|
@@ -1280,7 +1277,7 @@ export default class Inibase {
|
|
|
1280
1277
|
Utils.isNumber(where)) {
|
|
1281
1278
|
// "where" in this case, is the line(s) number(s) and not id(s)
|
|
1282
1279
|
await this.validateData(tableName, data, true);
|
|
1283
|
-
this.formatData(
|
|
1280
|
+
data = this.formatData(data, this.tablesMap.get(tableName).schema, true);
|
|
1284
1281
|
const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(tableName, Utils.isArrayOfObjects(data)
|
|
1285
1282
|
? data.map((item) => ({
|
|
1286
1283
|
...item,
|
package/dist/utils.server.js
CHANGED
|
@@ -210,9 +210,20 @@ export const isEqual = (originalValue, comparedValue, fieldType) => {
|
|
|
210
210
|
: false;
|
|
211
211
|
case "boolean":
|
|
212
212
|
return Number(originalValue) === Number(comparedValue);
|
|
213
|
-
default:
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
default: {
|
|
214
|
+
// Fast checks for null-like values
|
|
215
|
+
const isOriginalNullLike = originalValue === null ||
|
|
216
|
+
originalValue === undefined ||
|
|
217
|
+
originalValue === "";
|
|
218
|
+
const isComparedNullLike = comparedValue === null ||
|
|
219
|
+
comparedValue === undefined ||
|
|
220
|
+
comparedValue === "";
|
|
221
|
+
// If both are null-like, treat as equivalent
|
|
222
|
+
if (isOriginalNullLike && isComparedNullLike)
|
|
223
|
+
return true;
|
|
224
|
+
// Direct equality check for other cases
|
|
225
|
+
return originalValue === comparedValue;
|
|
226
|
+
}
|
|
216
227
|
}
|
|
217
228
|
};
|
|
218
229
|
/**
|