@pdtf/schemas 3.6.0-1 → 3.6.0-11

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.
@@ -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 = target.every(
121
- (item) =>
122
- typeof item === "string" &&
123
- item.length > 0 &&
124
- // Required field names are typically camelCase without spaces
125
- !item.includes(" ") &&
126
- // First character is usually lowercase for field names
127
- (item[0] === item[0].toLowerCase() || item.startsWith("is") || item.startsWith("has"))
128
- ) && source.every(
129
- (item) =>
130
- typeof item === "string" &&
131
- item.length > 0 &&
132
- !item.includes(" ") &&
133
- (item[0] === item[0].toLowerCase() || item.startsWith("is") || item.startsWith("has"))
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(`Invalid regex pattern in patternProperties: ${pattern}`, e);
244
+ console.warn(
245
+ `Invalid regex pattern in patternProperties: ${pattern}`,
246
+ e,
247
+ );
237
248
  }
238
249
  }
239
250
  }
@@ -246,6 +257,18 @@ const getCachedSchemaData = (path, schemaId, overlays) => {
246
257
  matchingProperty = aOneOf.items;
247
258
  } else if (aOneOf.properties?.[pathElement]) {
248
259
  matchingProperty = aOneOf.properties?.[pathElement];
260
+ } else if (aOneOf.patternProperties) {
261
+ for (const pattern in aOneOf.patternProperties) {
262
+ try {
263
+ const regex = new RegExp(pattern);
264
+ if (regex.test(pathElement)) {
265
+ matchingProperty = aOneOf.patternProperties[pattern];
266
+ break;
267
+ }
268
+ } catch (e) {
269
+ // Invalid regex pattern - skip
270
+ }
271
+ }
249
272
  }
250
273
  });
251
274
  if (matchingProperty) return matchingProperty;
@@ -258,7 +281,7 @@ const getCachedSchemaData = (path, schemaId, overlays) => {
258
281
  // Add schema to AJV and get validator
259
282
  // Only add valid schemas to AJV
260
283
  let validator;
261
- if (subSchema && typeof subSchema === 'object') {
284
+ if (subSchema && typeof subSchema === "object") {
262
285
  // Check if schema already exists in AJV to avoid duplicates
263
286
  validator = ajv.getSchema(cacheKey);
264
287
  if (!validator) {
@@ -275,7 +298,7 @@ const getCachedSchemaData = (path, schemaId, overlays) => {
275
298
  subSchema,
276
299
  validator,
277
300
  cacheKey,
278
- createdAt: Date.now()
301
+ createdAt: Date.now(),
279
302
  };
280
303
  schemaCache.set(cacheKey, cached);
281
304
  } else {
@@ -341,13 +364,13 @@ const getTitleAtPath = (schema, path, rootPath = path) => {
341
364
  if (oneOfs) {
342
365
  // only single dependency discriminator, oneOf keyword is supported
343
366
  const matchingOneOf = oneOfs.find(
344
- (oneOf) => oneOf["properties"][propertyName]
367
+ (oneOf) => oneOf["properties"][propertyName],
345
368
  );
346
369
  if (matchingOneOf)
347
370
  return getTitleAtPath(
348
371
  matchingOneOf["properties"][propertyName],
349
372
  subPath,
350
- rootPath
373
+ rootPath,
351
374
  );
352
375
  }
353
376
  };
@@ -380,7 +403,7 @@ const validateVerifiedClaims = (verifiedClaims, schemaId, overlays) => {
380
403
  }
381
404
  } else {
382
405
  validationErrorsArr.push(
383
- `Path ${path} is not a valid PDTF schema path`
406
+ `Path ${path} is not a valid PDTF schema path`,
384
407
  );
385
408
  }
386
409
  }
@@ -392,8 +415,11 @@ const validateVerifiedClaims = (verifiedClaims, schemaId, overlays) => {
392
415
  // Cache management functions
393
416
  const getCacheStats = () => {
394
417
  const runtime = Date.now() - cacheStats.cacheStartTime;
395
- const hitRate = cacheStats.totalQueries > 0 ? (cacheStats.hits / cacheStats.totalQueries * 100) : 0;
396
-
418
+ const hitRate =
419
+ cacheStats.totalQueries > 0
420
+ ? (cacheStats.hits / cacheStats.totalQueries) * 100
421
+ : 0;
422
+
397
423
  return {
398
424
  totalEntries: schemaCache.size,
399
425
  hits: cacheStats.hits,
@@ -405,8 +431,8 @@ const getCacheStats = () => {
405
431
  memoryUsage: {
406
432
  entriesCount: schemaCache.size,
407
433
  // Rough estimate of memory usage per entry
408
- estimatedSizeKB: Math.round((schemaCache.size * 2) / 1024 * 100) / 100 // Rough estimate
409
- }
434
+ estimatedSizeKB: Math.round(((schemaCache.size * 2) / 1024) * 100) / 100, // Rough estimate
435
+ },
410
436
  };
411
437
  };
412
438
 
@@ -416,15 +442,17 @@ const getDetailedCacheStats = () => {
416
442
  key,
417
443
  createdAt: value.createdAt,
418
444
  age: Date.now() - value.createdAt,
419
- hasValidator: typeof value.validator === 'function',
420
- hasSubSchema: value.subSchema !== undefined
445
+ hasValidator: typeof value.validator === "function",
446
+ hasSubSchema: value.subSchema !== undefined,
421
447
  }));
422
448
 
423
449
  return {
424
450
  ...baseStats,
425
451
  entries: entries.sort((a, b) => b.createdAt - a.createdAt), // Most recent first
426
- oldestEntry: entries.length > 0 ? Math.max(...entries.map(e => e.age)) : 0,
427
- newestEntry: entries.length > 0 ? Math.min(...entries.map(e => e.age)) : 0
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,
428
456
  };
429
457
  };
