New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

firestorm-db

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

firestorm-db - npm Package Compare versions

Comparing version 1.11.1 to 1.12.0

8

package.json
{
"name": "firestorm-db",
"version": "1.11.1",
"version": "1.12.0",
"description": "Self hosted Firestore-like database with API endpoints based on micro bulk operations",

@@ -45,3 +45,3 @@ "main": "src/index.js",

"devDependencies": {
"chai": "^4.3.10",
"chai": "^4.4.1",
"docdash": "^2.0.2",

@@ -52,5 +52,5 @@ "form-data": "^4.0.0",

"jsdoc-to-markdown": "^8.0.1",
"mocha": "^10.2.0",
"mocha": "^10.3.0",
"nyc": "^15.1.0",
"prettier": "^3.2.4",
"prettier": "^3.2.5",
"recursive-copy": "^2.0.14",

@@ -57,0 +57,0 @@ "typescript": "^5.3.3"

@@ -21,3 +21,3 @@ <div align="center">

## JavaScript Part
# JavaScript Part

@@ -62,3 +62,3 @@ The JavaScript [index.js](./src/index.js) file is just an [Axios](https://www.npmjs.com/package/axios) wrapper of the library.

- The name of the collection as a `String`.
- The method adder, which allows to inject methods to the get methods results. This would be a `Function` taking the element as an argument.
- The method adder, which lets you inject methods to query results. It's implemented similarly to [`Array.prototype.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map), taking an outputted element as an argument, modifying the element with methods and data inside a callback, and returning the modified element at the end.

@@ -68,7 +68,6 @@ ```js

// returns a Collection instance
const userCollection = firestorm.collection("users", (el) => {
el.hello = function () {
console.log(`${el.name} says hello!`);
};
el.hello = () => console.log(`${el.name} says hello!`);
// return the modified element back with the injected method
return el;
});

@@ -87,11 +86,12 @@

| Name | Parameters | Description |
| ----------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| sha1() | none | Get the sha1 hash of the file. Can be used to see if same file content without downloading the file. |
| readRaw() | none | Returns the whole content of the JSON. ID values are injected for easier iteration, so this may be different to sha1(). |
| get(id) | id: `string \| number` | Get an element from the collection. |
| search(searchOptions, random) | searchOptions: `SearchOption[]` random?:`boolean \| number` | Search through the collection You can randomize the output order with random as true or a given seed. |
| searchKeys(keys) | keys: `string[] \| number[]` | Search specific keys through the collection. |
| select(selectOption) | selectOption: `{ field: string[] }` | Get only selected fields from the collection Essentially an upgraded version of readRaw. |
| random(max, seed, offset) | max?: `integer >= -1` seed?: `integer` offset?:`integer >= 0` | Reads random entries of collection. |
| Name | Parameters | Description |
| ----------------------------- | ------------------------------------------------------------| --------------------------------------------------------------------------------------------------------------------- |
| sha1() | none | Get the sha1 hash of the file. Can be used to see if same file content without downloading the file. |
| readRaw() | none | Returns the whole content of the JSON. ID values are injected for easier iteration, so this may be different to sha1. |
| get(id) | id: `string \| number` | Get an element from the collection. |
| search(searchOptions, random) | searchOptions: `SearchOption[]` random?:`boolean \| number` | Search through the collection You can randomize the output order with random as true or a given seed. |
| searchKeys(keys) | keys: `string[] \| number[]` | Search specific keys through the collection. |
| select(selectOption) | selectOption: `{ fields: string[] }` | Get only selected fields from the collection Essentially an upgraded version of readRaw. |
| values(valueOption) | valueOption: `{ field: string, flatten?: boolean }` | Get all distinct non-null values for a given key across a collection. |
| random(max, seed, offset) | max?: `number >= -1` seed?: `number` offset?:`number >= 0` | Reads random entries of collection. |

@@ -104,22 +104,22 @@ The search method can take one or more options to filter entries in a collection. A search option takes a `field` with a `criteria` and compares it to a `value`. You can also use the boolean `ignoreCase` option for string values.

| Criteria | Types allowed | Description |
| ---------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- |
| `'!='` | `boolean`, `number`, `string` | Searches if the entry field's value is different from yours |
| `'=='` | `boolean`, `number`, `string` | Searches if the entry field's value is equal to yours |
| `'>='` | `number`, `string` | Searches if the entry field's value is greater or equal than yours |
| `'<='` | `number`, `string` | Searches if the entry field's value is equal to than yours |
| `'>'` | `number`, `string` | Searches if the entry field's value is greater than yours |
| `'<'` | `number`, `string` | Searches if the entry field's value is lower than yours |
| `'in'` | `number`, `string` | Searches if the entry field's value is in the array of values you gave |
| `'includes'` | `string` | Searches if the entry field's value includes your substring |
| `'startsWith'` | `string` | Searches if the entry field's value starts with your substring |
| `'endsWith'` | `string` | Searches if the entry field's value ends with your substring |
| `'array-contains'` | `Array` | Searches if the entry field's array contains your value |
| `'array-contains-any'` | `Array` | Searches if the entry field's array ends contains your one value of more inside your values array |
| `'array-length-eq'` | `number` | Searches if the entry field's array size is equal to your value |
| `'array-length-df'` | `number` | Searches if the entry field's array size is different from your value |
| `'array-length-lt'` | `number` | Searches if the entry field's array size is lower than your value |
| `'array-length-gt'` | `number` | Searches if the entry field's array size is lower greater than your value |
| `'array-length-le'` | `number` | Searches if the entry field's array size is lower or equal to your value |
| `'array-length-ge'` | `number` | Searches if the entry field's array size is greater or equal to your value |
| Criteria | Types allowed | Description |
| ---------------------- | ----------------------------- | --------------------------------------------------------------------------------- |
| `'!='` | `boolean`, `number`, `string` | Entry field's value is different from yours |
| `'=='` | `boolean`, `number`, `string` | Entry field's value is equal to yours |
| `'>='` | `number`, `string` | Entry field's value is greater or equal than yours |
| `'<='` | `number`, `string` | Entry field's value is equal to than yours |
| `'>'` | `number`, `string` | Entry field's value is greater than yours |
| `'<'` | `number`, `string` | Entry field's value is lower than yours |
| `'in'` | `number`, `string` | Entry field's value is in the array of values you gave |
| `'includes'` | `string` | Entry field's value includes your substring |
| `'startsWith'` | `string` | Entry field's value starts with your substring |
| `'endsWith'` | `string` | Entry field's value ends with your substring |
| `'array-contains'` | `Array` | Entry field's array contains your value |
| `'array-contains-any'` | `Array` | Entry field's array ends contains your one value of more inside your values array |
| `'array-length-eq'` | `number` | Entry field's array size is equal to your value |
| `'array-length-df'` | `number` | Entry field's array size is different from your value |
| `'array-length-lt'` | `number` | Entry field's array size is lower than your value |
| `'array-length-gt'` | `number` | Entry field's array size is lower greater than your value |
| `'array-length-le'` | `number` | Entry field's array size is lower or equal to your value |
| `'array-length-ge'` | `number` | Entry field's array size is greater or equal to your value |

@@ -130,3 +130,3 @@ ### Write operations

| ----------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------- |
| writeRaw() | none | Set the entire JSON file contents **/!\\ Very dangerous /!\\** |
| writeRaw() | none | Set the entire JSON file contents **⚠️ Very dangerous! ⚠️** |
| add(value) | value: `Object` | Adds one element with autoKey into the collection |

@@ -143,21 +143,21 @@ | addBulk(values) | value: `Object[]` | Adds multiple elements with autoKey into the collection |

Edit objects have an `id` to get the wanted element, a `field` they want to edit, an `operation` with what to do to this field, and a possible `value`. Here is a list of operations:
Edit objects have an `id` of the element, a `field` to edit, an `operation` with what to do to this field, and a possible `value`. Here is a list of operations:
| Operation | Value required | Types allowed | Description |
| -------------- | -------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `set` | Yes | `any` | Sets a field to a given value |
| `remove` | No | `any` | Removes a field from the element |
| `append` | Yes | `string` | Appends string at the end of the string field |
| `invert` | No | `any` | Inverts tate of boolean field |
| `increment` | No | `number` | Adds a number to the field, default is 1 |
| `decrement` | No | `number` | Retrieves a number to the field, default is -1 |
| `array-push ` | Yes | `any` | Push an element to the end of an array field |
| `array-delete` | Yes | `integer` | Removes and element at a certain index in an array field, check [array_splice documentation](https://www.php.net/manual/function.array-splice) offset for more infos |
| `array-splice` | Yes | `[integer, integer]` | Removes certain elements, check [array_splice documentation](https://www.php.net/manual/function.array-splice) offset and length for more infos |
| Operation | Needs value | Types allowed | Description |
| -------------- | ----------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `set` | Yes | `any` | Sets a field to a given value. |
| `remove` | No | `any` | Removes a field from the element. |
| `append` | Yes | `string` | Appends a new string at the end of the string field. |
| `invert` | No | `any` | Inverts the state of a boolean field. |
| `increment` | No | `number` | Adds a number to the field, default is 1. |
| `decrement` | No | `number` | Removes a number from the field, default is 1. |
| `array-push ` | Yes | `any` | Push an element to the end of an array field. |
| `array-delete` | Yes | `number` | Removes an element at a certain index in an array field. Check the PHP [array_splice](https://www.php.net/manual/function.array-splice) offset for more info. |
| `array-splice` | Yes | `[number, number]` | Removes certain elements. Check the PHP [array_splice](https://www.php.net/manual/function.array-splice) offset and length for more info. |
<br>
## PHP files
# PHP Part
The PHP files are the ones handling files, read and writes. They also handle GET and POST requests to manipulate the database.
The PHP files are the ones handling files, read and writes. They also handle `GET` and `POST` requests to manipulate the database.

@@ -197,3 +197,3 @@ ## PHP setup

## Files feature
## Firestorm Files

@@ -209,3 +209,3 @@ File API functions are detailed in the `files.php` PHP script. If you do not want to include this functionality, then just delete this file.

// subfolder of uploads location, must start with dirname($_SERVER['SCRIPT_FILENAME'])
// to force a subfolder of firestorm installation
// to force a subfolder of Firestorm installation
$STORAGE_LOCATION = dirname($_SERVER['SCRIPT_FILENAME']) . '/uploads/';

@@ -246,8 +246,4 @@ ```

uploadPromise
.then(() => {
console.log("Upload successful");
})
.catch((err) => {
consoler.error(err);
});
.then(() => console.log("Upload successful"))
.catch((err) => console.error(err));
```

@@ -266,8 +262,4 @@

getPromise
.then((fileContent) => {
console.log(fileContent); // 'but your kids are gonna love it.
})
.catch((err) => {
console.error(err);
});
.then((fileContent) => console.log(fileContent)) // 'but your kids are gonna love it.
.catch((err) => console.error(err));
```

@@ -287,8 +279,4 @@

deletePromise
.then(() => {
console.log("File successfully deleted");
})
.catch((err) => {
console.error(err);
});
.then(() => console.log("File successfully deleted"))
.catch((err) => console.error(err));
```

@@ -305,3 +293,3 @@

If you encounter a memory allocation issue, you have to allow more memory through this file `/etc/php/7.4/apache2/php.ini` with a bigger value here:
If you encounter a memory allocation issue, you have to allow more memory through `/etc/php/7.4/apache2/php.ini` with a bigger value:

@@ -314,5 +302,5 @@ ```

All Firestorm methods correspond to an equivalent Axios request to the relevant PHP file. Read requests are GET requests and write requests are POST requests with provided JSON data.
All Firestorm methods correspond to an equivalent Axios request to the relevant PHP file. Read requests are `GET` requests and write requests are `POST` requests with provided JSON data.
You always have the same first keys and the one key per method:
The first keys in the request will always be the same:

@@ -319,0 +307,0 @@ ```json

@@ -7,6 +7,6 @@ try {

* @typedef {Object} SearchOption
* @property {string} field - The field you want to search in
* @property {"!=" | "==" | ">=" | "<=" | "<" | ">" | "in" | "includes" | "startsWith" | "endsWith" | "array-contains" | "array-contains-any" | "array-length-(eq|df|gt|lt|ge|le)" } criteria - Filter criteria
* @property {string | number | boolean | Array } value - The value you want to compare
* @property {boolean} ignoreCase - Ignore case on search string
* @property {string} field - The field to be searched for
* @property {"!=" | "==" | ">=" | "<=" | "<" | ">" | "in" | "includes" | "startsWith" | "endsWith" | "array-contains" | "array-contains-any" | "array-length-(eq|df|gt|lt|ge|le)"} criteria - Search criteria to filter results
* @property {string | number | boolean | Array} value - The value to be searched for
* @property {boolean} [ignoreCase] - Is it case sensitive? (default true)
*/

@@ -16,11 +16,17 @@

* @typedef {Object} EditObject
* @property {string | number } id - The affected element
* @property {string} field - The field you want to edit
* @property {"set" | "remove" | "append" | "increment" | "decrement" | "array-push" | "array-delete" | "array-splice"} operation - Wanted operation on field
* @property {string | number | boolean | Array} [value] - The value you want to compare
* @property {string | number} id - The affected element
* @property {string} field - The field to edit
* @property {"set" | "remove" | "append" | "increment" | "decrement" | "array-push" | "array-delete" | "array-splice"} operation - Operation for the field
* @property {string | number | boolean | Array} [value] - The value to write
*/
/**
* @typedef {Object} ValueObject
* @property {string} field - Field to search
* @property {boolean} [flatten] - Flatten array fields? (default false)
*/
/**
* @typedef {Object} SelectOption
* @property {Array<string>} fields - Chosen fields to eventually return
* @property {Array<string>} fields - Selected fields to be returned
*/

@@ -43,13 +49,12 @@

if (!_address) throw new Error("Firestorm address was not configured");
return _address + "get.php";
};
const writeAddress = () => {
if (!_address) throw new Error("Firestorm address was not configured");
return _address + "post.php";
};
const fileAddress = () => {
if (!_address) throw new Error("Firestorm address was not configured");
return _address + "files.php";

@@ -60,3 +65,2 @@ };

if (!_token) throw new Error("Firestorm token was not configured");
return _token;

@@ -77,11 +81,6 @@ };

const __extract_data = (request) => {
return new Promise((resolve, reject) => {
request
.then((res) => {
if ("data" in res) return resolve(res.data);
resolve(res);
})
.catch((err) => {
reject(err);
});
if (!(request instanceof Promise)) request = Promise.resolve(request);
return request.then((res) => {
if ("data" in res) return res.data;
return res;
});

@@ -109,3 +108,3 @@ };

/**
* Add user methods to the returned data
* Add user methods to returned data
* @private

@@ -117,16 +116,10 @@ * @ignore

__add_methods(req) {
return new Promise((resolve, reject) => {
req
.then((el) => {
if (Array.isArray(el)) {
return resolve(el.map((e) => this.addMethods(e)));
}
if (!(req instanceof Promise)) req = Promise.resolve(req);
return req.then((el) => {
if (Array.isArray(el)) return el.map((el) => this.addMethods(el));
el[Object.keys(el)[0]][ID_FIELD_NAME] = Object.keys(el)[0];
el = el[Object.keys(el)[0]];
el[Object.keys(el)[0]][ID_FIELD_NAME] = Object.keys(el)[0];
el = el[Object.keys(el)[0]];
// else on the object itself
return resolve(this.addMethods(el));
})
.catch((err) => reject(err));
// else on the object itself
return this.addMethods(el);
});

@@ -168,9 +161,7 @@ }

get(id) {
return this.__add_methods(
this.__get_request({
collection: this.collectionName,
command: "get",
id: id,
}),
);
return this.__get_request({
collection: this.collectionName,
command: "get",
id: id,
}).then((res) => this.__add_methods(res));
}

@@ -219,3 +210,3 @@

let params = {
const params = {
collection: this.collectionName,

@@ -230,3 +221,3 @@ command: "search",

} else {
let seed = parseInt(random);
const seed = parseInt(random);
if (isNaN(seed))

@@ -236,27 +227,13 @@ return Promise.reject(

);
params.random = {
seed: seed,
};
params.random = { seed };
}
}
return new Promise((resolve, reject) => {
let raw;
this.__get_request(params)
.then((res) => {
const arr = [];
return this.__get_request(params).then((res) => {
const arr = Object.entries(res).map(([id, value]) => {
value[ID_FIELD_NAME] = id;
return value;
});
raw = res;
Object.keys(res).forEach((contribID) => {
const tmp = res[contribID];
tmp[ID_FIELD_NAME] = contribID;
arr.push(tmp);
});
resolve(this.__add_methods(Promise.resolve(arr)));
})
.catch((err) => {
err.raw = raw;
reject(err);
});
return this.__add_methods(arr);
});

@@ -273,19 +250,13 @@ }

return new Promise((resolve, reject) => {
this.__get_request({
collection: this.collectionName,
command: "searchKeys",
search: keys,
})
.then((res) => {
const arr = [];
Object.keys(res).forEach((contribID) => {
const tmp = res[contribID];
tmp[ID_FIELD_NAME] = contribID;
arr.push(tmp);
});
return this.__get_request({
collection: this.collectionName,
command: "searchKeys",
search: keys,
}).then((res) => {
const arr = Object.entries(res).map(([id, value]) => {
value[ID_FIELD_NAME] = id;
return value;
});
resolve(this.__add_methods(Promise.resolve(arr)));
})
.catch((err) => reject(err));
return this.__add_methods(arr);
});

@@ -299,16 +270,13 @@ }

readRaw() {
return new Promise((resolve, reject) => {
this.__get_request({
collection: this.collectionName,
command: "read_raw",
})
.then((data) => {
Object.keys(data).forEach((key) => {
data[key][ID_FIELD_NAME] = key;
this.addMethods(data[key]);
});
return this.__get_request({
collection: this.collectionName,
command: "read_raw",
}).then((data) => {
// preserve as object
Object.keys(data).forEach((key) => {
data[key][ID_FIELD_NAME] = key;
this.addMethods(data[key]);
});
resolve(data);
})
.catch(reject);
return data;
});

@@ -319,3 +287,3 @@ }

* Returns the whole content of the JSON
* @deprecated Use readRaw instead
* @deprecated Use {@link readRaw} instead
* @returns {Promise<Record<string, T>>} The entire collection

@@ -335,17 +303,13 @@ */

if (!selectOption) selectOption = {};
return new Promise((resolve, reject) => {
this.__get_request({
collection: this.collectionName,
command: "select",
select: selectOption,
})
.then((data) => {
Object.keys(data).forEach((key) => {
data[key][ID_FIELD_NAME] = key;
this.addMethods(data[key]);
});
return this.__get_request({
collection: this.collectionName,
command: "select",
select: selectOption,
}).then((data) => {
Object.keys(data).forEach((key) => {
data[key][ID_FIELD_NAME] = key;
this.addMethods(data[key]);
});
resolve(data);
})
.catch(reject);
return data;
});

@@ -355,2 +319,23 @@ }

/**
* Get all distinct non-null values for a given key across a collection
* @param {ValueObject} valueOption - Value options
* @returns {Promise<T[]>} Array of unique values
*/
values(valueOption) {
if (!valueOption) return Promise.reject("Value option must be provided");
if (typeof valueOption.field !== "string") return Promise.reject("Field must be a string");
if (valueOption.flatten !== undefined && typeof valueOption.flatten !== "boolean")
return Promise.reject("Flatten must be a boolean");
return this.__get_request({
collection: this.collectionName,
command: "values",
values: valueOption,
}).then((data) =>
// no ID_FIELD or method injection since no ids are returned
Object.values(data).filter((d) => d !== null),
);
}
/**
* Returns random max entries offsets with a given seed

@@ -397,3 +382,3 @@ * @param {number} max - The maximum number of entries

return Promise.resolve(data);
return data;
});

@@ -456,4 +441,4 @@ }

* Set the entire JSON file contents
* @deprecated Use {@link writeRaw} instead
* @param {Record<string, T>} value - The value to write
* @deprecated Use writeRaw instead
* @returns {Promise<WriteConfirmation>} Write confirmation

@@ -471,17 +456,10 @@ */

add(value) {
return new Promise((resolve, reject) => {
axios
.post(writeAddress(), this.__write_data("add", value))
.then((res) => {
return this.__extract_data(Promise.resolve(res));
})
.then((res) => {
if (typeof res != "object" || !("id" in res) || typeof res.id != "string")
throw new Error("Incorrect result");
resolve(res.id);
})
.catch((err) => {
reject(err);
});
});
return axios
.post(writeAddress(), this.__write_data("add", value))
.then((res) => this.__extract_data(res))
.then((res) => {
if (typeof res != "object" || !("id" in res) || typeof res.id != "string")
return Promise.reject(new Error("Incorrect result"));
return res.id;
});
}

@@ -495,9 +473,5 @@

addBulk(values) {
return new Promise((resolve, reject) => {
this.__extract_data(axios.post(writeAddress(), this.__write_data("addBulk", values, true)))
.then((res) => {
resolve(res.ids);
})
.catch(reject);
});
return this.__extract_data(
axios.post(writeAddress(), this.__write_data("addBulk", values, true)),
).then((res) => res.ids);
}

@@ -550,3 +524,3 @@

* @param {EditObject} obj - The edit object
* @returns {Promise<T>} The edited element
* @returns {Promise<{ success: boolean }>} Edit confirmation
*/

@@ -561,3 +535,3 @@ editField(obj) {

* @param {EditObject[]} objArray The edit object array with operations
* @returns {Promise<T[]>} The edited elements
* @returns {Promise<{ success: boolean[] }>} Edit confirmation
*/

@@ -581,2 +555,3 @@ editFieldBulk(objArray) {

if (newValue === undefined) return readAddress();
if (!newValue.endsWith("/")) newValue += "/";
if (newValue) _address = newValue;

@@ -624,3 +599,3 @@

/**
* Test child object with child namespace
* Firestorm file handler
* @memberof firestorm

@@ -632,5 +607,6 @@ * @type {Object}

/**
* Get file back
* Get a file by its path
* @memberof firestorm.files
* @param {string} path - The file path wanted
* @returns {Promise<any>} File contents
*/

@@ -648,29 +624,33 @@ get(path) {

/**
* Uploads file
* Upload a file
* @memberof firestorm.files
* @param {FormData} form - The form data with path, filename, and file
* @returns {Promise<any>} HTTP response
* @returns {Promise<WriteConfirmation>} Write confirmation
*/
upload(form) {
form.append("token", firestorm.token());
return axios.post(fileAddress(), form, {
headers: {
...form.getHeaders(),
},
});
return __extract_data(
axios.post(fileAddress(), form, {
headers: {
...form.getHeaders(),
},
}),
);
},
/**
* Deletes a file given its path
* Deletes a file by path
* @memberof firestorm.files
* @param {string} path - The file path to delete
* @returns {Promise<any>} HTTP response
* @returns {Promise<WriteConfirmation>} Write confirmation
*/
delete(path) {
return axios.delete(fileAddress(), {
data: {
path,
token: firestorm.token(),
},
});
return __extract_data(
axios.delete(fileAddress(), {
data: {
path,
token: firestorm.token(),
},
}),
);
},

@@ -677,0 +657,0 @@ },

export type NumberCriteria =
| "==" /** test if the value is equal to the provided value */
| "!=" /** test if the value is not equal to the provided value */
| "<" /** test if the value is less than the provided value */
| "<=" /** test if the value is less than or equal to the provided value */
| ">" /** test if the value is greater than the provided value */
| ">=" /** test if the value is greater than or equal to the provided value */
| "in" /** test if the value is in the given array */;
| "==" /** Value is equal to the provided value */
| "!=" /** Value is not equal to the provided value */
| "<" /** Value is less than the provided value */
| "<=" /** Value is less than or equal to the provided value */
| ">" /** Value is greater than the provided value */
| ">=" /** Value is greater than or equal to the provided value */
| "in"; /** Value is in the given array */
export type StringCriteria =
| "==" /** test if the string value is equal to the provided value */
| "!=" /** test if the string value is not equal to the provided value */
| "<" /** test if the string value length is less than the provided value */
| "<=" /** test if the string value length is less than or equal to the provided value */
| ">" /** test if the string value length is greater than the provided value */
| ">=" /** test if the string value length is greater than or equal to the provided value */
| "in" /** test if the string value is in the given array */
| "includes" /** test if the string value includes the provided value */
| "contains" /** same as "includes" */
| "startsWith" /** test if the string value starts with the provided value */
| "endsWith" /** test if the string value ends with the provided value */;
| "==" /** String value is equal to the provided value */
| "!=" /** String value is not equal to the provided value */
| "<" /** String value length is less than the provided value */
| "<=" /** String value length is less than or equal to the provided value */
| ">" /** String value length is greater than the provided value */
| ">=" /** String value length is greater than or equal to the provided value */
| "in" /** String value is in the given array */
| "includes" /** String value includes the provided value */
| "contains" /** Same as "includes" */
| "startsWith" /** String value starts with the provided value */
| "endsWith"; /** String value ends with the provided value */
export type ArrayCriteria =
| "array-contains" /** test if the value is in the given array */
| "array-contains-any" /** test if the any value of the array is in the given array */
| "array-length-eq" /** test if the array length is equal to the provided value */
| "array-length-df" /** test if the array length is different from the provided value */
| "array-length-gt" /** test if the array length is greater than the provided value */
| "array-length-lt" /** test if the array length is less than the provided value */
| "array-length-ge" /** test if the array length is greater than or equal to the provided value */
| "array-length-le" /** test if the array length is less than or equal to the provided value */;
| "array-contains" /** Value is in the given array */
| "array-contains-any" /** Any value of the array is in the given array */
| "array-length-eq" /** Array length is equal to the provided value */
| "array-length-df" /** Array length is different from the provided value */
| "array-length-gt" /** Array length is greater than the provided value */
| "array-length-lt" /** Array length is less than the provided value */
| "array-length-ge" /** Array length is greater than or equal to the provided value */
| "array-length-le"; /** Array length is less than or equal to the provided value */
export type BooleanCriteria =
| "!=" /** test if the value is not equal to the provided value */
| "==" /** test if the value is equal to the provided value */;
| "!=" /** Value is not equal to the provided value */
| "=="; /** Value is equal to the provided value */
export type AllCriteria =
| StringCriteria /** criteria applying to strings */
| ArrayCriteria /** criteria applying to arrays */
| BooleanCriteria /** criteria applying to boolean */
| NumberCriteria /** criteria applying to numbers */;
export type AnyCriteria = StringCriteria | ArrayCriteria | BooleanCriteria | NumberCriteria;

@@ -46,3 +42,3 @@ export type Criteria<T> = T extends Function

:
| never /** methods are not allowed in the field (they are not saved in the collection JSON file) */
| never /** Methods are not allowed in the field (they are not saved in the collection JSON file) */
| T extends Array<unknown>

@@ -143,9 +139,9 @@ ? ArrayCriteria

[K in keyof T]: {
/** the field to be searched for */
/** The field to be searched for */
field: Path<T>;
/** the criteria to be used to search for the field */
/** Search criteria to filter results */
criteria: Criteria<T[K]>;
/** the value to be searched for */
/** The value to be searched for */
value?: any;
/** is it case sensitive? (default true) */
/** Is it case sensitive? (default true) */
ignoreCase?: boolean;

@@ -155,15 +151,32 @@ };

export interface SelectOption<T> {
/** Chosen fields to eventually return */
fields: Array<keyof T | "id">;
export interface SelectOption<T extends any[]> {
/** Selected fields to be returned */
fields: T;
}
export interface CollectionMethods<T> {
(collectionElement: Collection<T> & T): Collection<T> & T;
export interface ValueOption<K, F extends boolean> {
/** Field to search */
field: K | "id";
/** Flatten array fields? (default false) */
flatten?: F;
}
export type NoMethods<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
/** Add methods to found elements */
export type CollectionMethods<T> = (collectionElement: T) => T;
/** Remove methods from a type */
export type RemoveMethods<T> = Pick<
T,
{
[K in keyof T]: T[K] extends Function ? never : K;
}[keyof T]
>;
/** ID field not known at add time */
export type Addable<T> = Omit<RemoveMethods<T>, "id">;
/** ID field can be provided in request */
export type Settable<T> = Addable<T> & {
id?: number | string;
};
export class Collection<T> {

@@ -198,3 +211,3 @@ /**

public search(
options: SearchOption<T & { id: string | number }>[],
options: SearchOption<RemoveMethods<T> & { id: string | number }>[],
random?: boolean | number,

@@ -218,3 +231,3 @@ ): Promise<T[]>;

* Returns the whole content of the JSON
* @deprecated Use readRaw instead
* @deprecated Use {@link readRaw} instead
* @returns The entire collection

@@ -230,5 +243,16 @@ */

*/
public select(option: SelectOption<T>): Promise<Record<string, Partial<T>>>;
public select<K extends Array<"id" | keyof T>>(
option: SelectOption<K>,
): Promise<Record<string, Pick<T & { id: string | number }, K[number]>>>;
/**
* Get all distinct non-null values for a given key across a collection
* @param option - Value options
* @returns Array of unique values
*/
public values<K extends keyof RemoveMethods<T>, F extends boolean = false>(
option: ValueOption<K, F>,
): Promise<T[K] extends Array<any> ? (F extends true ? T[K] : T[K][]) : T[K][]>;
/**
* Get random max entries offset with a given seed

@@ -247,11 +271,11 @@ * @param max - The maximum number of entries

*/
public writeRaw(value: Record<string, T>): Promise<WriteConfirmation>;
public writeRaw(value: Record<string, RemoveMethods<T>>): Promise<WriteConfirmation>;
/**
* Set the entire JSON file contents
* @deprecated Use writeRaw instead
* @deprecated Use {@link writeRaw} instead
* @param value - The value to write
* @returns Write confirmation
*/
public write_raw(value: Record<string, T>): Promise<WriteConfirmation>;
public write_raw(value: Record<string, RemoveMethods<T>>): Promise<WriteConfirmation>;

@@ -263,3 +287,3 @@ /**

*/
public add(value: Writable<T>): Promise<string>;
public add(value: Addable<T>): Promise<string>;

@@ -271,3 +295,3 @@ /**

*/
public addBulk(values: Writable<T>[]): Promise<string[]>;
public addBulk(values: Addable<T>[]): Promise<string[]>;

@@ -294,3 +318,3 @@ /**

*/
public set(id: string | number, value: Writable<T>): Promise<WriteConfirmation>;
public set(id: string | number, value: Settable<T>): Promise<WriteConfirmation>;

@@ -303,3 +327,3 @@ /**

*/
public setBulk(ids: string[] | number[], values: Writable<T>[]): Promise<WriteConfirmation>;
public setBulk(ids: string[] | number[], values: Settable<T>[]): Promise<WriteConfirmation>;

@@ -309,5 +333,5 @@ /**

* @param edit - The edit object
* @returns The edited element
* @returns Edit confirmation
*/
public editField(edit: EditField<T>): Promise<T>;
public editField(edit: EditField<RemoveMethods<T>>): Promise<{ success: boolean }>;

@@ -317,5 +341,5 @@ /**

* @param edits - The edit objects
* @returns The edited elements
* @returns Edit confirmation
*/
public editFieldBulk(edits: EditField<T>[]): Promise<T[]>;
public editFieldBulk(edits: EditField<RemoveMethods<T>>[]): Promise<{ success: boolean[] }>;
}

@@ -326,5 +350,2 @@

// don't need ID field when adding keys, and setting keys has a separate ID argument
type Writable<T> = Omit<Omit<T, NoMethods<T>>, "id">;
/**

@@ -364,4 +385,5 @@ * Change the current Firestorm address

/**
* Get file back
* Get a file by its path
* @param path - The file path wanted
* @returns File contents
*/

@@ -371,14 +393,14 @@ get(path: string): Promise<any>;

/**
* Upload file
* Upload a file
* @param form - The form data with path, filename, and file
* @returns HTTP response
* @returns Write confirmation
*/
upload(form: FormData): Promise<any>;
upload(form: FormData): Promise<WriteConfirmation>;
/**
* Deletes a file given its path
* Deletes a file by path
* @param path - The file path to delete
* @returns HTTP response
* @returns Write confirmation
*/
delete(path: string): Promise<any>;
delete(path: string): Promise<WriteConfirmation>;
};

@@ -385,0 +407,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc