@microfocus/alm-octane-js-rest-sdk
Version:
NodeJS wrapper for the OpenText Core Software Delivery Platform API
303 lines (260 loc) • 7.71 kB
text/typescript
/*
* Copyright 2020-2025 Open Text.
*
* The only warranties for products and services of Open Text and
* its affiliates and licensors (“Open Text”) are as may be set forth
* in the express warranty statements accompanying such products and services.
* Nothing herein should be construed as constituting an additional warranty.
* Open Text shall not be liable for technical or editorial errors or
* omissions contained herein. The information contained herein is subject
* to change without notice.
*
* Except as specifically indicated otherwise, this document contains
* confidential information and a valid license is required for possession,
* use or copying. If this work is provided to the U.S. Government,
* consistent with FAR 12.211 and 12.212, Commercial Computer Software,
* Computer Software Documentation, and Technical Data for Commercial Items are
* licensed to the U.S. Government under vendor's standard commercial license.
*
* 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.
*/
/** @module octane/query */
import assert from 'assert';
class Query {
private operator: Function;
private operand1: any;
private operand2: any;
private operand3: any;
static field: (name: string) => Field;
static NULL: Query;
static NULL_REFERENCE: Query;
static NONE: Query;
constructor(
operator: Function,
operand1?: any,
operand2?: any,
operand3?: any
) {
this.operator = operator;
this.operand1 = operand1;
this.operand2 = operand2;
this.operand3 = operand3;
}
group() {
return new Query(group, this);
}
not() {
return new Query(not, this);
}
and(q?: undefined): DelayQuery;
and(q: Query): Query;
and(q: any): any {
if (q && q instanceof Query) {
return new Query(and, this, q);
} else {
return new DelayQuery(and, this);
}
}
or(q?: undefined): DelayQuery;
or(q: Query): Query;
or(q: any): any {
if (q && q instanceof Query) {
return new Query(or, this, q);
} else {
return new DelayQuery(or, this);
}
}
build() {
return this.operator(this.operand1, this.operand2, this.operand3);
}
}
Query.field = (name) => new Field(name);
Query.NULL = new Query(none, null, null);
Query.NULL_REFERENCE = Query.NONE = new Query(none, null, null);
export default Query;
class DelayQuery {
operator: Function;
query: any;
constructor(operator: Function, query: Query) {
this.operator = operator;
this.query = query;
}
field(name: string) {
return new Field(name, this);
}
fulfill(query: Query) {
return new Query(this.operator, this.query, query);
}
}
class Field {
name: any;
delay?: DelayQuery;
constructor(name: string, delay?: DelayQuery) {
this.name = name;
this.delay = delay;
}
equal(value: any) {
const q = new Query(equal, this.name, value);
return this.fulfillDelay(q);
}
notEqual(value: any) {
const q1 = new Query(equal, this.name, value);
const q2 = new Query(not, q1);
return this.fulfillDelay(q2);
}
less(value: any) {
const q = new Query(less, this.name, value);
return this.fulfillDelay(q);
}
notLess(value: any) {
const q1 = new Query(less, this.name, value);
const q2 = new Query(not, q1);
return this.fulfillDelay(q2);
}
greater(value: any) {
const q = new Query(greater, this.name, value);
return this.fulfillDelay(q);
}
notGreater(value: any) {
const q1 = new Query(greater, this.name, value);
const q2 = new Query(not, q1);
return this.fulfillDelay(q2);
}
lessEqual(value: any) {
const q = new Query(lessEqual, this.name, value);
return this.fulfillDelay(q);
}
notLessEqual(value: any) {
const q1 = new Query(lessEqual, this.name, value);
const q2 = new Query(not, q1);
return this.fulfillDelay(q2);
}
greaterEqual(value: any) {
const q = new Query(greaterEqual, this.name, value);
return this.fulfillDelay(q);
}
notGreaterEqual(value: any) {
const q1 = new Query(greaterEqual, this.name, value);
const q2 = new Query(not, q1);
return this.fulfillDelay(q2);
}
between(value1: any, value2: any) {
const q = new Query(between, this.name, value1, value2);
return this.fulfillDelay(q);
}
inComparison(value: any) {
const q = new Query(inComparison, this.name, value);
return this.fulfillDelay(q);
}
fulfillDelay(query: Query) {
if (this.delay) {
return this.delay.fulfill(query);
} else {
return query;
}
}
}
function equal(f: any, v: any) {
assert(typeof f === 'string');
if (typeof v === 'number') {
return `${f} EQ ${v}`;
} else if (typeof v === 'boolean') {
return `${f} EQ ${v}`;
} else if (typeof v === 'string') {
return `${f} EQ ^${v}^`;
} else if (v instanceof Date) {
return `${f} EQ ^${v.toISOString()}^`;
} else if (v === Query.NULL) {
return `${f} EQ ${v.build()}`;
} else if (v instanceof Query) {
return `${f} EQ {${v.build()}}`;
} else {
assert(false, `Not supported data type: ${v}`);
}
}
function less(f: any, v: any) {
return compare(f, v, 'LT');
}
function greater(f: any, v: any) {
return compare(f, v, 'GT');
}
function lessEqual(f: any, v: any) {
return compare(f, v, 'LE');
}
function greaterEqual(f: any, v: any) {
return compare(f, v, 'GE');
}
function between(f: any, v: any, w: any) {
assert(typeof f === 'string');
assert(
(typeof v === 'number' && typeof w === 'number') ||
(v instanceof Date && w instanceof Date)
);
if (typeof v === 'number') {
return `${f} BTW ${v}...${w}`;
} else if (w instanceof Date) {
return `${f} BTW ^${v.toISOString()}^...^${w.toISOString()}^`;
}
}
function inComparison(f: any, v: any) {
assert(typeof f === 'string');
assert(Array.isArray(v));
let hasValueAlready = false;
let returnString = `${f} IN `;
v.forEach((value) => {
if (hasValueAlready) {
returnString += ',';
}
if (typeof value === 'number') {
returnString += value;
} else if (typeof value === 'string') {
returnString += `^${value}^`;
} else if (value instanceof Date) {
returnString += `^${value.toISOString()}^`;
} else if (value instanceof Query) {
returnString += `{${value.build()}}`;
} else {
assert(false, `Not supported data type: ${value}`);
}
hasValueAlready = true;
});
return returnString;
}
function compare(f: any, v: any, operator: string) {
assert(typeof f === 'string');
assert(typeof v === 'number' || v instanceof Date);
if (typeof v === 'number') {
return `${f} ${operator} ${v}`;
} else {
return `${f} ${operator} ^${v.toISOString()}^`;
}
}
function group(q: Query) {
assert(q instanceof Query);
return `(${q.build()})`;
}
function not(q: Query) {
assert(q instanceof Query);
return `!${q.build()}`;
}
function and(q1: Query, q2: Query) {
assert(q1 instanceof Query);
assert(q2 instanceof Query);
return `${q1.build()};${q2.build()}`;
}
function or(q1: Query, q2: Query) {
assert(q1 instanceof Query);
assert(q2 instanceof Query);
return `${q1.build()}||${q2.build()}`;
}
function none() {
return 'null';
}