430
458
 
@@ -437,17 +465,17 @@ const clearSchemaCache = (pattern) => {
437
465
  keysToDelete.push(key);
438
466
  }
439
467
  });
440
- keysToDelete.forEach(key => schemaCache.delete(key));
441
-
468
+ keysToDelete.forEach((key) => schemaCache.delete(key));
469
+
442
470
  // Also remove matching schemas from AJV
443
- keysToDelete.forEach(key => {
471
+ keysToDelete.forEach((key) => {
444
472
  try {
445
473
  ajv.removeSchema(key);
446
474
  } catch (e) {
447
475
  // Schema might not exist in AJV, ignore
448
476
  }
449
477
  });
450
-
478
+
451
479
  return keysToDelete.length;
452
480
  } else {
453
481
  // Clear all cache
@@ -458,20 +486,24 @@ const clearSchemaCache = (pattern) => {
458
486
  cacheStats.misses = 0;
459
487
  cacheStats.totalQueries = 0;
460
488
  cacheStats.cacheStartTime = Date.now();
461
-
489
+
462
490
  // Also clear AJV's internal cache to prevent duplicates
463
491
  ajv.removeSchema();
464
-
492
+
465
493
  return entriesCleared;
466
494
  }
467
495
  };
468
496
 
469
- const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3/pdtf-transaction.json", overlaysList = []) => {
497
+ const warmupCache = (
498
+ paths,
499
+ schemaId = "https://trust.propdata.org.uk/schemas/v3/pdtf-transaction.json",
500
+ overlaysList = [],
501
+ ) => {
470
502
  const warmupStats = {
471
503
  totalAttempted: 0,
472
504
  successful: 0,
473
505
  failed: 0,
474
- errors: []
506
+ errors: [],
475
507
  };
476
508
 
477
509
  // Default common paths if none provided
@@ -483,7 +515,7 @@ const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3
483
515
  "/propertyPack/valuations",
484
516
  "/propertyPack/waterAndDrainage",
485
517
  "/propertyPack/ownership",
486
- "/propertyPack/notices"
518
+ "/propertyPack/notices",
487
519
  ];
488
520
 
489
521
  // Default common overlays if none provided
@@ -492,14 +524,15 @@ const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3
492
524
  ["baspiV5"],
493
525
  ["ta6ed4"],
494
526
  ["nts2023"],
495
- ["baspiV5", "ta6ed4"]
527
+ ["baspiV5", "ta6ed4"],
496
528
  ];
