4652 lines
155 KiB
JavaScript
4652 lines
155 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
var common692d301d_node = require('./common-1ab68354.node.cjs.js');
|
|
require('@firebase/app');
|
|
require('@firebase/util');
|
|
require('@firebase/webchannel-wrapper/bloom-blob');
|
|
require('@firebase/logger');
|
|
require('util');
|
|
require('crypto');
|
|
require('@grpc/grpc-js');
|
|
require('@grpc/proto-loader');
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/* eslint @typescript-eslint/no-explicit-any: 0 */
|
|
function isITimestamp(obj) {
|
|
if (typeof obj !== 'object' || obj === null) {
|
|
return false; // Must be a non-null object
|
|
}
|
|
if ('seconds' in obj &&
|
|
(obj.seconds === null ||
|
|
typeof obj.seconds === 'number' ||
|
|
typeof obj.seconds === 'string') &&
|
|
'nanos' in obj &&
|
|
(obj.nanos === null || typeof obj.nanos === 'number')) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isILatLng(obj) {
|
|
if (typeof obj !== 'object' || obj === null) {
|
|
return false; // Must be a non-null object
|
|
}
|
|
if ('latitude' in obj &&
|
|
(obj.latitude === null || typeof obj.latitude === 'number') &&
|
|
'longitude' in obj &&
|
|
(obj.longitude === null || typeof obj.longitude === 'number')) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isIArrayValue(obj) {
|
|
if (typeof obj !== 'object' || obj === null) {
|
|
return false; // Must be a non-null object
|
|
}
|
|
if ('values' in obj && (obj.values === null || Array.isArray(obj.values))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isIMapValue(obj) {
|
|
if (typeof obj !== 'object' || obj === null) {
|
|
return false; // Must be a non-null object
|
|
}
|
|
if ('fields' in obj && (obj.fields === null || common692d301d_node.isPlainObject(obj.fields))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isIFunction(obj) {
|
|
if (typeof obj !== 'object' || obj === null) {
|
|
return false; // Must be a non-null object
|
|
}
|
|
if ('name' in obj &&
|
|
(obj.name === null || typeof obj.name === 'string') &&
|
|
'args' in obj &&
|
|
(obj.args === null || Array.isArray(obj.args))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isIPipeline(obj) {
|
|
if (typeof obj !== 'object' || obj === null) {
|
|
return false; // Must be a non-null object
|
|
}
|
|
if ('stages' in obj && (obj.stages === null || Array.isArray(obj.stages))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function isFirestoreValue(obj) {
|
|
if (typeof obj !== 'object' || obj === null) {
|
|
return false; // Must be a non-null object
|
|
}
|
|
// Check optional properties and their types
|
|
if (('nullValue' in obj &&
|
|
(obj.nullValue === null || obj.nullValue === 'NULL_VALUE')) ||
|
|
('booleanValue' in obj &&
|
|
(obj.booleanValue === null || typeof obj.booleanValue === 'boolean')) ||
|
|
('integerValue' in obj &&
|
|
(obj.integerValue === null ||
|
|
typeof obj.integerValue === 'number' ||
|
|
typeof obj.integerValue === 'string')) ||
|
|
('doubleValue' in obj &&
|
|
(obj.doubleValue === null || typeof obj.doubleValue === 'number')) ||
|
|
('timestampValue' in obj &&
|
|
(obj.timestampValue === null || isITimestamp(obj.timestampValue))) ||
|
|
('stringValue' in obj &&
|
|
(obj.stringValue === null || typeof obj.stringValue === 'string')) ||
|
|
('bytesValue' in obj &&
|
|
(obj.bytesValue === null || obj.bytesValue instanceof Uint8Array)) ||
|
|
('referenceValue' in obj &&
|
|
(obj.referenceValue === null ||
|
|
typeof obj.referenceValue === 'string')) ||
|
|
('geoPointValue' in obj &&
|
|
(obj.geoPointValue === null || isILatLng(obj.geoPointValue))) ||
|
|
('arrayValue' in obj &&
|
|
(obj.arrayValue === null || isIArrayValue(obj.arrayValue))) ||
|
|
('mapValue' in obj &&
|
|
(obj.mapValue === null || isIMapValue(obj.mapValue))) ||
|
|
('fieldReferenceValue' in obj &&
|
|
(obj.fieldReferenceValue === null ||
|
|
typeof obj.fieldReferenceValue === 'string')) ||
|
|
('functionValue' in obj &&
|
|
(obj.functionValue === null || isIFunction(obj.functionValue))) ||
|
|
('pipelineValue' in obj &&
|
|
(obj.pipelineValue === null || isIPipeline(obj.pipelineValue)))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/**
|
|
* Converts a value to an Expression, Returning either a Constant, MapFunction,
|
|
* ArrayFunction, or the input itself (if it's already an expression).
|
|
*
|
|
* @private
|
|
* @internal
|
|
* @param value
|
|
*/
|
|
function valueToDefaultExpr$1(value) {
|
|
let result;
|
|
if (value instanceof Expression) {
|
|
return value;
|
|
}
|
|
else if (common692d301d_node.isPlainObject(value)) {
|
|
result = _map(value);
|
|
}
|
|
else if (value instanceof Array) {
|
|
result = array(value);
|
|
}
|
|
else {
|
|
result = _constant(value, undefined);
|
|
}
|
|
return result;
|
|
}
|
|
/**
|
|
* Converts a value to an Expression, Returning either a Constant, MapFunction,
|
|
* ArrayFunction, or the input itself (if it's already an expression).
|
|
*
|
|
* @private
|
|
* @internal
|
|
* @param value
|
|
*/
|
|
function vectorToExpr$1(value) {
|
|
if (value instanceof Expression) {
|
|
return value;
|
|
}
|
|
else if (value instanceof common692d301d_node.VectorValue) {
|
|
return constant(value);
|
|
}
|
|
else if (Array.isArray(value)) {
|
|
return constant(common692d301d_node.vector(value));
|
|
}
|
|
else {
|
|
throw new Error('Unsupported value: ' + typeof value);
|
|
}
|
|
}
|
|
/**
|
|
* Converts a value to an Expression, Returning either a Constant, MapFunction,
|
|
* ArrayFunction, or the input itself (if it's already an expression).
|
|
* If the input is a string, it is assumed to be a field name, and a
|
|
* field(value) is returned.
|
|
*
|
|
* @private
|
|
* @internal
|
|
* @param value
|
|
*/
|
|
function fieldOrExpression$1(value) {
|
|
if (common692d301d_node.isString(value)) {
|
|
const result = field(value);
|
|
return result;
|
|
}
|
|
else {
|
|
return valueToDefaultExpr$1(value);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Represents an expression that can be evaluated to a value within the execution of a {@link
|
|
* @firebase/firestore/pipelines#Pipeline}.
|
|
*
|
|
* Expressions are the building blocks for creating complex queries and transformations in
|
|
* Firestore pipelines. They can represent:
|
|
*
|
|
* - **Field references:** Access values from document fields.
|
|
* - **Literals:** Represent constant values (strings, numbers, booleans).
|
|
* - **Function calls:** Apply functions to one or more expressions.
|
|
*
|
|
* The `Expression` class provides a fluent API for building expressions. You can chain together
|
|
* method calls to create complex expressions.
|
|
*/
|
|
class Expression {
|
|
constructor() {
|
|
this._protoValueType = 'ProtoValue';
|
|
}
|
|
/**
|
|
* Creates an expression that adds this expression to another expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Add the value of the 'quantity' field and the 'reserve' field.
|
|
* field("quantity").add(field("reserve"));
|
|
* ```
|
|
*
|
|
* @param second - The expression or literal to add to this expression.
|
|
* @param others - Optional additional expressions or literals to add to this expression.
|
|
* @returns A new `Expression` representing the addition operation.
|
|
*/
|
|
add(second) {
|
|
return new FunctionExpression('add', [this, valueToDefaultExpr$1(second)], 'add');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Wraps the expression in a [BooleanExpression].
|
|
*
|
|
* @returns A [BooleanExpression] representing the same expression.
|
|
*/
|
|
asBoolean() {
|
|
if (this instanceof BooleanExpression) {
|
|
return this;
|
|
}
|
|
else if (this instanceof Constant) {
|
|
return new BooleanConstant(this);
|
|
}
|
|
else if (this instanceof Field) {
|
|
return new BooleanField(this);
|
|
}
|
|
else if (this instanceof FunctionExpression) {
|
|
return new BooleanFunctionExpression(this);
|
|
}
|
|
else {
|
|
throw new common692d301d_node.FirestoreError('invalid-argument', `Conversion of type ${typeof this} to BooleanExpression not supported.`);
|
|
}
|
|
}
|
|
subtract(subtrahend) {
|
|
return new FunctionExpression('subtract', [this, valueToDefaultExpr$1(subtrahend)], 'subtract');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that multiplies this expression by another expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Multiply the 'quantity' field by the 'price' field
|
|
* field("quantity").multiply(field("price"));
|
|
* ```
|
|
*
|
|
* @param second - The second expression or literal to multiply by.
|
|
* @param others - Optional additional expressions or literals to multiply by.
|
|
* @returns A new `Expression` representing the multiplication operation.
|
|
*/
|
|
multiply(second) {
|
|
return new FunctionExpression('multiply', [this, valueToDefaultExpr$1(second)], 'multiply');
|
|
}
|
|
divide(divisor) {
|
|
return new FunctionExpression('divide', [this, valueToDefaultExpr$1(divisor)], 'divide');
|
|
}
|
|
mod(other) {
|
|
return new FunctionExpression('mod', [this, valueToDefaultExpr$1(other)], 'mod');
|
|
}
|
|
equal(other) {
|
|
return new FunctionExpression('equal', [this, valueToDefaultExpr$1(other)], 'equal').asBoolean();
|
|
}
|
|
notEqual(other) {
|
|
return new FunctionExpression('not_equal', [this, valueToDefaultExpr$1(other)], 'notEqual').asBoolean();
|
|
}
|
|
lessThan(other) {
|
|
return new FunctionExpression('less_than', [this, valueToDefaultExpr$1(other)], 'lessThan').asBoolean();
|
|
}
|
|
lessThanOrEqual(other) {
|
|
return new FunctionExpression('less_than_or_equal', [this, valueToDefaultExpr$1(other)], 'lessThanOrEqual').asBoolean();
|
|
}
|
|
greaterThan(other) {
|
|
return new FunctionExpression('greater_than', [this, valueToDefaultExpr$1(other)], 'greaterThan').asBoolean();
|
|
}
|
|
greaterThanOrEqual(other) {
|
|
return new FunctionExpression('greater_than_or_equal', [this, valueToDefaultExpr$1(other)], 'greaterThanOrEqual').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that concatenates an array expression with one or more other arrays.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Combine the 'items' array with another array field.
|
|
* field("items").arrayConcat(field("otherItems"));
|
|
* ```
|
|
* @param secondArray - Second array expression or array literal to concatenate.
|
|
* @param otherArrays - Optional additional array expressions or array literals to concatenate.
|
|
* @returns A new `Expression` representing the concatenated array.
|
|
*/
|
|
arrayConcat(secondArray, ...otherArrays) {
|
|
const elements = [secondArray, ...otherArrays];
|
|
const exprValues = elements.map(value => valueToDefaultExpr$1(value));
|
|
return new FunctionExpression('array_concat', [this, ...exprValues], 'arrayConcat');
|
|
}
|
|
arrayContains(element) {
|
|
return new FunctionExpression('array_contains', [this, valueToDefaultExpr$1(element)], 'arrayContains').asBoolean();
|
|
}
|
|
arrayContainsAll(values) {
|
|
const normalizedExpr = Array.isArray(values)
|
|
? new ListOfExprs(values.map(valueToDefaultExpr$1), 'arrayContainsAll')
|
|
: values;
|
|
return new FunctionExpression('array_contains_all', [this, normalizedExpr], 'arrayContainsAll').asBoolean();
|
|
}
|
|
arrayContainsAny(values) {
|
|
const normalizedExpr = Array.isArray(values)
|
|
? new ListOfExprs(values.map(valueToDefaultExpr$1), 'arrayContainsAny')
|
|
: values;
|
|
return new FunctionExpression('array_contains_any', [this, normalizedExpr], 'arrayContainsAny').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that reverses an array.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Reverse the value of the 'myArray' field.
|
|
* field("myArray").arrayReverse();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the reversed array.
|
|
*/
|
|
arrayReverse() {
|
|
return new FunctionExpression('array_reverse', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that calculates the length of an array.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the number of items in the 'cart' array
|
|
* field("cart").arrayLength();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the length of the array.
|
|
*/
|
|
arrayLength() {
|
|
return new FunctionExpression('array_length', [this], 'arrayLength');
|
|
}
|
|
equalAny(others) {
|
|
const exprOthers = Array.isArray(others)
|
|
? new ListOfExprs(others.map(valueToDefaultExpr$1), 'equalAny')
|
|
: others;
|
|
return new FunctionExpression('equal_any', [this, exprOthers], 'equalAny').asBoolean();
|
|
}
|
|
notEqualAny(others) {
|
|
const exprOthers = Array.isArray(others)
|
|
? new ListOfExprs(others.map(valueToDefaultExpr$1), 'notEqualAny')
|
|
: others;
|
|
return new FunctionExpression('not_equal_any', [this, exprOthers], 'notEqualAny').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that checks if a field exists in the document.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Check if the document has a field named "phoneNumber"
|
|
* field("phoneNumber").exists();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the 'exists' check.
|
|
*/
|
|
exists() {
|
|
return new FunctionExpression('exists', [this], 'exists').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that calculates the character length of a string in UTF-8.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the character length of the 'name' field in its UTF-8 form.
|
|
* field("name").charLength();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the length of the string.
|
|
*/
|
|
charLength() {
|
|
return new FunctionExpression('char_length', [this], 'charLength');
|
|
}
|
|
like(stringOrExpr) {
|
|
return new FunctionExpression('like', [this, valueToDefaultExpr$1(stringOrExpr)], 'like').asBoolean();
|
|
}
|
|
regexContains(stringOrExpr) {
|
|
return new FunctionExpression('regex_contains', [this, valueToDefaultExpr$1(stringOrExpr)], 'regexContains').asBoolean();
|
|
}
|
|
regexFind(stringOrExpr) {
|
|
return new FunctionExpression('regex_find', [this, valueToDefaultExpr$1(stringOrExpr)], 'regexFind');
|
|
}
|
|
regexFindAll(stringOrExpr) {
|
|
return new FunctionExpression('regex_find_all', [this, valueToDefaultExpr$1(stringOrExpr)], 'regexFindAll');
|
|
}
|
|
regexMatch(stringOrExpr) {
|
|
return new FunctionExpression('regex_match', [this, valueToDefaultExpr$1(stringOrExpr)], 'regexMatch').asBoolean();
|
|
}
|
|
stringContains(stringOrExpr) {
|
|
return new FunctionExpression('string_contains', [this, valueToDefaultExpr$1(stringOrExpr)], 'stringContains').asBoolean();
|
|
}
|
|
startsWith(stringOrExpr) {
|
|
return new FunctionExpression('starts_with', [this, valueToDefaultExpr$1(stringOrExpr)], 'startsWith').asBoolean();
|
|
}
|
|
endsWith(stringOrExpr) {
|
|
return new FunctionExpression('ends_with', [this, valueToDefaultExpr$1(stringOrExpr)], 'endsWith').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that converts a string to lowercase.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Convert the 'name' field to lowercase
|
|
* field("name").toLower();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the lowercase string.
|
|
*/
|
|
toLower() {
|
|
return new FunctionExpression('to_lower', [this], 'toLower');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that converts a string to uppercase.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Convert the 'title' field to uppercase
|
|
* field("title").toUpper();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the uppercase string.
|
|
*/
|
|
toUpper() {
|
|
return new FunctionExpression('to_upper', [this], 'toUpper');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that removes leading and trailing characters from a string or byte array.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Trim whitespace from the 'userInput' field
|
|
* field("userInput").trim();
|
|
*
|
|
* // Trim quotes from the 'userInput' field
|
|
* field("userInput").trim('"');
|
|
* ```
|
|
* @param valueToTrim - Optional This parameter is treated as a set of characters or bytes that will be
|
|
* trimmed from the input. If not specified, then whitespace will be trimmed.
|
|
* @returns A new `Expression` representing the trimmed string or byte array.
|
|
*/
|
|
trim(valueToTrim) {
|
|
const args = [this];
|
|
if (valueToTrim) {
|
|
args.push(valueToDefaultExpr$1(valueToTrim));
|
|
}
|
|
return new FunctionExpression('trim', args, 'trim');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Trims whitespace or a specified set of characters/bytes from the beginning of a string or byte array.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Trim whitespace from the beginning of the 'userInput' field
|
|
* field("userInput").ltrim();
|
|
*
|
|
* // Trim quotes from the beginning of the 'userInput' field
|
|
* field("userInput").ltrim('"');
|
|
* ```
|
|
*
|
|
* @param valueToTrim - Optional. A string or byte array containing the characters/bytes to trim.
|
|
* If not specified, whitespace will be trimmed.
|
|
* @returns A new `Expression` representing the trimmed string.
|
|
*/
|
|
ltrim(valueToTrim) {
|
|
const args = [this];
|
|
if (valueToTrim) {
|
|
args.push(valueToDefaultExpr$1(valueToTrim));
|
|
}
|
|
return new FunctionExpression('ltrim', args, 'ltrim');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Trims whitespace or a specified set of characters/bytes from the end of a string or byte array.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Trim whitespace from the end of the 'userInput' field
|
|
* field("userInput").rtrim();
|
|
*
|
|
* // Trim quotes from the end of the 'userInput' field
|
|
* field("userInput").rtrim('"');
|
|
* ```
|
|
*
|
|
* @param valueToTrim - Optional. A string or byte array containing the characters/bytes to trim.
|
|
* If not specified, whitespace will be trimmed.
|
|
* @returns A new `Expression` representing the trimmed string or byte array.
|
|
*/
|
|
rtrim(valueToTrim) {
|
|
const args = [this];
|
|
if (valueToTrim) {
|
|
args.push(valueToDefaultExpr$1(valueToTrim));
|
|
}
|
|
return new FunctionExpression('rtrim', args, 'rtrim');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that returns the data type of this expression's result, as a string.
|
|
*
|
|
* @remarks
|
|
* This is evaluated on the backend. This means:
|
|
* 1. Generic typed elements (like `array<string>`) evaluate strictly to the primitive `'array'`.
|
|
* 2. Any custom `FirestoreDataConverter` mappings are ignored.
|
|
* 3. For numeric values, the backend does not yield the JavaScript `"number"` type; it evaluates
|
|
* precisely as `"int64"` or `"float64"`.
|
|
* 4. For date or timestamp objects, the backend evaluates to `"timestamp"`.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the data type of the value in field 'title'
|
|
* field('title').type()
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the data type.
|
|
*/
|
|
type() {
|
|
return new FunctionExpression('type', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that checks if the result of this expression is of the given type.
|
|
*
|
|
* @remarks Null or undefined fields evaluate to skip/error. Use `ifAbsent()` / `isAbsent()` to evaluate missing data.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Check if the 'price' field is specifically an integer (not just 'number')
|
|
* field('price').isType('int64');
|
|
* ```
|
|
*
|
|
* @param type - The type to check for.
|
|
* @returns A new `BooleanExpression` that evaluates to true if the expression's result is of the given type, false otherwise.
|
|
*/
|
|
isType(type) {
|
|
return new FunctionExpression('is_type', [this, constant(type)], 'isType').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that concatenates string expressions together.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Combine the 'firstName', " ", and 'lastName' fields into a single string
|
|
* field("firstName").stringConcat(constant(" "), field("lastName"));
|
|
* ```
|
|
*
|
|
* @param secondString - The additional expression or string literal to concatenate.
|
|
* @param otherStrings - Optional additional expressions or string literals to concatenate.
|
|
* @returns A new `Expression` representing the concatenated string.
|
|
*/
|
|
stringConcat(secondString, ...otherStrings) {
|
|
const elements = [secondString, ...otherStrings];
|
|
const exprs = elements.map(valueToDefaultExpr$1);
|
|
return new FunctionExpression('string_concat', [this, ...exprs], 'stringConcat');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that finds the index of the first occurrence of a substring or byte sequence.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Find the index of "foo" in the 'text' field
|
|
* field("text").stringIndexOf("foo");
|
|
* ```
|
|
*
|
|
* @param search - The substring or byte sequence to search for.
|
|
* @returns A new `Expression` representing the index of the first occurrence.
|
|
*/
|
|
stringIndexOf(search) {
|
|
return new FunctionExpression('string_index_of', [this, valueToDefaultExpr$1(search)], 'stringIndexOf');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that repeats a string or byte array a specified number of times.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Repeat the 'label' field 3 times
|
|
* field("label").stringRepeat(3);
|
|
* ```
|
|
*
|
|
* @param repetitions - The number of times to repeat the string or byte array.
|
|
* @returns A new `Expression` representing the repeated string or byte array.
|
|
*/
|
|
stringRepeat(repetitions) {
|
|
return new FunctionExpression('string_repeat', [this, valueToDefaultExpr$1(repetitions)], 'stringRepeat');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that replaces all occurrences of a substring or byte sequence with a replacement.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Replace all occurrences of "foo" with "bar" in the 'text' field
|
|
* field("text").stringReplaceAll("foo", "bar");
|
|
* ```
|
|
*
|
|
* @param find - The substring or byte sequence to search for.
|
|
* @param replacement - The replacement string or byte sequence.
|
|
* @returns A new `Expression` representing the string or byte array with replacements.
|
|
*/
|
|
stringReplaceAll(find, replacement) {
|
|
return new FunctionExpression('string_replace_all', [this, valueToDefaultExpr$1(find), valueToDefaultExpr$1(replacement)], 'stringReplaceAll');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that replaces the first occurrence of a substring or byte sequence with a replacement.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Replace the first occurrence of "foo" with "bar" in the 'text' field
|
|
* field("text").stringReplaceOne("foo", "bar");
|
|
* ```
|
|
*
|
|
* @param find - The substring or byte sequence to search for.
|
|
* @param replacement - The replacement string or byte sequence.
|
|
* @returns A new `Expression` representing the string or byte array with the replacement.
|
|
*/
|
|
stringReplaceOne(find, replacement) {
|
|
return new FunctionExpression('string_replace_one', [this, valueToDefaultExpr$1(find), valueToDefaultExpr$1(replacement)], 'stringReplaceOne');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that concatenates expression results together.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Combine the 'firstName', ' ', and 'lastName' fields into a single value.
|
|
* field("firstName").concat(constant(" "), field("lastName"));
|
|
* ```
|
|
*
|
|
* @param second - The additional expression or literal to concatenate.
|
|
* @param others - Optional additional expressions or literals to concatenate.
|
|
* @returns A new `Expression` representing the concatenated value.
|
|
*/
|
|
concat(second, ...others) {
|
|
const elements = [second, ...others];
|
|
const exprs = elements.map(valueToDefaultExpr$1);
|
|
return new FunctionExpression('concat', [this, ...exprs], 'concat');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that reverses this string expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Reverse the value of the 'myString' field.
|
|
* field("myString").reverse();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the reversed string.
|
|
*/
|
|
reverse() {
|
|
return new FunctionExpression('reverse', [this], 'reverse');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that calculates the length of this string expression in bytes.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Calculate the length of the 'myString' field in bytes.
|
|
* field("myString").byteLength();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the length of the string in bytes.
|
|
*/
|
|
byteLength() {
|
|
return new FunctionExpression('byte_length', [this], 'byteLength');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that computes the ceiling of a numeric value.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Compute the ceiling of the 'price' field.
|
|
* field("price").ceil();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the ceiling of the numeric value.
|
|
*/
|
|
ceil() {
|
|
return new FunctionExpression('ceil', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that computes the floor of a numeric value.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Compute the floor of the 'price' field.
|
|
* field("price").floor();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the floor of the numeric value.
|
|
*/
|
|
floor() {
|
|
return new FunctionExpression('floor', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that computes the absolute value of a numeric value.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Compute the absolute value of the 'price' field.
|
|
* field("price").abs();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the absolute value of the numeric value.
|
|
*/
|
|
abs() {
|
|
return new FunctionExpression('abs', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that computes e to the power of this expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Compute e to the power of the 'value' field.
|
|
* field("value").exp();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the exp of the numeric value.
|
|
*/
|
|
exp() {
|
|
return new FunctionExpression('exp', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Accesses a value from a map (object) field using the provided key.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the 'city' value from the 'address' map field
|
|
* field("address").mapGet("city");
|
|
* ```
|
|
*
|
|
* @param subfield - The key to access in the map.
|
|
* @returns A new `Expression` representing the value associated with the given key in the map.
|
|
*/
|
|
mapGet(subfield) {
|
|
return new FunctionExpression('map_get', [this, constant(subfield)], 'mapGet');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that returns a new map with the specified entries added or updated.
|
|
*
|
|
* @remarks
|
|
* Note that `mapSet` only performs shallow updates to the map. Setting a value to `null`
|
|
* will retain the key with a `null` value. To remove a key entirely, use `mapRemove`.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Set the 'city' to "San Francisco" in the 'address' map
|
|
* field("address").mapSet("city", "San Francisco");
|
|
* ```
|
|
*
|
|
* @param key - The key to set. Must be a string or a constant string expression.
|
|
* @param value - The value to set.
|
|
* @param moreKeyValues - Additional key-value pairs to set.
|
|
* @returns A new `Expression` representing the map with the entries set.
|
|
*/
|
|
mapSet(key, value, ...moreKeyValues) {
|
|
const args = [
|
|
this,
|
|
valueToDefaultExpr$1(key),
|
|
valueToDefaultExpr$1(value),
|
|
...moreKeyValues.map(valueToDefaultExpr$1)
|
|
];
|
|
return new FunctionExpression('map_set', args, 'mapSet');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that returns the keys of a map.
|
|
*
|
|
* @remarks
|
|
* While the backend generally preserves insertion order, relying on the
|
|
* order of the output array is not guaranteed and should be avoided.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the keys of the 'address' map
|
|
* field("address").mapKeys();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the keys of the map.
|
|
*/
|
|
mapKeys() {
|
|
return new FunctionExpression('map_keys', [this], 'mapKeys');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that returns the values of a map.
|
|
*
|
|
* @remarks
|
|
* While the backend generally preserves insertion order, relying on the
|
|
* order of the output array is not guaranteed and should be avoided.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the values of the 'address' map
|
|
* field("address").mapValues();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the values of the map.
|
|
*/
|
|
mapValues() {
|
|
return new FunctionExpression('map_values', [this], 'mapValues');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that returns the entries of a map as an array of maps,
|
|
* where each map contains a `"k"` property for the key and a `"v"` property for the value.
|
|
* For example: `[{ k: "key1", v: "value1" }, ...]`.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the entries of the 'address' map
|
|
* field("address").mapEntries();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the entries of the map.
|
|
*/
|
|
mapEntries() {
|
|
return new FunctionExpression('map_entries', [this], 'mapEntries');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that counts the number of stage inputs with valid evaluations of the
|
|
* expression or field.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Count the total number of products
|
|
* field("productId").count().as("totalProducts");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'count' aggregation.
|
|
*/
|
|
count() {
|
|
return AggregateFunction._create('count', [this], 'count');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that calculates the sum of a numeric field across multiple stage inputs.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Calculate the total revenue from a set of orders
|
|
* field("orderAmount").sum().as("totalRevenue");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'sum' aggregation.
|
|
*/
|
|
sum() {
|
|
return AggregateFunction._create('sum', [this], 'sum');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that calculates the average (mean) of a numeric field across multiple
|
|
* stage inputs.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Calculate the average age of users
|
|
* field("age").average().as("averageAge");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'average' aggregation.
|
|
*/
|
|
average() {
|
|
return AggregateFunction._create('average', [this], 'average');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that finds the minimum value of a field across multiple stage inputs.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Find the lowest price of all products
|
|
* field("price").minimum().as("lowestPrice");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'minimum' aggregation.
|
|
*/
|
|
minimum() {
|
|
return AggregateFunction._create('minimum', [this], 'minimum');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that finds the maximum value of a field across multiple stage inputs.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Find the highest score in a leaderboard
|
|
* field("score").maximum().as("highestScore");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'maximum' aggregation.
|
|
*/
|
|
maximum() {
|
|
return AggregateFunction._create('maximum', [this], 'maximum');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that finds the first value of an expression across multiple stage inputs.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Find the first value of the 'rating' field
|
|
* field("rating").first().as("firstRating");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'first' aggregation.
|
|
*/
|
|
first() {
|
|
return AggregateFunction._create('first', [this], 'first');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that finds the last value of an expression across multiple stage inputs.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Find the last value of the 'rating' field
|
|
* field("rating").last().as("lastRating");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'last' aggregation.
|
|
*/
|
|
last() {
|
|
return AggregateFunction._create('last', [this], 'last');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that collects all values of an expression across multiple stage inputs
|
|
* into an array.
|
|
*
|
|
* @remarks
|
|
* If the expression resolves to an absent value, it is converted to `null`.
|
|
* The order of elements in the output array is not stable and shouldn't be relied upon.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Collect all tags from books into an array
|
|
* field("tags").arrayAgg().as("allTags");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'array_agg' aggregation.
|
|
*/
|
|
arrayAgg() {
|
|
return AggregateFunction._create('array_agg', [this], 'arrayAgg');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that collects all distinct values of an expression across multiple stage
|
|
* inputs into an array.
|
|
*
|
|
* @remarks
|
|
* If the expression resolves to an absent value, it is converted to `null`.
|
|
* The order of elements in the output array is not stable and shouldn't be relied upon.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Collect all distinct tags from books into an array
|
|
* field("tags").arrayAggDistinct().as("allDistinctTags");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'array_agg_distinct' aggregation.
|
|
*/
|
|
arrayAggDistinct() {
|
|
return AggregateFunction._create('array_agg_distinct', [this], 'arrayAggDistinct');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that counts the number of distinct values of the expression or field.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Count the distinct number of products
|
|
* field("productId").countDistinct().as("distinctProducts");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'count_distinct' aggregation.
|
|
*/
|
|
countDistinct() {
|
|
return AggregateFunction._create('count_distinct', [this], 'countDistinct');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that returns the larger value between this expression and another expression, based on Firestore's value type ordering.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Returns the larger value between the 'timestamp' field and the current timestamp.
|
|
* field("timestamp").logicalMaximum(Function.currentTimestamp());
|
|
* ```
|
|
*
|
|
* @param second - The second expression or literal to compare with.
|
|
* @param others - Optional additional expressions or literals to compare with.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the logical maximum operation.
|
|
*/
|
|
logicalMaximum(second, ...others) {
|
|
const values = [second, ...others];
|
|
return new FunctionExpression('maximum', [this, ...values.map(valueToDefaultExpr$1)], 'logicalMaximum');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that returns the smaller value between this expression and another expression, based on Firestore's value type ordering.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Returns the smaller value between the 'timestamp' field and the current timestamp.
|
|
* field("timestamp").logicalMinimum(Function.currentTimestamp());
|
|
* ```
|
|
*
|
|
* @param second - The second expression or literal to compare with.
|
|
* @param others - Optional additional expressions or literals to compare with.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the logical minimum operation.
|
|
*/
|
|
logicalMinimum(second, ...others) {
|
|
const values = [second, ...others];
|
|
return new FunctionExpression('minimum', [this, ...values.map(valueToDefaultExpr$1)], 'minimum');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that calculates the length (number of dimensions) of this Firestore Vector expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the vector length (dimension) of the field 'embedding'.
|
|
* field("embedding").vectorLength();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the length of the vector.
|
|
*/
|
|
vectorLength() {
|
|
return new FunctionExpression('vector_length', [this], 'vectorLength');
|
|
}
|
|
cosineDistance(other) {
|
|
return new FunctionExpression('cosine_distance', [this, vectorToExpr$1(other)], 'cosineDistance');
|
|
}
|
|
dotProduct(other) {
|
|
return new FunctionExpression('dot_product', [this, vectorToExpr$1(other)], 'dotProduct');
|
|
}
|
|
euclideanDistance(other) {
|
|
return new FunctionExpression('euclidean_distance', [this, vectorToExpr$1(other)], 'euclideanDistance');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that interprets this expression as the number of microseconds since the Unix epoch (1970-01-01 00:00:00 UTC)
|
|
* and returns a timestamp.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Interpret the 'microseconds' field as microseconds since epoch.
|
|
* field("microseconds").unixMicrosToTimestamp();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the timestamp.
|
|
*/
|
|
unixMicrosToTimestamp() {
|
|
return new FunctionExpression('unix_micros_to_timestamp', [this], 'unixMicrosToTimestamp');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that converts this timestamp expression to the number of microseconds since the Unix epoch (1970-01-01 00:00:00 UTC).
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Convert the 'timestamp' field to microseconds since epoch.
|
|
* field("timestamp").timestampToUnixMicros();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the number of microseconds since epoch.
|
|
*/
|
|
timestampToUnixMicros() {
|
|
return new FunctionExpression('timestamp_to_unix_micros', [this], 'timestampToUnixMicros');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that interprets this expression as the number of milliseconds since the Unix epoch (1970-01-01 00:00:00 UTC)
|
|
* and returns a timestamp.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Interpret the 'milliseconds' field as milliseconds since epoch.
|
|
* field("milliseconds").unixMillisToTimestamp();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the timestamp.
|
|
*/
|
|
unixMillisToTimestamp() {
|
|
return new FunctionExpression('unix_millis_to_timestamp', [this], 'unixMillisToTimestamp');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that converts this timestamp expression to the number of milliseconds since the Unix epoch (1970-01-01 00:00:00 UTC).
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Convert the 'timestamp' field to milliseconds since epoch.
|
|
* field("timestamp").timestampToUnixMillis();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the number of milliseconds since epoch.
|
|
*/
|
|
timestampToUnixMillis() {
|
|
return new FunctionExpression('timestamp_to_unix_millis', [this], 'timestampToUnixMillis');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that interprets this expression as the number of seconds since the Unix epoch (1970-01-01 00:00:00 UTC)
|
|
* and returns a timestamp.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Interpret the 'seconds' field as seconds since epoch.
|
|
* field("seconds").unixSecondsToTimestamp();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the timestamp.
|
|
*/
|
|
unixSecondsToTimestamp() {
|
|
return new FunctionExpression('unix_seconds_to_timestamp', [this], 'unixSecondsToTimestamp');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that converts this timestamp expression to the number of seconds since the Unix epoch (1970-01-01 00:00:00 UTC).
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Convert the 'timestamp' field to seconds since epoch.
|
|
* field("timestamp").timestampToUnixSeconds();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the number of seconds since epoch.
|
|
*/
|
|
timestampToUnixSeconds() {
|
|
return new FunctionExpression('timestamp_to_unix_seconds', [this], 'timestampToUnixSeconds');
|
|
}
|
|
timestampAdd(unit, amount) {
|
|
return new FunctionExpression('timestamp_add', [this, valueToDefaultExpr$1(unit), valueToDefaultExpr$1(amount)], 'timestampAdd');
|
|
}
|
|
timestampSubtract(unit, amount) {
|
|
return new FunctionExpression('timestamp_subtract', [this, valueToDefaultExpr$1(unit), valueToDefaultExpr$1(amount)], 'timestampSubtract');
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that returns the document ID from a path.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the document ID from a path.
|
|
* field("__path__").documentId();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the documentId operation.
|
|
*/
|
|
documentId() {
|
|
return new FunctionExpression('document_id', [this], 'documentId');
|
|
}
|
|
substring(position, length) {
|
|
const positionExpr = valueToDefaultExpr$1(position);
|
|
if (length === undefined) {
|
|
return new FunctionExpression('substring', [this, positionExpr], 'substring');
|
|
}
|
|
else {
|
|
return new FunctionExpression('substring', [this, positionExpr, valueToDefaultExpr$1(length)], 'substring');
|
|
}
|
|
}
|
|
arrayGet(offset) {
|
|
return new FunctionExpression('array_get', [this, valueToDefaultExpr$1(offset)], 'arrayGet');
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that checks if a given expression produces an error.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Check if the result of a calculation is an error
|
|
* field("title").arrayContains(1).isError();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#BooleanExpression} representing the 'isError' check.
|
|
*/
|
|
isError() {
|
|
return new FunctionExpression('is_error', [this], 'isError').asBoolean();
|
|
}
|
|
ifError(catchValue) {
|
|
const result = new FunctionExpression('if_error', [this, valueToDefaultExpr$1(catchValue)], 'ifError');
|
|
return catchValue instanceof BooleanExpression
|
|
? result.asBoolean()
|
|
: result;
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that returns `true` if the result of this expression
|
|
* is absent. Otherwise, returns `false` even if the value is `null`.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Check if the field `value` is absent.
|
|
* field("value").isAbsent();
|
|
* @example
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#BooleanExpression} representing the 'isAbsent' check.
|
|
*/
|
|
isAbsent() {
|
|
return new FunctionExpression('is_absent', [this], 'isAbsent').asBoolean();
|
|
}
|
|
mapRemove(stringExpr) {
|
|
return new FunctionExpression('map_remove', [this, valueToDefaultExpr$1(stringExpr)], 'mapRemove');
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that merges multiple map values.
|
|
*
|
|
* @example
|
|
* ```
|
|
* // Merges the map in the settings field with, a map literal, and a map in
|
|
* // that is conditionally returned by another expression
|
|
* field('settings').mapMerge({ enabled: true }, conditional(field('isAdmin'), { admin: true}, {})
|
|
* ```
|
|
*
|
|
* @param secondMap - A required second map to merge. Represented as a literal or
|
|
* an expression that returns a map.
|
|
* @param otherMaps - Optional additional maps to merge. Each map is represented
|
|
* as a literal or an expression that returns a map.
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the 'mapMerge' operation.
|
|
*/
|
|
mapMerge(secondMap, ...otherMaps) {
|
|
const secondMapExpr = valueToDefaultExpr$1(secondMap);
|
|
const otherMapExprs = otherMaps.map(valueToDefaultExpr$1);
|
|
return new FunctionExpression('map_merge', [this, secondMapExpr, ...otherMapExprs], 'mapMerge');
|
|
}
|
|
pow(exponent) {
|
|
return new FunctionExpression('pow', [this, valueToDefaultExpr$1(exponent)]);
|
|
}
|
|
trunc(decimalPlaces) {
|
|
if (decimalPlaces === undefined) {
|
|
return new FunctionExpression('trunc', [this]);
|
|
}
|
|
else {
|
|
return new FunctionExpression('trunc', [this, valueToDefaultExpr$1(decimalPlaces)], 'trunc');
|
|
}
|
|
}
|
|
round(decimalPlaces) {
|
|
if (decimalPlaces === undefined) {
|
|
return new FunctionExpression('round', [this]);
|
|
}
|
|
else {
|
|
return new FunctionExpression('round', [this, valueToDefaultExpr$1(decimalPlaces)], 'round');
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that returns the collection ID from a path.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the collection ID from a path.
|
|
* field("__path__").collectionId();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the collectionId operation.
|
|
*/
|
|
collectionId() {
|
|
return new FunctionExpression('collection_id', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that calculates the length of a string, array, map, vector, or bytes.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the length of the 'name' field.
|
|
* field("name").length();
|
|
*
|
|
* // Get the number of items in the 'cart' array.
|
|
* field("cart").length();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the length of the string, array, map, vector, or bytes.
|
|
*/
|
|
length() {
|
|
return new FunctionExpression('length', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that computes the natural logarithm of a numeric value.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Compute the natural logarithm of the 'value' field.
|
|
* field("value").ln();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the natural logarithm of the numeric value.
|
|
*/
|
|
ln() {
|
|
return new FunctionExpression('ln', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that computes the square root of a numeric value.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Compute the square root of the 'value' field.
|
|
* field("value").sqrt();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the square root of the numeric value.
|
|
*/
|
|
sqrt() {
|
|
return new FunctionExpression('sqrt', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that reverses a string.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Reverse the value of the 'myString' field.
|
|
* field("myString").stringReverse();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the reversed string.
|
|
*/
|
|
stringReverse() {
|
|
return new FunctionExpression('string_reverse', [this]);
|
|
}
|
|
ifAbsent(elseValueOrExpression) {
|
|
return new FunctionExpression('if_absent', [this, valueToDefaultExpr$1(elseValueOrExpression)], 'ifAbsent');
|
|
}
|
|
join(delimeterValueOrExpression) {
|
|
return new FunctionExpression('join', [this, valueToDefaultExpr$1(delimeterValueOrExpression)], 'join');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that computes the base-10 logarithm of a numeric value.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Compute the base-10 logarithm of the 'value' field.
|
|
* field("value").log10();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the base-10 logarithm of the numeric value.
|
|
*/
|
|
log10() {
|
|
return new FunctionExpression('log10', [this]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that computes the sum of the elements in an array.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Compute the sum of the elements in the 'scores' field.
|
|
* field("scores").arraySum();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the sum of the elements in the array.
|
|
*/
|
|
arraySum() {
|
|
return new FunctionExpression('sum', [this]);
|
|
}
|
|
split(delimiter) {
|
|
return new FunctionExpression('split', [
|
|
this,
|
|
valueToDefaultExpr$1(delimiter)
|
|
]);
|
|
}
|
|
timestampTruncate(granularity, timezone) {
|
|
const internalGranularity = common692d301d_node.isString(granularity)
|
|
? granularity.toLowerCase()
|
|
: granularity;
|
|
const args = [this, valueToDefaultExpr$1(internalGranularity)];
|
|
if (timezone) {
|
|
args.push(valueToDefaultExpr$1(timezone));
|
|
}
|
|
return new FunctionExpression('timestamp_trunc', args);
|
|
}
|
|
// TODO(new-expression): Add new expression method definitions above this line
|
|
/**
|
|
* @beta
|
|
* Creates an {@link @firebase/firestore/pipelines#Ordering} that sorts documents in ascending order based on this expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Sort documents by the 'name' field in ascending order
|
|
* pipeline().collection("users")
|
|
* .sort(field("name").ascending());
|
|
* ```
|
|
*
|
|
* @returns A new `Ordering` for ascending sorting.
|
|
*/
|
|
ascending() {
|
|
return ascending(this);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an {@link @firebase/firestore/pipelines#Ordering} that sorts documents in descending order based on this expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Sort documents by the 'createdAt' field in descending order
|
|
* firestore.pipeline().collection("users")
|
|
* .sort(field("createdAt").descending());
|
|
* ```
|
|
*
|
|
* @returns A new `Ordering` for descending sorting.
|
|
*/
|
|
descending() {
|
|
return descending(this);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Assigns an alias to this expression.
|
|
*
|
|
* Aliases are useful for renaming fields in the output of a stage or for giving meaningful
|
|
* names to calculated values.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Calculate the total price and assign it the alias "totalPrice" and add it to the output.
|
|
* firestore.pipeline().collection("items")
|
|
* .addFields(field("price").multiply(field("quantity")).as("totalPrice"));
|
|
* ```
|
|
*
|
|
* @param name - The alias to assign to this expression.
|
|
* @returns A new {@link @firebase/firestore/pipelines#AliasedExpression} that wraps this
|
|
* expression and associates it with the provided alias.
|
|
*/
|
|
as(name) {
|
|
return new AliasedExpression(this, name, 'as');
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* A class that represents an aggregate function.
|
|
*/
|
|
class AggregateFunction {
|
|
constructor(name, params) {
|
|
this.name = name;
|
|
this.params = params;
|
|
this.exprType = 'AggregateFunction';
|
|
this._protoValueType = 'ProtoValue';
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
static _create(name, params, methodName) {
|
|
const af = new AggregateFunction(name, params);
|
|
af._methodName = methodName;
|
|
return af;
|
|
}
|
|
/**
|
|
* @beta
|
|
* Assigns an alias to this AggregateFunction. The alias specifies the name that
|
|
* the aggregated value will have in the output document.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Calculate the average price of all items and assign it the alias "averagePrice".
|
|
* firestore.pipeline().collection("items")
|
|
* .aggregate(field("price").average().as("averagePrice"));
|
|
* ```
|
|
*
|
|
* @param name - The alias to assign to this AggregateFunction.
|
|
* @returns A new {@link @firebase/firestore/pipelines#AliasedAggregate} that wraps this
|
|
* AggregateFunction and associates it with the provided alias.
|
|
*/
|
|
as(name) {
|
|
return new AliasedAggregate(this, name, 'as');
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
functionValue: {
|
|
name: this.name,
|
|
args: this.params.map(p => p._toProto(serializer))
|
|
}
|
|
};
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) {
|
|
context = this._methodName
|
|
? context.contextWith({ methodName: this._methodName })
|
|
: context;
|
|
this.params.forEach(expr => {
|
|
return expr._readUserData(context);
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* An AggregateFunction with alias.
|
|
*/
|
|
class AliasedAggregate {
|
|
constructor(aggregate, alias, _methodName) {
|
|
this.aggregate = aggregate;
|
|
this.alias = alias;
|
|
this._methodName = _methodName;
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) {
|
|
this.aggregate._readUserData(context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class AliasedExpression {
|
|
constructor(expr, alias, _methodName) {
|
|
this.expr = expr;
|
|
this.alias = alias;
|
|
this._methodName = _methodName;
|
|
this.exprType = 'AliasedExpression';
|
|
this.selectable = true;
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) {
|
|
this.expr._readUserData(context);
|
|
}
|
|
}
|
|
/**
|
|
* @internal
|
|
*/
|
|
class ListOfExprs extends Expression {
|
|
constructor(exprs, _methodName) {
|
|
super();
|
|
this.exprs = exprs;
|
|
this._methodName = _methodName;
|
|
this.expressionType = 'ListOfExpressions';
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
arrayValue: {
|
|
values: this.exprs.map(p => p._toProto(serializer))
|
|
}
|
|
};
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) {
|
|
this.exprs.forEach((expr) => expr._readUserData(context));
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Represents a reference to a field in a Firestore document, or outputs of a {@link @firebase/firestore/pipelines#Pipeline} stage.
|
|
*
|
|
* <p>Field references are used to access document field values in expressions and to specify fields
|
|
* for sorting, filtering, and projecting data in Firestore pipelines.
|
|
*
|
|
* <p>You can create a `Field` instance using the static {@link @firebase/firestore/pipelines#field} method:
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Create a Field instance for the 'name' field
|
|
* const nameField = field("name");
|
|
*
|
|
* // Create a Field instance for a nested field 'address.city'
|
|
* const cityField = field("address.city");
|
|
* ```
|
|
*/
|
|
class Field extends Expression {
|
|
/**
|
|
* @internal
|
|
* @private
|
|
* @hideconstructor
|
|
* @param fieldPath
|
|
*/
|
|
constructor(fieldPath, _methodName) {
|
|
super();
|
|
this.fieldPath = fieldPath;
|
|
this._methodName = _methodName;
|
|
this.expressionType = 'Field';
|
|
this.selectable = true;
|
|
}
|
|
get fieldName() {
|
|
return this.fieldPath.canonicalString();
|
|
}
|
|
get alias() {
|
|
return this.fieldName;
|
|
}
|
|
get expr() {
|
|
return this;
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
fieldReferenceValue: this.fieldPath.canonicalString()
|
|
};
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) { }
|
|
}
|
|
function field(nameOrPath) {
|
|
return _field(nameOrPath, 'field');
|
|
}
|
|
function _field(nameOrPath, methodName) {
|
|
if (typeof nameOrPath === 'string') {
|
|
if (common692d301d_node.DOCUMENT_KEY_NAME === nameOrPath) {
|
|
return new Field(common692d301d_node.documentId()._internalPath, methodName);
|
|
}
|
|
return new Field(common692d301d_node.fieldPathFromArgument('field', nameOrPath), methodName);
|
|
}
|
|
else {
|
|
return new Field(nameOrPath._internalPath, methodName);
|
|
}
|
|
}
|
|
/**
|
|
* @internal
|
|
*
|
|
* Represents a constant value that can be used in a Firestore pipeline expression.
|
|
*
|
|
* You can create a `Constant` instance using the static {@link @firebase/firestore/pipelines#field} method:
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Create a Constant instance for the number 10
|
|
* const ten = constant(10);
|
|
*
|
|
* // Create a Constant instance for the string "hello"
|
|
* const hello = constant("hello");
|
|
* ```
|
|
*/
|
|
class Constant extends Expression {
|
|
/**
|
|
* @private
|
|
* @internal
|
|
* @hideconstructor
|
|
* @param value - The value of the constant.
|
|
*/
|
|
constructor(value, _methodName) {
|
|
super();
|
|
this.value = value;
|
|
this._methodName = _methodName;
|
|
this.expressionType = 'Constant';
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
static _fromProto(value) {
|
|
const result = new Constant(value, undefined);
|
|
result._protoValue = value;
|
|
return result;
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_toProto(_) {
|
|
common692d301d_node.hardAssert(this._protoValue !== undefined, 0x00ed);
|
|
return this._protoValue;
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) {
|
|
context = this._methodName
|
|
? context.contextWith({ methodName: this._methodName })
|
|
: context;
|
|
if (isFirestoreValue(this._protoValue)) {
|
|
return;
|
|
}
|
|
else {
|
|
this._protoValue = common692d301d_node.parseData(this.value, context);
|
|
}
|
|
}
|
|
}
|
|
function constant(value) {
|
|
return _constant(value, 'constant');
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
* @param value
|
|
* @param methodName
|
|
*/
|
|
function _constant(value, methodName) {
|
|
const c = new Constant(value, methodName);
|
|
if (typeof value === 'boolean') {
|
|
return new BooleanConstant(c);
|
|
}
|
|
else {
|
|
return c;
|
|
}
|
|
}
|
|
/**
|
|
* Internal only
|
|
* @internal
|
|
* @private
|
|
*/
|
|
class MapValue extends Expression {
|
|
constructor(plainObject, _methodName) {
|
|
super();
|
|
this.plainObject = plainObject;
|
|
this._methodName = _methodName;
|
|
this.expressionType = 'Constant';
|
|
}
|
|
_readUserData(context) {
|
|
context = this._methodName
|
|
? context.contextWith({ methodName: this._methodName })
|
|
: context;
|
|
this.plainObject.forEach(expr => {
|
|
expr._readUserData(context);
|
|
});
|
|
}
|
|
_toProto(serializer) {
|
|
return common692d301d_node.toMapValue(serializer, this.plainObject);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* This class defines the base class for Firestore {@link @firebase/firestore/pipelines#Pipeline} functions, which can be evaluated within pipeline
|
|
* execution.
|
|
*
|
|
* Typically, you would not use this class or its children directly. Use either the functions like {@link @firebase/firestore/pipelines#and}, {@link @firebase/firestore/pipelines#(equal:1)},
|
|
* or the methods on {@link @firebase/firestore/pipelines#Expression} ({@link @firebase/firestore/pipelines#Expression.(equal:1)}, {@link @firebase/firestore/pipelines#Expression.(lessThan:1)}, etc.) to construct new Function instances.
|
|
*/
|
|
class FunctionExpression extends Expression {
|
|
constructor(name, params, _methodName) {
|
|
super();
|
|
this.name = name;
|
|
this.params = params;
|
|
this._methodName = _methodName;
|
|
this.expressionType = 'Function';
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
functionValue: {
|
|
name: this.name,
|
|
args: this.params.map(p => p._toProto(serializer))
|
|
}
|
|
};
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) {
|
|
context = this._methodName
|
|
? context.contextWith({ methodName: this._methodName })
|
|
: context;
|
|
this.params.forEach(expr => {
|
|
return expr._readUserData(context);
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* An interface that represents a filter condition.
|
|
*/
|
|
class BooleanExpression extends Expression {
|
|
get _methodName() {
|
|
return this._expr._methodName;
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that finds the count of input documents satisfying
|
|
* this boolean expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Find the count of documents with a score greater than 90
|
|
* field("score").greaterThan(90).countIf().as("highestScore");
|
|
* ```
|
|
*
|
|
* @returns A new `AggregateFunction` representing the 'countIf' aggregation.
|
|
*/
|
|
countIf() {
|
|
return AggregateFunction._create('count_if', [this], 'countIf');
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an expression that negates this boolean expression.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Find documents where the 'tags' field does not contain 'completed'
|
|
* field("tags").arrayContains("completed").not();
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the negated filter condition.
|
|
*/
|
|
not() {
|
|
return new FunctionExpression('not', [this], 'not').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates a conditional expression that evaluates to the 'then' expression
|
|
* if `this` expression evaluates to `true`,
|
|
* or evaluates to the 'else' expression if `this` expressions evaluates `false`.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // If 'age' is greater than 18, return "Adult"; otherwise, return "Minor".
|
|
* field("age").greaterThanOrEqual(18).conditional(constant("Adult"), constant("Minor"));
|
|
* ```
|
|
*
|
|
* @param thenExpr - The expression to evaluate if the condition is true.
|
|
* @param elseExpr - The expression to evaluate if the condition is false.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the conditional expression.
|
|
*/
|
|
conditional(thenExpr, elseExpr) {
|
|
return new FunctionExpression('conditional', [this, thenExpr, elseExpr], 'conditional');
|
|
}
|
|
ifError(catchValue) {
|
|
const normalizedCatchValue = valueToDefaultExpr$1(catchValue);
|
|
const expr = new FunctionExpression('if_error', [this, normalizedCatchValue], 'ifError');
|
|
return normalizedCatchValue instanceof BooleanExpression
|
|
? expr.asBoolean()
|
|
: expr;
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_toProto(serializer) {
|
|
return this._expr._toProto(serializer);
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) {
|
|
this._expr._readUserData(context);
|
|
}
|
|
}
|
|
class BooleanFunctionExpression extends BooleanExpression {
|
|
constructor(_expr) {
|
|
super();
|
|
this._expr = _expr;
|
|
this.expressionType = 'Function';
|
|
}
|
|
}
|
|
class BooleanConstant extends BooleanExpression {
|
|
constructor(_expr) {
|
|
super();
|
|
this._expr = _expr;
|
|
this.expressionType = 'Constant';
|
|
}
|
|
}
|
|
class BooleanField extends BooleanExpression {
|
|
constructor(_expr) {
|
|
super();
|
|
this._expr = _expr;
|
|
this.expressionType = 'Field';
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that counts the number of stage inputs where the provided
|
|
* boolean expression evaluates to true.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Count the number of documents where 'is_active' field equals true
|
|
* countIf(field("is_active").equal(true)).as("numActiveDocuments");
|
|
* ```
|
|
*
|
|
* @param booleanExpr - The boolean expression to evaluate on each input.
|
|
* @returns A new `AggregateFunction` representing the 'countIf' aggregation.
|
|
*/
|
|
function countIf(booleanExpr) {
|
|
return booleanExpr.countIf();
|
|
}
|
|
function arrayGet(array, offset) {
|
|
return fieldOrExpression$1(array).arrayGet(valueToDefaultExpr$1(offset));
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that checks if a given expression produces an error.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Check if the result of a calculation is an error
|
|
* isError(field("title").arrayContains(1));
|
|
* ```
|
|
*
|
|
* @param value - The expression to check.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the 'isError' check.
|
|
*/
|
|
function isError(value) {
|
|
return value.isError().asBoolean();
|
|
}
|
|
function ifError(tryExpr, catchValue) {
|
|
if (tryExpr instanceof BooleanExpression &&
|
|
catchValue instanceof BooleanExpression) {
|
|
return tryExpr.ifError(catchValue).asBoolean();
|
|
}
|
|
else {
|
|
return tryExpr.ifError(valueToDefaultExpr$1(catchValue));
|
|
}
|
|
}
|
|
function isAbsent(value) {
|
|
return fieldOrExpression$1(value).isAbsent();
|
|
}
|
|
function mapRemove(mapExpr, stringExpr) {
|
|
return fieldOrExpression$1(mapExpr).mapRemove(valueToDefaultExpr$1(stringExpr));
|
|
}
|
|
function mapMerge(firstMap, secondMap, ...otherMaps) {
|
|
const secondMapExpr = valueToDefaultExpr$1(secondMap);
|
|
const otherMapExprs = otherMaps.map(valueToDefaultExpr$1);
|
|
return fieldOrExpression$1(firstMap).mapMerge(secondMapExpr, ...otherMapExprs);
|
|
}
|
|
function documentId(documentPath) {
|
|
// @ts-ignore
|
|
const documentPathExpr = valueToDefaultExpr$1(documentPath);
|
|
return documentPathExpr.documentId();
|
|
}
|
|
function substring(field, position, length) {
|
|
const fieldExpr = fieldOrExpression$1(field);
|
|
const positionExpr = valueToDefaultExpr$1(position);
|
|
const lengthExpr = length === undefined ? undefined : valueToDefaultExpr$1(length);
|
|
return fieldExpr.substring(positionExpr, lengthExpr);
|
|
}
|
|
function add(first, second) {
|
|
return fieldOrExpression$1(first).add(valueToDefaultExpr$1(second));
|
|
}
|
|
function subtract(left, right) {
|
|
const normalizedLeft = typeof left === 'string' ? field(left) : left;
|
|
const normalizedRight = valueToDefaultExpr$1(right);
|
|
return normalizedLeft.subtract(normalizedRight);
|
|
}
|
|
function multiply(first, second) {
|
|
return fieldOrExpression$1(first).multiply(valueToDefaultExpr$1(second));
|
|
}
|
|
function divide(left, right) {
|
|
const normalizedLeft = typeof left === 'string' ? field(left) : left;
|
|
const normalizedRight = valueToDefaultExpr$1(right);
|
|
return normalizedLeft.divide(normalizedRight);
|
|
}
|
|
function mod(left, right) {
|
|
const normalizedLeft = typeof left === 'string' ? field(left) : left;
|
|
const normalizedRight = valueToDefaultExpr$1(right);
|
|
return normalizedLeft.mod(normalizedRight);
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that creates a Firestore map value from an input object.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Create a map from the input object and reference the 'baz' field value from the input document.
|
|
* map({foo: 'bar', baz: Field.of('baz')}).as('data');
|
|
* ```
|
|
*
|
|
* @param elements - The input map to evaluate in the expression.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the map function.
|
|
*/
|
|
function map(elements) {
|
|
return _map(elements);
|
|
}
|
|
function _map(elements, methodName) {
|
|
const result = [];
|
|
for (const key in elements) {
|
|
if (Object.prototype.hasOwnProperty.call(elements, key)) {
|
|
const value = elements[key];
|
|
result.push(constant(key));
|
|
result.push(valueToDefaultExpr$1(value));
|
|
}
|
|
}
|
|
return new FunctionExpression('map', result, 'map');
|
|
}
|
|
/**
|
|
* Internal use only
|
|
* Converts a plainObject to a mapValue in the proto representation,
|
|
* rather than a functionValue+map that is the result of the map(...) function.
|
|
* This behaves different from constant(plainObject) because it
|
|
* traverses the input object, converts values in the object to expressions,
|
|
* and calls _readUserData on each of these expressions.
|
|
* @private
|
|
* @internal
|
|
* @param plainObject
|
|
*/
|
|
function _mapValue(plainObject) {
|
|
const result = new Map();
|
|
for (const key in plainObject) {
|
|
if (Object.prototype.hasOwnProperty.call(plainObject, key)) {
|
|
const value = plainObject[key];
|
|
result.set(key, valueToDefaultExpr$1(value));
|
|
}
|
|
}
|
|
return new MapValue(result, undefined);
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that creates a Firestore array value from an input array.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Create an array value from the input array and reference the 'baz' field value from the input document.
|
|
* array(['bar', Field.of('baz')]).as('foo');
|
|
* ```
|
|
*
|
|
* @param elements - The input array to evaluate in the expression.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the array function.
|
|
*/
|
|
function array(elements) {
|
|
return _array(elements, 'array');
|
|
}
|
|
function _array(elements, methodName) {
|
|
return new FunctionExpression('array', elements.map(element => valueToDefaultExpr$1(element)), methodName);
|
|
}
|
|
function equal(left, right) {
|
|
const leftExpr = left instanceof Expression ? left : field(left);
|
|
const rightExpr = valueToDefaultExpr$1(right);
|
|
return leftExpr.equal(rightExpr);
|
|
}
|
|
function notEqual(left, right) {
|
|
const leftExpr = left instanceof Expression ? left : field(left);
|
|
const rightExpr = valueToDefaultExpr$1(right);
|
|
return leftExpr.notEqual(rightExpr);
|
|
}
|
|
function lessThan(left, right) {
|
|
const leftExpr = left instanceof Expression ? left : field(left);
|
|
const rightExpr = valueToDefaultExpr$1(right);
|
|
return leftExpr.lessThan(rightExpr);
|
|
}
|
|
function lessThanOrEqual(left, right) {
|
|
const leftExpr = left instanceof Expression ? left : field(left);
|
|
const rightExpr = valueToDefaultExpr$1(right);
|
|
return leftExpr.lessThanOrEqual(rightExpr);
|
|
}
|
|
function greaterThan(left, right) {
|
|
const leftExpr = left instanceof Expression ? left : field(left);
|
|
const rightExpr = valueToDefaultExpr$1(right);
|
|
return leftExpr.greaterThan(rightExpr);
|
|
}
|
|
function greaterThanOrEqual(left, right) {
|
|
const leftExpr = left instanceof Expression ? left : field(left);
|
|
const rightExpr = valueToDefaultExpr$1(right);
|
|
return leftExpr.greaterThanOrEqual(rightExpr);
|
|
}
|
|
function arrayConcat(firstArray, secondArray, ...otherArrays) {
|
|
const exprValues = otherArrays.map(element => valueToDefaultExpr$1(element));
|
|
return fieldOrExpression$1(firstArray).arrayConcat(fieldOrExpression$1(secondArray), ...exprValues);
|
|
}
|
|
function arrayContains(array, element) {
|
|
const arrayExpr = fieldOrExpression$1(array);
|
|
const elementExpr = valueToDefaultExpr$1(element);
|
|
return arrayExpr.arrayContains(elementExpr);
|
|
}
|
|
function arrayContainsAny(array, values) {
|
|
// @ts-ignore implementation accepts both types
|
|
return fieldOrExpression$1(array).arrayContainsAny(values);
|
|
}
|
|
function arrayContainsAll(array, values) {
|
|
// @ts-ignore implementation accepts both types
|
|
return fieldOrExpression$1(array).arrayContainsAll(values);
|
|
}
|
|
function arrayLength(array) {
|
|
return fieldOrExpression$1(array).arrayLength();
|
|
}
|
|
function equalAny(element, values) {
|
|
// @ts-ignore implementation accepts both types
|
|
return fieldOrExpression$1(element).equalAny(values);
|
|
}
|
|
function notEqualAny(element, values) {
|
|
// @ts-ignore implementation accepts both types
|
|
return fieldOrExpression$1(element).notEqualAny(values);
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that performs a logical 'XOR' (exclusive OR) operation on multiple BooleanExpressions.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Check if only one of the conditions is true: 'age' greater than 18, 'city' is "London",
|
|
* // or 'status' is "active".
|
|
* const condition = xor(
|
|
* greaterThan("age", 18),
|
|
* equal("city", "London"),
|
|
* equal("status", "active"));
|
|
* ```
|
|
*
|
|
* @param first - The first condition.
|
|
* @param second - The second condition.
|
|
* @param additionalConditions - Additional conditions to 'XOR' together.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the logical 'XOR' operation.
|
|
*/
|
|
function xor(first, second, ...additionalConditions) {
|
|
return new FunctionExpression('xor', [first, second, ...additionalConditions], 'xor').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates a conditional expression that evaluates to a 'then' expression if a condition is true
|
|
* and an 'else' expression if the condition is false.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // If 'age' is greater than 18, return "Adult"; otherwise, return "Minor".
|
|
* conditional(
|
|
* greaterThan("age", 18), constant("Adult"), constant("Minor"));
|
|
* ```
|
|
*
|
|
* @param condition - The condition to evaluate.
|
|
* @param thenExpr - The expression to evaluate if the condition is true.
|
|
* @param elseExpr - The expression to evaluate if the condition is false.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the conditional expression.
|
|
*/
|
|
function conditional(condition, thenExpr, elseExpr) {
|
|
return new FunctionExpression('conditional', [condition, thenExpr, elseExpr], 'conditional');
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that negates a filter condition.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Find documents where the 'completed' field is NOT true
|
|
* not(equal("completed", true));
|
|
* ```
|
|
*
|
|
* @param booleanExpr - The filter condition to negate.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the negated filter condition.
|
|
*/
|
|
function not(booleanExpr) {
|
|
return booleanExpr.not();
|
|
}
|
|
function logicalMaximum(first, second, ...others) {
|
|
return fieldOrExpression$1(first).logicalMaximum(valueToDefaultExpr$1(second), ...others.map(value => valueToDefaultExpr$1(value)));
|
|
}
|
|
function logicalMinimum(first, second, ...others) {
|
|
return fieldOrExpression$1(first).logicalMinimum(valueToDefaultExpr$1(second), ...others.map(value => valueToDefaultExpr$1(value)));
|
|
}
|
|
function exists(valueOrField) {
|
|
return fieldOrExpression$1(valueOrField).exists();
|
|
}
|
|
function reverse(expr) {
|
|
return fieldOrExpression$1(expr).reverse();
|
|
}
|
|
function byteLength(expr) {
|
|
const normalizedExpr = fieldOrExpression$1(expr);
|
|
return normalizedExpr.byteLength();
|
|
}
|
|
function exp(expressionOrFieldName) {
|
|
return fieldOrExpression$1(expressionOrFieldName).exp();
|
|
}
|
|
function ceil(expr) {
|
|
return fieldOrExpression$1(expr).ceil();
|
|
}
|
|
function floor(expr) {
|
|
return fieldOrExpression$1(expr).floor();
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates an aggregation that counts the number of distinct values of a field.
|
|
*
|
|
* @param expr - The expression or field to count distinct values of.
|
|
* @returns A new `AggregateFunction` representing the 'count_distinct' aggregation.
|
|
*/
|
|
function countDistinct(expr) {
|
|
return fieldOrExpression$1(expr).countDistinct();
|
|
}
|
|
function charLength(value) {
|
|
const valueExpr = fieldOrExpression$1(value);
|
|
return valueExpr.charLength();
|
|
}
|
|
function like(left, pattern) {
|
|
const leftExpr = fieldOrExpression$1(left);
|
|
const patternExpr = valueToDefaultExpr$1(pattern);
|
|
return leftExpr.like(patternExpr);
|
|
}
|
|
function regexContains(left, pattern) {
|
|
const leftExpr = fieldOrExpression$1(left);
|
|
const patternExpr = valueToDefaultExpr$1(pattern);
|
|
return leftExpr.regexContains(patternExpr);
|
|
}
|
|
function regexFind(left, pattern) {
|
|
const leftExpr = fieldOrExpression$1(left);
|
|
const patternExpr = valueToDefaultExpr$1(pattern);
|
|
return leftExpr.regexFind(patternExpr);
|
|
}
|
|
function regexFindAll(left, pattern) {
|
|
const leftExpr = fieldOrExpression$1(left);
|
|
const patternExpr = valueToDefaultExpr$1(pattern);
|
|
return leftExpr.regexFindAll(patternExpr);
|
|
}
|
|
function regexMatch(left, pattern) {
|
|
const leftExpr = fieldOrExpression$1(left);
|
|
const patternExpr = valueToDefaultExpr$1(pattern);
|
|
return leftExpr.regexMatch(patternExpr);
|
|
}
|
|
function stringContains(left, substring) {
|
|
const leftExpr = fieldOrExpression$1(left);
|
|
const substringExpr = valueToDefaultExpr$1(substring);
|
|
return leftExpr.stringContains(substringExpr);
|
|
}
|
|
function startsWith(expr, prefix) {
|
|
return fieldOrExpression$1(expr).startsWith(valueToDefaultExpr$1(prefix));
|
|
}
|
|
function endsWith(expr, suffix) {
|
|
return fieldOrExpression$1(expr).endsWith(valueToDefaultExpr$1(suffix));
|
|
}
|
|
function toLower(expr) {
|
|
return fieldOrExpression$1(expr).toLower();
|
|
}
|
|
function toUpper(expr) {
|
|
return fieldOrExpression$1(expr).toUpper();
|
|
}
|
|
function trim(expr, valueToTrim) {
|
|
return fieldOrExpression$1(expr).trim(valueToTrim);
|
|
}
|
|
function ltrim(expr, valueToTrim) {
|
|
return fieldOrExpression$1(expr).ltrim(valueToTrim);
|
|
}
|
|
function rtrim(expr, valueToTrim) {
|
|
return fieldOrExpression$1(expr).rtrim(valueToTrim);
|
|
}
|
|
function type(fieldNameOrExpression) {
|
|
return fieldOrExpression$1(fieldNameOrExpression).type();
|
|
}
|
|
function isType(fieldNameOrExpression, type) {
|
|
return fieldOrExpression$1(fieldNameOrExpression).isType(type);
|
|
}
|
|
function stringConcat(first, second, ...elements) {
|
|
return fieldOrExpression$1(first).stringConcat(valueToDefaultExpr$1(second), ...elements.map(valueToDefaultExpr$1));
|
|
}
|
|
function stringIndexOf(expr, search) {
|
|
return fieldOrExpression$1(expr).stringIndexOf(search);
|
|
}
|
|
function stringRepeat(expr, repetitions) {
|
|
return fieldOrExpression$1(expr).stringRepeat(repetitions);
|
|
}
|
|
function stringReplaceAll(expr, find, replacement) {
|
|
return fieldOrExpression$1(expr).stringReplaceAll(find, replacement);
|
|
}
|
|
function stringReplaceOne(expr, find, replacement) {
|
|
return fieldOrExpression$1(expr).stringReplaceOne(find, replacement);
|
|
}
|
|
function mapGet(fieldOrExpr, subField) {
|
|
return fieldOrExpression$1(fieldOrExpr).mapGet(subField);
|
|
}
|
|
function mapSet(fieldOrExpr, key, value, ...moreKeyValues) {
|
|
return fieldOrExpression$1(fieldOrExpr).mapSet(key, value, ...moreKeyValues);
|
|
}
|
|
function mapKeys(fieldOrExpr) {
|
|
return fieldOrExpression$1(fieldOrExpr).mapKeys();
|
|
}
|
|
function mapValues(fieldOrExpr) {
|
|
return fieldOrExpression$1(fieldOrExpr).mapValues();
|
|
}
|
|
function mapEntries(fieldOrExpr) {
|
|
return fieldOrExpression$1(fieldOrExpr).mapEntries();
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an aggregation that counts the total number of stage inputs.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Count the total number of input documents
|
|
* countAll().as("totalDocument");
|
|
* ```
|
|
*
|
|
* @returns A new {@link @firebase/firestore/pipelines#AggregateFunction} representing the 'countAll' aggregation.
|
|
*/
|
|
function countAll() {
|
|
return AggregateFunction._create('count', [], 'count');
|
|
}
|
|
function count(value) {
|
|
return fieldOrExpression$1(value).count();
|
|
}
|
|
function sum(value) {
|
|
return fieldOrExpression$1(value).sum();
|
|
}
|
|
function average(value) {
|
|
return fieldOrExpression$1(value).average();
|
|
}
|
|
function minimum(value) {
|
|
return fieldOrExpression$1(value).minimum();
|
|
}
|
|
function maximum(value) {
|
|
return fieldOrExpression$1(value).maximum();
|
|
}
|
|
function first(value) {
|
|
return fieldOrExpression$1(value).first();
|
|
}
|
|
function last(value) {
|
|
return fieldOrExpression$1(value).last();
|
|
}
|
|
function arrayAgg(value) {
|
|
return fieldOrExpression$1(value).arrayAgg();
|
|
}
|
|
function arrayAggDistinct(value) {
|
|
return fieldOrExpression$1(value).arrayAggDistinct();
|
|
}
|
|
function cosineDistance(expr, other) {
|
|
const expr1 = fieldOrExpression$1(expr);
|
|
const expr2 = vectorToExpr$1(other);
|
|
return expr1.cosineDistance(expr2);
|
|
}
|
|
function dotProduct(expr, other) {
|
|
const expr1 = fieldOrExpression$1(expr);
|
|
const expr2 = vectorToExpr$1(other);
|
|
return expr1.dotProduct(expr2);
|
|
}
|
|
function euclideanDistance(expr, other) {
|
|
const expr1 = fieldOrExpression$1(expr);
|
|
const expr2 = vectorToExpr$1(other);
|
|
return expr1.euclideanDistance(expr2);
|
|
}
|
|
function vectorLength(expr) {
|
|
return fieldOrExpression$1(expr).vectorLength();
|
|
}
|
|
function unixMicrosToTimestamp(expr) {
|
|
return fieldOrExpression$1(expr).unixMicrosToTimestamp();
|
|
}
|
|
function timestampToUnixMicros(expr) {
|
|
return fieldOrExpression$1(expr).timestampToUnixMicros();
|
|
}
|
|
function unixMillisToTimestamp(expr) {
|
|
const normalizedExpr = fieldOrExpression$1(expr);
|
|
return normalizedExpr.unixMillisToTimestamp();
|
|
}
|
|
function timestampToUnixMillis(expr) {
|
|
const normalizedExpr = fieldOrExpression$1(expr);
|
|
return normalizedExpr.timestampToUnixMillis();
|
|
}
|
|
function unixSecondsToTimestamp(expr) {
|
|
const normalizedExpr = fieldOrExpression$1(expr);
|
|
return normalizedExpr.unixSecondsToTimestamp();
|
|
}
|
|
function timestampToUnixSeconds(expr) {
|
|
const normalizedExpr = fieldOrExpression$1(expr);
|
|
return normalizedExpr.timestampToUnixSeconds();
|
|
}
|
|
function timestampAdd(timestamp, unit, amount) {
|
|
const normalizedTimestamp = fieldOrExpression$1(timestamp);
|
|
const normalizedUnit = valueToDefaultExpr$1(unit);
|
|
const normalizedAmount = valueToDefaultExpr$1(amount);
|
|
return normalizedTimestamp.timestampAdd(normalizedUnit, normalizedAmount);
|
|
}
|
|
function timestampSubtract(timestamp, unit, amount) {
|
|
const normalizedTimestamp = fieldOrExpression$1(timestamp);
|
|
const normalizedUnit = valueToDefaultExpr$1(unit);
|
|
const normalizedAmount = valueToDefaultExpr$1(amount);
|
|
return normalizedTimestamp.timestampSubtract(normalizedUnit, normalizedAmount);
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that evaluates to the current server timestamp.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Get the current server timestamp
|
|
* currentTimestamp()
|
|
* ```
|
|
*
|
|
* @returns A new Expression representing the current server timestamp.
|
|
*/
|
|
function currentTimestamp() {
|
|
return new FunctionExpression('current_timestamp', [], 'currentTimestamp');
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that performs a logical 'AND' operation on multiple filter conditions.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Check if the 'age' field is greater than 18 AND the 'city' field is "London" AND
|
|
* // the 'status' field is "active"
|
|
* const condition = and(greaterThan("age", 18), equal("city", "London"), equal("status", "active"));
|
|
* ```
|
|
*
|
|
* @param first - The first filter condition.
|
|
* @param second - The second filter condition.
|
|
* @param more - Additional filter conditions to 'AND' together.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the logical 'AND' operation.
|
|
*/
|
|
function and(first, second, ...more) {
|
|
return new FunctionExpression('and', [first, second, ...more], 'and').asBoolean();
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that performs a logical 'OR' operation on multiple filter conditions.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Check if the 'age' field is greater than 18 OR the 'city' field is "London" OR
|
|
* // the 'status' field is "active"
|
|
* const condition = or(greaterThan("age", 18), equal("city", "London"), equal("status", "active"));
|
|
* ```
|
|
*
|
|
* @param first - The first filter condition.
|
|
* @param second - The second filter condition.
|
|
* @param more - Additional filter conditions to 'OR' together.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Expression} representing the logical 'OR' operation.
|
|
*/
|
|
function or(first, second, ...more) {
|
|
return new FunctionExpression('or', [first, second, ...more], 'xor').asBoolean();
|
|
}
|
|
function pow(base, exponent) {
|
|
return fieldOrExpression$1(base).pow(exponent);
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Creates an expression that generates a random number between 0.0 and 1.0 but not including 1.0.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Generate a random number between 0.0 and 1.0.
|
|
* rand();
|
|
* ```
|
|
*
|
|
* @returns A new `Expression` representing the rand operation.
|
|
*/
|
|
function rand() {
|
|
return new FunctionExpression('rand', [], 'rand');
|
|
}
|
|
function round(expr, decimalPlaces) {
|
|
if (decimalPlaces === undefined) {
|
|
return fieldOrExpression$1(expr).round();
|
|
}
|
|
else {
|
|
return fieldOrExpression$1(expr).round(valueToDefaultExpr$1(decimalPlaces));
|
|
}
|
|
}
|
|
function trunc(expr, decimalPlaces) {
|
|
if (decimalPlaces === undefined) {
|
|
return fieldOrExpression$1(expr).trunc();
|
|
}
|
|
else {
|
|
return fieldOrExpression$1(expr).trunc(valueToDefaultExpr$1(decimalPlaces));
|
|
}
|
|
}
|
|
function collectionId(expr) {
|
|
return fieldOrExpression$1(expr).collectionId();
|
|
}
|
|
function length(expr) {
|
|
return fieldOrExpression$1(expr).length();
|
|
}
|
|
function ln(expr) {
|
|
return fieldOrExpression$1(expr).ln();
|
|
}
|
|
function log(expr, base) {
|
|
return new FunctionExpression('log', [
|
|
fieldOrExpression$1(expr),
|
|
valueToDefaultExpr$1(base)
|
|
]);
|
|
}
|
|
function sqrt(expr) {
|
|
return fieldOrExpression$1(expr).sqrt();
|
|
}
|
|
function stringReverse(expr) {
|
|
return fieldOrExpression$1(expr).stringReverse();
|
|
}
|
|
function concat(fieldNameOrExpression, second, ...others) {
|
|
return new FunctionExpression('concat', [
|
|
fieldOrExpression$1(fieldNameOrExpression),
|
|
valueToDefaultExpr$1(second),
|
|
...others.map(valueToDefaultExpr$1)
|
|
]);
|
|
}
|
|
function abs(expr) {
|
|
return fieldOrExpression$1(expr).abs();
|
|
}
|
|
function ifAbsent(fieldNameOrExpression, elseValue) {
|
|
return fieldOrExpression$1(fieldNameOrExpression).ifAbsent(valueToDefaultExpr$1(elseValue));
|
|
}
|
|
function join(fieldNameOrExpression, delimiterValueOrExpression) {
|
|
return fieldOrExpression$1(fieldNameOrExpression).join(valueToDefaultExpr$1(delimiterValueOrExpression));
|
|
}
|
|
function log10(expr) {
|
|
return fieldOrExpression$1(expr).log10();
|
|
}
|
|
function arraySum(expr) {
|
|
return fieldOrExpression$1(expr).arraySum();
|
|
}
|
|
function split(fieldNameOrExpression, delimiter) {
|
|
return fieldOrExpression$1(fieldNameOrExpression).split(valueToDefaultExpr$1(delimiter));
|
|
}
|
|
function timestampTruncate(fieldNameOrExpression, granularity, timezone) {
|
|
const internalGranularity = common692d301d_node.isString(granularity)
|
|
? valueToDefaultExpr$1(granularity.toLowerCase())
|
|
: granularity;
|
|
return fieldOrExpression$1(fieldNameOrExpression).timestampTruncate(internalGranularity, timezone);
|
|
}
|
|
function ascending(field) {
|
|
return new Ordering(fieldOrExpression$1(field), 'ascending', 'ascending');
|
|
}
|
|
function descending(field) {
|
|
return new Ordering(fieldOrExpression$1(field), 'descending', 'descending');
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* Represents an ordering criterion for sorting documents in a Firestore pipeline.
|
|
*
|
|
* You create `Ordering` instances using the `ascending` and `descending` helper functions.
|
|
*/
|
|
class Ordering {
|
|
constructor(expr, direction, _methodName) {
|
|
this.expr = expr;
|
|
this.direction = direction;
|
|
this._methodName = _methodName;
|
|
this._protoValueType = 'ProtoValue';
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
mapValue: {
|
|
fields: {
|
|
direction: common692d301d_node.toStringValue(this.direction),
|
|
expression: this.expr._toProto(serializer)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_readUserData(context) {
|
|
this.expr._readUserData(context);
|
|
}
|
|
}
|
|
function isSelectable(val) {
|
|
const candidate = val;
|
|
return (candidate.selectable && common692d301d_node.isString(candidate.alias) && isExpr(candidate.expr));
|
|
}
|
|
function isOrdering(val) {
|
|
const candidate = val;
|
|
return (isExpr(candidate.expr) &&
|
|
(candidate.direction === 'ascending' ||
|
|
candidate.direction === 'descending'));
|
|
}
|
|
function isAliasedAggregate(val) {
|
|
const candidate = val;
|
|
return (common692d301d_node.isString(candidate.alias) &&
|
|
candidate.aggregate instanceof AggregateFunction);
|
|
}
|
|
function isExpr(val) {
|
|
return val instanceof Expression;
|
|
}
|
|
function isBooleanExpr(val) {
|
|
return val instanceof BooleanExpression;
|
|
}
|
|
function isField(val) {
|
|
return val instanceof Field;
|
|
}
|
|
function toField(value) {
|
|
if (common692d301d_node.isString(value)) {
|
|
const result = field(value);
|
|
return result;
|
|
}
|
|
else {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/* eslint @typescript-eslint/no-explicit-any: 0 */
|
|
function toPipelineBooleanExpr(f) {
|
|
if (f instanceof common692d301d_node.FieldFilter) {
|
|
const fieldValue = field(f.field.toString());
|
|
// Comparison filters
|
|
const value = f.value;
|
|
switch (f.op) {
|
|
case "<" /* Operator.LESS_THAN */:
|
|
return and(fieldValue.exists(), fieldValue.lessThan(Constant._fromProto(value)));
|
|
case "<=" /* Operator.LESS_THAN_OR_EQUAL */:
|
|
return and(fieldValue.exists(), fieldValue.lessThanOrEqual(Constant._fromProto(value)));
|
|
case ">" /* Operator.GREATER_THAN */:
|
|
return and(fieldValue.exists(), fieldValue.greaterThan(Constant._fromProto(value)));
|
|
case ">=" /* Operator.GREATER_THAN_OR_EQUAL */:
|
|
return and(fieldValue.exists(), fieldValue.greaterThanOrEqual(Constant._fromProto(value)));
|
|
case "==" /* Operator.EQUAL */:
|
|
return and(fieldValue.exists(), fieldValue.equal(Constant._fromProto(value)));
|
|
case "!=" /* Operator.NOT_EQUAL */:
|
|
return fieldValue.notEqual(Constant._fromProto(value));
|
|
case "array-contains" /* Operator.ARRAY_CONTAINS */:
|
|
return and(fieldValue.exists(), fieldValue.arrayContains(Constant._fromProto(value)));
|
|
case "in" /* Operator.IN */: {
|
|
const values = value?.arrayValue?.values?.map((val) => Constant._fromProto(val));
|
|
if (!values) {
|
|
return and(fieldValue.exists(), fieldValue.equalAny([]));
|
|
}
|
|
else if (values.length === 1) {
|
|
return and(fieldValue.exists(), fieldValue.equal(values[0]));
|
|
}
|
|
else {
|
|
return and(fieldValue.exists(), fieldValue.equalAny(values));
|
|
}
|
|
}
|
|
case "array-contains-any" /* Operator.ARRAY_CONTAINS_ANY */: {
|
|
const values = value?.arrayValue?.values?.map((val) => Constant._fromProto(val));
|
|
return and(fieldValue.exists(), fieldValue.arrayContainsAny(values));
|
|
}
|
|
case "not-in" /* Operator.NOT_IN */: {
|
|
const values = value?.arrayValue?.values?.map((val) => Constant._fromProto(val));
|
|
if (!values) {
|
|
return fieldValue.notEqualAny([]);
|
|
}
|
|
else if (values.length === 1) {
|
|
return fieldValue.notEqual(values[0]);
|
|
}
|
|
else {
|
|
return fieldValue.notEqualAny(values);
|
|
}
|
|
}
|
|
default:
|
|
common692d301d_node.fail(0x9047);
|
|
}
|
|
}
|
|
else if (f instanceof common692d301d_node.CompositeFilter) {
|
|
switch (f.op) {
|
|
case "and" /* CompositeOperator.AND */: {
|
|
const conditions = f.getFilters().map(f => toPipelineBooleanExpr(f));
|
|
return and(conditions[0], conditions[1], ...conditions.slice(2));
|
|
}
|
|
case "or" /* CompositeOperator.OR */: {
|
|
const conditions = f.getFilters().map(f => toPipelineBooleanExpr(f));
|
|
return or(conditions[0], conditions[1], ...conditions.slice(2));
|
|
}
|
|
default:
|
|
common692d301d_node.fail(0x89ea);
|
|
}
|
|
}
|
|
throw new Error(`Failed to convert filter to pipeline conditions: ${f}`);
|
|
}
|
|
function reverseOrderings(orderings) {
|
|
return orderings.map(o => new Ordering(o.expr, o.direction === 'ascending' ? 'descending' : 'ascending', undefined));
|
|
}
|
|
function toPipeline(query, db) {
|
|
let pipeline;
|
|
if (common692d301d_node.isCollectionGroupQuery(query)) {
|
|
pipeline = db.pipeline().collectionGroup(query.collectionGroup);
|
|
}
|
|
else if (common692d301d_node.isDocumentQuery$1(query)) {
|
|
pipeline = db.pipeline().documents([common692d301d_node.doc(db, query.path.canonicalString())]);
|
|
}
|
|
else {
|
|
pipeline = db.pipeline().collection(query.path.canonicalString());
|
|
}
|
|
// filters
|
|
for (const filter of query.filters) {
|
|
pipeline = pipeline.where(toPipelineBooleanExpr(filter));
|
|
}
|
|
// orders
|
|
const orders = common692d301d_node.queryNormalizedOrderBy(query);
|
|
const existsConditions = query.explicitOrderBy.map(order => field(order.field.canonicalString()).exists());
|
|
if (existsConditions.length > 0) {
|
|
const condition = existsConditions.length === 1
|
|
? existsConditions[0]
|
|
: and(existsConditions[0], existsConditions[1], ...existsConditions.slice(2));
|
|
pipeline = pipeline.where(condition);
|
|
}
|
|
const orderings = orders.map(order => order.dir === "asc" /* Direction.ASCENDING */
|
|
? field(order.field.canonicalString()).ascending()
|
|
: field(order.field.canonicalString()).descending());
|
|
if (orderings.length > 0) {
|
|
if (query.limitType === "L" /* LimitType.Last */) {
|
|
const actualOrderings = reverseOrderings(orderings);
|
|
pipeline = pipeline.sort(actualOrderings[0], ...actualOrderings.slice(1));
|
|
// cursors
|
|
if (query.startAt !== null) {
|
|
pipeline = pipeline.where(whereConditionsFromCursor(query.startAt, orderings, 'after'));
|
|
}
|
|
if (query.endAt !== null) {
|
|
pipeline = pipeline.where(whereConditionsFromCursor(query.endAt, orderings, 'before'));
|
|
}
|
|
pipeline = pipeline.limit(query.limit);
|
|
pipeline = pipeline.sort(orderings[0], ...orderings.slice(1));
|
|
}
|
|
else {
|
|
pipeline = pipeline.sort(orderings[0], ...orderings.slice(1));
|
|
if (query.startAt !== null) {
|
|
pipeline = pipeline.where(whereConditionsFromCursor(query.startAt, orderings, 'after'));
|
|
}
|
|
if (query.endAt !== null) {
|
|
pipeline = pipeline.where(whereConditionsFromCursor(query.endAt, orderings, 'before'));
|
|
}
|
|
if (query.limit !== null) {
|
|
pipeline = pipeline.limit(query.limit);
|
|
}
|
|
}
|
|
}
|
|
return pipeline;
|
|
}
|
|
function whereConditionsFromCursor(bound, orderings, position) {
|
|
// The filterFunc is either greater than or less than
|
|
const filterFunc = position === 'before' ? lessThan : greaterThan;
|
|
const cursors = bound.position.map(value => Constant._fromProto(value));
|
|
const size = cursors.length;
|
|
let field = orderings[size - 1].expr;
|
|
let value = cursors[size - 1];
|
|
// Add condition for last bound
|
|
let condition = filterFunc(field, value);
|
|
if (bound.inclusive) {
|
|
// When the cursor bound is inclusive, then the last bound
|
|
// can be equal to the value, otherwise it's not equal
|
|
condition = or(condition, field.equal(value));
|
|
}
|
|
// Iterate backwards over the remaining bounds, adding
|
|
// a condition for each one
|
|
for (let i = size - 2; i >= 0; i--) {
|
|
field = orderings[i].expr;
|
|
value = cursors[i];
|
|
// For each field in the orderings, the condition is either
|
|
// a) lt|gt the cursor value,
|
|
// b) or equal the cursor value and lt|gt the cursor values for other fields
|
|
condition = or(filterFunc(field, value), and(field.equal(value), condition));
|
|
}
|
|
return condition;
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Stage {
|
|
constructor(options) {
|
|
/**
|
|
* Store optionsProto parsed by _readUserData.
|
|
* @private
|
|
* @internal
|
|
* @protected
|
|
*/
|
|
this.optionsProto = undefined;
|
|
({ rawOptions: this.rawOptions, ...this.knownOptions } = options);
|
|
}
|
|
_readUserData(context) {
|
|
this.optionsProto = this._optionsUtil.getOptionsProto(context, this.knownOptions, this.rawOptions);
|
|
}
|
|
_toProto(_) {
|
|
return {
|
|
name: this._name,
|
|
options: this.optionsProto
|
|
};
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class AddFields extends Stage {
|
|
get _name() {
|
|
return 'add_fields';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(fields, options) {
|
|
super(options);
|
|
this.fields = fields;
|
|
}
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [common692d301d_node.toMapValue(serializer, this.fields)]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.fields, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class RemoveFields extends Stage {
|
|
get _name() {
|
|
return 'remove_fields';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(fields, options) {
|
|
super(options);
|
|
this.fields = fields;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: this.fields.map(f => f._toProto(serializer))
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.fields, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Aggregate extends Stage {
|
|
get _name() {
|
|
return 'aggregate';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(groups, accumulators, options) {
|
|
super(options);
|
|
this.groups = groups;
|
|
this.accumulators = accumulators;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [
|
|
common692d301d_node.toMapValue(serializer, this.accumulators),
|
|
common692d301d_node.toMapValue(serializer, this.groups)
|
|
]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.groups, context);
|
|
readUserDataHelper(this.accumulators, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Distinct extends Stage {
|
|
get _name() {
|
|
return 'distinct';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(groups, options) {
|
|
super(options);
|
|
this.groups = groups;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [common692d301d_node.toMapValue(serializer, this.groups)]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.groups, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class CollectionSource extends Stage {
|
|
get _name() {
|
|
return 'collection';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({
|
|
forceIndex: {
|
|
serverName: 'force_index'
|
|
}
|
|
});
|
|
}
|
|
constructor(collection, options) {
|
|
super(options);
|
|
// prepend slash to collection string
|
|
this.formattedCollectionPath = collection.startsWith('/')
|
|
? collection
|
|
: '/' + collection;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [{ referenceValue: this.formattedCollectionPath }]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class CollectionGroupSource extends Stage {
|
|
get _name() {
|
|
return 'collection_group';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({
|
|
forceIndex: {
|
|
serverName: 'force_index'
|
|
}
|
|
});
|
|
}
|
|
constructor(collectionId, options) {
|
|
super(options);
|
|
this.collectionId = collectionId;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [{ referenceValue: '' }, { stringValue: this.collectionId }]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class DatabaseSource extends Stage {
|
|
get _name() {
|
|
return 'database';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer)
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class DocumentsSource extends Stage {
|
|
get _name() {
|
|
return 'documents';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(docPaths, options) {
|
|
super(options);
|
|
this.formattedPaths = docPaths.map(path => path.startsWith('/') ? path : '/' + path);
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: this.formattedPaths.map(p => {
|
|
return { referenceValue: p };
|
|
})
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Where extends Stage {
|
|
get _name() {
|
|
return 'where';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(condition, options) {
|
|
super(options);
|
|
this.condition = condition;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [this.condition._toProto(serializer)]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.condition, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class FindNearest extends Stage {
|
|
get _name() {
|
|
return 'find_nearest';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({
|
|
limit: {
|
|
serverName: 'limit'
|
|
},
|
|
distanceField: {
|
|
serverName: 'distance_field'
|
|
}
|
|
});
|
|
}
|
|
constructor(vectorValue, field, distanceMeasure, options) {
|
|
super(options);
|
|
this.vectorValue = vectorValue;
|
|
this.field = field;
|
|
this.distanceMeasure = distanceMeasure;
|
|
}
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [
|
|
this.field._toProto(serializer),
|
|
this.vectorValue._toProto(serializer),
|
|
common692d301d_node.toStringValue(this.distanceMeasure)
|
|
]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.vectorValue, context);
|
|
readUserDataHelper(this.field, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Limit extends Stage {
|
|
get _name() {
|
|
return 'limit';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(limit, options) {
|
|
common692d301d_node.hardAssert(!isNaN(limit) && limit !== Infinity && limit !== -Infinity, 0x882c);
|
|
super(options);
|
|
this.limit = limit;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [common692d301d_node.toNumber(serializer, this.limit)]
|
|
};
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Offset extends Stage {
|
|
get _name() {
|
|
return 'offset';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(offset, options) {
|
|
super(options);
|
|
this.offset = offset;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [common692d301d_node.toNumber(serializer, this.offset)]
|
|
};
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Select extends Stage {
|
|
get _name() {
|
|
return 'select';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(selections, options) {
|
|
super(options);
|
|
this.selections = selections;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [common692d301d_node.toMapValue(serializer, this.selections)]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.selections, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Sort extends Stage {
|
|
get _name() {
|
|
return 'sort';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(orderings, options) {
|
|
super(options);
|
|
this.orderings = orderings;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: this.orderings.map(o => o._toProto(serializer))
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.orderings, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Sample extends Stage {
|
|
get _name() {
|
|
return 'sample';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(rate, mode, options) {
|
|
super(options);
|
|
this.rate = rate;
|
|
this.mode = mode;
|
|
}
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [common692d301d_node.toNumber(serializer, this.rate), common692d301d_node.toStringValue(this.mode)]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Union extends Stage {
|
|
get _name() {
|
|
return 'union';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(other, options) {
|
|
super(options);
|
|
this.other = other;
|
|
}
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [common692d301d_node.toPipelineValue(this.other._toProto(serializer))]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Unnest extends Stage {
|
|
get _name() {
|
|
return 'unnest';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({
|
|
indexField: {
|
|
serverName: 'index_field'
|
|
}
|
|
});
|
|
}
|
|
constructor(alias, expr, options) {
|
|
super(options);
|
|
this.alias = alias;
|
|
this.expr = expr;
|
|
}
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [
|
|
this.expr._toProto(serializer),
|
|
field(this.alias)._toProto(serializer)
|
|
]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.expr, context);
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Replace extends Stage {
|
|
get _name() {
|
|
return 'replace_with';
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
constructor(map, options) {
|
|
super(options);
|
|
this.map = map;
|
|
}
|
|
_toProto(serializer) {
|
|
return {
|
|
...super._toProto(serializer),
|
|
args: [this.map._toProto(serializer), common692d301d_node.toStringValue(Replace.MODE)]
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.map, context);
|
|
}
|
|
}
|
|
Replace.MODE = 'full_replace';
|
|
/**
|
|
* @beta
|
|
*/
|
|
class RawStage extends Stage {
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*/
|
|
constructor(name, params, rawOptions) {
|
|
super({ rawOptions });
|
|
this.name = name;
|
|
this.params = params;
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(serializer) {
|
|
return {
|
|
name: this.name,
|
|
args: this.params.map(o => o._toProto(serializer)),
|
|
options: this.optionsProto
|
|
};
|
|
}
|
|
_readUserData(context) {
|
|
super._readUserData(context);
|
|
readUserDataHelper(this.params, context);
|
|
}
|
|
get _name() {
|
|
return this.name;
|
|
}
|
|
get _optionsUtil() {
|
|
return new common692d301d_node.OptionsUtil({});
|
|
}
|
|
}
|
|
/**
|
|
* Helper to read user data across a number of different formats.
|
|
* @param name - Name of the calling function. Used for error messages when invalid user data is encountered.
|
|
* @param expressionMap
|
|
* @returns the expressionMap argument.
|
|
* @private
|
|
*/
|
|
function readUserDataHelper(expressionMap, context) {
|
|
if (common692d301d_node.isUserData(expressionMap)) {
|
|
expressionMap._readUserData(context);
|
|
}
|
|
else if (Array.isArray(expressionMap)) {
|
|
expressionMap.forEach(readableData => readableData._readUserData(context));
|
|
}
|
|
else {
|
|
expressionMap.forEach(expr => expr._readUserData(context));
|
|
}
|
|
return expressionMap;
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/**
|
|
* @beta
|
|
* Provides the entry point for defining the data source of a Firestore {@link @firebase/firestore/pipelines#Pipeline}.
|
|
*
|
|
* Use the methods of this class (e.g., {@link @firebase/firestore/pipelines#PipelineSource.(collection:1)}, {@link @firebase/firestore/pipelines#PipelineSource.(collectionGroup:1)},
|
|
* {@link @firebase/firestore/pipelines#PipelineSource.(database:1)}, or {@link @firebase/firestore/pipelines#PipelineSource.(documents:1)}) to specify the initial data
|
|
* for your pipeline, such as a collection, a collection group, the entire database, or a set of specific documents.
|
|
*/
|
|
class PipelineSource {
|
|
/**
|
|
* @internal
|
|
* @private
|
|
* @param databaseId
|
|
* @param userDataReader
|
|
* @param _createPipeline
|
|
*/
|
|
constructor(databaseId, userDataReader,
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_createPipeline) {
|
|
this.databaseId = databaseId;
|
|
this.userDataReader = userDataReader;
|
|
this._createPipeline = _createPipeline;
|
|
}
|
|
collection(collectionOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
const options = common692d301d_node.isString(collectionOrOptions) ||
|
|
common692d301d_node.isCollectionReference(collectionOrOptions)
|
|
? {}
|
|
: collectionOrOptions;
|
|
const collectionRefOrString = common692d301d_node.isString(collectionOrOptions) ||
|
|
common692d301d_node.isCollectionReference(collectionOrOptions)
|
|
? collectionOrOptions
|
|
: collectionOrOptions.collection;
|
|
// Validate that a user provided reference is for the same Firestore DB
|
|
if (common692d301d_node.isCollectionReference(collectionRefOrString)) {
|
|
this._validateReference(collectionRefOrString);
|
|
}
|
|
// Convert user land convenience types to internal types
|
|
const normalizedCollection = common692d301d_node.isString(collectionRefOrString)
|
|
? collectionRefOrString
|
|
: collectionRefOrString.path;
|
|
// Create stage object
|
|
const stage = new CollectionSource(normalizedCollection, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'collection');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._createPipeline([stage]);
|
|
}
|
|
collectionGroup(collectionIdOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
let collectionId;
|
|
let options;
|
|
if (common692d301d_node.isString(collectionIdOrOptions)) {
|
|
collectionId = collectionIdOrOptions;
|
|
options = {};
|
|
}
|
|
else {
|
|
({ collectionId, ...options } = collectionIdOrOptions);
|
|
}
|
|
// Create stage object
|
|
const stage = new CollectionGroupSource(collectionId, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'collectionGroup');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._createPipeline([stage]);
|
|
}
|
|
database(options) {
|
|
// Process argument union(s) from method overloads
|
|
options = options ?? {};
|
|
// Create stage object
|
|
const stage = new DatabaseSource(options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'database');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._createPipeline([stage]);
|
|
}
|
|
documents(docsOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
let options;
|
|
let docs;
|
|
if (Array.isArray(docsOrOptions)) {
|
|
docs = docsOrOptions;
|
|
options = {};
|
|
}
|
|
else {
|
|
({ docs, ...options } = docsOrOptions);
|
|
}
|
|
// Validate that all user provided references are for the same Firestore DB
|
|
docs
|
|
.filter(v => v instanceof common692d301d_node.DocumentReference)
|
|
.forEach(dr => this._validateReference(dr));
|
|
// Convert user land convenience types to internal types
|
|
const normalizedDocs = docs.map(doc => common692d301d_node.isString(doc) ? doc : doc.path);
|
|
// Create stage object
|
|
const stage = new DocumentsSource(normalizedDocs, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'documents');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._createPipeline([stage]);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Convert the given Query into an equivalent Pipeline.
|
|
*
|
|
* @param query - A Query to be converted into a Pipeline.
|
|
*
|
|
* @throws `FirestoreError` Thrown if any of the provided DocumentReferences target a different project or database than the pipeline.
|
|
*/
|
|
createFrom(query) {
|
|
return toPipeline(query._query, query.firestore);
|
|
}
|
|
_validateReference(reference) {
|
|
const refDbId = reference.firestore._databaseId;
|
|
if (!refDbId.isEqual(this.databaseId)) {
|
|
throw new common692d301d_node.FirestoreError(common692d301d_node.Code.INVALID_ARGUMENT, `Invalid ${reference instanceof common692d301d_node.CollectionReference
|
|
? 'CollectionReference'
|
|
: 'DocumentReference'}. ` +
|
|
`The project ID ("${refDbId.projectId}") or the database ("${refDbId.database}") does not match ` +
|
|
`the project ID ("${this.databaseId.projectId}") and database ("${this.databaseId.database}") of the target database of this Pipeline.`);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/**
|
|
* @beta
|
|
* Represents the results of a Firestore pipeline execution.
|
|
*
|
|
* A `PipelineSnapshot` contains zero or more {@link @firebase/firestore/pipelines#PipelineResult} objects
|
|
* representing the documents returned by a pipeline query. It provides methods
|
|
* to iterate over the documents and access metadata about the query results.
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* const snapshot: PipelineSnapshot = await firestore
|
|
* .pipeline()
|
|
* .collection('myCollection')
|
|
* .where(field('value').greaterThan(10))
|
|
* .execute();
|
|
*
|
|
* snapshot.results.forEach(doc => {
|
|
* console.log(doc.id, '=>', doc.data());
|
|
* });
|
|
* ```
|
|
*/
|
|
class PipelineSnapshot {
|
|
constructor(pipeline, results, executionTime) {
|
|
this._pipeline = pipeline;
|
|
this._executionTime = executionTime;
|
|
this._results = results;
|
|
}
|
|
/**
|
|
* @beta An array of all the results in the `PipelineSnapshot`.
|
|
*/
|
|
get results() {
|
|
return this._results;
|
|
}
|
|
/**
|
|
* @beta
|
|
* The time at which the pipeline producing this result is executed.
|
|
*
|
|
* @readonly
|
|
*
|
|
*/
|
|
get executionTime() {
|
|
if (this._executionTime === undefined) {
|
|
throw new Error("'executionTime' is expected to exist, but it is undefined");
|
|
}
|
|
return this._executionTime;
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
*
|
|
* A PipelineResult contains data read from a Firestore Pipeline. The data can be extracted with the
|
|
* {@link @firebase/firestore/pipelines#PipelineResult.data} or {@link @firebase/firestore/pipelines#PipelineResult.(get:1)} methods.
|
|
*
|
|
* <p>If the PipelineResult represents a non-document result, `ref` will return a undefined
|
|
* value.
|
|
*/
|
|
class PipelineResult {
|
|
/**
|
|
* @private
|
|
* @internal
|
|
*
|
|
* @param userDataWriter - The serializer used to encode/decode protobuf.
|
|
* @param ref - The reference to the document.
|
|
* @param fields - The fields of the Firestore `Document` Protobuf backing
|
|
* this document.
|
|
* @param createTime - The time when the document was created if the result is a document, undefined otherwise.
|
|
* @param updateTime - The time when the document was last updated if the result is a document, undefined otherwise.
|
|
*/
|
|
constructor(userDataWriter, fields, ref, createTime, updateTime) {
|
|
this._ref = ref;
|
|
this._userDataWriter = userDataWriter;
|
|
this._createTime = createTime;
|
|
this._updateTime = updateTime;
|
|
this._fields = fields;
|
|
}
|
|
/**
|
|
* @beta
|
|
* The reference of the document, if it is a document; otherwise `undefined`.
|
|
*/
|
|
get ref() {
|
|
return this._ref;
|
|
}
|
|
/**
|
|
* @beta
|
|
* The ID of the document for which this PipelineResult contains data, if it is a document; otherwise `undefined`.
|
|
*
|
|
* @readonly
|
|
*
|
|
*/
|
|
get id() {
|
|
return this._ref?.id;
|
|
}
|
|
/**
|
|
* @beta
|
|
* The time the document was created. Undefined if this result is not a document.
|
|
*
|
|
* @readonly
|
|
*/
|
|
get createTime() {
|
|
return this._createTime;
|
|
}
|
|
/**
|
|
* @beta
|
|
* The time the document was last updated (at the time the snapshot was
|
|
* generated). Undefined if this result is not a document.
|
|
*
|
|
* @readonly
|
|
*/
|
|
get updateTime() {
|
|
return this._updateTime;
|
|
}
|
|
/**
|
|
* @beta
|
|
* Retrieves all fields in the result as an object.
|
|
*
|
|
* @returns An object containing all fields in the document or
|
|
* 'undefined' if the document doesn't exist.
|
|
*
|
|
* @example
|
|
* ```
|
|
* let p = firestore.pipeline().collection('col');
|
|
*
|
|
* p.execute().then(results => {
|
|
* let data = results[0].data();
|
|
* console.log(`Retrieved data: ${JSON.stringify(data)}`);
|
|
* });
|
|
* ```
|
|
*/
|
|
data() {
|
|
return this._userDataWriter.convertValue(this._fields.value);
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*
|
|
* Retrieves all fields in the result as a proto value.
|
|
*
|
|
* @returns An `Object` containing all fields in the result.
|
|
*/
|
|
_fieldsProto() {
|
|
// Return a cloned value to prevent manipulation of the Snapshot's data
|
|
return this._fields.clone().value.mapValue.fields;
|
|
}
|
|
/**
|
|
* @beta
|
|
* Retrieves the field specified by `field`.
|
|
*
|
|
* @param field - The field path
|
|
* (e.g. 'foo' or 'foo.bar') to a specific field.
|
|
* @returns The data at the specified field location or `undefined` if no
|
|
* such field exists.
|
|
*
|
|
* @example
|
|
* ```
|
|
* let p = firestore.pipeline().collection('col');
|
|
*
|
|
* p.execute().then(results => {
|
|
* let field = results[0].get('a.b');
|
|
* console.log(`Retrieved field value: ${field}`);
|
|
* });
|
|
* ```
|
|
*/
|
|
// We deliberately use `any` in the external API to not impose type-checking
|
|
// on end users.
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
get(fieldPath) {
|
|
if (this._fields === undefined) {
|
|
return undefined;
|
|
}
|
|
if (isField(fieldPath)) {
|
|
fieldPath = fieldPath.fieldName;
|
|
}
|
|
const value = this._fields.field(common692d301d_node.fieldPathFromArgument('DocumentSnapshot.get', fieldPath));
|
|
if (value !== null) {
|
|
return this._userDataWriter.convertValue(value);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* @beta
|
|
* Test equality of two PipelineResults.
|
|
* @param left - First PipelineResult to compare.
|
|
* @param right - Second PipelineResult to compare.
|
|
*/
|
|
function pipelineResultEqual(left, right) {
|
|
if (left === right) {
|
|
return true;
|
|
}
|
|
return (common692d301d_node.isOptionalEqual(left._ref, right._ref, common692d301d_node.refEqual) &&
|
|
common692d301d_node.isOptionalEqual(left._fields, right._fields, (l, r) => l.isEqual(r)));
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
function selectablesToMap(selectables) {
|
|
const result = new Map();
|
|
for (const selectable of selectables) {
|
|
let alias;
|
|
let expression;
|
|
if (typeof selectable === 'string') {
|
|
alias = selectable;
|
|
expression = field(selectable);
|
|
}
|
|
else if (selectable instanceof Field) {
|
|
alias = selectable.alias;
|
|
expression = selectable.expr;
|
|
}
|
|
else if (selectable instanceof AliasedExpression) {
|
|
alias = selectable.alias;
|
|
expression = selectable.expr;
|
|
}
|
|
else {
|
|
common692d301d_node.fail(0x5319, { selectable });
|
|
}
|
|
if (result.get(alias) !== undefined) {
|
|
throw new common692d301d_node.FirestoreError('invalid-argument', `Duplicate alias or field '${alias}'`);
|
|
}
|
|
result.set(alias, expression);
|
|
}
|
|
return result;
|
|
}
|
|
function aliasedAggregateToMap(aliasedAggregatees) {
|
|
return aliasedAggregatees.reduce((map, selectable) => {
|
|
if (map.get(selectable.alias) !== undefined) {
|
|
throw new common692d301d_node.FirestoreError('invalid-argument', `Duplicate alias or field '${selectable.alias}'`);
|
|
}
|
|
map.set(selectable.alias, selectable.aggregate);
|
|
return map;
|
|
}, new Map());
|
|
}
|
|
/**
|
|
* Converts a value to an Expression, Returning either a Constant, MapFunction,
|
|
* ArrayFunction, or the input itself (if it's already an expression).
|
|
*
|
|
* @private
|
|
* @internal
|
|
* @param value
|
|
*/
|
|
function vectorToExpr(value) {
|
|
if (value instanceof Expression) {
|
|
return value;
|
|
}
|
|
else if (value instanceof common692d301d_node.VectorValue) {
|
|
const result = constant(value);
|
|
return result;
|
|
}
|
|
else if (Array.isArray(value)) {
|
|
const result = constant(common692d301d_node.vector(value));
|
|
return result;
|
|
}
|
|
else {
|
|
throw new Error('Unsupported value: ' + typeof value);
|
|
}
|
|
}
|
|
/**
|
|
* Converts a value to an Expression, Returning either a Constant, MapFunction,
|
|
* ArrayFunction, or the input itself (if it's already an expression).
|
|
* If the input is a string, it is assumed to be a field name, and a
|
|
* field(value) is returned.
|
|
*
|
|
* @private
|
|
* @internal
|
|
* @param value
|
|
*/
|
|
function fieldOrExpression(value) {
|
|
if (common692d301d_node.isString(value)) {
|
|
const result = field(value);
|
|
return result;
|
|
}
|
|
else {
|
|
return valueToDefaultExpr(value);
|
|
}
|
|
}
|
|
/**
|
|
* Converts a value to an Expression, Returning either a Constant, MapFunction,
|
|
* ArrayFunction, or the input itself (if it's already an expression).
|
|
*
|
|
* @private
|
|
* @internal
|
|
* @param value
|
|
*/
|
|
function valueToDefaultExpr(value) {
|
|
let result;
|
|
if (isFirestoreValue(value)) {
|
|
return constant(value);
|
|
}
|
|
if (value instanceof Expression) {
|
|
return value;
|
|
}
|
|
else if (common692d301d_node.isPlainObject(value)) {
|
|
result = map(value);
|
|
}
|
|
else if (value instanceof Array) {
|
|
result = array(value);
|
|
}
|
|
else {
|
|
result = _constant(value, undefined);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/**
|
|
* @beta
|
|
*
|
|
* The Pipeline class provides a flexible and expressive framework for building complex data
|
|
* transformation and query pipelines for Firestore.
|
|
*
|
|
* A pipeline takes data sources, such as Firestore collections or collection groups, and applies
|
|
* a series of stages that are chained together. Each stage takes the output from the previous stage
|
|
* (or the data source) and produces an output for the next stage (or as the final output of the
|
|
* pipeline).
|
|
*
|
|
* Expressions can be used within each stage to filter and transform data through the stage.
|
|
*
|
|
* NOTE: The chained stages do not prescribe exactly how Firestore will execute the pipeline.
|
|
* Instead, Firestore only guarantees that the result is the same as if the chained stages were
|
|
* executed in order.
|
|
*
|
|
* Usage Examples:
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* const db: Firestore; // Assumes a valid firestore instance.
|
|
*
|
|
* // Example 1: Select specific fields and rename 'rating' to 'bookRating'
|
|
* const results1 = await execute(db.pipeline()
|
|
* .collection("books")
|
|
* .select("title", "author", field("rating").as("bookRating")));
|
|
*
|
|
* // Example 2: Filter documents where 'genre' is "Science Fiction" and 'published' is after 1950
|
|
* const results2 = await execute(db.pipeline()
|
|
* .collection("books")
|
|
* .where(and(field("genre").eq("Science Fiction"), field("published").gt(1950))));
|
|
*
|
|
* // Example 3: Calculate the average rating of books published after 1980
|
|
* const results3 = await execute(db.pipeline()
|
|
* .collection("books")
|
|
* .where(field("published").gt(1980))
|
|
* .aggregate(avg(field("rating")).as("averageRating")));
|
|
* ```
|
|
*/
|
|
class Pipeline$1 {
|
|
/**
|
|
* @internal
|
|
* @private
|
|
* @param _db
|
|
* @param userDataReader
|
|
* @param _userDataWriter
|
|
* @param stages
|
|
*/
|
|
constructor(
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_db,
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
userDataReader,
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_userDataWriter,
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
stages) {
|
|
this._db = _db;
|
|
this.userDataReader = userDataReader;
|
|
this._userDataWriter = _userDataWriter;
|
|
this.stages = stages;
|
|
}
|
|
addFields(fieldOrOptions, ...additionalFields) {
|
|
// Process argument union(s) from method overloads
|
|
let fields;
|
|
let options;
|
|
if (isSelectable(fieldOrOptions)) {
|
|
fields = [fieldOrOptions, ...additionalFields];
|
|
options = {};
|
|
}
|
|
else {
|
|
({ fields, ...options } = fieldOrOptions);
|
|
}
|
|
// Convert user land convenience types to internal types
|
|
const normalizedFields = selectablesToMap(fields);
|
|
// Create stage object
|
|
const stage = new AddFields(normalizedFields, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'addFields');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
removeFields(fieldValueOrOptions, ...additionalFields) {
|
|
// Process argument union(s) from method overloads
|
|
const options = isField(fieldValueOrOptions) || common692d301d_node.isString(fieldValueOrOptions)
|
|
? {}
|
|
: fieldValueOrOptions;
|
|
const fields = isField(fieldValueOrOptions) || common692d301d_node.isString(fieldValueOrOptions)
|
|
? [fieldValueOrOptions, ...additionalFields]
|
|
: fieldValueOrOptions.fields;
|
|
// Convert user land convenience types to internal types
|
|
const convertedFields = fields.map(f => common692d301d_node.isString(f) ? field(f) : f);
|
|
// Create stage object
|
|
const stage = new RemoveFields(convertedFields, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
stage._readUserData(this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'removeFields'));
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
select(selectionOrOptions, ...additionalSelections) {
|
|
// Process argument union(s) from method overloads
|
|
const options = isSelectable(selectionOrOptions) || common692d301d_node.isString(selectionOrOptions)
|
|
? {}
|
|
: selectionOrOptions;
|
|
const selections = isSelectable(selectionOrOptions) || common692d301d_node.isString(selectionOrOptions)
|
|
? [selectionOrOptions, ...additionalSelections]
|
|
: selectionOrOptions.selections;
|
|
// Convert user land convenience types to internal types
|
|
const normalizedSelections = selectablesToMap(selections);
|
|
// Create stage object
|
|
const stage = new Select(normalizedSelections, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'select');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
where(conditionOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
const options = isBooleanExpr(conditionOrOptions) ? {} : conditionOrOptions;
|
|
const condition = isBooleanExpr(conditionOrOptions)
|
|
? conditionOrOptions
|
|
: conditionOrOptions.condition;
|
|
// Create stage object
|
|
const stage = new Where(condition, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'where');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
offset(offsetOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
let options;
|
|
let offset;
|
|
if (common692d301d_node.isNumber$1(offsetOrOptions)) {
|
|
options = {};
|
|
offset = offsetOrOptions;
|
|
}
|
|
else {
|
|
options = offsetOrOptions;
|
|
offset = offsetOrOptions.offset;
|
|
}
|
|
// Create stage object
|
|
const stage = new Offset(offset, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'offset');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
limit(limitOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
const options = common692d301d_node.isNumber$1(limitOrOptions) ? {} : limitOrOptions;
|
|
const limit = common692d301d_node.isNumber$1(limitOrOptions)
|
|
? limitOrOptions
|
|
: limitOrOptions.limit;
|
|
// Create stage object
|
|
const stage = new Limit(limit, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'limit');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
distinct(groupOrOptions, ...additionalGroups) {
|
|
// Process argument union(s) from method overloads
|
|
const options = common692d301d_node.isString(groupOrOptions) || isSelectable(groupOrOptions)
|
|
? {}
|
|
: groupOrOptions;
|
|
const groups = common692d301d_node.isString(groupOrOptions) || isSelectable(groupOrOptions)
|
|
? [groupOrOptions, ...additionalGroups]
|
|
: groupOrOptions.groups;
|
|
// Convert user land convenience types to internal types
|
|
const convertedGroups = selectablesToMap(groups);
|
|
// Create stage object
|
|
const stage = new Distinct(convertedGroups, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'distinct');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
aggregate(targetOrOptions, ...rest) {
|
|
// Process argument union(s) from method overloads
|
|
const options = isAliasedAggregate(targetOrOptions) ? {} : targetOrOptions;
|
|
const accumulators = isAliasedAggregate(targetOrOptions)
|
|
? [targetOrOptions, ...rest]
|
|
: targetOrOptions.accumulators;
|
|
const groups = isAliasedAggregate(targetOrOptions)
|
|
? []
|
|
: targetOrOptions.groups ?? [];
|
|
// Convert user land convenience types to internal types
|
|
const convertedAccumulators = aliasedAggregateToMap(accumulators);
|
|
const convertedGroups = selectablesToMap(groups);
|
|
// Create stage object
|
|
const stage = new Aggregate(convertedGroups, convertedAccumulators, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'aggregate');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Performs a vector proximity search on the documents from the previous stage, returning the
|
|
* K-nearest documents based on the specified query `vectorValue` and `distanceMeasure`. The
|
|
* returned documents will be sorted in order from nearest to furthest from the query `vectorValue`.
|
|
*
|
|
* <p>Example:
|
|
*
|
|
* ```typescript
|
|
* // Find the 10 most similar books based on the book description.
|
|
* const bookDescription = "Lorem ipsum...";
|
|
* const queryVector: number[] = ...; // compute embedding of `bookDescription`
|
|
*
|
|
* firestore.pipeline().collection("books")
|
|
* .findNearest({
|
|
* field: 'embedding',
|
|
* vectorValue: queryVector,
|
|
* distanceMeasure: 'euclidean',
|
|
* limit: 10, // optional
|
|
* distanceField: 'computedDistance' // optional
|
|
* });
|
|
* ```
|
|
*
|
|
* @param options - An object that specifies required and optional parameters for the stage.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Pipeline} object with this stage appended to the stage list.
|
|
*/
|
|
findNearest(options) {
|
|
// Convert user land convenience types to internal types
|
|
const field = toField(options.field);
|
|
const vectorValue = vectorToExpr(options.vectorValue);
|
|
const distanceField = options.distanceField
|
|
? toField(options.distanceField)
|
|
: undefined;
|
|
const internalOptions = {
|
|
distanceField,
|
|
limit: options.limit,
|
|
rawOptions: options.rawOptions
|
|
};
|
|
// Create stage object
|
|
const stage = new FindNearest(vectorValue, field, options.distanceMeasure, internalOptions);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'addFields');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
sort(orderingOrOptions, ...additionalOrderings) {
|
|
// Process argument union(s) from method overloads
|
|
const options = isOrdering(orderingOrOptions) ? {} : orderingOrOptions;
|
|
const orderings = isOrdering(orderingOrOptions)
|
|
? [orderingOrOptions, ...additionalOrderings]
|
|
: orderingOrOptions.orderings;
|
|
// Create stage object
|
|
const stage = new Sort(orderings, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'sort');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
replaceWith(valueOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
const options = common692d301d_node.isString(valueOrOptions) || isExpr(valueOrOptions) ? {} : valueOrOptions;
|
|
const fieldNameOrExpr = common692d301d_node.isString(valueOrOptions) || isExpr(valueOrOptions)
|
|
? valueOrOptions
|
|
: valueOrOptions.map;
|
|
// Convert user land convenience types to internal types
|
|
const mapExpr = fieldOrExpression(fieldNameOrExpr);
|
|
// Create stage object
|
|
const stage = new Replace(mapExpr, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'replaceWith');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
sample(documentsOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
const options = common692d301d_node.isNumber$1(documentsOrOptions) ? {} : documentsOrOptions;
|
|
let rate;
|
|
let mode;
|
|
if (common692d301d_node.isNumber$1(documentsOrOptions)) {
|
|
rate = documentsOrOptions;
|
|
mode = 'documents';
|
|
}
|
|
else if (common692d301d_node.isNumber$1(documentsOrOptions.documents)) {
|
|
rate = documentsOrOptions.documents;
|
|
mode = 'documents';
|
|
}
|
|
else {
|
|
rate = documentsOrOptions.percentage;
|
|
mode = 'percent';
|
|
}
|
|
// Create stage object
|
|
const stage = new Sample(rate, mode, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'sample');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
union(otherOrOptions) {
|
|
// Process argument union(s) from method overloads
|
|
let options;
|
|
let otherPipeline;
|
|
if (isPipeline(otherOrOptions)) {
|
|
options = {};
|
|
otherPipeline = otherOrOptions;
|
|
}
|
|
else {
|
|
({ other: otherPipeline, ...options } = otherOrOptions);
|
|
}
|
|
// Create stage object
|
|
const stage = new Union(otherPipeline, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'union');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
unnest(selectableOrOptions, indexField) {
|
|
// Process argument union(s) from method overloads
|
|
let options;
|
|
let selectable;
|
|
let indexFieldName;
|
|
if (isSelectable(selectableOrOptions)) {
|
|
options = {};
|
|
selectable = selectableOrOptions;
|
|
indexFieldName = indexField;
|
|
}
|
|
else {
|
|
({
|
|
selectable,
|
|
indexField: indexFieldName,
|
|
...options
|
|
} = selectableOrOptions);
|
|
}
|
|
// Convert user land convenience types to internal types
|
|
const alias = selectable.alias;
|
|
const expr = selectable.expr;
|
|
if (common692d301d_node.isString(indexFieldName)) {
|
|
options.indexField = _field(indexFieldName, 'unnest');
|
|
}
|
|
// Create stage object
|
|
const stage = new Unnest(alias, expr, options);
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'unnest');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
/**
|
|
* @beta
|
|
* Adds a raw stage to the pipeline.
|
|
*
|
|
* <p>This method provides a flexible way to extend the pipeline's functionality by adding custom
|
|
* stages. Each raw stage is defined by a unique `name` and a set of `params` that control its
|
|
* behavior.
|
|
*
|
|
* <p>Example (Assuming there is no 'where' stage available in SDK):
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* // Assume we don't have a built-in 'where' stage
|
|
* firestore.pipeline().collection('books')
|
|
* .rawStage('where', [field('published').lt(1900)]) // Custom 'where' stage
|
|
* .select('title', 'author');
|
|
* ```
|
|
*
|
|
* @param name - The unique name of the raw stage to add.
|
|
* @param params - A list of parameters to configure the raw stage's behavior.
|
|
* @param options - An object of key value pairs that specifies optional parameters for the stage.
|
|
* @returns A new {@link @firebase/firestore/pipelines#Pipeline} object with this stage appended to the stage list.
|
|
*/
|
|
rawStage(name, params, options) {
|
|
// Convert user land convenience types to internal types
|
|
const expressionParams = params.map((value) => {
|
|
if (value instanceof Expression) {
|
|
return value;
|
|
}
|
|
else if (value instanceof AggregateFunction) {
|
|
return value;
|
|
}
|
|
else if (common692d301d_node.isPlainObject(value)) {
|
|
return _mapValue(value);
|
|
}
|
|
else {
|
|
return _constant(value, 'rawStage');
|
|
}
|
|
});
|
|
// Create stage object
|
|
const stage = new RawStage(name, expressionParams, options ?? {});
|
|
// User data must be read in the context of the API method to
|
|
// provide contextual errors
|
|
const parseContext = this.userDataReader.createContext(3 /* UserDataSource.Argument */, 'rawStage');
|
|
stage._readUserData(parseContext);
|
|
// Add stage to the pipeline
|
|
return this._addStage(stage);
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
*/
|
|
_toProto(jsonProtoSerializer) {
|
|
const stages = this.stages.map(stage => stage._toProto(jsonProtoSerializer));
|
|
return { stages };
|
|
}
|
|
_addStage(stage) {
|
|
const copy = this.stages.map(s => s);
|
|
copy.push(stage);
|
|
return this.newPipeline(this._db, this.userDataReader, this._userDataWriter, copy);
|
|
}
|
|
/**
|
|
* @internal
|
|
* @private
|
|
* @param db
|
|
* @param userDataReader
|
|
* @param userDataWriter
|
|
* @param stages
|
|
* @protected
|
|
*/
|
|
newPipeline(db, userDataReader, userDataWriter, stages) {
|
|
return new Pipeline$1(db, userDataReader, userDataWriter, stages);
|
|
}
|
|
}
|
|
function isPipeline(val) {
|
|
return val instanceof Pipeline$1;
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
/**
|
|
* @beta
|
|
*/
|
|
class Pipeline extends Pipeline$1 {
|
|
/**
|
|
* @internal
|
|
* @private
|
|
* @param db
|
|
* @param userDataReader
|
|
* @param userDataWriter
|
|
* @param stages
|
|
* @param converter
|
|
* @protected
|
|
*/
|
|
newPipeline(db, userDataReader, userDataWriter, stages) {
|
|
return new Pipeline(db, userDataReader, userDataWriter, stages);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
function execute(pipelineOrOptions) {
|
|
const options = !(pipelineOrOptions instanceof Pipeline$1)
|
|
? pipelineOrOptions
|
|
: {
|
|
pipeline: pipelineOrOptions
|
|
};
|
|
const { pipeline, rawOptions, ...rest } = options;
|
|
const firestore = common692d301d_node.cast(pipeline._db, common692d301d_node.Firestore);
|
|
const client = common692d301d_node.ensureFirestoreConfigured(firestore);
|
|
const udr = new common692d301d_node.UserDataReader(firestore._databaseId,
|
|
/* ignoreUndefinedProperties */ true);
|
|
const context = udr.createContext(3 /* UserDataSource.Argument */, 'execute');
|
|
const structuredPipelineOptions = new common692d301d_node.StructuredPipelineOptions(rest, rawOptions);
|
|
structuredPipelineOptions._readUserData(context);
|
|
const structuredPipeline = new common692d301d_node.StructuredPipeline(pipeline, structuredPipelineOptions);
|
|
return common692d301d_node.firestoreClientExecutePipeline(client, structuredPipeline).then(result => {
|
|
// Get the execution time from the first result.
|
|
// firestoreClientExecutePipeline returns at least one PipelineStreamElement
|
|
// even if the returned document set is empty.
|
|
const executionTime = result.length > 0 ? result[0].executionTime?.toTimestamp() : undefined;
|
|
const docs = result
|
|
// Currently ignore any response from ExecutePipeline that does
|
|
// not contain any document data in the `fields` property.
|
|
.filter(element => !!element.fields)
|
|
.map(element => new PipelineResult(pipeline._userDataWriter, element.fields, element.key?.path
|
|
? new common692d301d_node.DocumentReference(firestore, null, element.key)
|
|
: undefined, element.createTime?.toTimestamp(), element.updateTime?.toTimestamp()));
|
|
return new PipelineSnapshot(pipeline, docs, executionTime);
|
|
});
|
|
}
|
|
/**
|
|
* @beta
|
|
* Creates and returns a new PipelineSource, which allows specifying the source stage of a {@link @firebase/firestore/pipelines#Pipeline}.
|
|
*
|
|
* @example
|
|
* ```
|
|
* let myPipeline: Pipeline = firestore.pipeline().collection('books');
|
|
* ```
|
|
*/
|
|
// Augment the Firestore class with the pipeline() factory method
|
|
common692d301d_node.Firestore.prototype.pipeline = function () {
|
|
const userDataReader = common692d301d_node.newUserDataReader(this);
|
|
return new PipelineSource(this._databaseId, userDataReader, (stages) => {
|
|
return new Pipeline(this, userDataReader, new common692d301d_node.ExpUserDataWriter(this), stages);
|
|
});
|
|
};
|
|
|
|
exports._internalPipelineToExecutePipelineRequestProto = common692d301d_node._internalPipelineToExecutePipelineRequestProto;
|
|
exports.AggregateFunction = AggregateFunction;
|
|
exports.AliasedAggregate = AliasedAggregate;
|
|
exports.AliasedExpression = AliasedExpression;
|
|
exports.BooleanExpression = BooleanExpression;
|
|
exports.Expression = Expression;
|
|
exports.Field = Field;
|
|
exports.FunctionExpression = FunctionExpression;
|
|
exports.Ordering = Ordering;
|
|
exports.Pipeline = Pipeline;
|
|
exports.PipelineResult = PipelineResult;
|
|
exports.PipelineSnapshot = PipelineSnapshot;
|
|
exports.PipelineSource = PipelineSource;
|
|
exports.abs = abs;
|
|
exports.add = add;
|
|
exports.and = and;
|
|
exports.array = array;
|
|
exports.arrayAgg = arrayAgg;
|
|
exports.arrayAggDistinct = arrayAggDistinct;
|
|
exports.arrayConcat = arrayConcat;
|
|
exports.arrayContains = arrayContains;
|
|
exports.arrayContainsAll = arrayContainsAll;
|
|
exports.arrayContainsAny = arrayContainsAny;
|
|
exports.arrayGet = arrayGet;
|
|
exports.arrayLength = arrayLength;
|
|
exports.arraySum = arraySum;
|
|
exports.ascending = ascending;
|
|
exports.average = average;
|
|
exports.byteLength = byteLength;
|
|
exports.ceil = ceil;
|
|
exports.charLength = charLength;
|
|
exports.collectionId = collectionId;
|
|
exports.concat = concat;
|
|
exports.conditional = conditional;
|
|
exports.constant = constant;
|
|
exports.cosineDistance = cosineDistance;
|
|
exports.count = count;
|
|
exports.countAll = countAll;
|
|
exports.countDistinct = countDistinct;
|
|
exports.countIf = countIf;
|
|
exports.currentTimestamp = currentTimestamp;
|
|
exports.descending = descending;
|
|
exports.divide = divide;
|
|
exports.documentId = documentId;
|
|
exports.dotProduct = dotProduct;
|
|
exports.endsWith = endsWith;
|
|
exports.equal = equal;
|
|
exports.equalAny = equalAny;
|
|
exports.euclideanDistance = euclideanDistance;
|
|
exports.execute = execute;
|
|
exports.exists = exists;
|
|
exports.exp = exp;
|
|
exports.field = field;
|
|
exports.first = first;
|
|
exports.floor = floor;
|
|
exports.greaterThan = greaterThan;
|
|
exports.greaterThanOrEqual = greaterThanOrEqual;
|
|
exports.ifAbsent = ifAbsent;
|
|
exports.ifError = ifError;
|
|
exports.isAbsent = isAbsent;
|
|
exports.isError = isError;
|
|
exports.isType = isType;
|
|
exports.join = join;
|
|
exports.last = last;
|
|
exports.length = length;
|
|
exports.lessThan = lessThan;
|
|
exports.lessThanOrEqual = lessThanOrEqual;
|
|
exports.like = like;
|
|
exports.ln = ln;
|
|
exports.log = log;
|
|
exports.log10 = log10;
|
|
exports.logicalMaximum = logicalMaximum;
|
|
exports.logicalMinimum = logicalMinimum;
|
|
exports.ltrim = ltrim;
|
|
exports.map = map;
|
|
exports.mapEntries = mapEntries;
|
|
exports.mapGet = mapGet;
|
|
exports.mapKeys = mapKeys;
|
|
exports.mapMerge = mapMerge;
|
|
exports.mapRemove = mapRemove;
|
|
exports.mapSet = mapSet;
|
|
exports.mapValues = mapValues;
|
|
exports.maximum = maximum;
|
|
exports.minimum = minimum;
|
|
exports.mod = mod;
|
|
exports.multiply = multiply;
|
|
exports.not = not;
|
|
exports.notEqual = notEqual;
|
|
exports.notEqualAny = notEqualAny;
|
|
exports.or = or;
|
|
exports.pipelineResultEqual = pipelineResultEqual;
|
|
exports.pow = pow;
|
|
exports.rand = rand;
|
|
exports.regexContains = regexContains;
|
|
exports.regexFind = regexFind;
|
|
exports.regexFindAll = regexFindAll;
|
|
exports.regexMatch = regexMatch;
|
|
exports.reverse = reverse;
|
|
exports.round = round;
|
|
exports.rtrim = rtrim;
|
|
exports.split = split;
|
|
exports.sqrt = sqrt;
|
|
exports.startsWith = startsWith;
|
|
exports.stringConcat = stringConcat;
|
|
exports.stringContains = stringContains;
|
|
exports.stringIndexOf = stringIndexOf;
|
|
exports.stringRepeat = stringRepeat;
|
|
exports.stringReplaceAll = stringReplaceAll;
|
|
exports.stringReplaceOne = stringReplaceOne;
|
|
exports.stringReverse = stringReverse;
|
|
exports.substring = substring;
|
|
exports.subtract = subtract;
|
|
exports.sum = sum;
|
|
exports.timestampAdd = timestampAdd;
|
|
exports.timestampSubtract = timestampSubtract;
|
|
exports.timestampToUnixMicros = timestampToUnixMicros;
|
|
exports.timestampToUnixMillis = timestampToUnixMillis;
|
|
exports.timestampToUnixSeconds = timestampToUnixSeconds;
|
|
exports.timestampTruncate = timestampTruncate;
|
|
exports.toLower = toLower;
|
|
exports.toUpper = toUpper;
|
|
exports.trim = trim;
|
|
exports.trunc = trunc;
|
|
exports.type = type;
|
|
exports.unixMicrosToTimestamp = unixMicrosToTimestamp;
|
|
exports.unixMillisToTimestamp = unixMillisToTimestamp;
|
|
exports.unixSecondsToTimestamp = unixSecondsToTimestamp;
|
|
exports.vectorLength = vectorLength;
|
|
exports.xor = xor;
|
|
//# sourceMappingURL=pipelines.node.cjs.js.map
|