Browse Source

build dist

Aneurin Barker Snook 2 năm trước cách đây
mục cha
commit
dd3d36a240
2 tập tin đã thay đổi với 54 bổ sung14 xóa
  1. 40 6
      dist/lib/index.d.ts
  2. 14 8
      dist/lib/index.js

+ 40 - 6
dist/lib/index.d.ts

@@ -1,13 +1,13 @@
 import { Document } from 'arangojs/documents';
 import { DocumentCollection } from 'arangojs/collection';
-import { GeneratedAqlQuery } from 'arangojs/aql';
+import { AqlLiteral, GeneratedAqlQuery } from 'arangojs/aql';
 import { Database } from 'arangojs';
 /**
  * A `CountFn` function returns the number of documents in a single collection matching search `terms` given.
  *
  * `count()` provides the standard implementation.
  */
-export declare type CountFn<T extends Searchable, S extends Searchable = T> = (terms?: Terms<Document<DeepNonNullable<S>>>) => Promise<number>;
+export declare type CountFn<T extends Searchable, S extends Searchable = T> = (terms?: Terms<Document<DeepNonNullable<S>>>, inject?: Inject) => Promise<number>;
 /**
  * Recursively renders all of a complex object's properties required, non-null, and non-undefined.
  *
@@ -48,7 +48,26 @@ export declare type Filter<T> = {
  *
  * `find()` provides the standard implementation.
  */
-export declare type FindFn<T extends Searchable, S extends Searchable = T> = (terms?: Terms<Document<DeepNonNullable<S>>>, sort?: Sort<Document<T>>[] | Sort<Document<T>>) => Promise<Document<T> | undefined>;
+export declare type FindFn<T extends Searchable, S extends Searchable = T> = (terms?: Terms<Document<DeepNonNullable<S>>>, sort?: Sort<Document<T>>[] | Sort<Document<T>>, inject?: Inject) => Promise<Document<T> | undefined>;
+/**
+ * An `Inject` object allows modifying a search query with user-defined AQL literal expressions.
+ * This can be useful for complex requirements, such as joining data or setting additional variables with `LET`.
+ *
+ * All injected strings are implicitly converted to AQL literals in the query, so should be manually escaped as needed.
+ *
+ * Note that while `CountFn` and `FindFn` do not use all the same parameters as `SearchFn`, all injections are still
+ * supported so a single injection provider can be used for all query types.
+ */
+export declare type Inject = {
+    /** Injected before FILTER statements. */
+    beforeFilter?: string;
+    /** Injected after FILTER statements, before SORT statements. */
+    beforeSort?: string;
+    /** Injected after SORT statements, before LIMIT statement. */
+    beforeLimit?: string;
+    /** Injected after all other statements. */
+    after?: string;
+};
 /**
  * Query limit.
  * Always a tuple, but the second value can be omitted.
@@ -69,8 +88,18 @@ export declare type Terms<T> = {
 /**
  * A `SearchFn` function matches documents in a single collection and returns a `SearchResult` based on the given
  * `terms`, `limit`, and `sort`.
+ *
+ * A fourth `inject` argument can be given to add user-defined sections to the query, allowing complex requirements
+ * to be added around the core query pattern.
+ */
+export declare type SearchFn<T extends Searchable, S extends Searchable = T> = (terms?: Terms<Document<DeepNonNullable<S>>>, limit?: Limit, sort?: Sort<Document<S>>[] | Sort<Document<S>>, inject?: Inject) => Promise<SearchResult<T>>;
+/**
+ * A `SimpleSearchFn` function matches documents in a single collection and returns a `SearchResult` based on the given
+ * `terms`, `limit`, and `sort`.
+ *
+ * This type can be implemented by user code as an alternative to `SearchFn` to prevent further injections.
  */
-export declare type SearchFn<T extends Searchable, S extends Searchable = T> = (terms?: Terms<Document<DeepNonNullable<S>>>, limit?: Limit, sort?: Sort<Document<S>>[] | Sort<Document<S>>) => Promise<SearchResult<T>>;
+export declare type SimpleSearchFn<T extends Searchable, S extends Searchable = T> = (terms?: Terms<Document<DeepNonNullable<S>>>, limit?: Limit, sort?: Sort<Document<S>>[] | Sort<Document<S>>) => Promise<SearchResult<T>>;
 /**
  * Search results are a tuple of three values:
  *   1. The **total** number of matching documents in the searched collection, ignoring limit
@@ -78,8 +107,13 @@ export declare type SearchFn<T extends Searchable, S extends Searchable = T> = (
  *   3. The AQL query object for the latter (for debugging purposes)
  */
 export declare type SearchResult<T extends Searchable> = [number, Document<T>[], GeneratedAqlQuery];
