This package has been deprecated

Author message:

The package name has been changed due to a typo. Please use this package instead 'https://www.npmjs.com/package/firestore-document-type-patterns'

firestore-document-type-partterns
TypeScript icon, indicating that this package has built-in type declarations

5.0.2 • Public • Published

firestore-document-type-patterns

firestore-document-type-patterns gives you type test patterns. Then you might be able to check value types for security rule test easily.

Installation

from v2.0.0 Please set the 'type' field in your package.json to 'module' since this package supports Pure ESM.

{
  "type": "module"
}

NPM Packages

$ npm i firestore-document-type-partterns

How To Use

import { assertSucceeds, assertFails } from '@firebase/rules-unit-testing'
import { doc, setDoc } from 'firebase/firestore'
import { v4 as randomStr } from 'uuid'
import {
  getKeyTypePatterns,
  convertTypeToValue,
  getRecursiveWrongTypes,
} from 'firestore-document-type-partterns/security-rule'
import {
  DocumentType,
  TypePattern,
  ALL_FIELD_TYPES,
} from 'firestore-document-type-partterns/types/firestore-field-types'

const documentTypes: DocumentType = {
  uid: ALL_FIELD_TYPES.string,
  'tags[]': ALL_FIELD_TYPES.string,
  createdAt: ALL_FIELD_TYPES.timestamp,
}

const wrongTypes = getRecursiveWrongTypes([documentTypes])
const rightTypes = getKeyTypePatterns([documentTypes])
const path = 'users'
const uid = randomStr()
const pathSegments = [uid]

describe('', () => {
  rightTypes.forEach(data => {
    test(`${JSON.stringify(data, null, 2)}`, async () => {
      await assertSucceeds(setDoc(doc(db, path, ...pathSegments), convertTypeToValue(data, db)))
    })
  })

  wrongTypes.forEach(data => {
    test(`${JSON.stringify(data, null, 2)}`, async () => {
      await assertFails(setDoc(doc(db, path, ...pathSegments), convertTypeToValue(data, db)))
    })
  })
})

Type Variables

Field type rule name
string is string ALL_FIELD_TYPES.string
number is number ALL_FIELD_TYPES.number
int is int ALL_FIELD_TYPES.int
float is float ALL_FIELD_TYPES.float
bool is bool ALL_FIELD_TYPES.bool
map is map ALL_FIELD_TYPES.map
list is list ALL_FIELD_TYPES.list
null == null ALL_FIELD_TYPES.null
timestamp is timestamp ALL_FIELD_TYPES.timestamp
latlng is latlng ALL_FIELD_TYPES.latlng
path is path ALL_FIELD_TYPES.path

DocumentType Rule

Ex1: Simple

function isStr(data) {
    return data is string;
}
const documentTypes: DocumentType = {
  uid: ALL_FIELD_TYPES.string,
}

getKeyTypePatterns

[
  { uid: 'hoge' }
]

getRecursiveWrongTypes

[
  { uid: -1 },
  { uid: 1 },
  { uid: 1.1 },
  { uid: true },
  { uid: {} },
  { uid: [] },
  { uid: null },
  { uid: FieldValue },
  { uid: GeoPoint },
  { uid: DocumentReference<DocumentData> },

]

Ex2: Multiple types of One Field

function(data) {
    return data.uid is string
        && (data.createdAt is timestamp || data.createdAt == null);
}
const documentTypes: DocumentType = {
  uid: ALL_FIELD_TYPES.string,
  createdAt: [ALL_FIELD_TYPES.timestamp, ALL_FIELD_TYPES.string.null],
}

getKeyTypePatterns

[
  {
    uid: 'hoge',
    createdAt: FieldValue,
  },
  {
    uid: 'hoge',
    createdAt: null,
  }
]

getRecursiveWrongTypes

[

  { uid: 1, createdAt: FieldValue },
  { uid: 1, createdAt: null },

  { uid: -1, createdAt: FieldValue },
  { uid: -1, createdAt: null },

  { uid: 1.1, createdAt: FieldValue },
  { uid: 1.1, createdAt: null },

  { uid: true, createdAt: FieldValue },
  { uid: true, createdAt: null },

  { uid: {}, createdAt: FieldValue },
  { uid: {}, createdAt: null },

  { uid: [], createdAt: FieldValue },
  { uid: [], createdAt: null },

  { uid: null, createdAt: FieldValue },
  { uid: null, createdAt: null },

  { uid: FieldValue, createdAt: FieldValue },
  { uid: FieldValue, createdAt: null },

  { uid: GeoPoint, createdAt: FieldValue },
  { uid: GeoPoint, createdAt: null },

  { uid: DocumentReference<DocumentData>, createdAt: FieldValue },
  { uid: DocumentReference<DocumentData>, createdAt: null },

  { uid: 'hoge', createdAt: 'hoge' },
  { uid: 'hoge', createdAt: -1 },
  { uid: 'hoge', createdAt: 1 },
  { uid: 'hoge', createdAt: 1.1 },
  { uid: 'hoge', createdAt: true },
  { uid: 'hoge', createdAt: {} },
  { uid: 'hoge', createdAt: [] },
  { uid: 'hoge', createdAt: GeoPoint },
  { uid: 'hoge', createdAt: DocumentReference<DocumentData> },
]

Ex3: Array Field

