{"id":19584846,"url":"https://github.com/flex-development/dreepo","last_synced_at":"2025-02-26T12:42:06.223Z","repository":{"id":51120604,"uuid":"360719920","full_name":"flex-development/dreepo","owner":"flex-development","description":":fire: Repository Pattern implementation for Firebase Realtime Database","archived":false,"fork":false,"pushed_at":"2023-03-06T02:07:58.000Z","size":1311,"stargazers_count":0,"open_issues_count":6,"forks_count":0,"subscribers_count":3,"default_branch":"next","last_synced_at":"2025-01-09T05:45:35.614Z","etag":null,"topics":["class-transformer","class-transformer-validator","class-validator","firebase-admin","firebase-realtime-database","mingo","qs-to-mongo","repository-pattern","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flex-development.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-23T00:41:39.000Z","updated_at":"2021-05-28T01:44:00.000Z","dependencies_parsed_at":"2025-01-10T07:35:40.715Z","dependency_job_id":null,"html_url":"https://github.com/flex-development/dreepo","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fdreepo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fdreepo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fdreepo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fdreepo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flex-development","download_url":"https://codeload.github.com/flex-development/dreepo/tar.gz/refs/heads/next","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240858536,"owners_count":19868997,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["class-transformer","class-transformer-validator","class-validator","firebase-admin","firebase-realtime-database","mingo","qs-to-mongo","repository-pattern","typescript"],"created_at":"2024-11-11T07:50:28.503Z","updated_at":"2025-02-26T12:42:06.181Z","avatar_url":"https://github.com/flex-development.png","language":"TypeScript","readme":"# dreepo\n\nRepository Pattern implementation for Firebase Realtime Database\n\n[![TypeScript](https://badgen.net/badge/-/typescript?icon=typescript\u0026label)](https://www.typescriptlang.org/)\n[![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest)\n\n## Overview\n\n[Getting Started](#getting-started)  \n[Installation](#installation)  \n[Usage](#usage)  \n[Built With](#built-with)  \n[Contributing](docs/CONTRIBUTING.md)\n\n## Getting Started\n\nInspired by [Fireorm][11], Dreepo exposes a Repository Pattern implementation\nfor [Firebase Realtime Database][2].\n\nAlongside an abstract database access layer, repositories also support:\n\n- aggregation pipelines, searches, and url queries using [mango][8]\n- model validation using [class-validator][6]\n\n## Installation\n\n1. Create or edit an `.npmrc` file with the following information:\n\n   ```utf-8\n   @flex-development:registry=https://npm.pkg.github.com/\n   ```\n\n2. Add project to `dependencies`\n\n   ```zsh\n   yarn add @flex-development/dreepo # or npm i @flex-development/dreepo\n   ```\n\n## Usage\n\n[Configuration](#configuration)  \n[Database Connection](#database-connection)  \n[Modeling Entities](#modeling-entities)  \n[Repository Options](#repository-options)  \n[Creating a New Repository](#creating-a-new-repository)  \n[Repository Cache](#repository-cache)  \n[Repository Class API](#repository-class-api)\n\n### Configuration\n\n#### Firebase Service Account\n\nDreepo communicates with your Realtime Database using the [Firebase Database\nREST API][2]. Generated by service accounts, [Google OAuth2 access tokens][12]\nare used to authenticate requests.\n\n1. Navigate to the [Service Accounts][13] section of the Firebase console\n\n2. Click **Generate New Private Key** to generate a new service account key file\n\n#### Environment Variables\n\n- `DEBUG`: Toggle [debug][7] logs from the `dreepo` namespace\n- `DEBUG_COLORS`: Toggle [debug][7] log namespace colors\n\n#### Mango\n\nThe `Repository` class integrates with [mango][8], a plugin for [mingo][9] and\n[qs-to-mongo][10]. This allows for aggregation pipelines and performing searches\nwith query criteria and options, as well as URL query handling.\n\n[mingo][9] operators loaded by [mango][8] can be viewed in the [config][14]\nfile. If additional operators are needed, you'll need to load them on your own\n_before_ [creating a new repository](#creating-a-new-repository).\n\n#### TypeScript\n\nFor shorter import paths, TypeScript users can add the following aliases:\n\n```json\n{\n  \"compilerOptions\": {\n    \"paths\": {\n      \"@dreepo\": [\"node_modules/@flex-development/dreepo/index\"],\n      \"@dreepo/*\": [\"node_modules/@flex-development/dreepo/*\"]\n    }\n  }\n}\n```\n\nThese aliases will be used in following code examples.\n\n### Database Connection\n\nBefore creating a new repository, initialize a `RepoDBConnection` provider to\nestablish a connection between your database and repository.\n\n```typescript\nimport { RepoDBConnection } from '@dreepo'\n\nconst path = 'users'\nconst url = process.env.FIREBASE_DATABASE_URL || ''\nconst client_email = process.env.FIREBASE_CLIENT_EMAIL || ''\nconst private_key = process.env.FIREBASE_PRIVATE_KEY || ''\n\nexport const dbconn = new RepoDBConnection(path, url, client_email, private_key)\n```\n\nNote:\n\n- An `Exception` will be thrown if any options are invalid\n- Private keys will be formatted using `private_key.replace(/\\\\n/g, '\\n')`\n\n### Modeling Entities\n\nBefore instantiating a new repository, a model needs to be created.\n\nFor the next set of examples, the model `User` will be used.\n\n```typescript\nimport { Entity } from '@dreepo'\nimport type { IEntity } from '@dreepo/interfaces'\nimport type { RepoParsedUrlQuery, RepoSearchParams } from '@dreepo/types'\nimport {\n  IsEmail,\n  IsNotEmpty,\n  IsOptional,\n  IsPhoneNumber,\n  IsString\n} from 'class-validator'\n\nexport interface IUser extends IEntity {\n  email: string\n  first_name: string\n  last_name: string\n  phone?: string\n}\n\nexport type UserParams = RepoSearchParams\u003cIUser\u003e\nexport type UserQuery = RepoParsedUrlQuery\u003cIUser\u003e\n\nexport class User extends Entity implements IUser {\n  @IsEmail()\n  email: IUser['email']\n\n  @IsString()\n  @IsNotEmpty()\n  first_name: IUser['first_name']\n\n  @IsString()\n  @IsNotEmpty()\n  last_name: IUser['last_name']\n\n  @IsOptional()\n  @IsPhoneNumber()\n  phone?: IUser['phone']\n}\n```\n\nFor more information about validation decorators, see the [class-validator][6]\npackage.\n\nDreepo also exposes a set of [custom decorators](src/decorators/index.ts).\n\n### Repository Options\n\nThe `Repository` class accepts an `options` object that passes additional\noptions to [mango][8], and [class-transformer-validator][4].\n\n```typescript\nimport type { RepoOptionsDTO } from '@dreepo/dto'\n\nconst options: RepoOptionsDTO\u003cIUser\u003e = {\n  cache: { collection: [] },\n  mingo: {},\n  parser: {},\n  validation: {\n    enabled: true,\n    transformer: {},\n    validator: {}\n  }\n}\n```\n\nNote that all properties are optional.\n\nFor more information about the `cache`, `mingo`, and `parser` options, see\n[Plugin][15] from the [mango][8] documentation. `options.mingo.idKey` will be\noverridden and always have the value `'id'`.\n\nValidation options will be merged with the following object:\n\n```typescript\nimport type { TVODefaults } from '@dreepo/types'\n\n/**\n * @property {TVODefaults} TVO_DEFAULTS - `class-transformer-validator` options\n * @see https://github.com/MichalLytek/class-transformer-validator\n */\nexport const TVO_DEFAULTS: TVODefaults = Object.freeze({\n  transformer: {},\n  validator: {\n    enableDebugMessages: true,\n    forbidNonWhitelisted: true,\n    stopAtFirstError: false,\n    validationError: { target: false, value: true },\n    whitelist: true\n  }\n})\n```\n\n### Creating a New Repository\n\n```typescript\nimport { Repository } from '@dreepo'\n\nexport const Users = new Repository\u003cIUser, UserParams, UserQuery\u003e(\n  dbconn,\n  User,\n  options\n)\n```\n\n### Repository Cache\n\nAfter instantiation, before calling any repository methods, the repository's\ncache must be refreshed to keep the database and repository cache in sync.\n\nIf the cache is empty before running an aggregation pipeline or executing a\nsearch, a warning will be logged to the console.\n\nNot refreshing the cache before a write operation (`create`, `patch`, or `save`)\ncould lead to accidental overwrites or other database inconsistencies.\n\n```typescript\nawait Users.refreshCache()\n```\n\n### Repository Class API\n\nThe `Repository` class allows users to perform CRUD operations on their Realtime\nDatabase, as well as check values against the repository model schema.\n\nDocumentation can be viewed [here](src/repositories/repository.ts).\n\n```typescript\n/**\n * `Repository` class interface.\n *\n * - https://github.com/flex-development/mango\n * - https://github.com/fox1t/qs-to-mongo\n * - https://github.com/kofrasa/mingo\n *\n * @template E - Entity\n * @template P - Repository search parameters (query criteria and options)\n * @template Q - Parsed URL query object\n */\nexport interface IRepository\u003c\n  E extends IEntity = IEntity,\n  P extends RepoSearchParams\u003cE\u003e = RepoSearchParams\u003cE\u003e,\n  Q extends RepoParsedUrlQuery\u003cE\u003e = RepoParsedUrlQuery\u003cE\u003e\n\u003e extends IMango\u003cE, EUID, P, Q\u003e {\n  readonly cache: RepoCache\u003cE\u003e\n  readonly dbconn: IRepoDBConnection\n  readonly model: EntityClass\u003cE\u003e\n  readonly options: RepoOptions\u003cE\u003e\n  readonly validator: IRepoValidator\u003cE\u003e\n\n  clear(): Promise\u003cboolean\u003e\n  create(dto: EntityDTO\u003cE\u003e): Promise\u003cE\u003e\n  delete(id: OneOrMany\u003cE['id']\u003e, should_exist?: boolean): Promise\u003ctypeof id\u003e\n  patch(id: E['id'], dto: Partial\u003cEntityDTO\u003cE\u003e\u003e, rfields?: string[]): Promise\u003cE\u003e\n  refreshCache(): Promise\u003cRepoCache\u003cE\u003e\u003e\n  save(dto: OneOrMany\u003cOrPartial\u003cEntityDTO\u003cE\u003e\u003e\u003e): Promise\u003cE[]\u003e\n}\n```\n\nLooking for the `Mango` plugin docs? [See here][16].\n\n## Built With\n\n- [Axios][1] - Promise based HTTP client\n- [Firebase Database REST API][2] - REST API for Firebase Realtime Database\n- [Google Auth Library Node.js Client][3] - Node.js library for Google OAuth2\n- [class-transformer-validator][4] - Plugin for [class-transformer][5] and\n  [class-validator][6]\n- [debug][7] - Debugging utility\n- [mango][8] - Plugin for [mingo][9] and [qs-to-mongo][10]\n\n[1]: https://github.com/axios/axios\n[2]: https://firebase.google.com/docs/reference/rest/database\n[3]: https://github.com/googleapis/google-auth-library-nodejs\n[4]: https://github.com/MichalLytek/class-transformer-validator\n[5]: https://github.com/typestack/class-transformer\n[6]: https://github.com/typestack/class-validator\n[7]: https://github.com/visionmedia/debug\n[8]: https://github.com/flex-development/mango\n[9]: https://github.com/kofrasa/mingo\n[10]: https://github.com/fox1t/qs-to-mongo\n[11]: https://github.com/wovalle/fireorm\n[12]: https://developers.google.com/identity/protocols/oauth2\n[13]:\n  https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk\n[14]: https://github.com/flex-development/mango/blob/next/src/config/mingo.ts\n[15]: https://github.com/flex-development/mango#plugin\n[16]:\n  https://github.com/flex-development/mango/blob/next/src/plugins/mango.plugin.ts\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflex-development%2Fdreepo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflex-development%2Fdreepo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflex-development%2Fdreepo/lists"}