@bufbuild/cel
Version:
A CEL evaluator for ECMAScript
133 lines (132 loc) • 3.61 kB
JavaScript
// Copyright 2024-2025 Buf Technologies, Inc.
//
// 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.
var _a, _b, _c;
import { isReflectList, } from "@bufbuild/protobuf/reflect";
import { celFromScalar } from "./proto.js";
import { reflectMsgToCel, toCel } from "./value.js";
const privateSymbol = Symbol.for("@bufbuild/cel/list");
/**
* Create a new list from a native array or a ReflectList.
*/
export function celList(arrayOrReflectList) {
if (isReflectList(arrayOrReflectList)) {
return new RepeatedFieldList(arrayOrReflectList);
}
return new ArrayList(arrayOrReflectList);
}
/**
* Returns a new List that has all the elements
* of the lists in order.
*/
export function celListConcat(...lists) {
return new ConcatList(lists);
}
/**
* Returns true if the given value is a CelList.
*/
export function isCelList(v) {
return typeof v === "object" && v !== null && privateSymbol in v;
}
class ArrayList {
constructor(_array) {
this._array = _array;
this[_a] = {};
}
get size() {
return this._array.length;
}
get(index) {
if (index < 0 || index >= this.size) {
return undefined;
}
return toCel(this._array[index]);
}
*values() {
for (const element of this._array.values()) {
yield toCel(element);
}
}
[(_a = privateSymbol, Symbol.iterator)]() {
return this.values();
}
}
class RepeatedFieldList {
constructor(_list) {
this._list = _list;
this[_b] = {};
}
get size() {
return this._list.size;
}
get(index) {
const val = this._list.get(index);
if (val === undefined) {
return undefined;
}
return celFromListElem(this._list.field(), val);
}
*values() {
for (const val of this._list) {
yield celFromListElem(this._list.field(), val);
}
}
[(_b = privateSymbol, Symbol.iterator)]() {
return this.values();
}
}
class ConcatList {
constructor(_lists) {
this._lists = _lists;
this[_c] = {};
let size = 0;
for (const list of _lists) {
size += list.size;
}
this._size = size;
}
get size() {
return this._size;
}
get(index) {
if (index < 0 || index >= this.size) {
return undefined;
}
for (const list of this._lists) {
if (index < list.size) {
return list.get(index);
}
index = index - list.size;
}
return undefined;
}
*values() {
for (const list of this._lists) {
yield* list.values();
}
}
[(_c = privateSymbol, Symbol.iterator)]() {
return this.values();
}
}
function celFromListElem(desc, v) {
switch (desc.listKind) {
case "enum":
return BigInt(v);
case "message":
return reflectMsgToCel(v);
case "scalar":
return celFromScalar(desc.scalar, v);
}
}
export const EMPTY_LIST = celList([]);