UNPKG

3.48 kBJavaScriptView Raw
1"use strict";
2// Copyright IBM Corp. and LoopBack contributors 2019. All Rights Reserved.
3// Node module: @loopback/context
4// This file is licensed under the MIT License.
5// License text available at https://opensource.org/licenses/MIT
6Object.defineProperty(exports, "__esModule", { value: true });
7exports.sortBindingsByPhase = exports.compareByOrder = exports.compareBindingsByTag = void 0;
8/**
9 * Creates a binding compare function to sort bindings by tagged phase name.
10 *
11 * @remarks
12 * Two bindings are compared as follows:
13 *
14 * 1. Get values for the given tag as `phase` for bindings, if the tag is not
15 * present, default `phase` to `''`.
16 * 2. If both bindings have `phase` value in `orderOfPhases`, honor the order
17 * specified by `orderOfPhases`.
18 * 3. If a binding's `phase` does not exist in `orderOfPhases`, it comes before
19 * the one with `phase` exists in `orderOfPhases`.
20 * 4. If both bindings have `phase` value outside of `orderOfPhases`, they are
21 * ordered by phase names alphabetically and symbol values come before string
22 * values.
23 *
24 * @param phaseTagName - Name of the binding tag for phase
25 * @param orderOfPhases - An array of phase names as the predefined order
26 */
27function compareBindingsByTag(phaseTagName = 'phase', orderOfPhases = []) {
28 return (a, b) => {
29 return compareByOrder(a.tagMap[phaseTagName], b.tagMap[phaseTagName], orderOfPhases);
30 };
31}
32exports.compareBindingsByTag = compareBindingsByTag;
33/**
34 * Compare two values by the predefined order
35 *
36 * @remarks
37 *
38 * The comparison is performed as follows:
39 *
40 * 1. If both values are included in `order`, they are sorted by their indexes in
41 * `order`.
42 * 2. The value included in `order` comes after the value not included in `order`.
43 * 3. If neither values are included in `order`, they are sorted:
44 * - symbol values come before string values
45 * - alphabetical order for two symbols or two strings
46 *
47 * @param a - First value
48 * @param b - Second value
49 * @param order - An array of values as the predefined order
50 */
51function compareByOrder(a, b, order = []) {
52 a = a !== null && a !== void 0 ? a : '';
53 b = b !== null && b !== void 0 ? b : '';
54 const i1 = order.indexOf(a);
55 const i2 = order.indexOf(b);
56 if (i1 !== -1 || i2 !== -1) {
57 // Honor the order
58 return i1 - i2;
59 }
60 else {
61 // Neither value is in the pre-defined order
62 // symbol comes before string
63 if (typeof a === 'symbol' && typeof b === 'string')
64 return -1;
65 if (typeof a === 'string' && typeof b === 'symbol')
66 return 1;
67 // both a and b are symbols or both a and b are strings
68 if (typeof a === 'symbol')
69 a = a.toString();
70 if (typeof b === 'symbol')
71 b = b.toString();
72 return a < b ? -1 : a > b ? 1 : 0;
73 }
74}
75exports.compareByOrder = compareByOrder;
76/**
77 * Sort bindings by phase names denoted by a tag and the predefined order
78 *
79 * @param bindings - An array of bindings
80 * @param phaseTagName - Tag name for phase, for example, we can use the value
81 * `'a'` of tag `order` as the phase name for `binding.tag({order: 'a'})`.
82 *
83 * @param orderOfPhases - An array of phase names as the predefined order
84 */
85function sortBindingsByPhase(bindings, phaseTagName, orderOfPhases) {
86 return bindings.sort(compareBindingsByTag(phaseTagName, orderOfPhases));
87}
88exports.sortBindingsByPhase = sortBindingsByPhase;
89//# sourceMappingURL=binding-sorter.js.map
\No newline at end of file