From 95df8ebc7d5d1b13ac95436408ae6b7798424e4e Mon Sep 17 00:00:00 2001 From: delvedor Date: Thu, 3 Sep 2020 15:24:16 +0200 Subject: [PATCH] Added fluent wrapper --- dsl/index.js | 3 +- dsl/src/fluent.ts | 262 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 dsl/src/fluent.ts diff --git a/dsl/index.js b/dsl/index.js index 6ffee05e2..1dd6d389c 100644 --- a/dsl/index.js +++ b/dsl/index.js @@ -21,5 +21,6 @@ const Q = require('./lib/query-helpers').default const A = require('./lib/aggregation-helpers').default +const F = require('./lib/fluent').default -module.exports = { Q, A } +module.exports = { Q, A, F } diff --git a/dsl/src/fluent.ts b/dsl/src/fluent.ts new file mode 100644 index 000000000..0c14389eb --- /dev/null +++ b/dsl/src/fluent.ts @@ -0,0 +1,262 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you 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 camelcase: 0 */ +/* eslint no-undef: 0 */ +/* eslint no-use-before-define: 0 */ +/* eslint no-redeclare: 0 */ +/* eslint no-dupe-class-members: 0 */ +/* eslint lines-between-class-members: 0 */ + +import Q from './query' +import * as t from './types' + +const kState = Symbol('dsl-state') +type nestedQFn = (f: Fluent) => Fluent + +class Fluent { + [kState]: Record[] + constructor () { + this[kState] = [] + } + + build (): Record { + return Q(...this[kState]) + } + + param (key: string): Symbol { + return Q.param(key) + } + + compileUnsafe = Record> (): t.compiledFunction { + return Q.compileUnsafe(this.build()) + } + + compile = Record> (): t.compiledFunction { + return Q.compile(this.build()) + } + + match (key: string, val: string | Symbol, opts?: Record): this + match (key: string, val: string[], opts?: Record): this + match (key: string, val: any, opts?: Record): this { + this[kState].push(Q.match(key, val, opts)) + return this + } + + matchPhrase (key: string, val: string | Symbol, opts?: Record): this { + this[kState].push(Q.matchPhrase(key, val, opts)) + return this + } + + matchPhrasePrefix (key: string, val: string | Symbol, opts?: Record): this { + this[kState].push(Q.matchPhrasePrefix(key, val, opts)) + return this + } + + multiMatch (keys: string[], val: string | Symbol, opts?: Record): this { + this[kState].push(Q.multiMatch(keys, val, opts)) + return this + } + + matchAll (opts?: Record): this { + this[kState].push(Q.matchAll(opts)) + return this + } + + matchNone (): this { + this[kState].push(Q.matchNone()) + return this + } + + common (key: string, val: string | Symbol, opts: Record): this { + this[kState].push(Q.common(key, val, opts)) + return this + } + + queryString (val: string | Symbol, opts: Record): this { + this[kState].push(Q.queryString(val, opts)) + return this + } + + simpleQueryString (val: string | Symbol, opts: Record): this { + this[kState].push(Q.simpleQueryString(val, opts)) + return this + } + + term (key: string, val: string | string[] | Symbol, opts?: Record): this { + if (Array.isArray(val)) { + return this.terms(key, val, opts) + } + this[kState].push(Q.term(key, val, opts)) + return this + } + + terms (key: string, val: string[] | Symbol, opts?: Record): this { + this[kState].push(Q.terms(key, val, opts)) + return this + } + + termsSet (key: string, val: string[] | Symbol, opts: Record): this { + this[kState].push(Q.termsSet(key, val, opts)) + return this + } + + range (key: string, val: any): this { + this[kState].push(Q.range(key, val)) + return this + } + + exists (key: string | Symbol): this + exists (key: string[]): this + exists (key: any): this { + if (Array.isArray(key)) { + for (const k of key) { + this[kState].push(Q.exists(k)) + } + return this + } + this[kState].push(Q.exists(key)) + return this + } + + prefix (key: string, val: string | Symbol, opts?: Record): this + prefix (key: string, val: string[], opts?: Record): this + prefix (key: string, val: any, opts?: Record): this { + this[kState].push(Q.prefix(key, val, opts)) + return this + } + + wildcard (key: string, val: string | Symbol, opts?: Record): this + wildcard (key: string, val: string[], opts?: Record): this + wildcard (key: string, val: any, opts?: Record): this { + this[kState].push(Q.wildcard(key, val, opts)) + return this + } + + regexp (key: string, val: string | Symbol, opts?: Record): this + regexp (key: string, val: string[], opts?: Record): this + regexp (key: string, val: any, opts?: Record): this { + this[kState].push(Q.regexp(key, val, opts)) + return this + } + + fuzzy (key: string, val: string | Symbol, opts?: Record): this + fuzzy (key: string, val: string[], opts?: Record): this + fuzzy (key: string, val: any, opts?: Record): this { + this[kState].push(Q.fuzzy(key, val, opts)) + return this + } + + ids (key: string, val: string[] | Symbol, opts: Record): this { + this[kState].push(Q.ids(key, val, opts)) + return this + } + + must (fn: nestedQFn): this { + const state = this[kState] + this[kState] = [] + const queries = fn(this)[kState] + this[kState] = state + this[kState].push(Q.must(queries)) + return this + } + + should (fn: nestedQFn): this { + const state = this[kState] + this[kState] = [] + const queries = fn(this)[kState] + this[kState] = state + this[kState].push(Q.should((queries))) + return this + } + + mustNot (fn: nestedQFn): this { + const state = this[kState] + this[kState] = [] + const queries = fn(this)[kState] + this[kState] = state + this[kState].push(Q.mustNot(queries)) + return this + } + + filter (fn: nestedQFn): this { + const state = this[kState] + this[kState] = [] + const queries = fn(this)[kState] + this[kState] = state + this[kState].push(Q.filter(queries)) + return this + } + + bool (fn: nestedQFn): this { + const state = this[kState] + this[kState] = [] + const queries = fn(this)[kState] + this[kState] = state + this[kState].push(Q.bool(queries)) + return this + } + + minShouldMatch (int: number): this { + this[kState].push(Q.minShouldMatch(int)) + return this + } + + name (queryName: string): this { + this[kState].push(Q.name(queryName)) + return this + } + + nested (path: string, query: any, opts: Record): this { + this[kState].push(Q.nested(path, query, opts)) + return this + } + + constantScore (query: any, boost: number): this { + this[kState].push(Q.constantScore(query, boost)) + return this + } + + disMax (queries: t.AnyQuery[], opts?: Record): this { + this[kState].push(Q.disMax(queries, opts)) + return this + } + + functionScore (function_score: any): this { + this[kState].push(Q.functionScore(function_score)) + return this + } + + boosting (boostOpts: Record): this { + this[kState].push(Q.boosting(boostOpts)) + return this + } + + sort (key: string | any[], opts?: Record): this { + this[kState].push(Q.sort(key)) + return this + } + + size (s: number | Symbol): this { + this[kState].push(Q.size(s)) + return this + } +} + +export default Fluent