function isStrings(strings) {
    return strings.size() == 0 || ( strings.size() >= 1 && strings[strings.size() - 1] is string )
}
const documentTypes: DocumentType = {
  'tags[]': ALL_FIELD_TYPES.string,
}

getKeyTypePatterns

[
  {
    tags: ['hoge'],
  }
]

getRecursiveWrongTypes

[
  { tags: [-1] },
  { tags: [1] },
  { tags: [1.1] },
  { tags: [true] },
  { tags: [{}] },
  { tags: [null] },
  { tags: [FieldValue] },
  { tags: [GeoPoint] },
  { tags: [DocumentReference<DocumentData>] },

]

Ex4: Map Field

function(data) {
    return data.map.size() == 1
        && data.map.uid is string
}
const documentTypes: DocumentType = {
  map: {
    uid: ALL_FIELD_TYPES.string,
  },
}

getKeyTypePatterns

[
  {
    map: {
      uid: 'hoge',
    }
  }
]

getRecursiveWrongTypes

[
  { map: { uid: 'hoge' } },
  { map: { uid: -1 } },
  { map: { uid: 1 } },
  { map: { uid: 1.1 } },
  { map: { uid: true } },
  { map: { uid: {} },
  { map: { uid: [] } },
  { map: { uid: null } },
  { map: { uid: FieldValue } },
  { map: { uid: GeoPoint } },
  { map: { uid: DocumentReference<DocumentData> } }
]

Ex5: Specific Value

function isStatus(status) {
    return status == 'success' || status == 'error';
}
function hasStatusKey(data) {
  return 'status' in data && isStatus(data.status);
}
const documentTypes: DocumentType = {
  status: ['success', 'error'],
}

getKeyTypePatterns

[
  { status: 'success' },
  { status: 'error' },
]

getRecursiveWrongTypes

[
  { status: 'hoge' },
  { status: -1 },
  { status: 1 },
  { status: 1.1 },
  { status: true },
  { status: {} },
  { status: [] },
  { status: null },
  { status: FieldValue },
  { status: GeoPoint },
  { status: DocumentReference<DocumentData> },

]

Tips

Might be work

const documentTypes: DocumentType = {
  uid: ALL_FIELD_TYPES.string,
  'list[]': [
    ALL_FIELD_TYPES.number,
    {
      uid: ALL_FIELD_TYPES.string,
      'list[]': ALL_FIELD_TYPES.bool,
    },
  ],
  map: {
    'list[]': [ALL_FIELD_TYPES.bool, ALL_FIELD_TYPES.number],
    nestedMap: [
      ALL_FIELD_TYPES.null,
      {
        hoge: ALL_FIELD_TYPES.string,
      },
    ],
  },
}

Timestamp for In Array

usually use serverTimestamp(), but use new Date() in Array because FieldValue.serverTimestamp() is not currently supported inside array.

number, int, float

number's concept include int and float

ex:

int: allow 1 and -1, reject 1.1 and -1.1
float: allow 1.1 and -1.1, reject 1 and -1
number: allow all these above (1, -1, 1.1, and -1.1)
then, wrong type of number not contain int or float neither.
and also wrong type of (int / float) not contain number.

Set Key Types / Type Values

import {
  getKeyTypePatterns,
  getRecursiveWrongTypes,
  getRecursiveRightTypeValues,
  getRecursiveWrongTypeValues,
} from 'firestore-document-type-partterns/core'
import { Inclusions } from 'firestore-document-type-partterns/types/inclusion-types'
import { KeyTypePatterns } from 'firestore-document-type-partterns/types/key-type-patterns'
import { KeyTypeValueFnc, KeyTypeValues, KeyValues } from 'firestore-document-type-partterns/types/key-type-values'
import { KeyType } from 'firestore-document-type-partterns/types/key-type'
import { REQUIRED_TYPE_VALUES } from 'firestore-document-type-partterns/types/types'

interface Data {
  hoge: string
  foo: string
}

type KeyTypeConst = {
  hoge: string
  foo: string
}

type KeyValue = {
  hoge: number
  foo: number
}

const keyType: KeyType<KeyTypeConst> = {
  hoge: 'hoge',
  foo: 'foo',
}
const inclusions: Inclusions<KeyTypeConst> = {
  [keyType.hoge]: [keyType.hoge, keyType.foo],
}
const keyTypesList: KeyTypePatterns<Data>[] = [
  {
    hoge: keyType.hoge,
    foo: keyType.foo,
  },
]

const KEY_VALUES: KeyTypeValues<KeyValue> = {
  hoge: 1,
  foo: 2,
  ...REQUIRED_TYPE_VALUES,
}
const keyValueFnc: KeyTypeValueFnc<KeyValue> = () => {
  return KEY_VALUES
}

const rightTypes = getKeyTypePatterns<D>(keyTypesList)
const wrongTypes = getRecursiveWrongTypes<Data, KeyTypeConst>(keyTypesList, keyType, inclusions)
const rightTypeValues = getRecursiveRightTypeValues<Data, KeyValue>(keyTypesList, keyValueFnc)
const wrongTypeValues = getRecursiveWrongTypeValues<Data, KeyTypeConst, KeyValue>(
  keyTypesList,
  keyType,
  inclusions,
  keyValueFnc
)

Package Sidebar

Install

npm i firestore-document-type-partterns

Weekly Downloads

117

Version

5.0.2

License

ISC

Unpacked Size

113 kB

Total Files

113

Last publish

Collaborators

  • cilly