@pdtf/schemas 3.6.0-dev.3 → 3.6.0-dev.32

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.
Files changed (193) hide show
  1. package/docs/ta6-certificate-permit-contract.md +51 -0
  2. package/docs/v4-mapping-and-recomposition.md +476 -0
  3. package/index.js +212 -0
  4. package/package.json +10 -1
  5. package/src/schemas/v3/combined.json +2267 -658
  6. package/src/schemas/v3/compactSkeleton.txt +120 -51
  7. package/src/schemas/v3/overlays/baspi4.json +54 -74
  8. package/src/schemas/v3/overlays/baspi5.json +54 -74
  9. package/src/schemas/v3/overlays/extensions/ac.json +2 -1
  10. package/src/schemas/v3/overlays/extensions/dk.json +3 -2
  11. package/src/schemas/v3/overlays/extensions/fd.json +2 -1
  12. package/src/schemas/v3/overlays/extensions/ic.json +44 -9
  13. package/src/schemas/v3/overlays/extensions/lc.json +3 -2
  14. package/src/schemas/v3/overlays/extensions/mi.json +2 -1
  15. package/src/schemas/v3/overlays/extensions/nd.json +3 -2
  16. package/src/schemas/v3/overlays/extensions/pc.json +3 -2
  17. package/src/schemas/v3/overlays/extensions/ph.json +2 -1
  18. package/src/schemas/v3/overlays/extensions/rw.json +4 -3
  19. package/src/schemas/v3/overlays/extensions/sc.json +8 -4
  20. package/src/schemas/v3/overlays/extensions/sd.json +3 -2
  21. package/src/schemas/v3/overlays/extensions/tr.json +3 -2
  22. package/src/schemas/v3/overlays/extensions/wg.json +2 -1
  23. package/src/schemas/v3/overlays/llc1.json +1 -2
  24. package/src/schemas/v3/overlays/lpe1.json +3 -2
  25. package/src/schemas/v3/overlays/nts.json +7 -3
  26. package/src/schemas/v3/overlays/nts2.json +9 -4
  27. package/src/schemas/v3/overlays/ntsl.json +5 -2
  28. package/src/schemas/v3/overlays/ntsl2.json +7 -3
  29. package/src/schemas/v3/overlays/piq.json +34 -25
  30. package/src/schemas/v3/overlays/rds.json +24 -50
  31. package/src/schemas/v3/overlays/sef25.json +16 -2
  32. package/src/schemas/v3/overlays/ta10.json +0 -9
  33. package/src/schemas/v3/overlays/ta6.json +39 -70
  34. package/src/schemas/v3/overlays/ta6ed6.json +331 -307
  35. package/{pensive-tesla-d0d355/src/schemas/v3/overlays/ta6.json → src/schemas/v3/overlays/ta6ed6v2.json} +1574 -1464
  36. package/src/schemas/v3/overlays/ta7.json +2 -1
  37. package/src/schemas/v3/overlays/ta7ed5.json +77 -21
  38. package/src/schemas/v3/pdtf-transaction.json +1030 -492
  39. package/src/schemas/v3/skeleton.json +163 -57
  40. package/src/schemas/v4/Gift.json +88 -0
  41. package/src/schemas/v4/Offer.json +425 -0
  42. package/src/schemas/v4/Organisation.json +167 -0
  43. package/src/schemas/v4/Person.json +321 -0
  44. package/src/schemas/v4/Property.json +27813 -0
  45. package/src/schemas/v4/PropertyTitleLink.json +183 -0
  46. package/src/schemas/v4/Representation.json +67 -0
  47. package/src/schemas/v4/SellerCapacity.json +193 -0
  48. package/src/schemas/v4/Title.json +14675 -0
  49. package/src/schemas/v4/Transaction.json +1612 -0
  50. package/src/schemas/v4/TransactionRole.json +59 -0
  51. package/src/schemas/v4/mapping.json +1188 -0
  52. package/src/utils/checkTa6OmissionCompatibility.js +146 -0
  53. package/src/utils/extractExtensionOverlays.js +11 -2
  54. package/src/utils/extractOverlay.js +21 -0
  55. package/src/utils/generateV4Schemas.js +1561 -0
  56. package/src/utils/syncTa6ed6v2Markers.js +92 -0
  57. package/src/utils/v4.js +956 -0
  58. package/CLAUDE.md +0 -101
  59. package/pensive-tesla-d0d355/CLAUDE.md +0 -101
  60. package/pensive-tesla-d0d355/LICENSE +0 -21
  61. package/pensive-tesla-d0d355/README.md +0 -435
  62. package/pensive-tesla-d0d355/docs/branch-release-workflow.md +0 -138
  63. package/pensive-tesla-d0d355/docs/sef25-extensions-ui-spec.md +0 -355
  64. package/pensive-tesla-d0d355/index.js +0 -654
  65. package/pensive-tesla-d0d355/package-lock.json +0 -7297
  66. package/pensive-tesla-d0d355/package.json +0 -44
  67. package/pensive-tesla-d0d355/src/examples/v1/exampleAddParticipantVouch.json +0 -32
  68. package/pensive-tesla-d0d355/src/examples/v1/exampleDocumentedVouch.json +0 -40
  69. package/pensive-tesla-d0d355/src/examples/v1/exampleElectronicRecord.json +0 -30
  70. package/pensive-tesla-d0d355/src/examples/v1/exampleTransaction.json +0 -878
  71. package/pensive-tesla-d0d355/src/examples/v1/exampleVouch.json +0 -25
  72. package/pensive-tesla-d0d355/src/examples/v2/exampleTransaction.json +0 -901
  73. package/pensive-tesla-d0d355/src/examples/v3/exampleAddParticipantVouch.json +0 -38
  74. package/pensive-tesla-d0d355/src/examples/v3/exampleCustomOverlay.json +0 -55
  75. package/pensive-tesla-d0d355/src/examples/v3/exampleCustomOverlay2.json +0 -93
  76. package/pensive-tesla-d0d355/src/examples/v3/exampleDocumentedVouch.json +0 -47
  77. package/pensive-tesla-d0d355/src/examples/v3/exampleElectronicRecord.json +0 -36
  78. package/pensive-tesla-d0d355/src/examples/v3/exampleTransaction.json +0 -1038
  79. package/pensive-tesla-d0d355/src/examples/v3/exampleVouch.json +0 -32
  80. package/pensive-tesla-d0d355/src/mappings/SendPropertyDetailsRequestSchema.json +0 -1588
  81. package/pensive-tesla-d0d355/src/mappings/adf.js +0 -198
  82. package/pensive-tesla-d0d355/src/schemas/v1/GeoJSON.json +0 -1279
  83. package/pensive-tesla-d0d355/src/schemas/v1/baspiNotes.html +0 -102
  84. package/pensive-tesla-d0d355/src/schemas/v1/energy-performance-certificate.json +0 -124
  85. package/pensive-tesla-d0d355/src/schemas/v1/freehold-information.json +0 -2051
  86. package/pensive-tesla-d0d355/src/schemas/v1/leasehold-information.json +0 -2064
  87. package/pensive-tesla-d0d355/src/schemas/v1/legal-information.json +0 -1045
  88. package/pensive-tesla-d0d355/src/schemas/v1/material-facts.json +0 -2109
  89. package/pensive-tesla-d0d355/src/schemas/v1/pdtf-transaction-search-results.json +0 -40
  90. package/pensive-tesla-d0d355/src/schemas/v1/pdtf-transaction.json +0 -191
  91. package/pensive-tesla-d0d355/src/schemas/v1/searches/drainage-and-water.json +0 -261
  92. package/pensive-tesla-d0d355/src/schemas/v1/searches/local-land-charges.json +0 -69
  93. package/pensive-tesla-d0d355/src/schemas/v1/searches/local-searches-required.json +0 -857
  94. package/pensive-tesla-d0d355/src/schemas/v1/searches.json +0 -237
  95. package/pensive-tesla-d0d355/src/schemas/v1/title-deed.json +0 -841
  96. package/pensive-tesla-d0d355/src/schemas/v2/baspiNotes.html +0 -102
  97. package/pensive-tesla-d0d355/src/schemas/v2/combined.json +0 -37731
  98. package/pensive-tesla-d0d355/src/schemas/v2/overlays/baspi.json +0 -8132
  99. package/pensive-tesla-d0d355/src/schemas/v2/overlays/con29DW.json +0 -705
  100. package/pensive-tesla-d0d355/src/schemas/v2/overlays/con29R.json +0 -2956
  101. package/pensive-tesla-d0d355/src/schemas/v2/overlays/fme1.json +0 -1259
  102. package/pensive-tesla-d0d355/src/schemas/v2/overlays/llc1.json +0 -25
  103. package/pensive-tesla-d0d355/src/schemas/v2/overlays/lpe1.json +0 -2171
  104. package/pensive-tesla-d0d355/src/schemas/v2/overlays/nts.json +0 -326
  105. package/pensive-tesla-d0d355/src/schemas/v2/overlays/oc1.json +0 -2799
  106. package/pensive-tesla-d0d355/src/schemas/v2/overlays/piq.json +0 -3419
  107. package/pensive-tesla-d0d355/src/schemas/v2/overlays/rds.json +0 -3736
  108. package/pensive-tesla-d0d355/src/schemas/v2/overlays/ta10.json +0 -5306
  109. package/pensive-tesla-d0d355/src/schemas/v2/overlays/ta6.json +0 -4533
  110. package/pensive-tesla-d0d355/src/schemas/v2/overlays/ta7.json +0 -1045
  111. package/pensive-tesla-d0d355/src/schemas/v2/pdtf-transaction.json +0 -34351
  112. package/pensive-tesla-d0d355/src/schemas/v2/skeleton.json +0 -3973
  113. package/pensive-tesla-d0d355/src/schemas/v3/combined.json +0 -48469
  114. package/pensive-tesla-d0d355/src/schemas/v3/compactSkeleton.txt +0 -4519
  115. package/pensive-tesla-d0d355/src/schemas/v3/overlays/README.md +0 -299
  116. package/pensive-tesla-d0d355/src/schemas/v3/overlays/baspi4.json +0 -8025
  117. package/pensive-tesla-d0d355/src/schemas/v3/overlays/baspi5.json +0 -8175
  118. package/pensive-tesla-d0d355/src/schemas/v3/overlays/con29DW.json +0 -716
  119. package/pensive-tesla-d0d355/src/schemas/v3/overlays/con29R.json +0 -2981
  120. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/ac.json +0 -333
  121. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/as.json +0 -74
  122. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/dk.json +0 -32
  123. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/dr.json +0 -73
  124. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/er.json +0 -85
  125. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/fd.json +0 -75
  126. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/hi.json +0 -51
  127. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/hs.json +0 -73
  128. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/ic.json +0 -59
  129. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/jk.json +0 -96
  130. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/la.json +0 -85
  131. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/lc.json +0 -75
  132. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/ma.json +0 -90
  133. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/mc.json +0 -38
  134. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/mi.json +0 -69
  135. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/nd.json +0 -43
  136. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/oa.json +0 -24
  137. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/oc.json +0 -57
  138. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/pc.json +0 -37
  139. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/ph.json +0 -194
  140. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/rw.json +0 -68
  141. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/sb.json +0 -73
  142. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/sc.json +0 -129
  143. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/sd.json +0 -63
  144. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/sf.json +0 -74
  145. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/sl.json +0 -68
  146. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/ta.json +0 -252
  147. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/tf.json +0 -103
  148. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/tr.json +0 -73
  149. package/pensive-tesla-d0d355/src/schemas/v3/overlays/extensions/wg.json +0 -350
  150. package/pensive-tesla-d0d355/src/schemas/v3/overlays/fme1.json +0 -1266
  151. package/pensive-tesla-d0d355/src/schemas/v3/overlays/llc1.json +0 -25
  152. package/pensive-tesla-d0d355/src/schemas/v3/overlays/lpe1.json +0 -2199
  153. package/pensive-tesla-d0d355/src/schemas/v3/overlays/nts.json +0 -2157
  154. package/pensive-tesla-d0d355/src/schemas/v3/overlays/nts2.json +0 -2742
  155. package/pensive-tesla-d0d355/src/schemas/v3/overlays/ntsl.json +0 -1813
  156. package/pensive-tesla-d0d355/src/schemas/v3/overlays/ntsl2.json +0 -2217
  157. package/pensive-tesla-d0d355/src/schemas/v3/overlays/oc1.json +0 -2817
  158. package/pensive-tesla-d0d355/src/schemas/v3/overlays/piq.json +0 -3322
  159. package/pensive-tesla-d0d355/src/schemas/v3/overlays/rds.json +0 -3665
  160. package/pensive-tesla-d0d355/src/schemas/v3/overlays/sef25.json +0 -1639
  161. package/pensive-tesla-d0d355/src/schemas/v3/overlays/sr24.json +0 -38
  162. package/pensive-tesla-d0d355/src/schemas/v3/overlays/ta10.json +0 -4654
  163. package/pensive-tesla-d0d355/src/schemas/v3/overlays/ta6ed6.json +0 -6534
  164. package/pensive-tesla-d0d355/src/schemas/v3/overlays/ta7.json +0 -1537
  165. package/pensive-tesla-d0d355/src/schemas/v3/overlays/ta7ed5.json +0 -1551
  166. package/pensive-tesla-d0d355/src/schemas/v3/pdtf-transaction.json +0 -41573
  167. package/pensive-tesla-d0d355/src/schemas/v3/skeleton.json +0 -5767
  168. package/pensive-tesla-d0d355/src/schemas/verifiedClaims/README.md +0 -21
  169. package/pensive-tesla-d0d355/src/schemas/verifiedClaims/pdtf-verified-claims.json +0 -447
  170. package/pensive-tesla-d0d355/src/utils/compactSkeleton.js +0 -84
  171. package/pensive-tesla-d0d355/src/utils/countTokens.js +0 -67
  172. package/pensive-tesla-d0d355/src/utils/extractExtensionOverlays.js +0 -624
  173. package/pensive-tesla-d0d355/src/utils/extractOverlay.js +0 -381
  174. package/pensive-tesla-d0d355/src/utils/extractProperties.js +0 -44
  175. package/pensive-tesla-d0d355/src/utils/listPathTitles.js +0 -36
  176. package/pensive-tesla-d0d355/src/utils/minimalSkeleton.js +0 -85
  177. package/pensive-tesla-d0d355/src/utils/pathList.csv +0 -903
  178. package/pensive-tesla-d0d355/src/utils/pathSkeleton.js +0 -181
  179. package/src/examples/v1/exampleAddParticipantVouch.json +0 -32
  180. package/src/examples/v1/exampleDocumentedVouch.json +0 -40
  181. package/src/examples/v1/exampleElectronicRecord.json +0 -30
  182. package/src/examples/v1/exampleTransaction.json +0 -878
  183. package/src/examples/v1/exampleVouch.json +0 -25
  184. package/src/examples/v2/exampleTransaction.json +0 -901
  185. package/src/examples/v3/exampleAddParticipantVouch.json +0 -38
  186. package/src/examples/v3/exampleCustomOverlay.json +0 -55
  187. package/src/examples/v3/exampleCustomOverlay2.json +0 -93
  188. package/src/examples/v3/exampleDocumentedVouch.json +0 -47
  189. package/src/examples/v3/exampleElectronicRecord.json +0 -36
  190. package/src/examples/v3/exampleTransaction.json +0 -1038
  191. package/src/examples/v3/exampleVouch.json +0 -32
  192. package/src/mappings/SendPropertyDetailsRequestSchema.json +0 -1588
  193. package/src/mappings/adf.js +0 -198
