@jahed/firebase-rules
Version:
A type-safe Firebase Real-time Database Security Rules builder.
60 lines (58 loc) • 2.06 kB
text/typescript
import { createRuleObject } from "./object.ts";
import { allOf } from "./operator.ts";
import { createRuleBoolean, createRuleNumber } from "./primitive.ts";
import { toJSONString } from "./serialise.ts";
import { createRuleString } from "./string.ts";
import type {
BooleanRule,
NumberRule,
PrimitiveOrExpression,
RuleDataSnapshot,
RuleExpression,
StringRule,
} from "./types.ts";
/**
* Creates a representation of a Firebase RuleDataSnapshots for use in rules.
*
* Note that `val()` is not type-specific so it's not available. Use `isString`,
* `isNumber`, etc. to apply rules to `val()`.
*
* `data.isString(val => lessThan(val.length, 100))` is the same as
* `data.isString() && data.val().length < 100`.
*
* https://firebase.google.com/docs/reference/security/database#ruledatasnapshot_methods
*/
export const createRuleDataSnapshot = (name: string): RuleDataSnapshot => {
return createRuleObject(name, {
isString: (valRule?: StringRule) => {
const baseRule: RuleExpression<boolean> = createRuleBoolean(
`${name}.isString()`,
);
return valRule
? allOf(baseRule, valRule(createRuleString(`${name}.val()`)))
: baseRule;
},
isBoolean: (valRule?: BooleanRule) => {
const baseRule = createRuleBoolean(`${name}.isBoolean()`);
return valRule
? allOf(baseRule, valRule(createRuleBoolean(`${name}.val()`)))
: baseRule;
},
isNumber: (valRule?: NumberRule) => {
const baseRule = createRuleBoolean(`${name}.isNumber()`);
return valRule
? allOf(baseRule, valRule(createRuleNumber(`${name}.val()`)))
: baseRule;
},
exists: () => {
return createRuleBoolean(`${name}.exists()`);
},
hasChildren: (keys: string[]) => {
return createRuleBoolean(`${name}.hasChildren(${toJSONString(keys)})`);
},
child: (...parts: PrimitiveOrExpression<string>[]) => {
const key = parts.map((part) => toJSONString(part)).join(" + ");
return createRuleDataSnapshot(`${name}.child(${key})`);
},
});
};