Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
@modelata/node-fire
Advanced tools
This library is a wrapper around firestore to implement kind of an ODM in Node.JS projects. It also can be used in Firestore cloud functions projects.
firebase-admin | @modelata/fire | @modelata/node-fire |
---|---|---|
11.5.2 | ^5.0.0 | ^5.0.0 |
10.0.2 | ^4.0.0 | ^4.0.0 |
npm i -s @modelata/node-fire firebase-admin reflect-metadata
import * as admin from 'firebase-admin';
const serviceAccount = require('./serviceAccount.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: `https://${serviceAccount.project_id}.firebaseio.com`,
storageBucket: `${serviceAccount.project_id}.appspot.com`,
});
const settings = { timestampsInSnapshots: true };
const db = admin.firestore();
db.settings(settings);
const auth = admin.auth();
const storage = admin.storage().bucket();
Your models must extend MFModel :
export class SomeModel extends MFModel<SomeModel> {
name: string = null;
constructor(
data: Partial<SomeModel> = {},
mustachePath?: string,
location?: Partial<IMFLocation>,
) {
super();
super.initialize(data, mustachePath, location);
}
}
modelata-node-fire set some attribute an all models.
You can use decorators on properties to extend your models :
@InSubDoc('data/private')
email: string = null;
this property is from a subdocument
/!\ the DAO must extends MFFlattableDao
@AuthUserProperty()
email: string = null;
@StorageProperty({
deletePreviousOnUpdate: false,
deleteOnDelete: true
})
picture: IMFFile = null;
this properties links to a file stored in storage The property must be of type : IMFFile.
To manipulate your models in database, you need to create the corresponding DAOs :
Simple :
@CollectionPath('somes')
export class SomeDao extends MFDao<SomeModel> {
constructor(database: FirebaseFirestore.Firestore) {
super(database);
}
getNewModel(data?: Partial<SomeModel>, location?: Partial<IMFLocation>): SomeModel {
return new SomeModel(data, this.mustachePath, location);
}
}
Flattable if your model is made of data from subdocuments :
@CollectionPath('somes')
export class SomeDao extends MFFlattableDao<SomeModel> {
constructor(db: FirebaseFirestore.Firestore) {
super(db);
}
getNewModel(data?: Partial<SomeModel>, location?: Partial<IMFLocation>): SomeModel {
const someModel = new SomeModel(data, this.mustachePath, location);
return someModel;
}
}
@CollectionPath('/users')
CollectionPath decorator must be used on all DAO. CollectionPath take in parameter a string representing the collection path in firestore db. If the collection is a subcollection (collection in a document), use the "mustache" syntaxe for all document id.
@CollectionPath('/users/{userId}/mySubCollection/{mySubDocId}/subSubcollection')
All methods that need an id or a location (like "get"), now take a Location with ids mentioned in CollectionPath.
const location = {
id: 'mySubSubDocId',
mySubDocId: 'id',
userId: 'id',
};
@DeletionMode(MFDeleteMode.SOFT)
DeletionMode decorator is used for set the deletion strategy for this DAO. (default : HARD) DeletionMode take in parameter a enum value MFDeleteMode.SOFT or MFDeleteMode.HARD.
MFDeleteMode.SOFT :
MFDeleteMode.HARD :
get(idOrLocation: string | IMFLocation, options?: IMFGetOneOptions)
Get a model from database from id or location
export interface IMFGetOneOptions {
/**
* Document will include an hidden property containing document snapshote
*/
withSnapshot?: boolean;
/**
* Observable returned will complete on first result
*/
completeOnFirst?: boolean;
/**
* Request result will be cached in order to get a faster answer on same getOne request
*/
cacheable?: boolean;
/**
* Display an error in console when requested document not exists (default: true)
*/
warnOnMissing?: boolean;
}
getByReference(reference: DocumentReference, options?: IMFGetOneOptions)
Get a model from database from its reference
getByPath(path: string, options?: IMFGetOneOptions)
Get a model from database from its path
getList(location?: MFOmit<IMFLocation, "id">, options?: IMFGetListOptions<M>)
Get a list of documents in the collection
export interface IMFGetListOptions<M> {
/**
* Documents will include an hidden property containing document snapshote
*/
withSnapshot?: boolean;
/**
* Observable returned will complete on first result
*/
completeOnFirst?: boolean;
/**
* Where conditions
*/
where?: IMFWhere[];
/**
* Order by
*/
orderBy?: IMFOrderBy;
/**
* Maximum result returned
*/
limit?: number;
/**
* boundary of the get, only one is applied
*/
offset?: IMFOffset<M>;
/**
* Request result will be cached in order to get a faster answer on same getList request
*/
cacheable?: boolean;
}
getReference(idOrLocation: string | Partial<IMFLocation>)
Get the reference from an id (document only), a location (document or collection) or a model (document only)
update(data: Partial<M>, location?: string | IMFLocation | M, options?: IMFUpdateOptions<M>)
update some field of a model.
/**
* List of file properties of the model M for which stored files MUST (true) or MUST NOT be deleted on document update
* (Overrides behaviour configured in model decorators)
*/
export type IMFDeletePreviousOnUpdateFilesOptions<M extends IMFModel<M>> = {
/**
* File property : true => the previous file will be deleted if updated
* File property : false => the fprevious ile will NOT be deleted if updated
*/ [fileAttribute in NonFunctionPropertyNames<M>]?: boolean;
};
/**
* Options to pass to update method
*/
export interface IMFUpdateOptions<M extends IMFModel<M>> {
deletePreviousOnUpdateFiles?: IMFDeletePreviousOnUpdateFilesOptions<M>;
}
create(data: M, location?: string | Partial<IMFLocation>, options?: IMFSaveOptions)
save a new model in db, update if already exist.
export interface IMFSaveOptions {
/**
* If document already exists, it will be fully overwritten
*/
overwrite?: boolean;
}
delete(idLocationOrModel: string | IMFLocation | M, options?: IMFDeleteOptions<M>)
Delete a model by id
/**
* List of file properties of the model M for which stored files MUST (true) or MUST NOT be deleted on document deletion
* (Overrides behaviour configured in model decorators)
*/
export declare type IMFDeleteOnDeleteFilesOptions<M extends IMFModel<M>> = {
/**
* File property : true => the file will be deleted
* File property : false => the file will NOT be deleted
*/
[fileAttribute in NonFunctionPropertyNames<M>]?: boolean;
};
/**
* Options to pass to delete method
*/
export interface IMFDeleteOptions<M extends IMFModel<M>> {
deleteOnDeleteFiles?: IMFDeleteOnDeleteFilesOptions<M>;
cascadeOnDelete?: boolean;
mode?: MFDeleteMode; // used for override defaultvalue (HARD or @DeletionMode)
}
deleteByReference(reference: DocumentReference)
Delete a model by its reference
getReferenceFromPath(path: string)
Get a reference from a compatible path
getSnapshot(idOrLocation: string | IMFLocation, options?: IMFGetOneOptions)
isCompatible(modelOrReference: M | DocumentReference | CollectionReference)
Check if the model or reference is compatible with this DAO based on its path
User Model must implement IMFUserInterface if you want to reference auth user propertties
export class UserModel extends MFModel<UserModel> implements IMFUserInterface {
@InSubDoc('data/private')
@AuthUserProperty()
email: string = null;
@InSubDoc('data/private')
@AuthUserProperty()
phoneNumber: string = null;
@InSubDoc('data/public')
@AuthUserProperty()
photoUrl: string = null;
@AuthUserProperty()
displayName: string = null;
constructor(data: Partial<UserModel>, mustachePath: string, location: Partial<IMFLocation>) {
super();
super.initialize(data, mustachePath, location);
}
}
Once everything is properly configured you can use standard methods like create, update, delete, get, getList to interact with database. Every async method is based on promises.
You can find more informations on https://moventes.github.io/modelata-node-fire/globals.html
You can test with https://gitlab.com/modelata/test-node-fire
FAQs
Modelata abstract layer for firebase-admin sdk in node.js
We found that @modelata/node-fire demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.