@fjell/core 4.4.63 → 4.4.64
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.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +28 -14
- package/dist/operations/Operations.d.ts +142 -11
- package/dist/operations/contained.d.ts +2 -2
- package/dist/operations/methods.d.ts +27 -3
- package/dist/operations/primary.d.ts +2 -2
- package/dist/operations/wrappers/createAllWrapper.d.ts +3 -3
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export * from './validation';
|
|
|
15
15
|
export * from './errors';
|
|
16
16
|
export * from './operations';
|
|
17
17
|
export * from './event';
|
|
18
|
-
export type { Operations, OperationParams, AffectedKeys, CreateOptions, UpdateOptions } from './operations/Operations';
|
|
18
|
+
export type { Operations, OperationParams, AffectedKeys, CreateOptions, UpdateOptions, AllOptions, PaginationMetadata, AllOperationResult } from './operations/Operations';
|
|
19
19
|
export { isPriKey as isOperationPriKey, isComKey as isOperationComKey } from './operations/Operations';
|
|
20
20
|
export type { GetMethod, CreateMethod, UpdateMethod, RemoveMethod, UpsertMethod, AllMethod, OneMethod, FindMethod, FindOneMethod, FinderMethod, ActionMethod, ActionOperationMethod, AllActionMethod, AllActionOperationMethod, FacetMethod, FacetOperationMethod, AllFacetMethod, AllFacetOperationMethod, OperationsExtensions } from './operations/methods';
|
|
21
21
|
export * from './operations/wrappers';
|
package/dist/index.js
CHANGED
|
@@ -1826,35 +1826,49 @@ function createOneWrapper(coordinate, implementation, options = {}) {
|
|
|
1826
1826
|
|
|
1827
1827
|
// src/operations/wrappers/createAllWrapper.ts
|
|
1828
1828
|
var logger10 = logger_default.get("operations", "wrappers", "all");
|
|
1829
|
-
function createAllWrapper(coordinate, implementation,
|
|
1830
|
-
const operationName =
|
|
1831
|
-
return async (query, locations) => {
|
|
1832
|
-
if (
|
|
1833
|
-
logger10.debug(`[${operationName}] Called with:`, { query, locations });
|
|
1829
|
+
function createAllWrapper(coordinate, implementation, wrapperOptions = {}) {
|
|
1830
|
+
const operationName = wrapperOptions.operationName || "all";
|
|
1831
|
+
return async (query, locations, allOptions) => {
|
|
1832
|
+
if (wrapperOptions.debug) {
|
|
1833
|
+
logger10.debug(`[${operationName}] Called with:`, { query, locations, allOptions });
|
|
1834
1834
|
}
|
|
1835
|
-
if (!
|
|
1835
|
+
if (!wrapperOptions.skipValidation) {
|
|
1836
1836
|
validateQuery(query, operationName);
|
|
1837
1837
|
validateLocations(locations, coordinate, operationName);
|
|
1838
|
+
if (allOptions && "limit" in allOptions && allOptions.limit != null) {
|
|
1839
|
+
if (!Number.isInteger(allOptions.limit) || allOptions.limit < 1) {
|
|
1840
|
+
throw new Error(`[${operationName}] limit must be a positive integer, got: ${allOptions.limit}`);
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
if (allOptions && "offset" in allOptions && allOptions.offset != null) {
|
|
1844
|
+
if (!Number.isInteger(allOptions.offset) || allOptions.offset < 0) {
|
|
1845
|
+
throw new Error(`[${operationName}] offset must be a non-negative integer, got: ${allOptions.offset}`);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1838
1848
|
}
|
|
1839
1849
|
const normalizedQuery = query ?? {};
|
|
1840
1850
|
const normalizedLocations = locations ?? [];
|
|
1841
1851
|
try {
|
|
1842
|
-
const result = await implementation(normalizedQuery, normalizedLocations);
|
|
1843
|
-
if (
|
|
1844
|
-
logger10.debug(`[${operationName}] Result: ${result.length} items`);
|
|
1852
|
+
const result = await implementation(normalizedQuery, normalizedLocations, allOptions);
|
|
1853
|
+
if (wrapperOptions.debug) {
|
|
1854
|
+
logger10.debug(`[${operationName}] Result: ${result.items.length} items, total: ${result.metadata.total}`);
|
|
1845
1855
|
}
|
|
1846
|
-
if (!
|
|
1847
|
-
|
|
1856
|
+
if (!wrapperOptions.skipValidation) {
|
|
1857
|
+
const validatedItems = validatePK(result.items, coordinate.kta[0]);
|
|
1858
|
+
return {
|
|
1859
|
+
items: validatedItems,
|
|
1860
|
+
metadata: result.metadata
|
|
1861
|
+
};
|
|
1848
1862
|
}
|
|
1849
1863
|
return result;
|
|
1850
1864
|
} catch (error) {
|
|
1851
|
-
if (
|
|
1865
|
+
if (wrapperOptions.onError) {
|
|
1852
1866
|
const context = {
|
|
1853
1867
|
operationName,
|
|
1854
|
-
params: [query, locations],
|
|
1868
|
+
params: [query, locations, allOptions],
|
|
1855
1869
|
coordinate
|
|
1856
1870
|
};
|
|
1857
|
-
throw
|
|
1871
|
+
throw wrapperOptions.onError(error, context);
|
|
1858
1872
|
}
|
|
1859
1873
|
throw new Error(
|
|
1860
1874
|
`[${operationName}] Operation failed: ${error.message}`,
|
|
@@ -19,6 +19,124 @@ export type CreateOptions<S extends string, L1 extends string = never, L2 extend
|
|
|
19
19
|
key?: never;
|
|
20
20
|
locations: LocKeyArray<L1, L2, L3, L4, L5>;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Options for the all() operation to control pagination.
|
|
24
|
+
*
|
|
25
|
+
* When provided, these options take precedence over any limit/offset
|
|
26
|
+
* specified in the ItemQuery.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* // Fetch first 50 items
|
|
33
|
+
* const result = await operations.all(query, [], { limit: 50, offset: 0 });
|
|
34
|
+
*
|
|
35
|
+
* // Fetch next page
|
|
36
|
+
* const nextPage = await operations.all(query, [], { limit: 50, offset: 50 });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export interface AllOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Maximum number of items to return.
|
|
42
|
+
*
|
|
43
|
+
* - Must be a positive integer (>= 1)
|
|
44
|
+
* - When not provided, returns all matching items
|
|
45
|
+
* - Takes precedence over query.limit when both are specified
|
|
46
|
+
*/
|
|
47
|
+
limit?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Number of items to skip before returning results.
|
|
50
|
+
*
|
|
51
|
+
* - Must be a non-negative integer (>= 0)
|
|
52
|
+
* - Defaults to 0 when not provided
|
|
53
|
+
* - Takes precedence over query.offset when both are specified
|
|
54
|
+
*/
|
|
55
|
+
offset?: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Metadata about the pagination state for an all() operation.
|
|
59
|
+
*
|
|
60
|
+
* This metadata enables proper pagination UI and logic by providing
|
|
61
|
+
* the total count of matching items before limit/offset are applied.
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export interface PaginationMetadata {
|
|
66
|
+
/**
|
|
67
|
+
* Total count of items matching the query BEFORE limit/offset applied.
|
|
68
|
+
*
|
|
69
|
+
* This represents the complete result set size and is used to:
|
|
70
|
+
* - Display "Showing X of Y results"
|
|
71
|
+
* - Calculate total pages
|
|
72
|
+
* - Determine if more items exist
|
|
73
|
+
*/
|
|
74
|
+
total: number;
|
|
75
|
+
/**
|
|
76
|
+
* Number of items actually returned in this response.
|
|
77
|
+
*
|
|
78
|
+
* This equals `items.length` and is provided for convenience.
|
|
79
|
+
* When offset + returned < total, more items exist.
|
|
80
|
+
*/
|
|
81
|
+
returned: number;
|
|
82
|
+
/**
|
|
83
|
+
* The limit that was applied, if any.
|
|
84
|
+
*
|
|
85
|
+
* - Undefined when no limit was applied
|
|
86
|
+
* - Reflects the effective limit (options.limit ?? query.limit)
|
|
87
|
+
*/
|
|
88
|
+
limit?: number;
|
|
89
|
+
/**
|
|
90
|
+
* The offset that was applied.
|
|
91
|
+
*
|
|
92
|
+
* - 0 when no offset was applied
|
|
93
|
+
* - Reflects the effective offset (options.offset ?? query.offset ?? 0)
|
|
94
|
+
*/
|
|
95
|
+
offset: number;
|
|
96
|
+
/**
|
|
97
|
+
* Convenience field indicating whether more items exist beyond this page.
|
|
98
|
+
*
|
|
99
|
+
* Calculated as: `offset + returned < total`
|
|
100
|
+
*
|
|
101
|
+
* Useful for:
|
|
102
|
+
* - "Load More" buttons
|
|
103
|
+
* - Infinite scroll implementations
|
|
104
|
+
* - "Next Page" button state
|
|
105
|
+
*/
|
|
106
|
+
hasMore: boolean;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Result structure for the all() operation with pagination support.
|
|
110
|
+
*
|
|
111
|
+
* This structure provides both the items and metadata needed for
|
|
112
|
+
* implementing proper pagination in applications.
|
|
113
|
+
*
|
|
114
|
+
* @template T - The item type being returned
|
|
115
|
+
*
|
|
116
|
+
* @public
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* const result = await operations.all(query, [], { limit: 50, offset: 0 });
|
|
121
|
+
*
|
|
122
|
+
* console.log(`Showing ${result.metadata.returned} of ${result.metadata.total}`);
|
|
123
|
+
* // "Showing 50 of 1234"
|
|
124
|
+
*
|
|
125
|
+
* if (result.metadata.hasMore) {
|
|
126
|
+
* // Load next page
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export interface AllOperationResult<T> {
|
|
131
|
+
/**
|
|
132
|
+
* Array of items matching the query, with limit/offset applied.
|
|
133
|
+
*/
|
|
134
|
+
items: T[];
|
|
135
|
+
/**
|
|
136
|
+
* Pagination metadata for the result set.
|
|
137
|
+
*/
|
|
138
|
+
metadata: PaginationMetadata;
|
|
139
|
+
}
|
|
22
140
|
/**
|
|
23
141
|
* Options for update operations across all Fjell libraries.
|
|
24
142
|
*
|
|
@@ -97,25 +215,38 @@ export interface UpdateOptions {
|
|
|
97
215
|
*/
|
|
98
216
|
export interface Operations<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> {
|
|
99
217
|
/**
|
|
100
|
-
* Retrieves all items matching the query.
|
|
218
|
+
* Retrieves all items matching the query with optional pagination.
|
|
101
219
|
*
|
|
102
|
-
* @param query - Optional query to filter items
|
|
220
|
+
* @param query - Optional query to filter items (may include limit/offset for backwards compatibility)
|
|
103
221
|
* @param locations - Optional location hierarchy to scope the query
|
|
104
|
-
* @
|
|
222
|
+
* @param options - Optional pagination options (takes precedence over query limit/offset)
|
|
223
|
+
* @returns Result containing items and pagination metadata
|
|
105
224
|
*
|
|
106
|
-
* @example
|
|
225
|
+
* @example Get all items
|
|
107
226
|
* ```typescript
|
|
108
|
-
*
|
|
109
|
-
*
|
|
227
|
+
* const result = await operations.all();
|
|
228
|
+
* // result.items = all items
|
|
229
|
+
* // result.metadata.total = items.length
|
|
230
|
+
* ```
|
|
110
231
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
232
|
+
* @example Get paginated items
|
|
233
|
+
* ```typescript
|
|
234
|
+
* const result = await operations.all({}, [], { limit: 50, offset: 0 });
|
|
235
|
+
* // result.items = first 50 items
|
|
236
|
+
* // result.metadata.total = total matching count
|
|
237
|
+
* // result.metadata.hasMore = true if more exist
|
|
238
|
+
* ```
|
|
113
239
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
240
|
+
* @example Get items in specific location with pagination
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const result = await operations.all(
|
|
243
|
+
* {},
|
|
244
|
+
* [{kt: 'post', lk: 'post-123'}],
|
|
245
|
+
* { limit: 20, offset: 0 }
|
|
246
|
+
* );
|
|
116
247
|
* ```
|
|
117
248
|
*/
|
|
118
|
-
all(query?: ItemQuery, locations?: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V
|
|
249
|
+
all(query?: ItemQuery, locations?: LocKeyArray<L1, L2, L3, L4, L5> | [], options?: AllOptions): Promise<AllOperationResult<V>>;
|
|
119
250
|
/**
|
|
120
251
|
* Retrieves the first item matching the query.
|
|
121
252
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Item } from "../items";
|
|
2
2
|
import { ComKey, LocKeyArray } from "../keys";
|
|
3
3
|
import { ItemQuery } from "../item/ItemQuery";
|
|
4
|
-
import { AffectedKeys, OperationParams, Operations } from "./Operations";
|
|
4
|
+
import { AffectedKeys, AllOperationResult, AllOptions, OperationParams, Operations } from "./Operations";
|
|
5
5
|
/**
|
|
6
6
|
* Contained Operations interface - specialized for contained (hierarchical) items only.
|
|
7
7
|
*
|
|
@@ -47,7 +47,7 @@ import { AffectedKeys, OperationParams, Operations } from "./Operations";
|
|
|
47
47
|
* ```
|
|
48
48
|
*/
|
|
49
49
|
export interface ContainedOperations<V extends Item<S, L1, L2, L3, L4, L5>, S extends string, L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends Omit<Operations<V, S, L1, L2, L3, L4, L5>, 'get' | 'update' | 'remove' | 'upsert' | 'create' | 'action' | 'facet' | 'allAction' | 'allFacet' | 'all' | 'one' | 'find' | 'findOne'> {
|
|
50
|
-
all(query: ItemQuery | undefined, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V
|
|
50
|
+
all(query: ItemQuery | undefined, locations: LocKeyArray<L1, L2, L3, L4, L5> | [], allOptions?: AllOptions): Promise<AllOperationResult<V>>;
|
|
51
51
|
one(query: ItemQuery | undefined, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V | null>;
|
|
52
52
|
find(finder: string, params: OperationParams | undefined, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V[]>;
|
|
53
53
|
findOne(finder: string, params: OperationParams | undefined, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V | null>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Item } from "../items";
|
|
2
2
|
import { ComKey, LocKeyArray, PriKey } from "../keys";
|
|
3
3
|
import { ItemQuery } from "../item/ItemQuery";
|
|
4
|
-
import { AffectedKeys, CreateOptions, OperationParams, UpdateOptions } from "./Operations";
|
|
4
|
+
import { AffectedKeys, AllOperationResult, AllOptions, CreateOptions, OperationParams, UpdateOptions } from "./Operations";
|
|
5
5
|
/**
|
|
6
6
|
* Get method signature - retrieves single item by key
|
|
7
7
|
*/
|
|
@@ -33,10 +33,34 @@ export interface UpsertMethod<V extends Item<S, L1, L2, L3, L4, L5>, S extends s
|
|
|
33
33
|
(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, item: Partial<Item<S, L1, L2, L3, L4, L5>>, locations?: LocKeyArray<L1, L2, L3, L4, L5>, options?: UpdateOptions): Promise<V>;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* All method signature - retrieves all items matching query
|
|
36
|
+
* All method signature - retrieves all items matching query with optional pagination.
|
|
37
|
+
*
|
|
38
|
+
* @param query - Optional query to filter items (may include limit/offset for backwards compatibility)
|
|
39
|
+
* @param locations - Optional location hierarchy to scope the query
|
|
40
|
+
* @param options - Optional pagination options (takes precedence over query limit/offset)
|
|
41
|
+
* @returns Result containing items and pagination metadata
|
|
42
|
+
*
|
|
43
|
+
* @example Without options (backwards compatible)
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const result = await operations.all({ compoundCondition: {...} });
|
|
46
|
+
* // result.items = [...all matching items...]
|
|
47
|
+
* // result.metadata.total = result.items.length
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @example With options (new pattern)
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const result = await operations.all(
|
|
53
|
+
* { compoundCondition: {...} },
|
|
54
|
+
* [],
|
|
55
|
+
* { limit: 50, offset: 0 }
|
|
56
|
+
* );
|
|
57
|
+
* // result.items = [...first 50 items...]
|
|
58
|
+
* // result.metadata.total = total matching count
|
|
59
|
+
* // result.metadata.hasMore = true if more items exist
|
|
60
|
+
* ```
|
|
37
61
|
*/
|
|
38
62
|
export interface AllMethod<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> {
|
|
39
|
-
(query?: ItemQuery, locations?: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V
|
|
63
|
+
(query?: ItemQuery, locations?: LocKeyArray<L1, L2, L3, L4, L5> | [], options?: AllOptions): Promise<AllOperationResult<V>>;
|
|
40
64
|
}
|
|
41
65
|
/**
|
|
42
66
|
* One method signature - retrieves first item matching query
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Item } from "../items";
|
|
2
2
|
import { PriKey } from "../keys";
|
|
3
3
|
import { ItemQuery } from "../item/ItemQuery";
|
|
4
|
-
import { AffectedKeys, OperationParams, Operations } from "./Operations";
|
|
4
|
+
import { AffectedKeys, AllOperationResult, AllOptions, OperationParams, Operations } from "./Operations";
|
|
5
5
|
/**
|
|
6
6
|
* Primary Operations interface - specialized for primary (top-level) items only.
|
|
7
7
|
*
|
|
@@ -39,7 +39,7 @@ import { AffectedKeys, OperationParams, Operations } from "./Operations";
|
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
41
|
export interface PrimaryOperations<V extends Item<S>, S extends string> extends Omit<Operations<V, S>, 'all' | 'one' | 'create' | 'get' | 'update' | 'upsert' | 'remove' | 'find' | 'findOne' | 'action' | 'allAction' | 'facet' | 'allFacet'> {
|
|
42
|
-
all(query?: ItemQuery): Promise<V
|
|
42
|
+
all(query?: ItemQuery, locations?: [], allOptions?: AllOptions): Promise<AllOperationResult<V>>;
|
|
43
43
|
one(query?: ItemQuery): Promise<V | null>;
|
|
44
44
|
find(finder: string, params?: OperationParams): Promise<V[]>;
|
|
45
45
|
findOne(finder: string, params?: OperationParams): Promise<V | null>;
|
|
@@ -19,10 +19,10 @@ import type { WrapperOptions } from "./types";
|
|
|
19
19
|
* ```typescript
|
|
20
20
|
* const all = createAllWrapper(
|
|
21
21
|
* coordinate,
|
|
22
|
-
* async (query, locations) => {
|
|
23
|
-
* return await database.findAll(query, locations);
|
|
22
|
+
* async (query, locations, options) => {
|
|
23
|
+
* return await database.findAll(query, locations, options);
|
|
24
24
|
* }
|
|
25
25
|
* );
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
|
-
export declare function createAllWrapper<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>(coordinate: Coordinate<S, L1, L2, L3, L4, L5>, implementation: AllMethod<V, S, L1, L2, L3, L4, L5>,
|
|
28
|
+
export declare function createAllWrapper<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>(coordinate: Coordinate<S, L1, L2, L3, L4, L5>, implementation: AllMethod<V, S, L1, L2, L3, L4, L5>, wrapperOptions?: WrapperOptions): AllMethod<V, S, L1, L2, L3, L4, L5>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjell/core",
|
|
3
3
|
"description": "Core Item and Key Framework for Fjell",
|
|
4
|
-
"version": "4.4.
|
|
4
|
+
"version": "4.4.64",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"core",
|
|
7
7
|
"fjell"
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"docs:test": "cd docs && npm run test"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@fjell/logging": "^4.4.
|
|
44
|
+
"@fjell/logging": "^4.4.59",
|
|
45
45
|
"deepmerge": "^4.3.1",
|
|
46
46
|
"luxon": "^3.7.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@eslint/eslintrc": "^3.3.1",
|
|
50
50
|
"@eslint/js": "^9.39.1",
|
|
51
|
-
"@fjell/common-config": "^1.1.
|
|
51
|
+
"@fjell/common-config": "^1.1.31",
|
|
52
52
|
"@swc/core": "^1.15.2",
|
|
53
53
|
"@tsconfig/recommended": "^1.0.13",
|
|
54
54
|
"@types/luxon": "^3.7.1",
|