@@ -1,624 +0,0 @@
1
- const traverse = require("traverse");
2
- const jp = require("jsonpointer");
3
- const fs = require("fs");
4
- const path = require("path");
5
-
6
- const combinedSchema = require("../schemas/v3/combined.json");
7
-
8
- // Derive ref-related field names from a refType
9
- function getRefConfig(refType) {
10
- if (refType === "nts2Ref") {
11
- // Legacy mapping: nts2Ref -> ntsRef in output
12
- return {
13
- ref: "nts2Ref",
14
- outputRef: "ntsRef",
15
- required: "nts2Required",
16
- title: "nts2Title",
17
- description: "nts2Description",
18
- enumKey: "nts2Enum",
19
- };
20
- }
21
- if (refType === "sef25Ref") {
22
- // SEF25 extensions also appear as ntsRef in output
23
- return {
24
- ref: "sef25Ref",
25
- outputRef: "ntsRef",
26
- required: "sef25Required",
27
- title: "sef25Title",
28
- description: "sef25Description",
29
- enumKey: "sef25Enum",
30
- };
31
- }
32
- // For other ref types, derive keys by replacing "Ref" suffix
33
- return {
34
- ref: refType,
35
- outputRef: refType,
36
- required: refType.replace("Ref", "Required"),
37
- title: refType.replace("Ref", "Title"),
38
- description: refType.replace("Ref", "Description"),
39
- enumKey: refType.replace("Ref", "Enum"),
40
- };
41
- }
42
-
43
- // Define the extension overlay mappings
44
- const extensionMappings = {
45
- // Outside areas
46
- oa: {
47
- name: "outsideAreas",
48
- description: "Outside areas extension for NTS",
49
- paths: [
50
- "/properties/propertyPack/properties/residentialPropertyFeatures/properties/outsideAreas",
51
- ],
52
- },
53
-
54
- // Estate rentcharges for freehold
55
- er: {
56
- name: "estateRentcharges",
57
- description: "Estate rentcharges for freehold properties",
58
- paths: [
59
- "/properties/propertyPack/properties/ownership/properties/ownershipsToBeTransferred/items/oneOf/0/properties/estateRentcharges",
60
- ],
61
- },
62
-
63
- // Managing agent contact details for leasehold
64
- ma: {
65
- name: "managingAgent",
66
- description: "Managing agent contact details for leasehold",
67
- paths: [
68
- "/properties/propertyPack/properties/ownership/properties/ownershipsToBeTransferred/items/oneOf/2/properties/leaseholdInformation/properties/contactDetails",
69
- ],
70
- },
71
-
72
- // Transfer fees for leasehold
73
- tf: {
74
- name: "transferFees",
75
- description: "Transfer fees for leasehold",
76
- paths: [
77
- "/properties/propertyPack/properties/ownership/properties/ownershipsToBeTransferred/items/oneOf/2/properties/leaseholdInformation/properties/serviceCharge/oneOf/1/properties/transferFees",
78
- ],
79
- },
80
-
81
- // Main construction type if standard
82
- mc: {
83
- name: "mainConstruction",
84
- description: "Main construction type if standard form",
85
- paths: [
86
- "/properties/propertyPack/properties/typeOfConstruction/properties/isStandardForm/oneOf/0/properties/constructionType",
87
- ],
88
- },
89
-
90
- // Loft access and details
91
- la: {
92
- name: "loftAccess",
93
- description: "Loft access and details",
94
- paths: [
95
- "/properties/propertyPack/properties/typeOfConstruction/properties/loft",
96
- ],
97
- },
98
-
99
- // Spray foam insulation
100
- sf: {
101
- name: "sprayFoam",
102
- description: "Spray foam insulation",
103
- paths: [
104
- "/properties/propertyPack/properties/typeOfConstruction/properties/sprayFoamInsulation",
105
- ],
106
- },
107
-
108
- // Specialist issues - dry rot
109
- dr: {
110
- name: "dryRot",
111
- description: "Dry rot treatment specialist issue",
112
- paths: [
113
- "/properties/propertyPack/properties/specialistIssues/properties/dryRotEtcTreatment",
114
- ],
115
- },
116
-
117
- // Specialist issues - asbestos
118
- as: {
119
- name: "asbestos",
120
- description: "Asbestos specialist issue",
121
- paths: [
122
- "/properties/propertyPack/properties/specialistIssues/properties/containsAsbestos",
123
- ],
124
- },
125
-
126
- // Specialist issues - Japanese knotweed
127
- jk: {
128
- name: "japaneseKnotweed",
129
- description: "Japanese knotweed specialist issue",
130
- paths: [
131
- "/properties/propertyPack/properties/specialistIssues/properties/japaneseKnotweed",
132
- ],
133
- },
134
-
135
- // Specialist issues - subsidence
136
- sb: {
137
- name: "subsidence",
138
- description: "Subsidence or structural fault specialist issue",
139
- paths: [
140
- "/properties/propertyPack/properties/specialistIssues/properties/subsidenceOrStructuralFault",
141
- ],
142
- },
143
-
144
- // Specialist issues - health and safety
145
- hs: {
146
- name: "healthSafety",
147
- description: "Health and safety specialist issue",
148
- paths: [
149
- "/properties/propertyPack/properties/specialistIssues/properties/ongoingHealthOrSafetyIssue",
150
- ],
151
- },
152
-
153
- // Solar panels leased
154
- sl: {
155
- name: "solarPanelsLeased",
156
- description: "Solar panels ownership details",
157
- paths: [
158
- "/properties/propertyPack/properties/electricity/properties/solarPanels/oneOf/1/properties/panelsOwnedOutright",
159
- ],
160
- },
161
-
162
- // Heating installation date
163
- hi: {
164
- name: "heatingInstalled",
165
- description: "Central heating installation date",
166
- paths: [
167
- "/properties/propertyPack/properties/heating/properties/heatingSystem/oneOf/1/properties/centralHeatingDetails/properties/centralHeatingInstalled",
168
- ],
169
- },
170
-
171
- // Flood defences
172
- fd: {
173
- name: "floodDefences",
174
- description: "Flood defence information",
175
- paths: [
176
- "/properties/propertyPack/properties/environmentalIssues/properties/flooding/properties/floodDefences",
177
- ],
178
- },
179
-
180
- // Other property in chain
181
- oc: {
182
- name: "otherPropertyChain",
183
- description: "Other property in chain dependency",
184
- paths: [
185
- "/properties/propertyPack/properties/completionAndMoving/properties/otherPropertyInChain",
186
- ],
187
- },
188
-
189
- // Private supply costs (water & sewerage)
190
- sc: {
191
- name: "supplyCosts",
192
- description: "Associated costs for private water and sewerage supply",
193
- refType: "sef25Ref",
194
- paths: [
195
- "/properties/propertyPack/properties/waterAndDrainage/properties/water/properties/mainsWater/oneOf/0/properties/associatedCost",
196
- "/properties/propertyPack/properties/waterAndDrainage/properties/drainage/properties/mainsFoulDrainage/oneOf/2/properties/associatedCost",
197
- ],
198
- },
199
-
200
- // Parking permit costs
201
- pc: {
202
- name: "parkingPermitCost",
203
- description: "Parking permit cost and frequency",
204
- refType: "sef25Ref",
205
- paths: [
206
- "/properties/propertyPack/properties/parking/properties/controlledParking/oneOf/1/properties/costOfPermit",
207
- "/properties/propertyPack/properties/parking/properties/controlledParking/oneOf/1/properties/costOfPermitFrequency",
208
- ],
209
- },
210
-
211
- // Property hazards
212
- ph: {
213
- name: "propertyHazards",
214
- description: "Property hazards and known issues",
215
- refType: "sef25Ref",
216
- paths: [
217
- "/properties/propertyPack/properties/specialistIssues",
218
- ],
219
- },
220
-
221
- // Dropped kerb access to parking
222
- dk: {
223
- name: "droppedKerbAccess",
224
- description: "Dropped kerb access to parking",
225
- refType: "sef25Ref",
226
- paths: [
227
- "/properties/propertyPack/properties/parking/properties/droppedKerbAccess",
228
- ],
229
- },
230
-
231
- // Private right of way
232
- rw: {
233
- name: "privateRightOfWay",
234
- description: "Private right of way",
235
- refType: "sef25Ref",
236
- paths: [
237
- "/properties/propertyPack/properties/rightsAndInformalArrangements/properties/rightsOrArrangements/properties/privateRightOfWay",
238
- ],
239
- },
240
-
241
- // Storm, fire or flood damage
242
- sd: {
243
- name: "stormFireFloodDamage",
244
- description: "Storm, fire or flood damage",
245
- refType: "sef25Ref",
246
- paths: [
247
- "/properties/propertyPack/properties/environmentalIssues/properties/stormFireFloodDamage",
248
- ],
249
- },
250
-
251
- // Solar panel lease costs
252
- lc: {
253
- name: "solarLeaseCosts",
254
- description: "Solar panel lease costs",
255
- refType: "sef25Ref",
256
- paths: [
257
- "/properties/propertyPack/properties/electricity/properties/solarPanels/oneOf/1/properties/panelsOwnedOutright/oneOf/1/properties/associatedCost",
258
- ],
259
- },
260
-
261
- // Warranties and guarantees upfront
262
- wg: {
263
- name: "warrantiesGuarantees",
264
- description: "Warranties and guarantees upfront Y/N for SEF25",
265
- refType: "sef25Ref",
266
- paths: [
267
- "/properties/propertyPack/properties/guaranteesWarrantiesAndIndemnityInsurances",
268
- ],
269
- },
270
-
271
- // Insurance claims upfront
272
- ic: {
273
- name: "insuranceClaims",
274
- description: "Insurance claims upfront for SEF25",
275
- refType: "sef25Ref",
276
- paths: [
277
- "/properties/propertyPack/properties/insurance/oneOf/1/properties/insuranceClaims",
278
- ],
279
- },
280
-
281
- // Neighbour development upfront
282
- nd: {
283
- name: "neighbourDevelopment",
284
- description: "Neighbour development upfront for SEF25",
285
- refType: "sef25Ref",
286
- paths: [
287
- "/properties/propertyPack/properties/notices/properties/neighbourDevelopment",
288
- ],
289
- },
290
-
291
- // Other material issue upfront
292
- mi: {
293
- name: "otherMaterialIssue",
294
- description: "Other material issue upfront for SEF25",
295
- refType: "sef25Ref",
296
- paths: [
297
- "/properties/propertyPack/properties/additionalInformation/properties/otherMaterialIssue",
298
- ],
299
- },
300
-
301
- // Title restrictions for freehold
302
- tr: {
303
- name: "titleRestrictions",
304
- description: "Title restrictions for freehold properties",
305
- refType: "sef25Ref",
306
- paths: [
307
- "/properties/propertyPack/properties/ownership/properties/ownershipsToBeTransferred/items/oneOf/0/properties/titleRestrictions",
308
- ],
309
- },
310
-
311
- // Alterations and changes
312
- ac: {
313
- name: "alterationsAndChanges",
314
- description: "Selected alterations and changes fields for SEF25",
315
- refType: "sef25Ref",
316
- preserveDiscriminators: true,
317
- paths: [
318
- "/properties/propertyPack/properties/alterationsAndChanges/properties/extension/properties/yesNo",
319
- "/properties/propertyPack/properties/alterationsAndChanges/properties/extension/oneOf/1/properties/details",
320
- "/properties/propertyPack/properties/alterationsAndChanges/properties/extension/oneOf/1/properties/planningPermission/properties/yesNo",
321
- "/properties/propertyPack/properties/alterationsAndChanges/properties/extension/oneOf/1/properties/buildingRegApproval/properties/yesNo",
322
- "/properties/propertyPack/properties/alterationsAndChanges/properties/loftConversion/properties/yesNo",
323
- "/properties/propertyPack/properties/alterationsAndChanges/properties/loftConversion/oneOf/1/properties/details",
324
- "/properties/propertyPack/properties/alterationsAndChanges/properties/loftConversion/oneOf/1/properties/planningPermission/properties/yesNo",
325
- "/properties/propertyPack/properties/alterationsAndChanges/properties/loftConversion/oneOf/1/properties/buildingRegApproval/properties/yesNo",
326
- "/properties/propertyPack/properties/alterationsAndChanges/properties/garageConversion/properties/yesNo",
327
- "/properties/propertyPack/properties/alterationsAndChanges/properties/garageConversion/oneOf/1/properties/details",
328
- "/properties/propertyPack/properties/alterationsAndChanges/properties/garageConversion/oneOf/1/properties/planningPermission/properties/yesNo",
329
- "/properties/propertyPack/properties/alterationsAndChanges/properties/garageConversion/oneOf/1/properties/buildingRegApproval/properties/yesNo",
330
- "/properties/propertyPack/properties/alterationsAndChanges/properties/removalOfInternalWalls/properties/yesNo",
331
- "/properties/propertyPack/properties/alterationsAndChanges/properties/removalOfInternalWalls/oneOf/1/properties/details",
332
- "/properties/propertyPack/properties/alterationsAndChanges/properties/removalOfInternalWalls/oneOf/1/properties/planningPermission/properties/yesNo",
333
- "/properties/propertyPack/properties/alterationsAndChanges/properties/removalOfInternalWalls/oneOf/1/properties/buildingRegApproval/properties/yesNo",
334
- "/properties/propertyPack/properties/alterationsAndChanges/properties/changeOfUse/properties/yesNo",
335
- "/properties/propertyPack/properties/alterationsAndChanges/properties/changeOfUse/oneOf/1/properties/details",
336
- "/properties/propertyPack/properties/alterationsAndChanges/properties/changeOfUse/oneOf/1/properties/planningPermission/properties/yesNo",
337
- "/properties/propertyPack/properties/alterationsAndChanges/properties/changeOfUse/oneOf/1/properties/buildingRegApproval/properties/yesNo",
338
- ],
339
- },
340
-
341
- // TA6 edition 6 compatibility for shared MI/NTS validation
342
- ta: {
343
- name: "ta6Ed6Compatibility",
344
- description:
345
- "Compatibility enum ranges for validating shared PDTF state containing TA6 edition 6 answers",
346
- refType: "ta6ed6CompatRef",
347
- paths: [
348
- "/properties/propertyPack/properties/parking",
349
- "/properties/propertyPack/properties/heating",
350
- "/properties/propertyPack/properties/rightsAndInformalArrangements",
351
- "/properties/propertyPack/properties/legalBoundaries",
352
- ],
353
- },
354
- };
355
-
356
- // Function to extract properties at specific paths with given ref type
357
- function extractPathsWithRef(
358
- schema,
359
- paths,
360
- refConfig,
361
- preserveDiscriminators = false
362
- ) {
363
- const result = {};
364
-
365
- paths.forEach((path) => {
366
- try {
367
- const value = jp.get(schema, path);
368
- if (value && hasRef(value, refConfig)) {
369
- // Set the value at the same path in result
370
- jp.set(result, path, extractRefProperties(value, refConfig));
371
- if (preserveDiscriminators) {
372
- addAncestorDiscriminators(result, schema, path);
373
- }
374
- }
375
- } catch (err) {
376
- console.warn(`Path not found: ${path}`);
377
- }
378
- });
379
-
380
- return result;
381
- }
382
-
383
- function addAncestorDiscriminators(result, schema, path) {
384
- const parts = path.split("/").filter(Boolean);
385
-
386
- for (let index = 1; index <= parts.length; index += 1) {
387
- const ancestorPath = `/${parts.slice(0, index).join("/")}`;
388
-
389
- try {
390
- const schemaNode = jp.get(schema, ancestorPath);
391
- if (!schemaNode?.discriminator) continue;
392
-
393
- const resultNode = jp.get(result, ancestorPath);
394
- if (resultNode && typeof resultNode === "object") {
395
- resultNode.discriminator = schemaNode.discriminator;
396
- }
397
- } catch (err) {
398
- // Ancestor was not materialised by this selected path.
399
- }
400
- }
401
- }
402
-
403
- // Check if an object or its descendants have the specified ref
404
- function hasRef(obj, refConfig) {
405
- let found = false;
406
- traverse(obj).forEach(function (element) {
407
- if (element && element[refConfig.ref]) {
408
- found = true;
409
- this.stop();
410
- }
411
- });
412
- return found;
413
- }
414
-
415
- // Extract only ref-specific properties
416
- function extractRefProperties(obj, refConfig, parentKey) {
417
- const result = {};
418
-
419
- // Copy ref-specific metadata at current level
420
- if (obj[refConfig.ref]) result[refConfig.outputRef] = obj[refConfig.ref];
421
- if (obj[refConfig.required]) result.required = obj[refConfig.required];
422
- if (obj[refConfig.title]) result.title = obj[refConfig.title];
423
- if (obj[refConfig.description]) result.description = obj[refConfig.description];
424
- if (obj[refConfig.enumKey]) result.enum = obj[refConfig.enumKey];
425
-
426
- // Handle discriminator
427
- if (obj.discriminator) {
428
- result.discriminator = obj.discriminator;
429
- }
430
-
431
- // Recursively process properties
432
- if (obj.properties) {
433
- result.properties = {};
434
- Object.keys(obj.properties).forEach((key) => {
435
- const prop = obj.properties[key];
436
- if (hasRef(prop, refConfig)) {
437
- result.properties[key] = extractRefProperties(prop, refConfig, key);
438
- }
439
- });
440
- // Only keep properties if we found some with ref
441
- if (Object.keys(result.properties).length === 0) {
442
- delete result.properties;
443
- }
444
- }
445
-
446
- // Handle arrays
447
- if (obj.items) {
448
- if (hasRef(obj.items, refConfig)) {
449
- result.items = extractRefProperties(obj.items, refConfig);
450
- }
451
- }
452
-
453
- // Handle oneOf
454
- if (obj.oneOf) {
455
- // Always preserve the full array structure and order
456
- const processedOneOf = obj.oneOf.map((schema, index) => {
457
- if (hasRef(schema, refConfig)) {
458
- const extracted = extractRefProperties(schema, refConfig);
459
- // For oneOf schemas, we need to preserve discriminator enum values
460
- if (obj.discriminator && schema.properties) {
461
- const propName = obj.discriminator.propertyName;
462
- if (schema.properties[propName]) {
463
- if (!extracted.properties) extracted.properties = {};
464
- extracted.properties[propName] = {
465
- enum:
466
- schema.properties[propName][refConfig.enumKey] ||
467
- schema.properties[propName].enum,
468
- };
469
- }
470
- }
471
- // Also preserve base enum values for all other properties in the extension
472
- if (schema.properties) {
473
- if (!extracted.properties) extracted.properties = {};
474
- Object.keys(schema.properties).forEach((propName) => {
475
- const prop = schema.properties[propName];
476
- if (prop.enum) {
477
- if (!extracted.properties[propName]) {
478
- extracted.properties[propName] = {
479
- enum: prop.enum,
480
- };
481
- } else if (!extracted.properties[propName].enum) {
482
- // If the property exists but doesn't have enum, add it
483
- extracted.properties[propName].enum = prop.enum;
484
- }
485
- }
486
- });
487
- }
488
- return extracted;
489
- } else {
490
- // If this branch doesn't have ref, preserve the base discriminator enum
491
- if (obj.discriminator && schema.properties) {
492
- const propName = obj.discriminator.propertyName;
493
- if (schema.properties[propName]) {
494
- return {
495
- properties: {
496
- [propName]: {
497
- enum: schema.properties[propName].enum,
498
- },
499
- },
500
- };
501
- }
502
- }
503
- // If no discriminator, return empty object to preserve structure
504
- return {};
505
- }
506
- });
507
- result.oneOf = processedOneOf;
508
-
509
- // --- NEW: If this is an extension property inside a oneOf, promote it to the parent overlay ---
510
- // If parentKey is set, and this object has extension metadata, return a stub for the parent
511
- if (
512
- parentKey &&
513
- (result[refConfig.outputRef] || result.required || result.discriminator)
514
- ) {
515
- // This is an extension property inside a oneOf branch
516
- // Return a stub for the parent property with metadata and oneOf structure
517
- const parentStub = {};
518
- Object.assign(parentStub, result);
519
- return parentStub;
520
- }
521
- }
522
-
523
- // Copy other JSON Schema keywords that might be present
524
- [
525
- "type",
526
- "format",
527
- "minimum",
528
- "maximum",
529
- "minLength",
530
- "maxLength",
531
- "minItems",
532
- "maxItems",
533
- ].forEach((keyword) => {
534
- if (obj[keyword] !== undefined) {
535
- result[keyword] = obj[keyword];
536
- }
537
- });
538
-
539
- return result;
540
- }
541
-
542
- // Add required array at parent levels if needed
543
- function addRequiredArrays(overlay, schema, refConfig) {
544
- traverse(overlay).forEach(function (node) {
545
- if (node && node.properties) {
546
- const schemaPath = "/" + this.path.join("/");
547
- try {
548
- const schemaNode = jp.get(schema, schemaPath);
549
- if (schemaNode && schemaNode[refConfig.required]) {
550
- // Filter to only include properties that exist in this overlay
551
- const overlayProps = Object.keys(node.properties);
552
- const requiredProps = schemaNode[refConfig.required].filter((prop) =>
553
- overlayProps.includes(prop)
554
- );
555
- if (requiredProps.length > 0) {
556
- node.required = requiredProps;
557
- }
558
- }
559
- } catch (err) {
560
- // Path doesn't exist in schema, skip
561
- }
562
- }
563
- });
564
- return overlay;
565
- }
566
-
567
- // Annotate intermediate nodes with refs from the source schema
568
- // This ensures every level of the overlay tree carries an ntsRef
569
- function addIntermediateRefs(overlay, schema, refConfig) {
570
- traverse(overlay).forEach(function (node) {
571
- if (node && typeof node === "object" && !Array.isArray(node) && node.properties) {
572
- // Skip if this node already has a ref
573
- if (node[refConfig.outputRef]) return;
574
-
575
- const schemaPath = "/" + this.path.join("/");
576
- try {
577
- const schemaNode = jp.get(schema, schemaPath);
578
- if (schemaNode && schemaNode[refConfig.ref]) {
579
- node[refConfig.outputRef] = schemaNode[refConfig.ref];
580
- }
581
- } catch (err) {
582
- // Path doesn't exist in schema, skip
583
- }
584
- }
585
- });
586
- return overlay;
587
- }
588
-
589
- // Generate extension overlays
590
- Object.entries(extensionMappings).forEach(([code, config]) => {
591
- const refType = config.refType || "nts2Ref";
592
- const refConfig = getRefConfig(refType);
593
-
594
- console.log(`\nGenerating extension overlay: ${code} (${config.name}) [${refType}]`);
595
-
596
- // Extract the specific paths
597
- let overlay = extractPathsWithRef(
598
- combinedSchema,
599
- config.paths,
600
- refConfig,
601
- config.preserveDiscriminators
602
- );
603
-
604
- // Add required arrays where needed
605
- overlay = addRequiredArrays(overlay, combinedSchema, refConfig);
606
-
607
- // Add refs to intermediate nodes in the path hierarchy
608
- overlay = addIntermediateRefs(overlay, combinedSchema, refConfig);
609
-
610
- // Add schema metadata
611
- overlay.$schema = "http://json-schema.org/draft-07/schema#";
612
- overlay.$id = `https://trust.propdata.org.uk/schemas/v3/overlays/extensions/${code}.json`;
613
- overlay.$comment = config.description;
614
-
615
- // Write the overlay file
616
- const fileName = path.join(
617
- __dirname,
618
- `../schemas/v3/overlays/extensions/${code}.json`
619
- );
620
- fs.writeFileSync(fileName, JSON.stringify(overlay, null, 2));
621
- console.log(`Extension overlay ${code} written to ${fileName}`);
622
- });
623
-
624
- console.log("\nExtension overlay extraction complete!");