lucid-extension-sdk 0.0.409 → 0.0.411
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/core/cardintegration/cardintegrationparams.d.ts +2 -0
- package/core/cardintegration/lucidcardintegrationregistry.js +23 -15
- package/core/cardintegration/lucidcardintegrationstandardimportmodal.d.ts +10 -2
- package/core/sharedcardintegration/cardintegrationdefinitions.d.ts +26 -2
- package/core/sharedcardintegration/cardintegrationdefinitions.js +5 -1
- package/core/validators/compactvalidatorsandpruners.d.ts +50 -16
- package/core/validators/compactvalidatorsandpruners.js +105 -15
- package/package.json +1 -1
|
@@ -163,12 +163,15 @@ class LucidCardIntegrationRegistry {
|
|
|
163
163
|
}
|
|
164
164
|
static serializeSearchResult(searchResult) {
|
|
165
165
|
return {
|
|
166
|
-
'
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
'
|
|
170
|
-
|
|
171
|
-
|
|
166
|
+
'srs': searchResult.searchResults.map((resultPerCollection) => ({
|
|
167
|
+
'd': (0, collectiondefinition_1.serializeCollectionDefinition)(resultPerCollection.data),
|
|
168
|
+
'f': (0, cardintegrationdefinitions_1.serializeCardFieldArrayDefinition)(resultPerCollection.fields),
|
|
169
|
+
'm': resultPerCollection.partialImportMetadata && {
|
|
170
|
+
'cid': resultPerCollection.partialImportMetadata.collectionId,
|
|
171
|
+
'sid': resultPerCollection.partialImportMetadata.syncDataSourceId,
|
|
172
|
+
},
|
|
173
|
+
})),
|
|
174
|
+
'ipsr': searchResult.itemsPerSearchResult,
|
|
172
175
|
};
|
|
173
176
|
}
|
|
174
177
|
static registerImportCardFromPastedLinkHandler(client, cardIntegration, serialized) {
|
|
@@ -281,16 +284,21 @@ class LucidCardIntegrationRegistry {
|
|
|
281
284
|
const result = await importModal.getSearchFields(new Map(searchSoFar));
|
|
282
285
|
return (0, cardintegrationdefinitions_1.serializeCardFieldArrayDefinition)(result);
|
|
283
286
|
});
|
|
284
|
-
client.registerAction(serialized['im']['s'], async ({ 's': param }) => {
|
|
285
|
-
const result = await importModal.search(new Map(param));
|
|
286
|
-
if ((0,
|
|
287
|
-
|
|
288
|
-
return this.serializeSearchResult(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
287
|
+
client.registerAction(serialized['im']['s'], async ({ 's': param, 'o': offset, 'l': limit }) => {
|
|
288
|
+
const result = await importModal.search(new Map(param), offset, limit);
|
|
289
|
+
if (!(0, cardintegrationdefinitions_1.isSearchResult)(result)) {
|
|
290
|
+
if ((0, checks_1.isArray)(result)) {
|
|
291
|
+
return this.serializeSearchResult({
|
|
292
|
+
searchResults: result,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
return this.serializeSearchResult({
|
|
297
|
+
searchResults: [result],
|
|
298
|
+
});
|
|
299
|
+
}
|
|
293
300
|
}
|
|
301
|
+
return this.serializeSearchResult(result);
|
|
294
302
|
});
|
|
295
303
|
client.registerAction(serialized['im']['i'], async ({ 'pks': primaryKeys, 's': searchFields }) => {
|
|
296
304
|
const result = await importModal.import(primaryKeys, new Map(searchFields));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SerializedFieldType } from '../data/serializedfield/serializedfields';
|
|
2
|
-
import { ExtensionCardFieldDefinition, ImportResult, SearchResult } from '../sharedcardintegration/cardintegrationdefinitions';
|
|
2
|
+
import { DeprecatedSearchResult, ExtensionCardFieldDefinition, ImportResult, SearchResult } from '../sharedcardintegration/cardintegrationdefinitions';
|
|
3
3
|
import { ExtensionImportModalWidthBreakpoint } from './extensionimportmodalwidthbreakpoint';
|
|
4
4
|
/**
|
|
5
5
|
* You can use the standard import modal can be used by providing the following data:
|
|
@@ -18,6 +18,14 @@ import { ExtensionImportModalWidthBreakpoint } from './extensionimportmodalwidth
|
|
|
18
18
|
* The last requirement for the partial import to work is that the primary keys in the data also
|
|
19
19
|
* returned in this search need to match the primary keys that will be returned
|
|
20
20
|
* on import.
|
|
21
|
+
* Offset and limit are used for pagination. The offset is the number of items to skip and the limit
|
|
22
|
+
* is the maximum number of items to return. To use pagination, you have to return `totalNumberOfItems` field in
|
|
23
|
+
* the `SearchResult`.
|
|
24
|
+
* Note: When using pagination and returning a `SearchResult` array:
|
|
25
|
+
* - The `totalNumberOfItems` in each `SearchResult` represents the total number of items
|
|
26
|
+
* for the specific workspace associated with that `SearchResult`.
|
|
27
|
+
* - The length of the `SearchResult` array must remain consistent across all pages of the search.
|
|
28
|
+
*
|
|
21
29
|
*
|
|
22
30
|
* import:
|
|
23
31
|
* The user checked the boxes beside the given list of items in the collection returned from search().
|
|
@@ -39,7 +47,7 @@ export interface LucidCardIntegrationStandardImportModal {
|
|
|
39
47
|
useIsolatedSearchBarUI?: boolean;
|
|
40
48
|
maxModalWidth?: ExtensionImportModalWidthBreakpoint;
|
|
41
49
|
getSearchFields: (searchSoFar: Map<string, SerializedFieldType>) => Promise<ExtensionCardFieldDefinition[]>;
|
|
42
|
-
search: (fields: Map<string, SerializedFieldType
|
|
50
|
+
search: (fields: Map<string, SerializedFieldType>, offset?: number, limit?: number) => Promise<SearchResult | DeprecatedSearchResult | DeprecatedSearchResult[]>;
|
|
43
51
|
import: (primaryKeys: string[], searchFields: Map<string, SerializedFieldType>) => Promise<ImportResult | ImportResult[]>;
|
|
44
52
|
onSetup?: () => Promise<void>;
|
|
45
53
|
}
|
|
@@ -4,7 +4,7 @@ import { DataItemProxy } from '../../data/dataitemproxy';
|
|
|
4
4
|
import { DataSourceProxy } from '../../data/datasourceproxy';
|
|
5
5
|
import { FieldDefinition } from '../../data/schemadefinition';
|
|
6
6
|
import { FieldDescriptor } from '../cardintegration/lucidcardintegration';
|
|
7
|
-
import { isString } from '../checks';
|
|
7
|
+
import { isArray, isString } from '../checks';
|
|
8
8
|
import { isSerializedFieldTypeDefinition } from '../data/fieldtypedefinition/fieldtypedefinition';
|
|
9
9
|
import { SerializedFieldDefinition } from '../data/serializedfield/serializedfielddefinition';
|
|
10
10
|
import { SerializedFieldType, SerializedLucidDictionary, isSerializedFieldType } from '../data/serializedfield/serializedfields';
|
|
@@ -105,7 +105,6 @@ export declare const isSerializedExtensionCardFieldDefinition: (subject: unknown
|
|
|
105
105
|
Type: typeof isSerializedFieldTypeDefinition;
|
|
106
106
|
Constraints: (x: unknown) => x is import("../guards").DestructureGuardedTypeObj<{
|
|
107
107
|
Type: (x: unknown) => x is import("../data/serializedfield/serializedfielddefinition").FieldConstraintType;
|
|
108
|
-
/** If defined, the default value for this field */
|
|
109
108
|
Details: (x: unknown) => x is any;
|
|
110
109
|
Reason: (x: unknown) => x is string | null | undefined;
|
|
111
110
|
}>[] | undefined;
|
|
@@ -124,14 +123,39 @@ export declare const isSerializedExtensionCardFieldDefinition: (subject: unknown
|
|
|
124
123
|
export declare function deserializeCardFieldDefinition(field: SerializedExtensionCardFieldDefinition): ExtensionCardFieldDefinition;
|
|
125
124
|
/** @ignore */
|
|
126
125
|
export declare function deserializeCardFieldArrayDefinition(fields: SerializedExtensionCardFieldDefinition[]): ExtensionCardFieldDefinition[];
|
|
126
|
+
export interface SearchResultPerCollection {
|
|
127
|
+
partialImportMetadata?: {
|
|
128
|
+
collectionId: string;
|
|
129
|
+
syncDataSourceId?: string;
|
|
130
|
+
};
|
|
131
|
+
data: CollectionDefinition;
|
|
132
|
+
fields: ExtensionCardFieldDefinition[];
|
|
133
|
+
}
|
|
127
134
|
/**
|
|
128
135
|
* Result of searching for data in the import modal
|
|
129
136
|
*
|
|
130
137
|
* If you change this interface, check if your changes need to be synced with
|
|
131
138
|
* editorextensioncardintegrationregistry.ts.
|
|
132
139
|
*
|
|
140
|
+
* By specifying the itemsPerSearchResult, you can enable pagination for results in the import modal. The offset and limit
|
|
141
|
+
* parameters in the search function will tell you which page of results to return.
|
|
142
|
+
*
|
|
133
143
|
*/
|
|
134
144
|
export interface SearchResult {
|
|
145
|
+
searchResults: SearchResultPerCollection[];
|
|
146
|
+
itemsPerSearchResult?: number | undefined;
|
|
147
|
+
}
|
|
148
|
+
export declare const isSearchResult: (subject: unknown) => subject is import("../guards").DestructureGuardedTypeObj<{
|
|
149
|
+
searchResults: typeof isArray;
|
|
150
|
+
itemsPerSearchResult: (x: unknown) => x is number | undefined;
|
|
151
|
+
}>;
|
|
152
|
+
/**
|
|
153
|
+
* @deprecated
|
|
154
|
+
* Deprecated version of SearchResult for backwards compatibility. Please use
|
|
155
|
+
* SearchResult instead.
|
|
156
|
+
* This will be removed in a future update.
|
|
157
|
+
*/
|
|
158
|
+
export interface DeprecatedSearchResult {
|
|
135
159
|
partialImportMetadata?: {
|
|
136
160
|
collectionId: string;
|
|
137
161
|
syncDataSourceId?: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isSerializedExtensionCardFieldLabelIcons = exports.deserializePlaceholderImportMetadata = exports.serializePlaceholderImportMetadata = exports.isSerializedPlaceholderImportMetadata = exports.deserializeCardFieldArrayDefinition = exports.deserializeCardFieldDefinition = exports.isSerializedExtensionCardFieldDefinition = exports.isSerializedFieldOptions = exports.isSerializedFieldOption = exports.deserializeFieldOption = exports.serializeCardFieldArrayDefinition = exports.serializeCardFieldDefinition = exports.serializeCardFieldOption = exports.isSerializedCardUserDataArray = exports.isSerializedCardUserData = exports.deserializeCardUserData = exports.serializeCardUserData = void 0;
|
|
3
|
+
exports.isSerializedExtensionCardFieldLabelIcons = exports.deserializePlaceholderImportMetadata = exports.serializePlaceholderImportMetadata = exports.isSerializedPlaceholderImportMetadata = exports.isSearchResult = exports.deserializeCardFieldArrayDefinition = exports.deserializeCardFieldDefinition = exports.isSerializedExtensionCardFieldDefinition = exports.isSerializedFieldOptions = exports.isSerializedFieldOption = exports.deserializeFieldOption = exports.serializeCardFieldArrayDefinition = exports.serializeCardFieldDefinition = exports.serializeCardFieldOption = exports.isSerializedCardUserDataArray = exports.isSerializedCardUserData = exports.deserializeCardUserData = exports.serializeCardUserData = void 0;
|
|
4
4
|
const collectiondefinition_1 = require("../../data/collectiondefinition");
|
|
5
5
|
const schemadefinition_1 = require("../../data/schemadefinition");
|
|
6
6
|
const checks_1 = require("../checks");
|
|
@@ -83,6 +83,10 @@ function deserializeCardFieldArrayDefinition(fields) {
|
|
|
83
83
|
return fields.map(deserializeCardFieldDefinition);
|
|
84
84
|
}
|
|
85
85
|
exports.deserializeCardFieldArrayDefinition = deserializeCardFieldArrayDefinition;
|
|
86
|
+
exports.isSearchResult = (0, validators_1.objectValidator)({
|
|
87
|
+
searchResults: checks_1.isArray,
|
|
88
|
+
itemsPerSearchResult: (0, validators_1.option)(checks_1.isNumber),
|
|
89
|
+
});
|
|
86
90
|
/** @ignore */
|
|
87
91
|
exports.isSerializedPlaceholderImportMetadata = (0, validators_1.objectValidator)({
|
|
88
92
|
'cid': checks_1.isString,
|
|
@@ -6,7 +6,7 @@ type ObjectAttributeType = keyof any;
|
|
|
6
6
|
/**
|
|
7
7
|
* A generic type for a Validator that narrows FROM to TO.
|
|
8
8
|
*/
|
|
9
|
-
type Validator<TO extends FROM, FROM = unknown> = (unknownVariable: FROM) => unknownVariable is TO;
|
|
9
|
+
export type Validator<TO extends FROM, FROM = unknown> = (unknownVariable: FROM) => unknownVariable is TO;
|
|
10
10
|
/**
|
|
11
11
|
* A record that maps each key in an object to its respective ValidatorWithOptionalPruner.
|
|
12
12
|
*/
|
|
@@ -16,7 +16,7 @@ type ObjectValidatorConfig = Record<ObjectAttributeType, ValidatorWithOptionalPr
|
|
|
16
16
|
* - prunerResult: The pruned data (or possibly the same data if no pruning is needed) which also constains
|
|
17
17
|
* invalidFields: a map of invalid fields (represented by keys) to their original invalid values.
|
|
18
18
|
*/
|
|
19
|
-
type Pruner = (unprunedData: unknown) => PrunerResult;
|
|
19
|
+
export type Pruner = (unprunedData: unknown) => PrunerResult;
|
|
20
20
|
/**
|
|
21
21
|
* The result object returned from a pruner function.
|
|
22
22
|
*/
|
|
@@ -30,11 +30,11 @@ export interface PrunerResult {
|
|
|
30
30
|
* - `validator` is the function used to validate the data.
|
|
31
31
|
* - `pruner` can optionally used to prune invalid data fields if validation fails.
|
|
32
32
|
*/
|
|
33
|
-
interface ValidatorWithOptionalPruner<TO = unknown> {
|
|
33
|
+
export interface ValidatorWithOptionalPruner<TO = unknown> {
|
|
34
34
|
'validator': Validator<TO>;
|
|
35
35
|
'pruner'?: Pruner;
|
|
36
36
|
}
|
|
37
|
-
interface ValidatorWithPruner<TO = unknown> {
|
|
37
|
+
export interface ValidatorWithPruner<TO = unknown> {
|
|
38
38
|
'validator': Validator<TO>;
|
|
39
39
|
'pruner': Pruner;
|
|
40
40
|
}
|
|
@@ -51,19 +51,21 @@ type ExtractValidatedTypeFromConfig<V> = V extends {
|
|
|
51
51
|
type ObjectValidatorToValidatedType<T extends ObjectValidatorConfig> = WithUndefinedAsOptional<{
|
|
52
52
|
[K in keyof T]: ExtractValidatedTypeFromConfig<T[K]>;
|
|
53
53
|
}>;
|
|
54
|
+
type Primitive = string | number | boolean | null | undefined | symbol | bigint;
|
|
55
|
+
type ExcludedTypes = ((...args: any[]) => any) | Primitive | Date;
|
|
54
56
|
/**
|
|
55
57
|
* Recursively applies a "prettifying" transformation to the inferred object type.
|
|
56
58
|
* - For functions, it leaves them as-is.
|
|
57
59
|
* - For objects, it recurses down into properties.
|
|
58
60
|
* - Otherwise, returns the type unchanged.
|
|
59
61
|
*/
|
|
60
|
-
type PrettifyDeep<T> = T extends
|
|
62
|
+
type PrettifyDeep<T> = T extends ExcludedTypes ? T : T extends object ? {
|
|
61
63
|
[K in keyof T]: PrettifyDeep<T[K]>;
|
|
62
64
|
} : T;
|
|
63
65
|
/**
|
|
64
66
|
* Extracts the final type from @param ObjectValidatorConfig
|
|
65
67
|
*/
|
|
66
|
-
type PrettifiedObjectValidatorType<T extends ObjectValidatorConfig> = PrettifyDeep<ObjectValidatorToValidatedType<T>>;
|
|
68
|
+
export type PrettifiedObjectValidatorType<T extends ObjectValidatorConfig> = PrettifyDeep<ObjectValidatorToValidatedType<T>>;
|
|
67
69
|
export type ExtractValidatedTypeFromValidator<V extends Validator<unknown>> = V extends Validator<infer U> ? U : never;
|
|
68
70
|
/**
|
|
69
71
|
* Creates a validator and pruner for an object.
|
|
@@ -85,6 +87,14 @@ export declare function getObjectValidatorAndPruner<T extends ObjectValidatorCon
|
|
|
85
87
|
* @returns ValidatorWithPruner for the array.
|
|
86
88
|
*/
|
|
87
89
|
export declare function getArrayValidatorAndPruner<ElementType>(arrayElementConfig: ValidatorWithOptionalPruner<ElementType> | Validator<ElementType>): ValidatorWithPruner<ElementType[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Creates a validator and pruner for objects keyed by K and valued by T.
|
|
92
|
+
*
|
|
93
|
+
* @param valueConfig Validator (and optional pruner) for each object's value.
|
|
94
|
+
* @param keyConfig Validator (and optional pruner) for each object's key.
|
|
95
|
+
* @returns A ValidatorWithPruner for a Record<K, T>.
|
|
96
|
+
*/
|
|
97
|
+
export declare function getObjectOfValidatorAndPruner<T, K extends string | number | symbol = string>(valueConfig: ValidatorWithOptionalPruner<T> | Validator<T>, keyValidator?: Validator<K>): ValidatorWithPruner<Record<K, T>>;
|
|
88
98
|
/**
|
|
89
99
|
* Function used in objectFieldConfig and arrayElementConfig to speficy that invalid
|
|
90
100
|
* items must be pruned/marked as undefined.
|
|
@@ -92,20 +102,44 @@ export declare function getArrayValidatorAndPruner<ElementType>(arrayElementConf
|
|
|
92
102
|
*/
|
|
93
103
|
export declare const pruneElement: (element: unknown) => PrunerResult;
|
|
94
104
|
/**
|
|
95
|
-
*
|
|
105
|
+
* Selects and applies one of two pruners based on whether the input data is an array.
|
|
106
|
+
*
|
|
107
|
+
* This function acts as a router. If the input `data` is an array, it delegates the pruning
|
|
108
|
+
* task to the `prunerForArray`. If the input `data` is *not* an array (e.g., could be null,
|
|
109
|
+
* a string, an object, etc.), it delegates to the `prunerForNonArray`.
|
|
110
|
+
*
|
|
111
|
+
* Use Case: This is useful when you need distinct pruning logic depending on whether you
|
|
112
|
+
* received an array or something else entirely at a specific point in your data structure.
|
|
113
|
+
* For instance, you might have a pruner designed to process arrays (perhaps iterating
|
|
114
|
+
* through elements) and another pruner designed to handle scalar values or objects that
|
|
115
|
+
* might appear in the same data field.
|
|
116
|
+
*
|
|
117
|
+
* @param prunerForArray The Pruner function to execute if the input `data` is an array.
|
|
118
|
+
* This pruner is responsible for handling the entire array data.
|
|
119
|
+
* @param prunerForNonArray The Pruner function to execute if the input `data` is *not* an array.
|
|
120
|
+
* @returns A new Pruner function that implements this conditional logic.
|
|
121
|
+
*/
|
|
122
|
+
export declare function selectPrunerByArrayType(prunerForArray: Pruner, prunerForNonArray: Pruner): Pruner;
|
|
123
|
+
/**
|
|
124
|
+
* Selects and applies one of two pruners based on whether the input data is an object.
|
|
96
125
|
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
126
|
+
* This function acts as a router. If the input `data` is an object it delegates the
|
|
127
|
+
* pruning task to the `prunerForObject`. If the input `data` is *not*
|
|
128
|
+
* an object (e.g., could be null, an array, a string, a number, etc.), it delegates
|
|
129
|
+
* to the `prunerForNonObject`.
|
|
99
130
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
131
|
+
* Use Case: Similar to `selectPrunerByArrayType`, this is useful for applying different
|
|
132
|
+
* pruning strategies based on whether the data at a certain point is an object or some other
|
|
133
|
+
* type. For example, within an array pruner you can use this to apply an object pruner
|
|
134
|
+
* if an element is an object, but use a simpler pruner (like `pruneElement` which will
|
|
135
|
+
* remove `null` or invalid types) if the element is not an object.
|
|
103
136
|
*
|
|
104
|
-
* @param
|
|
105
|
-
*
|
|
106
|
-
* @
|
|
137
|
+
* @param prunerForObject The Pruner function to execute if the input `data` is an object.
|
|
138
|
+
* This pruner is responsible for handling the entire object data.
|
|
139
|
+
* @param prunerForNonObject The Pruner function to execute if the input `data` is *not* an object.
|
|
140
|
+
* @returns A new Pruner function that implements this conditional logic.
|
|
107
141
|
*/
|
|
108
|
-
export declare function
|
|
142
|
+
export declare function selectPrunerByObjectType(prunerForObject: Pruner, prunerForNonObject: Pruner): Pruner;
|
|
109
143
|
/**
|
|
110
144
|
* Helper function to easily create a `ValidatorWithOptionalPruner`.
|
|
111
145
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getValidatorPrunerConfig = exports.
|
|
3
|
+
exports.getValidatorPrunerConfig = exports.selectPrunerByObjectType = exports.selectPrunerByArrayType = exports.pruneElement = exports.getObjectOfValidatorAndPruner = exports.getArrayValidatorAndPruner = exports.getObjectValidatorAndPruner = void 0;
|
|
4
4
|
const checks_1 = require("../checks");
|
|
5
5
|
function getValidatorFromConfig(validatorConfig) {
|
|
6
6
|
if ('validator' in validatorConfig) {
|
|
@@ -115,6 +115,56 @@ function getArrayValidatorAndPruner(arrayElementConfig) {
|
|
|
115
115
|
return { validator: arrayValidatorFunction, pruner: arrayPrunerFunction };
|
|
116
116
|
}
|
|
117
117
|
exports.getArrayValidatorAndPruner = getArrayValidatorAndPruner;
|
|
118
|
+
/**
|
|
119
|
+
* Creates a validator and pruner for objects keyed by K and valued by T.
|
|
120
|
+
*
|
|
121
|
+
* @param valueConfig Validator (and optional pruner) for each object's value.
|
|
122
|
+
* @param keyConfig Validator (and optional pruner) for each object's key.
|
|
123
|
+
* @returns A ValidatorWithPruner for a Record<K, T>.
|
|
124
|
+
*/
|
|
125
|
+
function getObjectOfValidatorAndPruner(valueConfig, keyValidator = (key) => true) {
|
|
126
|
+
const valueValidator = getValidatorFromConfig(valueConfig);
|
|
127
|
+
const valuePruner = getPrunerFromConfig(valueConfig);
|
|
128
|
+
const objectOfValidator = (subject) => {
|
|
129
|
+
if ((0, checks_1.isArray)(subject) || !(0, checks_1.isObjectUnsafe)(subject)) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
return Object.entries(subject).every(([k, v]) => keyValidator(k) && valueValidator(v));
|
|
133
|
+
};
|
|
134
|
+
const objectOfPruner = (subject) => {
|
|
135
|
+
if ((0, checks_1.isArray)(subject) || !(0, checks_1.isObjectUnsafe)(subject)) {
|
|
136
|
+
return {
|
|
137
|
+
prunerResult: subject,
|
|
138
|
+
invalidFields: createElementInvalidField(subject),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const invalidFields = new Map();
|
|
142
|
+
const prunerResult = Object.assign({}, subject);
|
|
143
|
+
Object.entries(prunerResult).forEach(([k, v]) => {
|
|
144
|
+
if (!keyValidator(k)) {
|
|
145
|
+
invalidFields.set(`key:${k}`, v);
|
|
146
|
+
// If the key is invalid, we remove the key-value pair from the object.
|
|
147
|
+
prunerResult[k] = undefined;
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (!valueValidator(v)) {
|
|
151
|
+
if (!valuePruner) {
|
|
152
|
+
invalidFields.set(k, v);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const valPrunerResult = valuePruner(v);
|
|
156
|
+
prunerResult[k] = valPrunerResult.prunerResult;
|
|
157
|
+
for (const [subKey, subVal] of valPrunerResult.invalidFields) {
|
|
158
|
+
invalidFields.set(`${k}.${subKey}`, subVal);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return { prunerResult, invalidFields };
|
|
164
|
+
};
|
|
165
|
+
return { validator: objectOfValidator, pruner: objectOfPruner };
|
|
166
|
+
}
|
|
167
|
+
exports.getObjectOfValidatorAndPruner = getObjectOfValidatorAndPruner;
|
|
118
168
|
/**
|
|
119
169
|
* Creates a Map signifying that the entire `element` was invalid,
|
|
120
170
|
* with a key of `""` or some placeholder to represent the entire item.
|
|
@@ -132,28 +182,68 @@ const pruneElement = (element) => {
|
|
|
132
182
|
};
|
|
133
183
|
exports.pruneElement = pruneElement;
|
|
134
184
|
/**
|
|
135
|
-
*
|
|
185
|
+
* Selects and applies one of two pruners based on whether the input data is an array.
|
|
186
|
+
*
|
|
187
|
+
* This function acts as a router. If the input `data` is an array, it delegates the pruning
|
|
188
|
+
* task to the `prunerForArray`. If the input `data` is *not* an array (e.g., could be null,
|
|
189
|
+
* a string, an object, etc.), it delegates to the `prunerForNonArray`.
|
|
190
|
+
*
|
|
191
|
+
* Use Case: This is useful when you need distinct pruning logic depending on whether you
|
|
192
|
+
* received an array or something else entirely at a specific point in your data structure.
|
|
193
|
+
* For instance, you might have a pruner designed to process arrays (perhaps iterating
|
|
194
|
+
* through elements) and another pruner designed to handle scalar values or objects that
|
|
195
|
+
* might appear in the same data field.
|
|
196
|
+
*
|
|
197
|
+
* @param prunerForArray The Pruner function to execute if the input `data` is an array.
|
|
198
|
+
* This pruner is responsible for handling the entire array data.
|
|
199
|
+
* @param prunerForNonArray The Pruner function to execute if the input `data` is *not* an array.
|
|
200
|
+
* @returns A new Pruner function that implements this conditional logic.
|
|
201
|
+
*/
|
|
202
|
+
function selectPrunerByArrayType(prunerForArray, prunerForNonArray) {
|
|
203
|
+
return (data) => {
|
|
204
|
+
if ((0, checks_1.isArray)(data)) {
|
|
205
|
+
// Data is an array, apply the pruner designated for arrays.
|
|
206
|
+
return prunerForArray(data);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// Data is not an array, apply the pruner designated for non-arrays.
|
|
210
|
+
return prunerForNonArray(data);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
exports.selectPrunerByArrayType = selectPrunerByArrayType;
|
|
215
|
+
/**
|
|
216
|
+
* Selects and applies one of two pruners based on whether the input data is an object.
|
|
136
217
|
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
218
|
+
* This function acts as a router. If the input `data` is an object it delegates the
|
|
219
|
+
* pruning task to the `prunerForObject`. If the input `data` is *not*
|
|
220
|
+
* an object (e.g., could be null, an array, a string, a number, etc.), it delegates
|
|
221
|
+
* to the `prunerForNonObject`.
|
|
139
222
|
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
223
|
+
* Use Case: Similar to `selectPrunerByArrayType`, this is useful for applying different
|
|
224
|
+
* pruning strategies based on whether the data at a certain point is an object or some other
|
|
225
|
+
* type. For example, within an array pruner you can use this to apply an object pruner
|
|
226
|
+
* if an element is an object, but use a simpler pruner (like `pruneElement` which will
|
|
227
|
+
* remove `null` or invalid types) if the element is not an object.
|
|
143
228
|
*
|
|
144
|
-
* @param
|
|
145
|
-
*
|
|
146
|
-
* @
|
|
229
|
+
* @param prunerForObject The Pruner function to execute if the input `data` is an object.
|
|
230
|
+
* This pruner is responsible for handling the entire object data.
|
|
231
|
+
* @param prunerForNonObject The Pruner function to execute if the input `data` is *not* an object.
|
|
232
|
+
* @returns A new Pruner function that implements this conditional logic.
|
|
147
233
|
*/
|
|
148
|
-
function
|
|
234
|
+
function selectPrunerByObjectType(prunerForObject, prunerForNonObject) {
|
|
149
235
|
return (data) => {
|
|
150
|
-
if (
|
|
151
|
-
|
|
236
|
+
if ((0, checks_1.isObjectUnsafe)(data)) {
|
|
237
|
+
// Data is an object, apply the pruner designated for objects.
|
|
238
|
+
return prunerForObject(data);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// Data is not an object, apply the pruner designated for non-objects.
|
|
242
|
+
return prunerForNonObject(data);
|
|
152
243
|
}
|
|
153
|
-
return perElementPruner(data);
|
|
154
244
|
};
|
|
155
245
|
}
|
|
156
|
-
exports.
|
|
246
|
+
exports.selectPrunerByObjectType = selectPrunerByObjectType;
|
|
157
247
|
/**
|
|
158
248
|
* Helper function to easily create a `ValidatorWithOptionalPruner`.
|
|
159
249
|
*
|