-/** Query sort order. */
-export declare type Sort<T> = [keyof T, Direction];
+/**
+ * Query sort order as a tuple of key and direction.
+ *
+ * The sort key can be specified as an AQL literal, in which case it will be used exactly as given.
+ * This can be useful in conjunction with query injections.
+ */
+export declare type Sort<T> = [AqlLiteral | keyof T, Direction];
 /** Format scalar or scalar array data for use in AQL. */
 export declare const formatData: <T>(data: T | T[]) => string;
 /** Format scalar data for use in AQL. */

+ 14 - 8
dist/lib/index.js

@@ -109,7 +109,7 @@ var parseFilterOps = function (search) {
  */
 var parseSort = function (s, parent) {
     if (s[0] instanceof Array)
-        return s.map(function (ss) { return "".concat(parent, ".").concat(String(ss[0]), " ").concat(ss[1]); });
+        return s.map(function (ss) { return "".concat(renderSortKey(ss, parent), " ").concat(ss[1]); });
     return ["".concat(parent, ".").concat(String(s[0]), " ").concat(s[1])];
 };
 exports.parseSort = parseSort;
@@ -133,6 +133,12 @@ var parseTerms = function (s, parent) { return Object.keys(s)
     return filters;
 }, []); };
 exports.parseTerms = parseTerms;
+var renderSortKey = function (_a, parent) {
+    var key = _a[0];
+    if (key instanceof Object)
+        return key.toAQL();
+    return "".concat(parent, ".").concat(String(key));
+};
 /**
  * Build and execute a count query that matches documents in a single collection.
  * Returns the total number of matches.
@@ -146,7 +152,7 @@ exports.parseTerms = parseTerms;
 var count = function (db, c, i, n) {
     if (i === void 0) { i = 'i'; }
     if (n === void 0) { n = 'n'; }
-    return function (terms) { return __awaiter(void 0, void 0, void 0, function () {
+    return function (terms, inject) { return __awaiter(void 0, void 0, void 0, function () {
         var filters, filterStr, l, countQuery;
         return __generator(this, function (_a) {
             switch (_a.label) {
@@ -154,7 +160,7 @@ var count = function (db, c, i, n) {
                     filters = terms && (0, exports.parseTerms)(terms, i);
                     filterStr = arangojs_1.aql.literal(filters ? filters.map(function (f) { return "FILTER ".concat(f); }).join(' ') : '');
                     l = { i: arangojs_1.aql.literal(i), n: arangojs_1.aql.literal(n) };
-                    countQuery = (0, arangojs_1.aql)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n      FOR ", " IN ", "\n        ", "\n        COLLECT WITH COUNT INTO ", "\n        RETURN ", "\n    "], ["\n      FOR ", " IN ", "\n        ", "\n        COLLECT WITH COUNT INTO ", "\n        RETURN ", "\n    "])), l.i, c, filterStr, l.n, l.n);
+                    countQuery = (0, arangojs_1.aql)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        COLLECT WITH COUNT INTO ", "\n        RETURN ", "\n    "], ["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        COLLECT WITH COUNT INTO ", "\n        RETURN ", "\n    "])), l.i, c, (inject === null || inject === void 0 ? void 0 : inject.beforeFilter) && arangojs_1.aql.literal(inject.beforeFilter), filterStr, (inject === null || inject === void 0 ? void 0 : inject.beforeSort) && arangojs_1.aql.literal(inject.beforeSort), (inject === null || inject === void 0 ? void 0 : inject.beforeLimit) && arangojs_1.aql.literal(inject.beforeLimit), (inject === null || inject === void 0 ? void 0 : inject.after) && arangojs_1.aql.literal(inject.after), l.n, l.n);
                     return [4 /*yield*/, db.query(countQuery)];
                 case 1: return [4 /*yield*/, (_a.sent()).next()];
                 case 2: return [2 /*return*/, _a.sent()];
