@pdtf/schemas 3.6.0-10 → 3.6.0-12
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/.claude/settings.local.json +16 -2
- package/index.js +80 -58
- package/package.json +1 -1
- package/src/schemas/v3/combined.json +6360 -1365
- package/src/schemas/v3/compactSkeleton.txt +278 -3
- package/src/schemas/v3/overlays/baspi4.json +150 -17
- package/src/schemas/v3/overlays/baspi5.json +153 -17
- package/src/schemas/v3/overlays/fme1.json +16 -14
- package/src/schemas/v3/overlays/lpe1.json +48 -30
- package/src/schemas/v3/overlays/nts.json +68 -1
- package/src/schemas/v3/overlays/nts2.json +68 -1
- package/src/schemas/v3/overlays/ntsl.json +68 -1
- package/src/schemas/v3/overlays/ntsl2.json +68 -1
- package/src/schemas/v3/overlays/piq.json +37 -3
- package/src/schemas/v3/overlays/rds.json +117 -8
- package/src/schemas/v3/overlays/ta6.json +28 -10
- package/src/schemas/v3/overlays/ta6ed6.json +6153 -0
- package/src/schemas/v3/overlays/ta7.json +43 -3
- package/src/schemas/v3/overlays/ta7ed5.json +1551 -0
- package/src/schemas/v3/pdtf-transaction.json +3212 -521
- package/src/schemas/v3/skeleton.json +365 -21
- package/src/tests/v3/ta6ed6.test.js +2351 -0
- package/src/tests/v3/ta7ed5.test.js +567 -0
- package/src/utils/extractOverlay.js +76 -10
- package/src/utils/pathSkeleton.js +1 -1
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"Bash(git commit:*)",
|
|
16
16
|
"Bash(git push:*)",
|
|
17
17
|
"Bash(git fetch:*)",
|
|
18
|
-
"Bash(git checkout:*)",
|
|
19
18
|
"Bash(gh pr view:*)",
|
|
20
19
|
"WebFetch(domain:github.com)",
|
|
21
20
|
"Bash(tree:*)",
|
|
@@ -35,7 +34,22 @@
|
|
|
35
34
|
"Bash(base64:*)",
|
|
36
35
|
"Bash(gh issue view:*)",
|
|
37
36
|
"Read(//Users/ed/.claude/**)",
|
|
38
|
-
"Bash(npm init:*)"
|
|
37
|
+
"Bash(npm init:*)",
|
|
38
|
+
"Bash(do echo \"=== printWidth $w ===\")",
|
|
39
|
+
"Bash(pdftoppm:*)",
|
|
40
|
+
"Bash(pdftotext:*)",
|
|
41
|
+
"Bash(/tmp/inspect2.js:*)",
|
|
42
|
+
"Bash(/tmp/inspect3.js:*)",
|
|
43
|
+
"Bash(/tmp/inspect4.js:*)",
|
|
44
|
+
"Bash(/tmp/inspect5.js:*)",
|
|
45
|
+
"Bash(/tmp/inspect6.js:*)",
|
|
46
|
+
"Bash(/tmp/final_inspect.js:*)",
|
|
47
|
+
"Bash(file:*)",
|
|
48
|
+
"Bash(gh pr create:*)",
|
|
49
|
+
"Bash(claude --version)",
|
|
50
|
+
"Bash(gh pr list --head ta6ed6 --json number,title,url)",
|
|
51
|
+
"Bash(gh pr:*)",
|
|
52
|
+
"Bash(sort -t'.' -k1,1n -k2,2n -k3,3n -k4,4n)"
|
|
39
53
|
],
|
|
40
54
|
"deny": []
|
|
41
55
|
}
|
package/index.js
CHANGED
|
@@ -18,7 +18,7 @@ const cacheStats = {
|
|
|
18
18
|
hits: 0,
|
|
19
19
|
misses: 0,
|
|
20
20
|
totalQueries: 0,
|
|
21
|
-
cacheStartTime: Date.now()
|
|
21
|
+
cacheStartTime: Date.now(),
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const verifiedClaimsSchema = require("./src/schemas/verifiedClaims/pdtf-verified-claims.json");
|
|
@@ -75,7 +75,9 @@ const overlaysMap = {
|
|
|
75
75
|
baspiV4: require("./src/schemas/v3/overlays/baspi4.json"),
|
|
76
76
|
baspiV5: require("./src/schemas/v3/overlays/baspi5.json"),
|
|
77
77
|
ta6ed4: require("./src/schemas/v3/overlays/ta6.json"),
|
|
78
|
+
ta6ed6: require("./src/schemas/v3/overlays/ta6ed6.json"),
|
|
78
79
|
ta7ed3: require("./src/schemas/v3/overlays/ta7.json"),
|
|
80
|
+
ta7ed5: require("./src/schemas/v3/overlays/ta7ed5.json"),
|
|
79
81
|
ta10ed3: require("./src/schemas/v3/overlays/ta10.json"),
|
|
80
82
|
lpe1ed4: require("./src/schemas/v3/overlays/lpe1.json"),
|
|
81
83
|
fme1ed2: require("./src/schemas/v3/overlays/fme1.json"),
|
|
@@ -117,21 +119,27 @@ const arrayMerge = (target, source, options) => {
|
|
|
117
119
|
// Detect if this is a required array by checking the parent key
|
|
118
120
|
// Required arrays are property names (camelCase, no spaces)
|
|
119
121
|
// Enum arrays are values (can contain spaces, capitals, etc.)
|
|
120
|
-
const isRequiredArray =
|
|
121
|
-
(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
(item
|
|
134
|
-
|
|
122
|
+
const isRequiredArray =
|
|
123
|
+
target.every(
|
|
124
|
+
(item) =>
|
|
125
|
+
typeof item === "string" &&
|
|
126
|
+
item.length > 0 &&
|
|
127
|
+
// Required field names are typically camelCase without spaces
|
|
128
|
+
!item.includes(" ") &&
|
|
129
|
+
// First character is usually lowercase for field names
|
|
130
|
+
(item[0] === item[0].toLowerCase() ||
|
|
131
|
+
item.startsWith("is") ||
|
|
132
|
+
item.startsWith("has")),
|
|
133
|
+
) &&
|
|
134
|
+
source.every(
|
|
135
|
+
(item) =>
|
|
136
|
+
typeof item === "string" &&
|
|
137
|
+
item.length > 0 &&
|
|
138
|
+
!item.includes(" ") &&
|
|
139
|
+
(item[0] === item[0].toLowerCase() ||
|
|
140
|
+
item.startsWith("is") ||
|
|
141
|
+
item.startsWith("has")),
|
|
142
|
+
);
|
|
135
143
|
|
|
136
144
|
if (isRequiredArray) {
|
|
137
145
|
// Combine required arrays
|
|
@@ -176,7 +184,7 @@ const arrayMerge = (target, source, options) => {
|
|
|
176
184
|
|
|
177
185
|
const getTransactionSchema = (
|
|
178
186
|
schemaId = "https://trust.propdata.org.uk/schemas/v3/pdtf-transaction.json",
|
|
179
|
-
overlays
|
|
187
|
+
overlays,
|
|
180
188
|
) => {
|
|
181
189
|
const sourceSchema = transactionSchemas[schemaId];
|
|
182
190
|
if (!overlays || overlays.length < 1) return sourceSchema;
|
|
@@ -184,7 +192,7 @@ const getTransactionSchema = (
|
|
|
184
192
|
let mergedSchema = JSON.parse(JSON.stringify(sourceSchema)); // Deep copy
|
|
185
193
|
overlays.forEach((overlay) => {
|
|
186
194
|
const overlaySchema = JSON.parse(
|
|
187
|
-
JSON.stringify(overlaysMap[schemaId][overlay] || {})
|
|
195
|
+
JSON.stringify(overlaysMap[schemaId][overlay] || {}),
|
|
188
196
|
); // Deep copy
|
|
189
197
|
mergedSchema = merge(mergedSchema, overlaySchema, { arrayMerge });
|
|
190
198
|
});
|
|
@@ -211,7 +219,7 @@ const getCachedSchemaData = (path, schemaId, overlays) => {
|
|
|
211
219
|
const sourceSchema = getTransactionSchema(schemaId, overlays);
|
|
212
220
|
const pathArray = path.split("/").slice(1);
|
|
213
221
|
let subSchema = sourceSchema;
|
|
214
|
-
|
|
222
|
+
|
|
215
223
|
if (pathArray.length >= 1) {
|
|
216
224
|
subSchema = pathArray.reduce((schema, pathElement) => {
|
|
217
225
|
if (!schema) return undefined;
|
|
@@ -233,7 +241,10 @@ const getCachedSchemaData = (path, schemaId, overlays) => {
|
|
|
233
241
|
}
|
|
234
242
|
} catch (e) {
|
|
235
243
|
// Invalid regex pattern in schema - skip it
|
|
236
|
-
console.warn(
|
|
244
|
+
console.warn(
|
|
245
|
+
`Invalid regex pattern in patternProperties: ${pattern}`,
|
|
246
|
+
e,
|
|
247
|
+
);
|
|
237
248
|
}
|
|
238
249
|
}
|
|
239
250
|
}
|
|
@@ -270,7 +281,7 @@ const getCachedSchemaData = (path, schemaId, overlays) => {
|
|
|
270
281
|
// Add schema to AJV and get validator
|
|
271
282
|
// Only add valid schemas to AJV
|
|
272
283
|
let validator;
|
|
273
|
-
if (subSchema && typeof subSchema ===
|
|
284
|
+
if (subSchema && typeof subSchema === "object") {
|
|
274
285
|
// Check if schema already exists in AJV to avoid duplicates
|
|
275
286
|
validator = ajv.getSchema(cacheKey);
|
|
276
287
|
if (!validator) {
|
|
@@ -287,7 +298,7 @@ const getCachedSchemaData = (path, schemaId, overlays) => {
|
|
|
287
298
|
subSchema,
|
|
288
299
|
validator,
|
|
289
300
|
cacheKey,
|
|
290
|
-
createdAt: Date.now()
|
|
301
|
+
createdAt: Date.now(),
|
|
291
302
|
};
|
|
292
303
|
schemaCache.set(cacheKey, cached);
|
|
293
304
|
} else {
|
|
@@ -353,13 +364,13 @@ const getTitleAtPath = (schema, path, rootPath = path) => {
|
|
|
353
364
|
if (oneOfs) {
|
|
354
365
|
// only single dependency discriminator, oneOf keyword is supported
|
|
355
366
|
const matchingOneOf = oneOfs.find(
|
|
356
|
-
(oneOf) => oneOf["properties"][propertyName]
|
|
367
|
+
(oneOf) => oneOf["properties"][propertyName],
|
|
357
368
|
);
|
|
358
369
|
if (matchingOneOf)
|
|
359
370
|
return getTitleAtPath(
|
|
360
371
|
matchingOneOf["properties"][propertyName],
|
|
361
372
|
subPath,
|
|
362
|
-
rootPath
|
|
373
|
+
rootPath,
|
|
363
374
|
);
|
|
364
375
|
}
|
|
365
376
|
};
|
|
@@ -392,7 +403,7 @@ const validateVerifiedClaims = (verifiedClaims, schemaId, overlays) => {
|
|
|
392
403
|
}
|
|
393
404
|
} else {
|
|
394
405
|
validationErrorsArr.push(
|
|
395
|
-
`Path ${path} is not a valid PDTF schema path
|
|
406
|
+
`Path ${path} is not a valid PDTF schema path`,
|
|
396
407
|
);
|
|
397
408
|
}
|
|
398
409
|
}
|
|
@@ -404,8 +415,11 @@ const validateVerifiedClaims = (verifiedClaims, schemaId, overlays) => {
|
|
|
404
415
|
// Cache management functions
|
|
405
416
|
const getCacheStats = () => {
|
|
406
417
|
const runtime = Date.now() - cacheStats.cacheStartTime;
|
|
407
|
-
const hitRate =
|
|
408
|
-
|
|
418
|
+
const hitRate =
|
|
419
|
+
cacheStats.totalQueries > 0
|
|
420
|
+
? (cacheStats.hits / cacheStats.totalQueries) * 100
|
|
421
|
+
: 0;
|
|
422
|
+
|
|
409
423
|
return {
|
|
410
424
|
totalEntries: schemaCache.size,
|
|
411
425
|
hits: cacheStats.hits,
|
|
@@ -417,8 +431,8 @@ const getCacheStats = () => {
|
|
|
417
431
|
memoryUsage: {
|
|
418
432
|
entriesCount: schemaCache.size,
|
|
419
433
|
// Rough estimate of memory usage per entry
|
|
420
|
-
estimatedSizeKB: Math.round((schemaCache.size * 2) / 1024 * 100) / 100 // Rough estimate
|
|
421
|
-
}
|
|
434
|
+
estimatedSizeKB: Math.round(((schemaCache.size * 2) / 1024) * 100) / 100, // Rough estimate
|
|
435
|
+
},
|
|
422
436
|
};
|
|
423
437
|
};
|
|
424
438
|
|
|
@@ -428,15 +442,17 @@ const getDetailedCacheStats = () => {
|
|
|
428
442
|
key,
|
|
429
443
|
createdAt: value.createdAt,
|
|
430
444
|
age: Date.now() - value.createdAt,
|
|
431
|
-
hasValidator: typeof value.validator ===
|
|
432
|
-
hasSubSchema: value.subSchema !== undefined
|
|
445
|
+
hasValidator: typeof value.validator === "function",
|
|
446
|
+
hasSubSchema: value.subSchema !== undefined,
|
|
433
447
|
}));
|
|
434
448
|
|
|
435
449
|
return {
|
|
436
450
|
...baseStats,
|
|
437
451
|
entries: entries.sort((a, b) => b.createdAt - a.createdAt), // Most recent first
|
|
438
|
-
oldestEntry:
|
|
439
|
-
|
|
452
|
+
oldestEntry:
|
|
453
|
+
entries.length > 0 ? Math.max(...entries.map((e) => e.age)) : 0,
|
|
454
|
+
newestEntry:
|
|
455
|
+
entries.length > 0 ? Math.min(...entries.map((e) => e.age)) : 0,
|
|
440
456
|
};
|
|
441
457
|
};
|
|
442
458
|
|
|
@@ -449,17 +465,17 @@ const clearSchemaCache = (pattern) => {
|
|
|
449
465
|
keysToDelete.push(key);
|
|
450
466
|
}
|
|
451
467
|
});
|
|
452
|
-
keysToDelete.forEach(key => schemaCache.delete(key));
|
|
453
|
-
|
|
468
|
+
keysToDelete.forEach((key) => schemaCache.delete(key));
|
|
469
|
+
|
|
454
470
|
// Also remove matching schemas from AJV
|
|
455
|
-
keysToDelete.forEach(key => {
|
|
471
|
+
keysToDelete.forEach((key) => {
|
|
456
472
|
try {
|
|
457
473
|
ajv.removeSchema(key);
|
|
458
474
|
} catch (e) {
|
|
459
475
|
// Schema might not exist in AJV, ignore
|
|
460
476
|
}
|
|
461
477
|
});
|
|
462
|
-
|
|
478
|
+
|
|
463
479
|
return keysToDelete.length;
|
|
464
480
|
} else {
|
|
465
481
|
// Clear all cache
|
|
@@ -470,20 +486,24 @@ const clearSchemaCache = (pattern) => {
|
|
|
470
486
|
cacheStats.misses = 0;
|
|
471
487
|
cacheStats.totalQueries = 0;
|
|
472
488
|
cacheStats.cacheStartTime = Date.now();
|
|
473
|
-
|
|
489
|
+
|
|
474
490
|
// Also clear AJV's internal cache to prevent duplicates
|
|
475
491
|
ajv.removeSchema();
|
|
476
|
-
|
|
492
|
+
|
|
477
493
|
return entriesCleared;
|
|
478
494
|
}
|
|
479
495
|
};
|
|
480
496
|
|
|
481
|
-
const warmupCache = (
|
|
497
|
+
const warmupCache = (
|
|
498
|
+
paths,
|
|
499
|
+
schemaId = "https://trust.propdata.org.uk/schemas/v3/pdtf-transaction.json",
|
|
500
|
+
overlaysList = [],
|
|
501
|
+
) => {
|
|
482
502
|
const warmupStats = {
|
|
483
503
|
totalAttempted: 0,
|
|
484
504
|
successful: 0,
|
|
485
505
|
failed: 0,
|
|
486
|
-
errors: []
|
|
506
|
+
errors: [],
|
|
487
507
|
};
|
|
488
508
|
|
|
489
509
|
// Default common paths if none provided
|
|
@@ -495,7 +515,7 @@ const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3
|
|
|
495
515
|
"/propertyPack/valuations",
|
|
496
516
|
"/propertyPack/waterAndDrainage",
|
|
497
517
|
"/propertyPack/ownership",
|
|
498
|
-
"/propertyPack/notices"
|
|
518
|
+
"/propertyPack/notices",
|
|
499
519
|
];
|
|
500
520
|
|
|
501
521
|
// Default common overlays if none provided
|
|
@@ -504,14 +524,15 @@ const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3
|
|
|
504
524
|
["baspiV5"],
|
|
505
525
|
["ta6ed4"],
|
|
506
526
|
["nts2023"],
|
|
507
|
-
["baspiV5", "ta6ed4"]
|
|
527
|
+
["baspiV5", "ta6ed4"],
|
|
508
528
|
];
|
|
509
529
|
|
|
510
530
|
const pathsToWarm = paths || defaultPaths;
|
|
511
|
-
const overlaysToWarm =
|
|
531
|
+
const overlaysToWarm =
|
|
532
|
+
overlaysList.length > 0 ? overlaysList : defaultOverlays;
|
|
512
533
|
|
|
513
|
-
pathsToWarm.forEach(path => {
|
|
514
|
-
overlaysToWarm.forEach(overlays => {
|
|
534
|
+
pathsToWarm.forEach((path) => {
|
|
535
|
+
overlaysToWarm.forEach((overlays) => {
|
|
515
536
|
warmupStats.totalAttempted++;
|
|
516
537
|
try {
|
|
517
538
|
// This will populate the cache
|
|
@@ -523,7 +544,7 @@ const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3
|
|
|
523
544
|
warmupStats.errors.push({
|
|
524
545
|
path,
|
|
525
546
|
overlays,
|
|
526
|
-
error: error.message
|
|
547
|
+
error: error.message,
|
|
527
548
|
});
|
|
528
549
|
}
|
|
529
550
|
});
|
|
@@ -535,14 +556,14 @@ const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3
|
|
|
535
556
|
const pruneCacheByAge = (maxAgeMs) => {
|
|
536
557
|
const now = Date.now();
|
|
537
558
|
const keysToDelete = [];
|
|
538
|
-
|
|
559
|
+
|
|
539
560
|
schemaCache.forEach((value, key) => {
|
|
540
561
|
if (now - value.createdAt > maxAgeMs) {
|
|
541
562
|
keysToDelete.push(key);
|
|
542
563
|
}
|
|
543
564
|
});
|
|
544
|
-
|
|
545
|
-
keysToDelete.forEach(key => {
|
|
565
|
+
|
|
566
|
+
keysToDelete.forEach((key) => {
|
|
546
567
|
schemaCache.delete(key);
|
|
547
568
|
try {
|
|
548
569
|
ajv.removeSchema(key);
|
|
@@ -550,21 +571,22 @@ const pruneCacheByAge = (maxAgeMs) => {
|
|
|
550
571
|
// Schema might not exist in AJV, ignore
|
|
551
572
|
}
|
|
552
573
|
});
|
|
553
|
-
|
|
574
|
+
|
|
554
575
|
return keysToDelete.length;
|
|
555
576
|
};
|
|
556
577
|
|
|
557
578
|
const setCacheMaxSize = (maxSize) => {
|
|
558
579
|
if (schemaCache.size <= maxSize) return 0;
|
|
559
|
-
|
|
580
|
+
|
|
560
581
|
// Get entries sorted by creation time (oldest first)
|
|
561
|
-
const entries = Array.from(schemaCache.entries())
|
|
562
|
-
|
|
563
|
-
|
|
582
|
+
const entries = Array.from(schemaCache.entries()).sort(
|
|
583
|
+
(a, b) => a[1].createdAt - b[1].createdAt,
|
|
584
|
+
);
|
|
585
|
+
|
|
564
586
|
const toRemove = schemaCache.size - maxSize;
|
|
565
587
|
const keysToDelete = entries.slice(0, toRemove).map(([key]) => key);
|
|
566
|
-
|
|
567
|
-
keysToDelete.forEach(key => {
|
|
588
|
+
|
|
589
|
+
keysToDelete.forEach((key) => {
|
|
568
590
|
schemaCache.delete(key);
|
|
569
591
|
try {
|
|
570
592
|
ajv.removeSchema(key);
|
|
@@ -572,7 +594,7 @@ const setCacheMaxSize = (maxSize) => {
|
|
|
572
594
|
// Schema might not exist in AJV, ignore
|
|
573
595
|
}
|
|
574
596
|
});
|
|
575
|
-
|
|
597
|
+
|
|
576
598
|
return keysToDelete.length;
|
|
577
599
|
};
|
|
578
600
|
|