Skip to content

feat: Add support for new Firestore types #8994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/seven-actors-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@firebase/firestore": minor
---

feat: Adds support for MinKey, MaxKey, RegexValue, Int32Value, BsonObjectId, BsonTimestamp, and BsonBinaryData.
60 changes: 60 additions & 0 deletions common/api-review/firestore-lite.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,34 @@ export function arrayUnion(...elements: unknown[]): FieldValue;
// @public
export function average(field: string | FieldPath): AggregateField<number | null>;

// @public
export class BsonBinaryData {
constructor(subtype: number, data: Uint8Array);
// (undocumented)
readonly data: Uint8Array;
isEqual(other: BsonBinaryData): boolean;
// (undocumented)
readonly subtype: number;
}

// @public
export class BsonObjectId {
constructor(value: string);
isEqual(other: BsonObjectId): boolean;
// (undocumented)
readonly value: string;
}

// @public
export class BsonTimestamp {
constructor(seconds: number, increment: number);
// (undocumented)
readonly increment: number;
isEqual(other: BsonTimestamp): boolean;
// (undocumented)
readonly seconds: number;
}

// @public
export class Bytes {
static fromBase64String(base64: string): Bytes;
Expand Down Expand Up @@ -249,6 +277,14 @@ export function initializeFirestore(app: FirebaseApp, settings: Settings): Fires
// @beta
export function initializeFirestore(app: FirebaseApp, settings: Settings, databaseId?: string): Firestore;

// @public
export class Int32Value {
constructor(value: number);
isEqual(other: Int32Value): boolean;
// (undocumented)
readonly value: number;
}

// @public
export function limit(limit: number): QueryLimitConstraint;

Expand All @@ -257,6 +293,20 @@ export function limitToLast(limit: number): QueryLimitConstraint;

export { LogLevel }

// @public
export class MaxKey {
// (undocumented)
static instance(): MaxKey;
readonly type = "MaxKey";
}

// @public
export class MinKey {
// (undocumented)
static instance(): MinKey;
readonly type = "MinKey";
}

// @public
export type NestedUpdateFields<T extends Record<string, unknown>> = UnionToIntersection<{
[K in keyof T & string]: ChildUpdateFields<K, T[K]>;
Expand Down Expand Up @@ -360,6 +410,16 @@ export class QueryStartAtConstraint extends QueryConstraint {
// @public
export function refEqual<AppModelType, DbModelType extends DocumentData>(left: DocumentReference<AppModelType, DbModelType> | CollectionReference<AppModelType, DbModelType>, right: DocumentReference<AppModelType, DbModelType> | CollectionReference<AppModelType, DbModelType>): boolean;

// @public
export class RegexValue {
constructor(pattern: string, options: string);
isEqual(other: RegexValue): boolean;
// (undocumented)
readonly options: string;
// (undocumented)
readonly pattern: string;
}

// @public
export function runTransaction<T>(firestore: Firestore, updateFunction: (transaction: Transaction) => Promise<T>, options?: TransactionOptions): Promise<T>;

Expand Down
60 changes: 60 additions & 0 deletions common/api-review/firestore.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,34 @@ export function arrayUnion(...elements: unknown[]): FieldValue;
// @public
export function average(field: string | FieldPath): AggregateField<number | null>;

// @public
export class BsonBinaryData {
constructor(subtype: number, data: Uint8Array);
// (undocumented)
readonly data: Uint8Array;
isEqual(other: BsonBinaryData): boolean;
// (undocumented)
readonly subtype: number;
}

// @public
export class BsonObjectId {
constructor(value: string);
isEqual(other: BsonObjectId): boolean;
// (undocumented)
readonly value: string;
}

// @public
export class BsonTimestamp {
constructor(seconds: number, increment: number);
// (undocumented)
readonly increment: number;
isEqual(other: BsonTimestamp): boolean;
// (undocumented)
readonly seconds: number;
}

// @public
export class Bytes {
static fromBase64String(base64: string): Bytes;
Expand Down Expand Up @@ -344,6 +372,14 @@ export interface IndexField {
// @public
export function initializeFirestore(app: FirebaseApp, settings: FirestoreSettings, databaseId?: string): Firestore;

// @public
export class Int32Value {
constructor(value: number);
isEqual(other: Int32Value): boolean;
// (undocumented)
readonly value: number;
}

// @public
export function limit(limit: number): QueryLimitConstraint;

Expand Down Expand Up @@ -374,6 +410,13 @@ export interface LoadBundleTaskProgress {

export { LogLevel }

// @public
export class MaxKey {
// (undocumented)
static instance(): MaxKey;
readonly type = "MaxKey";
}

// @public
export interface MemoryCacheSettings {
garbageCollector?: MemoryGarbageCollector;
Expand Down Expand Up @@ -411,6 +454,13 @@ export function memoryLruGarbageCollector(settings?: {
cacheSizeBytes?: number;
}): MemoryLruGarbageCollector;

// @public
export class MinKey {
// (undocumented)
static instance(): MinKey;
readonly type = "MinKey";
}

// @public
export function namedQuery(firestore: Firestore, name: string): Promise<Query | null>;

Expand Down Expand Up @@ -620,6 +670,16 @@ export class QueryStartAtConstraint extends QueryConstraint {
// @public
export function refEqual<AppModelType, DbModelType extends DocumentData>(left: DocumentReference<AppModelType, DbModelType> | CollectionReference<AppModelType, DbModelType>, right: DocumentReference<AppModelType, DbModelType> | CollectionReference<AppModelType, DbModelType>): boolean;

// @public
export class RegexValue {
constructor(pattern: string, options: string);
isEqual(other: RegexValue): boolean;
// (undocumented)
readonly options: string;
// (undocumented)
readonly pattern: string;
}

// @public
export function runTransaction<T>(firestore: Firestore, updateFunction: (transaction: Transaction) => Promise<T>, options?: TransactionOptions): Promise<T>;

Expand Down
14 changes: 14 additions & 0 deletions packages/firestore/lite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,20 @@ export {

export { VectorValue } from '../src/lite-api/vector_value';

export { Int32Value } from '../src/lite-api/int32_value';

export { RegexValue } from '../src/lite-api/regex_value';

export { BsonBinaryData } from '../src/lite-api/bson_binary_data';

export { BsonObjectId } from '../src/lite-api/bson_object_Id';

export { BsonTimestamp } from '../src/lite-api/bson_timestamp';

export { MinKey } from '../src/lite-api/min_key';

export { MaxKey } from '../src/lite-api/max_key';

export { WriteBatch, writeBatch } from '../src/lite-api/write_batch';

export { TransactionOptions } from '../src/lite-api/transaction_options';
Expand Down
14 changes: 14 additions & 0 deletions packages/firestore/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,20 @@ export {

export { VectorValue } from './lite-api/vector_value';

export { Int32Value } from './lite-api/int32_value';

export { RegexValue } from './lite-api/regex_value';

export { BsonBinaryData } from './lite-api/bson_binary_data';

export { BsonObjectId } from './lite-api/bson_object_Id';

export { BsonTimestamp } from './lite-api/bson_timestamp';

export { MinKey } from './lite-api/min_key';

export { MaxKey } from './lite-api/max_key';

export { LogLevelString as LogLevel, setLogLevel } from './util/log';

export { Bytes } from './api/bytes';
Expand Down
22 changes: 12 additions & 10 deletions packages/firestore/src/core/target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ import {
import { FieldPath, ResourcePath } from '../model/path';
import {
canonicalId,
MAX_VALUE,
MIN_VALUE,
INTERNAL_MAX_VALUE,
INTERNAL_MIN_VALUE,
lowerBoundCompare,
MAX_KEY_VALUE,
MIN_KEY_VALUE,
upperBoundCompare,
valuesGetLowerBound,
valuesGetUpperBound
Expand Down Expand Up @@ -302,7 +304,7 @@ export function targetGetNotInValues(

/**
* Returns a lower bound of field values that can be used as a starting point to
* scan the index defined by `fieldIndex`. Returns `MIN_VALUE` if no lower bound
* scan the index defined by `fieldIndex`. Returns `INTERNAL_MIN_VALUE` if no lower bound
* exists.
*/
export function targetGetLowerBound(
Expand All @@ -328,7 +330,7 @@ export function targetGetLowerBound(

/**
* Returns an upper bound of field values that can be used as an ending point
* when scanning the index defined by `fieldIndex`. Returns `MAX_VALUE` if no
* when scanning the index defined by `fieldIndex`. Returns `INTERNAL_MAX_VALUE` if no
* upper bound exists.
*/
export function targetGetUpperBound(
Expand Down Expand Up @@ -362,13 +364,13 @@ function targetGetAscendingBound(
fieldPath: FieldPath,
bound: Bound | null
): { value: ProtoValue; inclusive: boolean } {
let value: ProtoValue = MIN_VALUE;
let value: ProtoValue = INTERNAL_MIN_VALUE;

let inclusive = true;

// Process all filters to find a value for the current field segment
for (const fieldFilter of targetGetFieldFiltersForPath(target, fieldPath)) {
let filterValue: ProtoValue = MIN_VALUE;
let filterValue: ProtoValue = INTERNAL_MIN_VALUE;
let filterInclusive = true;

switch (fieldFilter.op) {
Expand All @@ -387,7 +389,7 @@ function targetGetAscendingBound(
break;
case Operator.NOT_EQUAL:
case Operator.NOT_IN:
filterValue = MIN_VALUE;
filterValue = MIN_KEY_VALUE;
break;
default:
// Remaining filters cannot be used as lower bounds.
Expand Down Expand Up @@ -437,12 +439,12 @@ function targetGetDescendingBound(
fieldPath: FieldPath,
bound: Bound | null
): { value: ProtoValue; inclusive: boolean } {
let value: ProtoValue = MAX_VALUE;
let value: ProtoValue = INTERNAL_MAX_VALUE;
let inclusive = true;

// Process all filters to find a value for the current field segment
for (const fieldFilter of targetGetFieldFiltersForPath(target, fieldPath)) {
let filterValue: ProtoValue = MAX_VALUE;
let filterValue: ProtoValue = INTERNAL_MAX_VALUE;
let filterInclusive = true;

switch (fieldFilter.op) {
Expand All @@ -462,7 +464,7 @@ function targetGetDescendingBound(
break;
case Operator.NOT_EQUAL:
case Operator.NOT_IN:
filterValue = MAX_VALUE;
filterValue = MAX_KEY_VALUE;
break;
default:
// Remaining filters cannot be used as upper bounds.
Expand Down
Loading
Loading