@@ -174,7 +180,7 @@ exports.count = count;
  */
 var find = function (db, c, i) {
     if (i === void 0) { i = 'i'; }
-    return function (terms, sort) {
+    return function (terms, sort, inject) {
         if (sort === void 0) { sort = ['_key', 'ASC']; }
         return __awaiter(void 0, void 0, void 0, function () {
             var filters, filterStr, sortStr, l, query, data;
@@ -185,7 +191,7 @@ var find = function (db, c, i) {
                         filterStr = arangojs_1.aql.literal(filters ? filters.map(function (f) { return "FILTER ".concat(f); }).join(' ') : '');
                         sortStr = arangojs_1.aql.literal(sort ? "SORT ".concat((0, exports.parseSort)(sort, 'i').join(', ')) : '');
                         l = { i: arangojs_1.aql.literal(i) };
-                        query = (0, arangojs_1.aql)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        LIMIT 1\n        RETURN ", "\n    "], ["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        LIMIT 1\n        RETURN ", "\n    "])), l.i, c, filterStr, sortStr, l.i);
+                        query = (0, arangojs_1.aql)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        LIMIT 1\n        RETURN ", "\n    "], ["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        LIMIT 1\n        RETURN ", "\n    "])), l.i, c, (inject === null || inject === void 0 ? void 0 : inject.beforeFilter) && arangojs_1.aql.literal(inject.beforeFilter), filterStr, (inject === null || inject === void 0 ? void 0 : inject.beforeSort) && arangojs_1.aql.literal(inject.beforeSort), sortStr, (inject === null || inject === void 0 ? void 0 : inject.beforeLimit) && arangojs_1.aql.literal(inject.beforeLimit), (inject === null || inject === void 0 ? void 0 : inject.after) && arangojs_1.aql.literal(inject.after), l.i);
                         return [4 /*yield*/, db.query(query)];
                     case 1: return [4 /*yield*/, (_a.sent()).next()];
                     case 2:
@@ -211,7 +217,7 @@ exports.find = find;
 var search = function (db, c, i, n) {
     if (i === void 0) { i = 'i'; }
     if (n === void 0) { n = 'n'; }
-    return function (terms, limit, sort) {
+    return function (terms, limit, sort, inject) {
         if (sort === void 0) { sort = ['_rev', 'ASC']; }
         return __awaiter(void 0, void 0, void 0, function () {
             var filters, filterStr, limitStr, sortStr, l, count, countQuery, query, data;
@@ -225,14 +231,14 @@ var search = function (db, c, i, n) {
                         l = { i: arangojs_1.aql.literal(i), n: arangojs_1.aql.literal(n) };
                         count = 0;
                         if (!limit) return [3 /*break*/, 3];
-                        countQuery = (0, arangojs_1.aql)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n        FOR ", " IN ", "\n          ", "\n          COLLECT WITH COUNT INTO ", "\n          RETURN ", "\n      "], ["\n        FOR ", " IN ", "\n          ", "\n          COLLECT WITH COUNT INTO ", "\n          RETURN ", "\n      "])), l.i, c, filterStr, l.n, l.n);
+                        countQuery = (0, arangojs_1.aql)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n        FOR ", " IN ", "\n          ", "\n          ", "\n          ", "\n          ", "\n          ", "\n          COLLECT WITH COUNT INTO ", "\n          RETURN ", "\n      "], ["\n        FOR ", " IN ", "\n          ", "\n          ", "\n          ", "\n          ", "\n          ", "\n          COLLECT WITH COUNT INTO ", "\n          RETURN ", "\n      "])), l.i, c, (inject === null || inject === void 0 ? void 0 : inject.beforeFilter) && arangojs_1.aql.literal(inject.beforeFilter), filterStr, (inject === null || inject === void 0 ? void 0 : inject.beforeSort) && arangojs_1.aql.literal(inject.beforeSort), (inject === null || inject === void 0 ? void 0 : inject.beforeLimit) && arangojs_1.aql.literal(inject.beforeLimit), (inject === null || inject === void 0 ? void 0 : inject.after) && arangojs_1.aql.literal(inject.after), l.n, l.n);
                         return [4 /*yield*/, db.query(countQuery)];
                     case 1: return [4 /*yield*/, (_a.sent()).next()];
                     case 2:
                         count = _a.sent();
                         _a.label = 3;
                     case 3:
-                        query = (0, arangojs_1.aql)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        ", "\n        RETURN ", "\n    "], ["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        ", "\n        RETURN ", "\n    "])), l.i, c, filterStr, sortStr, limitStr, l.i);
+                        query = (0, arangojs_1.aql)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        RETURN ", "\n    "], ["\n      FOR ", " IN ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        ", "\n        RETURN ", "\n    "])), l.i, c, (inject === null || inject === void 0 ? void 0 : inject.beforeFilter) && arangojs_1.aql.literal(inject.beforeFilter), filterStr, (inject === null || inject === void 0 ? void 0 : inject.beforeSort) && arangojs_1.aql.literal(inject.beforeSort), sortStr, (inject === null || inject === void 0 ? void 0 : inject.beforeLimit) && arangojs_1.aql.literal(inject.beforeLimit), limitStr, (inject === null || inject === void 0 ? void 0 : inject.after) && arangojs_1.aql.literal(inject.after), l.i);
                         return [4 /*yield*/, db.query(query)];
                     case 4: return [4 /*yield*/, (_a.sent()).all()];
                     case 5: