@fjell/core 4.4.0 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,305 @@
1
+ import { isPriKey, isItemKeyEqual } from '../key/KUtils.js';
2
+ import LibLogger from '../logger.js';
3
+ import { DateTime } from 'luxon';
4
+ import { isCondition } from './ItemQuery.js';
5
+
6
+ const logger = LibLogger.get('IQUtils');
7
+ /**
8
+ * When we query or search, we're sending a GET request. This converts everything in ItemQuery into a flat
9
+ * object that can be sent over a GET request.
10
+ *
11
+ * Note that there is some discussion about this. Evidently Elastic supports search with POST, but that also
12
+ * feels like a bit of a hack. It's not a RESTful way to do things. So we're sticking with GET for now.
13
+ *
14
+ * For reference, look at RFC 9110 "HTTP Semantics", June which clarified on top of and RFC 7231. It's possible
15
+ * but there are so many caveats and conditions in the standard, it's not worth it.
16
+ *
17
+ * Anticipating the next question - "isn't there a limit to the length of a URL?" The specification does not
18
+ * specify a limit, and there are limits in various browsers and servers - Apache is 4,000 chars, Chrome is 2M chars.
19
+ * Short answer is that if this query is being used to craft something that complex, it is probably a better idea
20
+ * to provide an action or a custom query endpoint on the server.
21
+ *
22
+ * @param query
23
+ * @returns QueryParams ready to be get over a GET request.
24
+ */ const queryToParams = (query)=>{
25
+ const params = {};
26
+ if (query.compoundCondition) {
27
+ params.compoundCondition = JSON.stringify(query.compoundCondition);
28
+ }
29
+ if (query.refs) {
30
+ params.refs = JSON.stringify(query.refs);
31
+ }
32
+ if (query.limit) {
33
+ params.limit = query.limit;
34
+ }
35
+ if (query.offset) {
36
+ params.offset = query.offset;
37
+ }
38
+ if (query.aggs) {
39
+ params.aggs = JSON.stringify(query.aggs);
40
+ }
41
+ if (query.events) {
42
+ params.events = JSON.stringify(query.events);
43
+ }
44
+ return params;
45
+ };
46
+ // This is a dateTimeReviver used for JSON parse - when we convert a param back to a query, we need this.
47
+ const dateTimeReviver = function(key, value) {
48
+ if (typeof value === 'string') {
49
+ const parsedDate = DateTime.fromISO(value);
50
+ if (parsedDate.isValid) {
51
+ return parsedDate.toJSDate();
52
+ }
53
+ }
54
+ return value;
55
+ };
56
+ /**
57
+ * This method translates from a flat QueryParams object with stringify'd JSON back to a full ItemQuery.
58
+ *
59
+ * @param params Parameters sent over a GET request
60
+ * @returns A fully hydrated ItemQuery object.
61
+ */ const paramsToQuery = (params)=>{
62
+ const query = {};
63
+ if (params.compoundCondition) {
64
+ query.compoundCondition = JSON.parse(params.compoundCondition);
65
+ }
66
+ if (params.refs) {
67
+ query.refs = JSON.parse(params.refs);
68
+ }
69
+ if (params.limit) {
70
+ query.limit = Number(params.limit);
71
+ }
72
+ if (params.offset) {
73
+ query.offset = Number(params.offset);
74
+ }
75
+ if (params.aggs) {
76
+ query.aggs = JSON.parse(params.aggs);
77
+ }
78
+ if (params.events) {
79
+ query.events = JSON.parse(params.events, dateTimeReviver);
80
+ }
81
+ return query;
82
+ };
83
+ const isRefQueryMatch = (refKey, queryRef, references)=>{
84
+ logger.trace('doesRefMatch', {
85
+ queryRef,
86
+ references
87
+ });
88
+ logger.debug('Comparing Ref', {
89
+ refKey,
90
+ itemRef: references[refKey],
91
+ queryRef
92
+ });
93
+ return isItemKeyEqual(queryRef, references[refKey]);
94
+ };
95
+ const isCompoundConditionQueryMatch = (queryCondition, item)=>{
96
+ if (queryCondition.compoundType === 'AND') {
97
+ // If this is an AND compound condition, we need to check if all of the conditions match
98
+ return queryCondition.conditions.every((condition)=>isCondition(condition) ? isConditionQueryMatch(condition, item) : isCompoundConditionQueryMatch(condition, item));
99
+ } else {
100
+ // If this is an OR compound condition, we need to check if any of the conditions match
101
+ return queryCondition.conditions.some((condition)=>isCondition(condition) ? isConditionQueryMatch(condition, item) : isCompoundConditionQueryMatch(condition, item));
102
+ }
103
+ };
104
+ const isConditionQueryMatch = (queryCondition, item)=>{
105
+ const propKey = queryCondition.column;
106
+ logger.trace('doesConditionMatch', {
107
+ propKey,
108
+ queryCondition,
109
+ item
110
+ });
111
+ // eslint-disable-next-line no-undefined
112
+ if (item[propKey] === undefined) {
113
+ logger.debug('Item does not contain prop under key', {
114
+ propKey,
115
+ item
116
+ });
117
+ return false;
118
+ }
119
+ logger.debug('Comparing Condition', {
120
+ propKey,
121
+ itemProp: item[propKey],
122
+ queryCondition
123
+ });
124
+ let result = false;
125
+ switch(queryCondition.operator){
126
+ case '==':
127
+ result = item[propKey] === queryCondition.value;
128
+ break;
129
+ case '!=':
130
+ result = item[propKey] !== queryCondition.value;
131
+ break;
132
+ case '>':
133
+ result = item[propKey] > queryCondition.value;
134
+ break;
135
+ case '>=':
136
+ result = item[propKey] >= queryCondition.value;
137
+ break;
138
+ case '<':
139
+ result = item[propKey] < queryCondition.value;
140
+ break;
141
+ case '<=':
142
+ result = item[propKey] <= queryCondition.value;
143
+ break;
144
+ case 'in':
145
+ result = queryCondition.value.includes(item[propKey]);
146
+ break;
147
+ case 'not-in':
148
+ result = !queryCondition.value.includes(item[propKey]);
149
+ break;
150
+ case 'array-contains':
151
+ result = item[propKey].includes(queryCondition.value);
152
+ break;
153
+ case 'array-contains-any':
154
+ result = queryCondition.value.some((value)=>item[propKey].includes(value));
155
+ break;
156
+ }
157
+ return result;
158
+ };
159
+ const isAggQueryMatch = (aggKey, aggQuery, agg)=>{
160
+ const aggItem = agg.item;
161
+ logger.debug('Comparing Agg', {
162
+ aggKey,
163
+ aggItem,
164
+ aggQuery
165
+ });
166
+ // Fancy, right? This is a recursive call to isQueryMatch
167
+ return isQueryMatch(aggItem, aggQuery);
168
+ };
169
+ const isEventQueryMatch = (eventKey, eventQuery, item)=>{
170
+ if (!item.events[eventKey]) {
171
+ logger.debug('Item does not contain event under key', {
172
+ eventKey,
173
+ events: item.events
174
+ });
175
+ return false;
176
+ } else {
177
+ const itemEvent = item.events[eventKey];
178
+ if (itemEvent.at !== null) {
179
+ if (eventQuery.start && !(eventQuery.start.getTime() <= itemEvent.at.getTime())) {
180
+ logger.debug('Item date before event start query', {
181
+ eventQuery,
182
+ itemEvent
183
+ });
184
+ return false;
185
+ }
186
+ if (eventQuery.end && !(eventQuery.end.getTime() > itemEvent.at.getTime())) {
187
+ logger.debug('Item date after event end query', {
188
+ eventQuery,
189
+ itemEvent
190
+ });
191
+ return false;
192
+ }
193
+ } else {
194
+ logger.debug('Item event does contains a null at', {
195
+ itemEvent
196
+ });
197
+ return false;
198
+ }
199
+ return true;
200
+ }
201
+ };
202
+ const isQueryMatch = (item, query)=>{
203
+ logger.trace('isMatch', {
204
+ item,
205
+ query
206
+ });
207
+ if (query.refs && item.refs) {
208
+ for(const key in query.refs){
209
+ const queryRef = query.refs[key];
210
+ if (!isRefQueryMatch(key, queryRef, item.refs)) return false;
211
+ }
212
+ } else if (query.refs && !item.refs) {
213
+ logger.debug('Query contains refs but item does not have refs', {
214
+ query,
215
+ item
216
+ });
217
+ return false;
218
+ }
219
+ if (query.compoundCondition && item) {
220
+ if (!isCompoundConditionQueryMatch(query.compoundCondition, item)) return false;
221
+ }
222
+ if (query.events && item.events) {
223
+ for(const key in query.events){
224
+ const queryEvent = query.events[key];
225
+ if (!isEventQueryMatch(key, queryEvent, item)) return false;
226
+ }
227
+ return true;
228
+ }
229
+ if (query.aggs && item.aggs) {
230
+ for(const key in query.aggs){
231
+ const aggQuery = query.aggs[key];
232
+ if (item.aggs[key] && !isAggQueryMatch(key, aggQuery, item.aggs[key])) return false;
233
+ }
234
+ }
235
+ if (query.aggs && !item.aggs) {
236
+ logger.debug('Query contains aggs but item does not have aggs', {
237
+ query,
238
+ item
239
+ });
240
+ return false;
241
+ }
242
+ // If it hasn't returned false by now, it must be a match
243
+ return true;
244
+ };
245
+ const abbrevQuery = (query)=>{
246
+ const abbrev = [
247
+ 'IQ'
248
+ ];
249
+ if (query) {
250
+ if (query.refs) {
251
+ for(const key in query.refs){
252
+ const ref = abbrevRef(key, query.refs[key]);
253
+ abbrev.push(ref);
254
+ }
255
+ }
256
+ if (query.compoundCondition) {
257
+ const props = abbrevCompoundCondition(query.compoundCondition);
258
+ abbrev.push(props);
259
+ }
260
+ if (query.aggs) {
261
+ for(const key in query.aggs){
262
+ const agg = abbrevAgg(key, query.aggs[key]);
263
+ abbrev.push(agg);
264
+ }
265
+ }
266
+ if (query.events) {
267
+ const events = `(E${Object.keys(query.events).join(',')})`;
268
+ abbrev.push(events);
269
+ }
270
+ if (query.limit) {
271
+ abbrev.push(`L${query.limit}`);
272
+ }
273
+ if (query.offset) {
274
+ abbrev.push(`O${query.offset}`);
275
+ }
276
+ } else {
277
+ abbrev.push('(empty)');
278
+ }
279
+ return abbrev.join(' ');
280
+ };
281
+ const abbrevRef = (key, ref)=>{
282
+ if (isPriKey(ref)) {
283
+ const priKey = ref;
284
+ return `R(${key},${priKey.kt},${priKey.pk})`;
285
+ } else {
286
+ const comKey = ref;
287
+ return `R(${key},${JSON.stringify(comKey)})`;
288
+ }
289
+ };
290
+ const abbrevAgg = (key, agg)=>{
291
+ return `A(${key},${abbrevQuery(agg)})`;
292
+ };
293
+ const abbrevCompoundCondition = (compoundCondition)=>{
294
+ return `CC(${compoundCondition.compoundType},` + `${compoundCondition.conditions ? compoundCondition.conditions.map(abbrevCondition).join(',') : 'No Conditions'})`;
295
+ };
296
+ const abbrevCondition = (condition)=>{
297
+ if (isCondition(condition)) {
298
+ return `(${condition.column},${condition.value},${condition.operator})`;
299
+ } else {
300
+ return abbrevCompoundCondition(condition);
301
+ }
302
+ };
303
+
304
+ export { abbrevAgg, abbrevCompoundCondition, abbrevCondition, abbrevQuery, abbrevRef, isQueryMatch, paramsToQuery, queryToParams };
305
+ //# sourceMappingURL=IQUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IQUtils.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,6 @@
1
+ import { Item } from '../items';
2
+ import { AllItemTypeArrays } from '../keys';
3
+ export declare const validatePK: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(input: Item<S, L1, L2, L3, L4, L5> | Item<S, L1, L2, L3, L4, L5>[], pkType: S) => Item<S, L1, L2, L3, L4, L5> | Item<S, L1, L2, L3, L4, L5>[];
4
+ export declare const validateKeys: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(item: Item<S, L1, L2, L3, L4, L5>, keyTypes: AllItemTypeArrays<S, L1, L2, L3, L4, L5>) => Item<S, L1, L2, L3, L4, L5>;
5
+ export declare const isPriItem: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(item: Item<S, L1, L2, L3, L4, L5>) => item is Item<S, L1, L2, L3, L4, L5>;
6
+ export declare const isComItem: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(item: Item<S, L1, L2, L3, L4, L5>) => item is Item<S, L1, L2, L3, L4, L5>;
@@ -0,0 +1,77 @@
1
+ import { toKeyTypeArray, isPriKey, isComKey } from '../key/KUtils.js';
2
+ import LibLogger from '../logger.js';
3
+
4
+ const logger = LibLogger.get('IUtils');
5
+ const validatePK = (input, pkType)=>{
6
+ logger.trace('Checking Return Type', {
7
+ input
8
+ });
9
+ if (Array.isArray(input)) {
10
+ const itemArray = input;
11
+ return itemArray.map((item)=>validatePK(item, pkType));
12
+ } else {
13
+ const item = input;
14
+ if (item) {
15
+ if (item.key) {
16
+ const keyTypeArray = toKeyTypeArray(item.key);
17
+ const match = keyTypeArray[0] === pkType;
18
+ if (!match) {
19
+ logger.error('Key Type Array Mismatch', {
20
+ keyTypeArray,
21
+ pkType
22
+ });
23
+ throw new Error('Item does not have the correct primary key type');
24
+ } else {
25
+ return item;
26
+ }
27
+ } else {
28
+ logger.error('Validating PK, Item does not have a key', {
29
+ item
30
+ });
31
+ throw new Error('Validating PK, Item does not have a key');
32
+ }
33
+ } else {
34
+ logger.error('Validating PK, Item is undefined', {
35
+ item
36
+ });
37
+ throw new Error('Validating PK, Item is undefined');
38
+ }
39
+ }
40
+ };
41
+ const validateKeys = (item, keyTypes)=>{
42
+ logger.trace('Checking Return Type', {
43
+ item
44
+ });
45
+ if (item) {
46
+ if (item.key) {
47
+ const keyTypeArray = toKeyTypeArray(item.key);
48
+ if (keyTypeArray.length !== keyTypes.length) {
49
+ throw new Error('Item does not have the correct number of keys');
50
+ } else {
51
+ const match = JSON.stringify(keyTypeArray) === JSON.stringify(keyTypes);
52
+ if (!match) {
53
+ logger.error('Key Type Array Mismatch', {
54
+ keyTypeArray,
55
+ thisKeyTypes: keyTypes
56
+ });
57
+ throw new Error('Item does not have the correct key types');
58
+ } else {
59
+ return item;
60
+ }
61
+ }
62
+ } else {
63
+ throw new Error('validating keys, item does not have a key: ' + JSON.stringify(item));
64
+ }
65
+ } else {
66
+ throw new Error('validating keys, item is undefined');
67
+ }
68
+ };
69
+ const isPriItem = (item)=>{
70
+ return item && item.key ? isPriKey(item.key) : false;
71
+ };
72
+ const isComItem = (item)=>{
73
+ return item && item.key ? isComKey(item.key) : false;
74
+ };
75
+
76
+ export { isComItem, isPriItem, validateKeys, validatePK };
77
+ //# sourceMappingURL=IUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IUtils.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,62 @@
1
+ import { References } from '../items';
2
+ export type QueryParams = Record<string, string | number | boolean | Date>;
3
+ /**
4
+ * The operator for a condition. This is the same as the operators used in the Firestore query language.
5
+ */
6
+ export type ConditionOperator = '==' | '!=' | '>' | '>=' | '<' | '<=' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
7
+ /**
8
+ * A single property condition is defined with a column, value, and operator.
9
+ * This is a condition that is used in a query.
10
+ */
11
+ export type Condition = {
12
+ column: string;
13
+ value: string[] | string | number[] | number | boolean | Date;
14
+ operator: ConditionOperator;
15
+ };
16
+ /**
17
+ * When applying a compound condition, the CompoundType defines the type of compound condition.
18
+ */
19
+ export type CompoundType = 'AND' | 'OR';
20
+ /**
21
+ * When configuring a CompoundCondition this can contain a collection of conditions
22
+ * that will be applied to the query. By default, this is an AND conditiion that is associated
23
+ * with an array of Condition objects OR an array of CompoundCondition objects.
24
+ *
25
+ * For example, I could have { compoundType: 'AND', conditions: [{column: 'name', value: 'test', operator: '=='},
26
+ * {column: 'age', value: 21, operator: '>='}]} which would filter the query to only include items
27
+ * where the name is 'test' and the age is greater than or equal to 21.
28
+ *
29
+ * Or, I could have a { compoundType: 'OR', conditions: [{column: 'name', value: 'test', operator: '=='},
30
+ * {column: 'age', value: 21, operator: '>='}]} which would filter the query to only include items
31
+ * where the name is 'test' OR the age is greater than or equal to 21.
32
+ *
33
+ * I could also nest an OR within an AND, like this:
34
+ * ['AND', [{column: 'name', value: 'test', operator: '=='},
35
+ * { compoundType: 'OR', conditions: [{column: 'age', value: 21, operator: '<='},
36
+ * {column: 'age', value: 52, operator: '>='}]}]] which would filter the query to only include items where the
37
+ * name is 'test' and the age is less than or equal to 21 or greater than or equal to 52.
38
+ */
39
+ export type CompoundCondition = {
40
+ compoundType: CompoundType;
41
+ conditions: Array<Condition | CompoundCondition>;
42
+ };
43
+ export declare const isCondition: (condition: any) => condition is Condition;
44
+ export type EventQuery = {
45
+ start?: Date;
46
+ end?: Date;
47
+ by?: string;
48
+ };
49
+ export type OrderDirection = 'asc' | 'desc';
50
+ export type OrderBy = {
51
+ field: string;
52
+ direction: OrderDirection;
53
+ };
54
+ export type ItemQuery = {
55
+ refs?: References;
56
+ compoundCondition?: CompoundCondition;
57
+ limit?: number;
58
+ offset?: number;
59
+ aggs?: Record<string, ItemQuery>;
60
+ events?: Record<string, EventQuery>;
61
+ orderBy?: OrderBy[];
62
+ };
@@ -0,0 +1,6 @@
1
+ const isCondition = (condition)=>{
2
+ return (typeof condition.column === 'string' && Array.isArray(condition.value) && condition.value.every((item)=>typeof item === 'string') || Array.isArray(condition.value) && condition.value.every((item)=>typeof item === 'number') || typeof condition.value === 'string' || typeof condition.value === 'number' || typeof condition.value === 'boolean' || condition.value instanceof Date) && (condition.operator ? typeof condition.operator === 'string' : true);
3
+ };
4
+
5
+ export { isCondition };
6
+ //# sourceMappingURL=ItemQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ItemQuery.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -0,0 +1,51 @@
1
+ import { ComKey, PriKey } from './keys';
2
+ export type RecursivePartial<T> = {
3
+ [P in keyof T]?: T[P] extends (infer U)[] ? RecursivePartial<U>[] : T[P] extends object | undefined ? RecursivePartial<T[P]> : T[P];
4
+ };
5
+ export type Identified<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = {
6
+ key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>;
7
+ };
8
+ export type Propertied = {
9
+ [key: string]: any;
10
+ };
11
+ /**
12
+ * This is a generic item event, and it's designed to make sure we have the ability to define not just
13
+ * the required fields, but also the optional fields.
14
+ */
15
+ export interface ItemEvent {
16
+ at: Date | null;
17
+ by?: ComKey<any, any | never, any | never, any | never, any | never, any | never> | PriKey<any>;
18
+ agg?: Item<any, any, any, any, any, any>;
19
+ }
20
+ /**
21
+ * This is a required item event, and it's here mainly to define that there are events that must be present.
22
+ */
23
+ export interface RequiredItemEvent extends ItemEvent {
24
+ at: Date;
25
+ }
26
+ export type Evented = Record<string, ItemEvent>;
27
+ export interface Timestamped extends Evented {
28
+ created: RequiredItemEvent;
29
+ updated: RequiredItemEvent;
30
+ }
31
+ export interface Deletable extends Partial<Evented> {
32
+ deleted: ItemEvent;
33
+ }
34
+ export type ManagedEvents = Timestamped & Deletable;
35
+ export type ItemProperties<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = Omit<Item<S, L1, L2, L3, L4, L5>, 'events' | 'key'> & {
36
+ events?: Evented;
37
+ };
38
+ export type TypesProperties<V extends Item<S, L1, L2, L3, L4, L5>, S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = Omit<V, 'events' | 'key'> & {
39
+ events?: Evented;
40
+ };
41
+ export type References = Record<string, ComKey<string, string | never, string | never, string | never, string | never, string | never> | PriKey<string>>;
42
+ export type ReferenceItem<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = {
43
+ key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>;
44
+ item: Item<S, L1, L2, L3, L4, L5>;
45
+ };
46
+ export type ReferenceItems = Record<string, ReferenceItem<string, string | never, string | never, string | never, string | never, string | never>>;
47
+ export interface Item<S extends string = never, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends Identified<S, L1, L2, L3, L4, L5>, Propertied {
48
+ events: ManagedEvents & Evented;
49
+ aggs?: ReferenceItems;
50
+ refs?: References;
51
+ }
@@ -0,0 +1,35 @@
1
+ import { ComKey, LocKey, LocKeyArray, PriKey } from '../keys';
2
+ export declare const isItemKeyEqual: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(a: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, b: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => boolean;
3
+ export declare const isPriKeyEqual: <S extends string>(a: PriKey<S>, b: PriKey<S>) => boolean;
4
+ export declare const isLocKeyEqual: <L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(a: LocKey<L1 | L2 | L3 | L4 | L5>, b: LocKey<L1 | L2 | L3 | L4 | L5>) => boolean;
5
+ export declare const isComKeyEqual: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(a: ComKey<S, L1, L2, L3, L4, L5>, b: ComKey<S, L1, L2, L3, L4, L5>) => boolean;
6
+ export declare const isItemKey: (key: any) => boolean;
7
+ export declare const isComKey: (key: any) => boolean;
8
+ export declare const isPriKey: (key: any) => boolean;
9
+ export declare const isLocKey: (key: any) => boolean;
10
+ export declare const generateKeyArray: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S> | LocKeyArray<L1, L2, L3, L4, L5> | []) => Array<PriKey<S> | LocKey<L1 | L2 | L3 | L4 | L5>>;
11
+ export declare const constructPriKey: <S extends string>(pk: string | PriKey<S>, kt: S) => PriKey<S>;
12
+ export declare const cPK: <S extends string>(pk: string | PriKey<S>, kt: S) => PriKey<S>;
13
+ export declare const toKeyTypeArray: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>) => string[];
14
+ export declare const abbrevIK: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(ik: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;
15
+ export declare const abbrevLKA: <L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(keyArray: Array<LocKey<L1 | L2 | L3 | L4 | L5>> | null) => string;
16
+ export declare const primaryType: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(ik: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;
17
+ /**
18
+ *
19
+ * @param ik ItemKey to be used as a basis for a location
20
+ * @returns
21
+ */
22
+ export declare const itemKeyToLocKeyArray: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>) => LocKeyArray<S, L1, L2, L3, L4>;
23
+ export declare const ikToLKA: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>) => LocKeyArray<S, L1, L2, L3, L4>;
24
+ /**
25
+ * Sometimes you need to take a location key array and convert it to the item key that points to the containing item.
26
+ * @param lka A location key array
27
+ * @returns An item key corresponding to the containing item this location refers to.
28
+ */
29
+ export declare const locKeyArrayToItemKey: <L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(lka: LocKeyArray<L1, L2, L3, L4, L5>) => PriKey<L1> | ComKey<L1, L2, L3, L4, L5>;
30
+ export declare const isValidPriKey: <S extends string>(key: PriKey<S>) => boolean;
31
+ export declare const isValidLocKey: <L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(key: LocKey<L1 | L2 | L3 | L4 | L5>) => boolean;
32
+ export declare const isValidLocKeyArray: <L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(keyArray: Array<LocKey<L1 | L2 | L3 | L4 | L5>>) => boolean;
33
+ export declare const isValidComKey: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(key: ComKey<S, L1, L2, L3, L4, L5>) => boolean;
34
+ export declare const isValidItemKey: <S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => boolean;
35
+ export declare const lkaToIK: <L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(lka: LocKeyArray<L1, L2, L3, L4, L5>) => PriKey<L1> | ComKey<L1, L2, L3, L4, L5>;