@land-catalyst/batch-data-sdk 1.1.12 → 1.1.19
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/{builders.d.ts → builders/builders.d.ts} +75 -1
- package/dist/{builders.js → builders/builders.js} +90 -0
- package/dist/builders/property-field-builder-mixin.d.ts +47 -0
- package/dist/builders/property-field-builder-mixin.js +35 -0
- package/dist/{client.d.ts → client/client.d.ts} +2 -2
- package/dist/{client.interface.d.ts → client/client.interface.d.ts} +1 -1
- package/dist/{client.js → client/client.js} +2 -2
- package/dist/{types.d.ts → core/types.d.ts} +217 -0
- package/dist/index.d.ts +11 -7
- package/dist/index.js +8 -6
- package/dist/property-field/metadata.d.ts +105 -0
- package/dist/property-field/metadata.js +6251 -0
- package/dist/property-field/types.d.ts +33 -0
- package/dist/property-field/types.js +9 -0
- package/dist/property-field/utils.d.ts +306 -0
- package/dist/property-field/utils.js +479 -0
- package/package.json +5 -2
- /package/dist/{client.interface.js → client/client.interface.js} +0 -0
- /package/dist/{errors.d.ts → core/errors.d.ts} +0 -0
- /package/dist/{errors.js → core/errors.js} +0 -0
- /package/dist/{logger.interface.d.ts → core/logger.interface.d.ts} +0 -0
- /package/dist/{logger.interface.js → core/logger.interface.js} +0 -0
- /package/dist/{types.js → core/types.js} +0 -0
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Property Field Utilities
|
|
4
|
+
*
|
|
5
|
+
* Utilities for working with property field paths and metadata
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.getPropertyFieldMetadata = getPropertyFieldMetadata;
|
|
9
|
+
exports.getPropertyFieldValue = getPropertyFieldValue;
|
|
10
|
+
exports.getPropertyGroupFields = getPropertyGroupFields;
|
|
11
|
+
exports.getNestedFieldMetadata = getNestedFieldMetadata;
|
|
12
|
+
exports.isValidPropertyField = isValidPropertyField;
|
|
13
|
+
exports.getPropertyGroupFieldPaths = getPropertyGroupFieldPaths;
|
|
14
|
+
exports.getPropertyFieldDescription = getPropertyFieldDescription;
|
|
15
|
+
exports.getPropertyFieldType = getPropertyFieldType;
|
|
16
|
+
exports.mapSearchCriteriaToPropertyPath = mapSearchCriteriaToPropertyPath;
|
|
17
|
+
exports.getSearchCriteriaFieldMetadata = getSearchCriteriaFieldMetadata;
|
|
18
|
+
exports.getSearchCriteriaMetadata = getSearchCriteriaMetadata;
|
|
19
|
+
exports.getSearchCriteriaFieldsForPropertyGroup = getSearchCriteriaFieldsForPropertyGroup;
|
|
20
|
+
exports.getSearchCriteriaFieldsWithMetadata = getSearchCriteriaFieldsWithMetadata;
|
|
21
|
+
exports.getSearchCriteriaMetadataForGroup = getSearchCriteriaMetadataForGroup;
|
|
22
|
+
exports.extractSearchCriteriaFieldPaths = extractSearchCriteriaFieldPaths;
|
|
23
|
+
exports.getSearchCriteriaFieldsMetadata = getSearchCriteriaFieldsMetadata;
|
|
24
|
+
exports.getPropertyFieldsMetadata = getPropertyFieldsMetadata;
|
|
25
|
+
const metadata_1 = require("./metadata");
|
|
26
|
+
/**
|
|
27
|
+
* Get metadata for a property field by its path
|
|
28
|
+
* @param fieldPath The field path (e.g., "address.city", "owner.fullName")
|
|
29
|
+
* @returns The field metadata, or undefined if not found
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const cityMeta = getPropertyFieldMetadata("address.city");
|
|
33
|
+
* console.log(cityMeta?.description); // "The city (e.g. Chicago)"
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function getPropertyFieldMetadata(fieldPath) {
|
|
37
|
+
return (0, metadata_1.getFieldMetadata)(fieldPath);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the value at a field path from a property object
|
|
41
|
+
* @param property The property object
|
|
42
|
+
* @param fieldPath The field path (e.g., "address.city", "owner.fullName")
|
|
43
|
+
* @returns The value at the path, or undefined if not found
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const city = getPropertyFieldValue(property, "address.city");
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
function getPropertyFieldValue(property, fieldPath) {
|
|
50
|
+
const parts = fieldPath.split(".");
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
52
|
+
let value = property;
|
|
53
|
+
for (const part of parts) {
|
|
54
|
+
if (value == null) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
// Handle array notation like "[n]"
|
|
58
|
+
if (part === "[n]") {
|
|
59
|
+
// This is an array element - return the array itself
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
+
value = value[part];
|
|
64
|
+
}
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get metadata for all fields in a response group
|
|
69
|
+
* @param groupName The response group name (e.g., "address", "owner", "building")
|
|
70
|
+
* @returns Array of field metadata for that group
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const addressFields = getPropertyGroupFields("address");
|
|
74
|
+
* // Returns all fields under address.*
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
function getPropertyGroupFields(groupName) {
|
|
78
|
+
return Object.values(metadata_1.PROPERTY_FIELD_METADATA).filter((field) => field.responseGroupName === groupName);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get metadata for a nested field path
|
|
82
|
+
* Handles nested paths like "owner.mailingAddress.city"
|
|
83
|
+
* @param fieldPath The full field path
|
|
84
|
+
* @returns The field metadata, or undefined if not found
|
|
85
|
+
*/
|
|
86
|
+
function getNestedFieldMetadata(fieldPath) {
|
|
87
|
+
return (0, metadata_1.getFieldMetadata)(fieldPath);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Type guard to check if a field path exists in metadata
|
|
91
|
+
* @param fieldPath The field path to check
|
|
92
|
+
* @returns True if the field exists in metadata
|
|
93
|
+
*/
|
|
94
|
+
function isValidPropertyField(fieldPath) {
|
|
95
|
+
return fieldPath in metadata_1.PROPERTY_FIELD_METADATA;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get all field paths for a specific property group
|
|
99
|
+
* @param groupName The response group name
|
|
100
|
+
* @returns Array of field paths
|
|
101
|
+
*/
|
|
102
|
+
function getPropertyGroupFieldPaths(groupName) {
|
|
103
|
+
return Object.values(metadata_1.PROPERTY_FIELD_METADATA)
|
|
104
|
+
.filter((field) => field.responseGroupName === groupName)
|
|
105
|
+
.map((field) => field.fieldPath);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get field description for a property field
|
|
109
|
+
* @param fieldPath The field path
|
|
110
|
+
* @returns The description, or undefined if not found
|
|
111
|
+
*/
|
|
112
|
+
function getPropertyFieldDescription(fieldPath) {
|
|
113
|
+
return (0, metadata_1.getFieldMetadata)(fieldPath)?.description;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get field data type for a property field
|
|
117
|
+
* @param fieldPath The field path
|
|
118
|
+
* @returns The data type, or undefined if not found
|
|
119
|
+
*/
|
|
120
|
+
function getPropertyFieldType(fieldPath) {
|
|
121
|
+
return (0, metadata_1.getFieldMetadata)(fieldPath)?.dataType;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Map a SearchCriteria field path to its corresponding Property field path
|
|
125
|
+
* Most SearchCriteria fields map directly to Property fields (e.g., "address.city" -> "address.city")
|
|
126
|
+
* @param searchCriteriaPath The field path in SearchCriteria (e.g., "address.city", "building.yearBuilt")
|
|
127
|
+
* @returns The corresponding Property field path, or undefined if no mapping exists
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const propertyPath = mapSearchCriteriaToPropertyPath("address.city");
|
|
131
|
+
* // Returns "address.city"
|
|
132
|
+
*
|
|
133
|
+
* const propertyPath = mapSearchCriteriaToPropertyPath("building.yearBuilt");
|
|
134
|
+
* // Returns "building.yearBuilt"
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
function mapSearchCriteriaToPropertyPath(searchCriteriaPath) {
|
|
138
|
+
// Most SearchCriteria paths map directly to Property paths
|
|
139
|
+
// The field names are the same, just used in different contexts
|
|
140
|
+
// Examples:
|
|
141
|
+
// - SearchCriteria.address.city -> Property.address.city
|
|
142
|
+
// - SearchCriteria.building.yearBuilt -> Property.building.yearBuilt
|
|
143
|
+
// - SearchCriteria.assessment.assessmentYear -> Property.assessment.assessmentYear (if exists)
|
|
144
|
+
// Check if the path exists in Property metadata
|
|
145
|
+
if (searchCriteriaPath in metadata_1.PROPERTY_FIELD_METADATA) {
|
|
146
|
+
return searchCriteriaPath;
|
|
147
|
+
}
|
|
148
|
+
// If not found, return undefined to indicate no mapping exists
|
|
149
|
+
// The caller can use this to determine if there's a Property field mapping
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get Property field metadata for a SearchCriteria field path
|
|
154
|
+
* This helps users understand what Property field they're filtering on
|
|
155
|
+
* @param searchCriteriaPath The field path in SearchCriteria (e.g., "address.city", "building.yearBuilt")
|
|
156
|
+
* @returns The Property field metadata, or undefined if not found
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* // When building a search criteria, see what Property field you're filtering on
|
|
160
|
+
* const metadata = getSearchCriteriaFieldMetadata("address.city");
|
|
161
|
+
* console.log(metadata?.description); // "The city (e.g. Chicago)"
|
|
162
|
+
* console.log(metadata?.dataType); // "string"
|
|
163
|
+
*
|
|
164
|
+
* const builder = new AddressSearchCriteriaBuilder();
|
|
165
|
+
* builder.city((c) => {
|
|
166
|
+
* // You're filtering on Property.address.city
|
|
167
|
+
* const meta = getSearchCriteriaFieldMetadata("address.city");
|
|
168
|
+
* console.log(`Filtering on: ${meta?.description}`);
|
|
169
|
+
* c.equals("Phoenix");
|
|
170
|
+
* });
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
function getSearchCriteriaFieldMetadata(searchCriteriaPath) {
|
|
174
|
+
const propertyPath = mapSearchCriteriaToPropertyPath(searchCriteriaPath);
|
|
175
|
+
if (!propertyPath) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
return (0, metadata_1.getFieldMetadata)(propertyPath);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get SearchCriteria field metadata inferred from Property field metadata
|
|
182
|
+
* This creates a SearchCriteria-specific metadata object that references the Property field
|
|
183
|
+
* @param searchCriteriaPath The field path in SearchCriteria (e.g., "address.city", "building.yearBuilt")
|
|
184
|
+
* @returns SearchCriteria field metadata with Property field information
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* // Get metadata for a SearchCriteria field, even if it doesn't map exactly
|
|
188
|
+
* const scMetadata = getSearchCriteriaMetadata("address.city");
|
|
189
|
+
* console.log(scMetadata.description); // "Filter on: The city (e.g. Chicago)"
|
|
190
|
+
* console.log(scMetadata.propertyPath); // "address.city"
|
|
191
|
+
* console.log(scMetadata.hasPropertyMapping); // true
|
|
192
|
+
*
|
|
193
|
+
* // Works even for fields that might not have exact Property mappings
|
|
194
|
+
* const scMetadata2 = getSearchCriteriaMetadata("assessment.assessmentYear");
|
|
195
|
+
* if (scMetadata2.hasPropertyMapping) {
|
|
196
|
+
* console.log(`Filtering on: ${scMetadata2.propertyMetadata?.description}`);
|
|
197
|
+
* }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
function getSearchCriteriaMetadata(searchCriteriaPath) {
|
|
201
|
+
const propertyPath = mapSearchCriteriaToPropertyPath(searchCriteriaPath);
|
|
202
|
+
const propertyMetadata = propertyPath
|
|
203
|
+
? (0, metadata_1.getFieldMetadata)(propertyPath)
|
|
204
|
+
: undefined;
|
|
205
|
+
// Generate description based on Property metadata
|
|
206
|
+
let description;
|
|
207
|
+
if (propertyMetadata) {
|
|
208
|
+
// If we have Property metadata, create a description that explains
|
|
209
|
+
// this SearchCriteria field filters on that Property field
|
|
210
|
+
description = `Filter on: ${propertyMetadata.description}`;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// If no Property metadata, create a generic description
|
|
214
|
+
const parts = searchCriteriaPath.split(".");
|
|
215
|
+
const fieldName = parts[parts.length - 1] || searchCriteriaPath;
|
|
216
|
+
description = `Filter on ${fieldName} field`;
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
searchCriteriaPath,
|
|
220
|
+
propertyPath,
|
|
221
|
+
propertyMetadata: propertyMetadata || undefined,
|
|
222
|
+
hasPropertyMapping: propertyMetadata !== undefined,
|
|
223
|
+
description,
|
|
224
|
+
propertyDataType: propertyMetadata?.dataType,
|
|
225
|
+
dataset: propertyMetadata?.dataset,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get all SearchCriteria field paths that map to a specific Property response group
|
|
230
|
+
* @param propertyGroupName The Property response group name (e.g., "address", "owner", "building")
|
|
231
|
+
* @returns Array of SearchCriteria field paths that filter on fields in that group
|
|
232
|
+
* @example
|
|
233
|
+
* ```typescript
|
|
234
|
+
* // Get all SearchCriteria fields that filter on address fields
|
|
235
|
+
* const addressSearchFields = getSearchCriteriaFieldsForPropertyGroup("address");
|
|
236
|
+
* // Returns: ["address.street", "address.city", "address.state", ...]
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
function getSearchCriteriaFieldsForPropertyGroup(propertyGroupName) {
|
|
240
|
+
// Get all Property fields in this group
|
|
241
|
+
const propertyFields = getPropertyGroupFields(propertyGroupName);
|
|
242
|
+
// Map them to SearchCriteria paths (usually 1:1)
|
|
243
|
+
return propertyFields.map((field) => field.fieldPath);
|
|
244
|
+
}
|
|
245
|
+
function getSearchCriteriaFieldsWithMetadata(propertyGroupName) {
|
|
246
|
+
const propertyFields = getPropertyGroupFields(propertyGroupName);
|
|
247
|
+
return propertyFields.map((field) => ({
|
|
248
|
+
searchCriteriaPath: field.fieldPath,
|
|
249
|
+
propertyPath: field.fieldPath,
|
|
250
|
+
metadata: field,
|
|
251
|
+
}));
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get SearchCriteria metadata for all fields in a Property response group
|
|
255
|
+
* @param propertyGroupName The Property response group name (e.g., "address", "owner", "building")
|
|
256
|
+
* @returns Array of SearchCriteria field metadata objects
|
|
257
|
+
* @example
|
|
258
|
+
* ```typescript
|
|
259
|
+
* // Get all address-related SearchCriteria fields with inferred metadata
|
|
260
|
+
* const addressFields = getSearchCriteriaMetadataForGroup("address");
|
|
261
|
+
* // Returns SearchCriteriaFieldMetadata[] with descriptions like
|
|
262
|
+
* // "Filter on: The city (e.g. Chicago)"
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
function getSearchCriteriaMetadataForGroup(propertyGroupName) {
|
|
266
|
+
const propertyFields = getPropertyGroupFields(propertyGroupName);
|
|
267
|
+
return propertyFields.map((field) => getSearchCriteriaMetadata(field.fieldPath));
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Extract all field paths from a SearchCriteria object
|
|
271
|
+
* Recursively walks through the SearchCriteria structure and collects all field paths
|
|
272
|
+
* @param searchCriteria The SearchCriteria object to analyze
|
|
273
|
+
* @param prefix Optional prefix for nested paths (used internally for recursion)
|
|
274
|
+
* @returns Array of field paths found in the SearchCriteria
|
|
275
|
+
* @example
|
|
276
|
+
* ```typescript
|
|
277
|
+
* const criteria = {
|
|
278
|
+
* address: { city: { equals: "Phoenix" }, state: { equals: "AZ" } },
|
|
279
|
+
* building: { yearBuilt: { min: 1990, max: 2020 } }
|
|
280
|
+
* };
|
|
281
|
+
* const paths = extractSearchCriteriaFieldPaths(criteria);
|
|
282
|
+
* // Returns: ["address.city", "address.state", "building.yearBuilt"]
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
function extractSearchCriteriaFieldPaths(searchCriteria, prefix = "") {
|
|
286
|
+
const paths = [];
|
|
287
|
+
function processValue(value, currentPath) {
|
|
288
|
+
if (value == null) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
// Check if this is a filter object (StringFilter, NumericRangeFilter, etc.)
|
|
292
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
293
|
+
const obj = value;
|
|
294
|
+
const filterKeys = [
|
|
295
|
+
"equals",
|
|
296
|
+
"contains",
|
|
297
|
+
"startsWith",
|
|
298
|
+
"endsWith",
|
|
299
|
+
"inList",
|
|
300
|
+
"notInList",
|
|
301
|
+
"matches",
|
|
302
|
+
"min",
|
|
303
|
+
"max",
|
|
304
|
+
"minDate",
|
|
305
|
+
"maxDate",
|
|
306
|
+
];
|
|
307
|
+
const isFilterObject = filterKeys.some((key) => key in obj);
|
|
308
|
+
if (isFilterObject) {
|
|
309
|
+
// This is a filter object, so the current path is the field path
|
|
310
|
+
if (currentPath) {
|
|
311
|
+
paths.push(currentPath);
|
|
312
|
+
}
|
|
313
|
+
return; // Don't recurse into filter objects
|
|
314
|
+
}
|
|
315
|
+
// It's a nested criteria object, process its properties
|
|
316
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
317
|
+
// Skip special fields
|
|
318
|
+
if (key === "query" ||
|
|
319
|
+
key === "quickList" ||
|
|
320
|
+
key === "quickLists" ||
|
|
321
|
+
key === "orQuickLists" ||
|
|
322
|
+
key === "or") {
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
const fieldPath = currentPath ? `${currentPath}.${key}` : key;
|
|
326
|
+
processValue(val, fieldPath);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else if (Array.isArray(value)) {
|
|
330
|
+
// Handle arrays (like orQuickLists, or criteria)
|
|
331
|
+
value.forEach((item, index) => {
|
|
332
|
+
if (typeof item === "object" && item !== null) {
|
|
333
|
+
processValue(item, `${currentPath}[${index}]`);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Start processing
|
|
339
|
+
for (const [key, value] of Object.entries(searchCriteria)) {
|
|
340
|
+
// Skip special top-level fields
|
|
341
|
+
if (key === "query" ||
|
|
342
|
+
key === "quickList" ||
|
|
343
|
+
key === "quickLists" ||
|
|
344
|
+
key === "orQuickLists" ||
|
|
345
|
+
key === "or") {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
const fieldPath = prefix ? `${prefix}.${key}` : key;
|
|
349
|
+
processValue(value, fieldPath);
|
|
350
|
+
}
|
|
351
|
+
return paths;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Get metadata for all fields present in a SearchCriteria object
|
|
355
|
+
* Extracts all field paths and generates metadata for each one
|
|
356
|
+
* @param searchCriteria The SearchCriteria object to analyze
|
|
357
|
+
* @returns Array of SearchCriteria field metadata for all fields found
|
|
358
|
+
* @example
|
|
359
|
+
* ```typescript
|
|
360
|
+
* const criteria = new SearchCriteriaBuilder("US")
|
|
361
|
+
* .address((a) => {
|
|
362
|
+
* a.city((c) => c.equals("Phoenix"))
|
|
363
|
+
* .state((s) => s.equals("AZ"));
|
|
364
|
+
* })
|
|
365
|
+
* .building((b) => {
|
|
366
|
+
* b.yearBuilt((y) => y.min(1990).max(2020));
|
|
367
|
+
* })
|
|
368
|
+
* .build();
|
|
369
|
+
*
|
|
370
|
+
* const metadata = getSearchCriteriaFieldsMetadata(criteria);
|
|
371
|
+
* // Returns metadata for address.city, address.state, building.yearBuilt
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
function getSearchCriteriaFieldsMetadata(searchCriteria) {
|
|
375
|
+
const fieldPaths = extractSearchCriteriaFieldPaths(searchCriteria);
|
|
376
|
+
return fieldPaths.map((path) => getSearchCriteriaMetadata(path));
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Get metadata for all fields present in a property object
|
|
380
|
+
* Recursively iterates through the property object and collects metadata for each field.
|
|
381
|
+
*
|
|
382
|
+
* Note: This function is designed for Property response objects, not SearchCriteria.
|
|
383
|
+
* The metadata describes Property response fields (their types, descriptions, datasets),
|
|
384
|
+
* which are different from SearchCriteria filter objects.
|
|
385
|
+
*
|
|
386
|
+
* @param property The property object to analyze
|
|
387
|
+
* @param prefix Optional prefix for nested paths (used internally for recursion)
|
|
388
|
+
* @returns Array of field metadata entries
|
|
389
|
+
* @example
|
|
390
|
+
* ```typescript
|
|
391
|
+
* const property = {
|
|
392
|
+
* address: { city: "Phoenix", state: "AZ" },
|
|
393
|
+
* owner: { fullName: "John Doe" }
|
|
394
|
+
* };
|
|
395
|
+
* const metadata = getPropertyFieldsMetadata(property);
|
|
396
|
+
* // Returns metadata for address.city, address.state, owner.fullName
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
function getPropertyFieldsMetadata(property, prefix = "") {
|
|
400
|
+
const entries = [];
|
|
401
|
+
// Helper function to recursively process objects
|
|
402
|
+
function processValue(value, currentPath, depth = 0) {
|
|
403
|
+
// Limit recursion depth to prevent infinite loops
|
|
404
|
+
if (depth > 10) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (value == null) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
// Handle arrays
|
|
411
|
+
if (Array.isArray(value)) {
|
|
412
|
+
// For arrays, check if there's metadata for the array element pattern
|
|
413
|
+
const arrayPath = currentPath ? `${currentPath}.[n]` : "[n]";
|
|
414
|
+
const arrayMetadata = (0, metadata_1.getFieldMetadata)(arrayPath);
|
|
415
|
+
if (arrayMetadata) {
|
|
416
|
+
entries.push({
|
|
417
|
+
fieldPath: currentPath || arrayPath,
|
|
418
|
+
value: value,
|
|
419
|
+
metadata: arrayMetadata,
|
|
420
|
+
hasMetadata: true,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
// Process each element in the array
|
|
424
|
+
value.forEach((item, index) => {
|
|
425
|
+
if (typeof item === "object" && item !== null) {
|
|
426
|
+
processValue(item, `${currentPath}.[${index}]`, depth + 1);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
// Handle objects
|
|
432
|
+
if (typeof value === "object" && value !== null) {
|
|
433
|
+
const obj = value;
|
|
434
|
+
// Process each property in the object
|
|
435
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
436
|
+
const fieldPath = currentPath ? `${currentPath}.${key}` : key;
|
|
437
|
+
// Try to get metadata for this field path
|
|
438
|
+
const metadata = (0, metadata_1.getFieldMetadata)(fieldPath);
|
|
439
|
+
// Add entry for this field
|
|
440
|
+
entries.push({
|
|
441
|
+
fieldPath,
|
|
442
|
+
value: val,
|
|
443
|
+
metadata,
|
|
444
|
+
hasMetadata: metadata !== undefined,
|
|
445
|
+
});
|
|
446
|
+
// Recursively process nested objects
|
|
447
|
+
if (val != null && typeof val === "object" && !Array.isArray(val)) {
|
|
448
|
+
processValue(val, fieldPath, depth + 1);
|
|
449
|
+
}
|
|
450
|
+
else if (Array.isArray(val)) {
|
|
451
|
+
// Process array elements
|
|
452
|
+
processValue(val, fieldPath, depth + 1);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
// Start processing from the root
|
|
458
|
+
if (prefix) {
|
|
459
|
+
processValue(property, prefix, 0);
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
// Process top-level properties
|
|
463
|
+
for (const [key, value] of Object.entries(property)) {
|
|
464
|
+
const fieldPath = key;
|
|
465
|
+
const metadata = (0, metadata_1.getFieldMetadata)(fieldPath);
|
|
466
|
+
entries.push({
|
|
467
|
+
fieldPath,
|
|
468
|
+
value,
|
|
469
|
+
metadata,
|
|
470
|
+
hasMetadata: metadata !== undefined,
|
|
471
|
+
});
|
|
472
|
+
// Recursively process nested objects and arrays
|
|
473
|
+
if (value != null) {
|
|
474
|
+
processValue(value, fieldPath, 0);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return entries;
|
|
479
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@land-catalyst/batch-data-sdk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.19",
|
|
4
4
|
"description": "TypeScript SDK for BatchData.io Property API - Types, Builders, and Utilities",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"lint:fix": "eslint src --fix",
|
|
19
19
|
"format": "prettier --write \"src/**/*.ts\"",
|
|
20
20
|
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
21
|
+
"generate:metadata": "node scripts/generate-property-field-metadata.js",
|
|
22
|
+
"generate:docs": "npx tsx scripts/generate-property-type-docs.ts",
|
|
23
|
+
"add:jsdoc": "node scripts/add-jsdoc-to-types.js",
|
|
21
24
|
"v:patch": "npm version patch && git push --follow-tags",
|
|
22
25
|
"v:minor": "npm version minor && git push --follow-tags",
|
|
23
26
|
"v:major": "npm version major && git push --follow-tags"
|
|
@@ -34,7 +37,7 @@
|
|
|
34
37
|
"license": "MIT",
|
|
35
38
|
"repository": {
|
|
36
39
|
"type": "git",
|
|
37
|
-
"url": "https://github.com/land-catalyst/batch-data-sdk.git"
|
|
40
|
+
"url": "git+https://github.com/land-catalyst/batch-data-sdk.git"
|
|
38
41
|
},
|
|
39
42
|
"dependencies": {
|
|
40
43
|
"axios": "^1.7.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|