Home

Awesome

<!-- markdownlint-disable MD010 --> <!-- markdownlint-disable MD033 --> <!-- markdownlint-disable MD041 --> <div align="center"> <img src="https://raw.githubusercontent.com/tylim88/Firelord/main/img/ozai.png" width="200px"/> <h1>FirelordJS 烈火君JS</h1> </div> <div align="center"> <a href="https://www.npmjs.com/package/firelordjs" target="_blank"> <img src="https://img.shields.io/npm/v/firelordjs" alt="Created by tylim88" /> </a> &nbsp; <a href="https://github.com/tylim88/firelordjs/blob/main/LICENSE" target="_blank" > <img src="https://img.shields.io/github/license/tylim88/firelordjs" alt="License" /> </a> &nbsp; <img src="https://img.shields.io/badge/gzipped-2.6KB-brightgreen" alt="package size" /> &nbsp; <a href="https://github.com/tylim88/Firelordjs/actions" target="_blank"> <img src="https://github.com/tylim88/Firelordjs/workflows/Main/badge.svg" alt="github action" /> </a> &nbsp; <a href="https://codecov.io/gh/tylim88/Firelordjs" target="_blank"> <img src="https://codecov.io/gh/tylim88/Firelordjs/branch/main/graph/badge.svg" alt="code coverage" /> </a> &nbsp; <a href="https://github.com/tylim88/Firelordjs/issues" target="_blank"> <img alt="GitHub issues" src="https://img.shields.io/github/issues-raw/tylim88/firelordjs" ></img> </a> &nbsp; <a href="https://snyk.io/test/github/tylim88/FirelordJS" target="_blank"> <img src="https://snyk.io/test/github/tylim88/FirelordJS/badge.svg" alt="vulnerabilities" /> </a> </div> <br/> <div align="center"> <i>High Precision Firestore Web Typescript Wrapper, Providing Unparalleled Type Safety and Dev Experience</i> </div> <br/> <div align="center"> <i>Modular, Minuscule, Intuitive, Unopinionated, Craftsmanship, Ultimate, Peaceful, Deep</i> </div> <br/> <div align="center"> <i>Of The VFQAT &#160;&#160;&#160;&#160;&#160;||&#160;&#160;&#160;&#160;&#160; By The VFQAT &#160;&#160;&#160;&#160;&#160;|| &#160;&#160;&#160;&#160;&#160; For The VFQAT</i> </div> <br /> <div align="center"> <i>Be The Master Of Your Fire, Be Firelord</i> </div> <br /> <div align="center"> <i>Beyond Typing</i> </div> <br> <div align="center"> <a href="https://firelordjs.com" target="_blank" style="color:blue"><strong>Doc</strong></a> </div> <br/>

FirelordJS

FirelordJS is the only library capable of providing truly generic type safety while exposing almost all the API of the official Firestore SDK. The goal is to end Firestore typing madness.

Example of how Firelord transforms ServerTimestamp type in different operations:

<p align="center"> <img src="https://github.com/tylim88/FirelordJS/blob/main/img/example.png?raw=true" alt="Example of how Firelord handles `ServerTimestamp` type in different operations" /> </p>

FirelordJS:

Firelord is the only library capable of typing against Firestore limitations. It also blocks undocumented errors and prevent pesky runtime errors like empty array errors filter, cursors and implicit data deletion in update operation. Firelord provides over 30 custom error messages to assist you in writing proper Firestore code! Here is an example:

<p align="center"> <img src="https://github.com/tylim88/FirelordJS/blob/main/img/custom.png?raw=true" alt="Example of how Firelord handles `ServerTimestamp` type in different operations" /> </p>

Bounty

I am confident Firelord is the best among its kind in terms of best safety and developer experience. I stand behind my words, and I will buy you x cups of coffee if you:

  1. find something better: 300 cups
  2. created something better: 3000 cups.

The bounty has been available and keeps increasing since July 14, 2022.

Nested Composite Query Rulings

(Web feature only, admin can skip this section)

Rulings for or & and composite query are ready, rulings works with nested query, example:

Official SDK runtime error:

<p align="center"> <img src="https://github.com/tylim88/FirelordJS/blob/main/img/composite2.png?raw=true" alt="Example of how Firelord handles `ServerTimestamp` type in different operations" /> </p>

Firelord compile time error:

<p align="center"> <img src="https://github.com/tylim88/FirelordJS/blob/main/img/composite1.png?raw=true" alt="Example of how Firelord handles `ServerTimestamp` type in different operations" /> </p>

It has all the regular rulings plus new composite rulings. See also peeling composite query error messages

Eslint False Errors

Below ESLint rules give false error, please turn them off.

{
	"rules": {
		"@typescript-eslint/no-unsafe-assignment": "off",
		"@typescript-eslint/no-unsafe-call": "off",
		"@typescript-eslint/no-redundant-type-constituents": "off",
		"@typescript-eslint/no-unsafe-return": "off",
		"@typescript-eslint/no-unsafe-member-access": "off"
	}
}

ESM? CommonJS?

(Web version's issue only, admin can skip this section)

FirelordJS built files are a bit complicated. It is not an ESM module(no "type":"module" in package.json) but it also does not transpile import statements to CommonJS.

Results tested with various build tools:

  1. (Default) Non ESM with import statements (Pseudo ESM)
  1. Real ESM (Not available on NPM)
  1. CommonJS

Using CommonJS Firelord with Firebase v9.17.0 and beyond break most of the build tools because of this Firebase issue

Pseudo ESM has the highest compatibility which is why it is the default package. If you see cannot use import statement outside a module error, please install the CommonJS version with

npm i firelordjs@cjs

Types That You Need To Pay Attention To

These are types that are supported but be careful when using them. They are not limitations, but how things work.

Record<string, something> Support

By design Firelord banned mapped type, this was until version 2.5.10. To understand why mapped was banned in the first place and why it is possible now, see this issue. In short, querying mapped type requires extra information, make sure you know what you are doing.

Object Unions Type

Object unions type was banned before v2.6.2 because it brings uncertainty that cannot be handled reasonably. For example, with {a:number}|{b:string}, you can set {a:1} then update {b:"x"}, in this case the type is no longer unions type but an intersection type: {a:number} & {b:string}. This limitation is lifted to allow users to fully utilize discriminated unions. Plus in future update operation Mandatory Field could mitigate this problem.

TO DO

Dropped TO DO

TO FIX

  1. Bytes type is not working correctly and is unusable.
  2. The rule You can use at most one array-contains or array-contains-any clause per query. You can't combine array-contains with array-contains-any is not enabled, see this release note
  3. The type check of composite query (or() / and()) value is wrong if the field is __name__ of collection reference, example: query(collectionRef, or(where("__name__", "==", "id_only_not_full_path"))) result in false negative because Firelord will ask for full path but we only need full path if the reference is group collection.
  4. Significant lag when trying to import anything from the library. (turn out this is due to Import Cost VS Code extension. This extension is no longer maintained, please uninstall it.)

Trivial

Related Projects

  1. FirelordJS - Typescript wrapper for Firestore Web.
  2. Firelord - Typescript wrapper for Firestore Admin.
  3. FireSageJS - Typescript wrapper for Realtime Database Web
  4. Firelordrn - Typescript wrapper for Firestore React Native
  5. FireSage - Typescript wrapper for Realtime Database Admin.