497
529
 
498
530
  const pathsToWarm = paths || defaultPaths;
499
- const overlaysToWarm = overlaysList.length > 0 ? overlaysList : defaultOverlays;
531
+ const overlaysToWarm =
532
+ overlaysList.length > 0 ? overlaysList : defaultOverlays;
500
533
 
501
- pathsToWarm.forEach(path => {
502
- overlaysToWarm.forEach(overlays => {
534
+ pathsToWarm.forEach((path) => {
535
+ overlaysToWarm.forEach((overlays) => {
503
536
  warmupStats.totalAttempted++;
504
537
  try {
505
538
  // This will populate the cache
@@ -511,7 +544,7 @@ const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3
511
544
  warmupStats.errors.push({
512
545
  path,
513
546
  overlays,
514
- error: error.message
547
+ error: error.message,
515
548
  });
516
549
  }
517
550
  });
@@ -523,14 +556,14 @@ const warmupCache = (paths, schemaId = "https://trust.propdata.org.uk/schemas/v3
523
556
  const pruneCacheByAge = (maxAgeMs) => {
524
557
  const now = Date.now();
525
558
  const keysToDelete = [];
526
-
559
+
527
560
  schemaCache.forEach((value, key) => {
528
561
  if (now - value.createdAt > maxAgeMs) {
529
562
  keysToDelete.push(key);
530
563
  }
531
564
  });
532
-
533
- keysToDelete.forEach(key => {
565
+
566
+ keysToDelete.forEach((key) => {
534
567
  schemaCache.delete(key);
535
568
  try {
536
569
  ajv.removeSchema(key);
@@ -538,21 +571,22 @@ const pruneCacheByAge = (maxAgeMs) => {
538
571
  // Schema might not exist in AJV, ignore
539
572
  }
540
573
  });
541
-
574
+
542
575
  return keysToDelete.length;
543
576
  };
544
577
 
545
578
  const setCacheMaxSize = (maxSize) => {
546
579
  if (schemaCache.size <= maxSize) return 0;
547
-
580
+
548
581
  // Get entries sorted by creation time (oldest first)
549
- const entries = Array.from(schemaCache.entries())
550
- .sort((a, b) => a[1].createdAt - b[1].createdAt);
551
-
582
+ const entries = Array.from(schemaCache.entries()).sort(
583
+ (a, b) => a[1].createdAt - b[1].createdAt,
584
+ );
585
+
552
586
  const toRemove = schemaCache.size - maxSize;
553
587
  const keysToDelete = entries.slice(0, toRemove).map(([key]) => key);
554
-
555
- keysToDelete.forEach(key => {
588
+
589
+ keysToDelete.forEach((key) => {
556
590
  schemaCache.delete(key);
557
591
  try {
558
592
  ajv.removeSchema(key);
@@ -560,7 +594,7 @@ const setCacheMaxSize = (maxSize) => {
560
594
  // Schema might not exist in AJV, ignore
561
595
  }
562
596
  });
563
-
597
+
564
598
  return keysToDelete.length;
565
599
  };
566
600
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdtf/schemas",
3
- "version": "3.6.0-1",
3
+ "version": "3.6.0-11",
4
4
  "description": "Property Data Trust Framework Schemas and Utilities",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -8,7 +8,8 @@
8
8
  },
9
9
  "scripts": {
10
10
  "test": "jest",
11
- "test:watch": "jest --watch"
11
+ "test:watch": "jest --watch",
12
+ "extract-overlays": "cd src/utils && node extractOverlay.js"
12
13
  },
13
14
  "repository": {
14
15
  "type": "git",