@pdtf/schemas 3.6.0-dev.7 → 3.6.0-dev.8

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 (130) hide show
  1. package/busy-spence-79c6bf/CLAUDE.md +101 -0
  2. package/busy-spence-79c6bf/LICENSE +21 -0
  3. package/busy-spence-79c6bf/README.md +435 -0
  4. package/busy-spence-79c6bf/docs/branch-release-workflow.md +138 -0
  5. package/busy-spence-79c6bf/docs/sef25-extensions-ui-spec.md +355 -0
  6. package/busy-spence-79c6bf/index.js +654 -0
  7. package/busy-spence-79c6bf/package-lock.json +7299 -0
  8. package/busy-spence-79c6bf/package.json +44 -0
  9. package/busy-spence-79c6bf/scripts/ta6ed6-titles.js +403 -0
  10. package/busy-spence-79c6bf/scripts/ta7ed5-titles.js +183 -0
  11. package/busy-spence-79c6bf/src/examples/v1/exampleAddParticipantVouch.json +32 -0
  12. package/busy-spence-79c6bf/src/examples/v1/exampleDocumentedVouch.json +40 -0
  13. package/busy-spence-79c6bf/src/examples/v1/exampleElectronicRecord.json +30 -0
  14. package/busy-spence-79c6bf/src/examples/v1/exampleTransaction.json +878 -0
  15. package/busy-spence-79c6bf/src/examples/v1/exampleVouch.json +25 -0
  16. package/busy-spence-79c6bf/src/examples/v2/exampleTransaction.json +901 -0
  17. package/busy-spence-79c6bf/src/examples/v3/exampleAddParticipantVouch.json +38 -0
  18. package/busy-spence-79c6bf/src/examples/v3/exampleCustomOverlay.json +55 -0
  19. package/busy-spence-79c6bf/src/examples/v3/exampleCustomOverlay2.json +93 -0
  20. package/busy-spence-79c6bf/src/examples/v3/exampleDocumentedVouch.json +47 -0
  21. package/busy-spence-79c6bf/src/examples/v3/exampleElectronicRecord.json +36 -0
  22. package/busy-spence-79c6bf/src/examples/v3/exampleTransaction.json +1038 -0
  23. package/busy-spence-79c6bf/src/examples/v3/exampleVouch.json +32 -0
  24. package/busy-spence-79c6bf/src/mappings/SendPropertyDetailsRequestSchema.json +1588 -0
  25. package/busy-spence-79c6bf/src/mappings/adf.js +198 -0
  26. package/busy-spence-79c6bf/src/schemas/v1/GeoJSON.json +1279 -0
  27. package/busy-spence-79c6bf/src/schemas/v1/baspiNotes.html +102 -0
  28. package/busy-spence-79c6bf/src/schemas/v1/energy-performance-certificate.json +124 -0
  29. package/busy-spence-79c6bf/src/schemas/v1/freehold-information.json +2051 -0
  30. package/busy-spence-79c6bf/src/schemas/v1/leasehold-information.json +2064 -0
  31. package/busy-spence-79c6bf/src/schemas/v1/legal-information.json +1045 -0
  32. package/busy-spence-79c6bf/src/schemas/v1/material-facts.json +2109 -0
  33. package/busy-spence-79c6bf/src/schemas/v1/pdtf-transaction-search-results.json +40 -0
  34. package/busy-spence-79c6bf/src/schemas/v1/pdtf-transaction.json +191 -0
  35. package/busy-spence-79c6bf/src/schemas/v1/searches/drainage-and-water.json +261 -0
  36. package/busy-spence-79c6bf/src/schemas/v1/searches/local-land-charges.json +69 -0
  37. package/busy-spence-79c6bf/src/schemas/v1/searches/local-searches-required.json +857 -0
  38. package/busy-spence-79c6bf/src/schemas/v1/searches.json +237 -0
  39. package/busy-spence-79c6bf/src/schemas/v1/title-deed.json +841 -0
  40. package/busy-spence-79c6bf/src/schemas/v2/baspiNotes.html +102 -0
  41. package/busy-spence-79c6bf/src/schemas/v2/combined.json +37731 -0
  42. package/busy-spence-79c6bf/src/schemas/v2/overlays/baspi.json +8132 -0
  43. package/busy-spence-79c6bf/src/schemas/v2/overlays/con29DW.json +705 -0
  44. package/busy-spence-79c6bf/src/schemas/v2/overlays/con29R.json +2956 -0
  45. package/busy-spence-79c6bf/src/schemas/v2/overlays/fme1.json +1259 -0
  46. package/busy-spence-79c6bf/src/schemas/v2/overlays/llc1.json +25 -0
  47. package/busy-spence-79c6bf/src/schemas/v2/overlays/lpe1.json +2171 -0
  48. package/busy-spence-79c6bf/src/schemas/v2/overlays/nts.json +326 -0
  49. package/busy-spence-79c6bf/src/schemas/v2/overlays/oc1.json +2799 -0
  50. package/busy-spence-79c6bf/src/schemas/v2/overlays/piq.json +3419 -0
  51. package/busy-spence-79c6bf/src/schemas/v2/overlays/rds.json +3736 -0
  52. package/busy-spence-79c6bf/src/schemas/v2/overlays/ta10.json +5306 -0
  53. package/busy-spence-79c6bf/src/schemas/v2/overlays/ta6.json +4533 -0
  54. package/busy-spence-79c6bf/src/schemas/v2/overlays/ta7.json +1045 -0
  55. package/busy-spence-79c6bf/src/schemas/v2/pdtf-transaction.json +34351 -0
  56. package/busy-spence-79c6bf/src/schemas/v2/skeleton.json +3973 -0
  57. package/busy-spence-79c6bf/src/schemas/v3/combined.json +48643 -0
  58. package/busy-spence-79c6bf/src/schemas/v3/compactSkeleton.txt +4519 -0
  59. package/busy-spence-79c6bf/src/schemas/v3/overlays/README.md +299 -0
  60. package/busy-spence-79c6bf/src/schemas/v3/overlays/baspi4.json +8030 -0
  61. package/busy-spence-79c6bf/src/schemas/v3/overlays/baspi5.json +8180 -0
  62. package/busy-spence-79c6bf/src/schemas/v3/overlays/con29DW.json +716 -0
  63. package/busy-spence-79c6bf/src/schemas/v3/overlays/con29R.json +2981 -0
  64. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/ac.json +334 -0
  65. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/as.json +74 -0
  66. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/dk.json +33 -0
  67. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/dr.json +73 -0
  68. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/er.json +85 -0
  69. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/fd.json +75 -0
  70. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/hi.json +51 -0
  71. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/hs.json +73 -0
  72. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/ic.json +94 -0
  73. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/jk.json +96 -0
  74. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/la.json +85 -0
  75. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/lc.json +76 -0
  76. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/ma.json +90 -0
  77. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/mc.json +38 -0
  78. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/mi.json +70 -0
  79. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/nd.json +44 -0
  80. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/oa.json +24 -0
  81. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/oc.json +57 -0
  82. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/pc.json +38 -0
  83. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/ph.json +195 -0
  84. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/rw.json +69 -0
  85. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/sb.json +73 -0
  86. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/sc.json +133 -0
  87. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/sd.json +64 -0
  88. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/sf.json +74 -0
  89. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/sl.json +68 -0
  90. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/ta.json +204 -0
  91. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/tf.json +103 -0
  92. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/tr.json +74 -0
  93. package/busy-spence-79c6bf/src/schemas/v3/overlays/extensions/wg.json +351 -0
  94. package/busy-spence-79c6bf/src/schemas/v3/overlays/fme1.json +1266 -0
  95. package/busy-spence-79c6bf/src/schemas/v3/overlays/llc1.json +25 -0
  96. package/busy-spence-79c6bf/src/schemas/v3/overlays/lpe1.json +2199 -0
  97. package/busy-spence-79c6bf/src/schemas/v3/overlays/nts.json +2159 -0
  98. package/busy-spence-79c6bf/src/schemas/v3/overlays/nts2.json +2744 -0
  99. package/busy-spence-79c6bf/src/schemas/v3/overlays/ntsl.json +1815 -0
  100. package/busy-spence-79c6bf/src/schemas/v3/overlays/ntsl2.json +2219 -0
  101. package/busy-spence-79c6bf/src/schemas/v3/overlays/oc1.json +2817 -0
  102. package/busy-spence-79c6bf/src/schemas/v3/overlays/piq.json +3324 -0
  103. package/busy-spence-79c6bf/src/schemas/v3/overlays/rds.json +3668 -0
  104. package/busy-spence-79c6bf/src/schemas/v3/overlays/sef25.json +1653 -0
  105. package/busy-spence-79c6bf/src/schemas/v3/overlays/sr24.json +38 -0
  106. package/busy-spence-79c6bf/src/schemas/v3/overlays/ta10.json +4645 -0
  107. package/busy-spence-79c6bf/src/schemas/v3/overlays/ta6.json +4572 -0
  108. package/busy-spence-79c6bf/src/schemas/v3/overlays/ta6ed6.json +6665 -0
  109. package/busy-spence-79c6bf/src/schemas/v3/overlays/ta7.json +1537 -0
  110. package/busy-spence-79c6bf/src/schemas/v3/overlays/ta7ed5.json +1585 -0
  111. package/busy-spence-79c6bf/src/schemas/v3/pdtf-transaction.json +41570 -0
  112. package/busy-spence-79c6bf/src/schemas/v3/skeleton.json +5767 -0
  113. package/busy-spence-79c6bf/src/schemas/verifiedClaims/README.md +21 -0
  114. package/busy-spence-79c6bf/src/schemas/verifiedClaims/pdtf-verified-claims.json +447 -0
  115. package/busy-spence-79c6bf/src/utils/compactSkeleton.js +84 -0
  116. package/busy-spence-79c6bf/src/utils/countTokens.js +67 -0
  117. package/busy-spence-79c6bf/src/utils/extractExtensionOverlays.js +633 -0
  118. package/busy-spence-79c6bf/src/utils/extractOverlay.js +381 -0
  119. package/busy-spence-79c6bf/src/utils/extractProperties.js +44 -0
  120. package/busy-spence-79c6bf/src/utils/listPathTitles.js +36 -0
  121. package/busy-spence-79c6bf/src/utils/minimalSkeleton.js +85 -0
  122. package/busy-spence-79c6bf/src/utils/pathList.csv +903 -0
  123. package/busy-spence-79c6bf/src/utils/pathSkeleton.js +181 -0
  124. package/busy-spence-79c6bf/ta6ed6-titles-plan.md +118 -0
  125. package/busy-spence-79c6bf/ta7ed5-titles-spec.md +89 -0
  126. package/package.json +1 -1
  127. package/src/schemas/v3/combined.json +225 -47
  128. package/src/schemas/v3/overlays/llc1.json +1 -2
  129. package/src/schemas/v3/overlays/ta6ed6.json +204 -75
  130. package/src/schemas/v3/overlays/ta7ed5.json +54 -20
@@ -0,0 +1,381 @@
1
+ const { dereference } = require("@jdw/jst");
2
+ const traverse = require("traverse");
3
+ const jp = require("jsonpointer");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const merge = require("deepmerge");
7
+
8
+ const combinedPath =
9
+ process.env.COMBINED_PATH ||
10
+ path.resolve(__dirname, "../schemas/v3/combined.json");
11
+ const outputDir =
12
+ process.env.OUTPUT_DIR ||
13
+ path.resolve(__dirname, "../schemas/v3");
14
+
15
+ if (!fs.existsSync(combinedPath)) {
16
+ throw new Error(`Combined schema not found: ${combinedPath}`);
17
+ }
18
+ if (!fs.existsSync(outputDir)) {
19
+ fs.mkdirSync(outputDir, { recursive: true });
20
+ }
21
+
22
+ const combinedSchema = JSON.parse(fs.readFileSync(combinedPath, "utf8"));
23
+
24
+ const extractFields = [
25
+ "baspi4",
26
+ "baspi5",
27
+ "nts",
28
+ "nts2",
29
+ "ntsl",
30
+ "ntsl2",
31
+ "ta6",
32
+ "ta6ed6",
33
+ "ta7",
34
+ "ta7ed5",
35
+ "ta10",
36
+ "lpe1",
37
+ "fme1",
38
+ "piq",
39
+ "con29R",
40
+ "con29DW",
41
+ "llc1",
42
+ "rds",
43
+ "oc1",
44
+ "sr24",
45
+ "sef25",
46
+ ];
47
+
48
+ const metadataFields = [...extractFields, "ta6ed6Compat"];
49
+
50
+ const flattenSkeleton = (schema) => {
51
+ if (!schema) return undefined;
52
+
53
+ // Handle arrays - mark with special notation
54
+ if (schema.type === "array" && schema.items) {
55
+ const itemSchema = flattenSkeleton(schema.items);
56
+ // Use array notation to indicate this is an array
57
+ return [itemSchema];
58
+ }
59
+
60
+ // Handle patternProperties (dynamic keys like in offers and enquiries)
61
+ if (schema.type === "object" && schema.patternProperties) {
62
+ // Get the schema from the first pattern (usually ".*")
63
+ const patternKeys = Object.keys(schema.patternProperties);
64
+ if (patternKeys.length > 0) {
65
+ const patternSchema = schema.patternProperties[patternKeys[0]];
66
+ const itemSchema = flattenSkeleton(patternSchema);
67
+ // Use {*: schema} notation to indicate this is a keyed object
68
+ return { "*": itemSchema };
69
+ }
70
+ }
71
+
72
+ // Handle primitives - return type indicator
73
+ if (schema.type && !schema.properties && !schema.oneOf && !schema.items && !schema.patternProperties) {
74
+ // Return a type indicator for primitive types
75
+ if (schema.type === "string") return "string";
76
+ if (schema.type === "number") return "number";
77
+ if (schema.type === "integer") return "integer";
78
+ if (schema.type === "boolean") return "boolean";
79
+ if (schema.type === "null") return "null";
80
+ }
81
+
82
+ let returnStructure = {};
83
+
84
+ // Handle object properties
85
+ if (schema.properties) {
86
+ Object.keys(schema.properties).forEach((key) => {
87
+ returnStructure[key] = flattenSkeleton(schema.properties[key]);
88
+ });
89
+ }
90
+
91
+ // Handle oneOf - merge all possible properties (recursively handles nested oneOf)
92
+ if (schema.oneOf) {
93
+ schema.oneOf.forEach((aOneOf) => {
94
+ const variantResult = flattenSkeleton(aOneOf);
95
+ if (variantResult && typeof variantResult === "object" && !Array.isArray(variantResult)) {
96
+ Object.entries(variantResult).forEach(([key, value]) => {
97
+ if (key === "_variants") return;
98
+ if (returnStructure[key] && JSON.stringify(returnStructure[key]) !== JSON.stringify(value)) {
99
+ if (typeof returnStructure[key] === "string" || typeof value === "string") {
100
+ returnStructure[key] = "variant";
101
+ } else {
102
+ returnStructure[key] = { ...returnStructure[key], ...value, _variants: true };
103
+ }
104
+ } else {
105
+ returnStructure[key] = value;
106
+ }
107
+ });
108
+ }
109
+ });
110
+ }
111
+
112
+ // Return empty object for objects without properties
113
+ return Object.keys(returnStructure).length > 0 ? returnStructure : {};
114
+ };
115
+
116
+ const extractOverlay = (sourceSchema, ref) => {
117
+ const refName = `${ref}Ref`;
118
+ const extendedTagMap = {
119
+ Type: "type",
120
+ MinLength: "minLength",
121
+ MaxLength: "maxLength",
122
+ Pattern: "pattern",
123
+ Minimum: "minimum",
124
+ Maximum: "maximum",
125
+ MinItems: "minItems",
126
+ MaxItems: "maxItems",
127
+ UniqueItems: "uniqueItems",
128
+ AdditionalProperties: "additionalProperties",
129
+ Format: "format",
130
+ MinProperties: "minProperties",
131
+ MaxProperties: "maxProperties",
132
+ MultipleOf: "multipleOf",
133
+ Const: "const",
134
+ };
135
+ const returnSchema = {
136
+ $schema: "http://json-schema.org/draft-07/schema#",
137
+ $id: `https://trust.propdata.org.uk/schemas/v3/overlays/${ref}.json`,
138
+ };
139
+ traverse(sourceSchema).forEach(function (element) {
140
+ let path = "/" + this.path.join("/");
141
+ if (path === "/") path = "";
142
+ if (element[refName]) {
143
+ jp.set(returnSchema, `${path}/${refName}`, element[refName]);
144
+
145
+ if (element.discriminator && Array.isArray(element.oneOf)) {
146
+ jp.set(returnSchema, `${path}/discriminator`, element.discriminator);
147
+ const { propertyName } = element.discriminator;
148
+ element.oneOf.forEach((oneOf, index) => {
149
+ const discriminatorProperty = oneOf.properties[propertyName];
150
+ // must be an enum
151
+ const discriminatorEnumPath = `${path}/oneOf/${index}/properties/${propertyName}/enum`;
152
+ // if a refEnum use that
153
+ const refEnum = `${ref}Enum`;
154
+ if (discriminatorProperty[refEnum]) {
155
+ jp.set(
156
+ returnSchema,
157
+ discriminatorEnumPath,
158
+ discriminatorProperty[refEnum]
159
+ );
160
+ } else {
161
+ // use the base enum
162
+ jp.set(
163
+ returnSchema,
164
+ discriminatorEnumPath,
165
+ discriminatorProperty.enum
166
+ );
167
+ }
168
+ });
169
+ }
170
+
171
+ // also handle discriminator properties nested in items
172
+ if (element.items?.discriminator && Array.isArray(element.items.oneOf)) {
173
+ jp.set(
174
+ returnSchema,
175
+ `${path}/items/discriminator`,
176
+ element.items.discriminator
177
+ );
178
+ const { propertyName } = element.items.discriminator;
179
+ element.items.oneOf.forEach((oneOf, index) => {
180
+ const discriminatorProperty = oneOf.properties[propertyName];
181
+ // must be an enum
182
+ const discriminatorEnumPath = `${path}/items/oneOf/${index}/properties/${propertyName}/enum`;
183
+ // if a refEnum use that
184
+ const refEnum = `${ref}Enum`;
185
+ if (discriminatorProperty[refEnum]) {
186
+ jp.set(
187
+ returnSchema,
188
+ discriminatorEnumPath,
189
+ discriminatorProperty[refEnum]
190
+ );
191
+ } else {
192
+ // use the base enum
193
+ jp.set(
194
+ returnSchema,
195
+ discriminatorEnumPath,
196
+ discriminatorProperty.enum
197
+ );
198
+ }
199
+ });
200
+ }
201
+ }
202
+
203
+ const refRequired = `${ref}Required`;
204
+ if (element[refRequired]) {
205
+ jp.set(returnSchema, `${path}/required`, element[refRequired]);
206
+ }
207
+
208
+ const refTitle = `${ref}Title`;
209
+ if (element[refTitle]) {
210
+ jp.set(returnSchema, `${path}/title`, element[refTitle]);
211
+ }
212
+
213
+ const refDescription = `${ref}Description`;
214
+ if (element[refDescription]) {
215
+ jp.set(returnSchema, `${path}/description`, element[refDescription]);
216
+ }
217
+
218
+ const refEnum = `${ref}Enum`;
219
+ if (element[refEnum]) {
220
+ jp.set(returnSchema, `${path}/enum`, element[refEnum]);
221
+ }
222
+
223
+ const refConst = `${ref}Const`;
224
+ if (Object.prototype.hasOwnProperty.call(element, refConst)) {
225
+ jp.set(returnSchema, `${path}/const`, element[refConst]);
226
+ }
227
+
228
+ Object.entries(extendedTagMap).forEach(([suffix, schemaKey]) => {
229
+ const tagKey = `${ref}${suffix}`;
230
+ if (Object.prototype.hasOwnProperty.call(element, tagKey)) {
231
+ jp.set(returnSchema, `${path}/${schemaKey}`, element[tagKey]);
232
+ }
233
+ });
234
+ });
235
+ return returnSchema;
236
+ };
237
+
238
+ const deleteProperties = (sourceSchema, propertyNames) => {
239
+ traverse(sourceSchema).forEach(function (element) {
240
+ if (propertyNames.includes(this.key)) {
241
+ this.delete(true); // true = stop here
242
+ }
243
+ });
244
+ return sourceSchema;
245
+ };
246
+
247
+ const overlays = {};
248
+ const overlaysDir = path.join(outputDir, "overlays");
249
+ if (!fs.existsSync(overlaysDir)) {
250
+ fs.mkdirSync(overlaysDir, { recursive: true });
251
+ }
252
+
253
+ extractFields.forEach((key) => {
254
+ let overlay = extractOverlay(combinedSchema, key);
255
+ overlays[key] = overlay;
256
+ const fileName = path.join(overlaysDir, `${key}.json`);
257
+ fs.writeFileSync(fileName, JSON.stringify(overlay, null, 2));
258
+ console.log(`Overlay ${key} written to ${fileName}`);
259
+ });
260
+
261
+ const coreSchema = deleteProperties(combinedSchema, [
262
+ "discriminator",
263
+ ...metadataFields.map((item) => `${item}Ref`),
264
+ ...metadataFields.map((item) => `${item}Required`),
265
+ ...metadataFields.map((item) => `${item}Title`),
266
+ ...metadataFields.map((item) => `${item}Description`),
267
+ ...metadataFields.map((item) => `${item}Enum`),
268
+ ...metadataFields.map((item) => `${item}Type`),
269
+ ...metadataFields.map((item) => `${item}MinLength`),
270
+ ...metadataFields.map((item) => `${item}MaxLength`),
271
+ ...metadataFields.map((item) => `${item}Pattern`),
272
+ ...metadataFields.map((item) => `${item}Minimum`),
273
+ ...metadataFields.map((item) => `${item}Maximum`),
274
+ ...metadataFields.map((item) => `${item}MinItems`),
275
+ ...metadataFields.map((item) => `${item}MaxItems`),
276
+ ...metadataFields.map((item) => `${item}UniqueItems`),
277
+ ...metadataFields.map((item) => `${item}AdditionalProperties`),
278
+ ...metadataFields.map((item) => `${item}Format`),
279
+ ...metadataFields.map((item) => `${item}MinProperties`),
280
+ ...metadataFields.map((item) => `${item}MaxProperties`),
281
+ ...metadataFields.map((item) => `${item}MultipleOf`),
282
+ ...metadataFields.map((item) => `${item}Const`),
283
+ ]);
284
+
285
+ fs.writeFileSync(
286
+ path.join(outputDir, "pdtf-transaction.json"),
287
+ JSON.stringify(coreSchema, null, 2)
288
+ );
289
+ console.log(`Core schema written to ${path.join(outputDir, "pdtf-transaction.json")}`);
290
+
291
+ const skeletonSchema = deleteProperties(coreSchema, [
292
+ "$schema",
293
+ "$id",
294
+ "title",
295
+ "description",
296
+ "required",
297
+ "enum",
298
+ "minItems",
299
+ "minLength",
300
+ "format",
301
+ "minimum",
302
+ "maximum",
303
+ ]);
304
+
305
+ const skeletonSchemaFlattened = flattenSkeleton(skeletonSchema);
306
+
307
+ fs.writeFileSync(
308
+ path.join(outputDir, "skeleton.json"),
309
+ JSON.stringify(skeletonSchemaFlattened, null, 2)
310
+ );
311
+ console.log(`Flat Skeleton schema written to ${path.join(outputDir, "skeleton.json")}`);
312
+
313
+ // Generate compact skeleton format for better token efficiency
314
+ const toCompact = (obj, indent = "") => {
315
+ if (typeof obj === "string") {
316
+ // Skip type indicators entirely
317
+ return "";
318
+ }
319
+
320
+ if (Array.isArray(obj)) {
321
+ if (obj.length === 0) return "[]";
322
+ // Array with content
323
+ const inner = toCompact(obj[0], indent);
324
+ if (inner === "") {
325
+ return "[]"; // Array of primitives
326
+ }
327
+ return `[\n${inner}\n${indent}]`;
328
+ }
329
+
330
+ if (obj && typeof obj === "object") {
331
+ const keys = Object.keys(obj);
332
+ if (keys.length === 0) return "";
333
+
334
+ // Check if this is a keyed object (has "*" key)
335
+ if (keys.length === 1 && keys[0] === "*") {
336
+ const inner = toCompact(obj["*"], indent);
337
+ if (inner === "" || inner === "{*}") {
338
+ return "{*}"; // Keyed object of primitives (or nested keyed objects with no structure)
339
+ }
340
+ return `{*}\n${inner}`;
341
+ }
342
+
343
+ // Process each key
344
+ const lines = [];
345
+ keys.forEach(k => {
346
+ const val = toCompact(obj[k], indent + " ");
347
+
348
+ if (val === "") {
349
+ // Leaf node - just show the property name
350
+ lines.push(`${indent} ${k}`);
351
+ } else if (val === "[]") {
352
+ // Array property
353
+ lines.push(`${indent} ${k}[]`);
354
+ } else if (val.startsWith("[")) {
355
+ // Array with nested content - simple concatenation
356
+ lines.push(`${indent} ${k}${val}`);
357
+ } else if (val.startsWith("{*}")) {
358
+ // Keyed object property - simple concatenation
359
+ lines.push(`${indent} ${k}${val}`);
360
+ } else {
361
+ // Object property - show name on its own line, content below
362
+ lines.push(`${indent} ${k}`);
363
+ lines.push(val);
364
+ }
365
+ });
366
+
367
+ return lines.length > 0 ? lines.join("\n") : "";
368
+ }
369
+
370
+ return "";
371
+ };
372
+
373
+ // Since toCompact returns lines without wrapping braces, add them for the root
374
+ const innerContent = toCompact(skeletonSchemaFlattened, "");
375
+ const compactSkeleton = innerContent ? innerContent : "";
376
+
377
+ fs.writeFileSync(
378
+ path.join(outputDir, "compactSkeleton.txt"),
379
+ compactSkeleton
380
+ );
381
+ console.log(`Compact Skeleton written to ${path.join(outputDir, "compactSkeleton.txt")}`);
@@ -0,0 +1,44 @@
1
+ const { dereference } = require("@jdw/jst");
2
+ const traverse = require("traverse");
3
+ const jp = require("jsonpointer");
4
+ const fs = require("fs");
5
+ const merge = require("deepmerge");
6
+
7
+ const combinedSchema = require("../schemas/v2/combined.json");
8
+
9
+ const overlay = "baspiUI";
10
+ const keys = [
11
+ "isDependent",
12
+ "component",
13
+ "htmlClass",
14
+ "addButtonLabelFirst",
15
+ "addButtonLabelSubsequent",
16
+ ];
17
+
18
+ const returnSchema = {
19
+ $schema: "http://json-schema.org/draft-07/schema#",
20
+ $id: `https://trust.propdata.org.uk/schemas/v2/overlays/${overlay}.json`,
21
+ };
22
+
23
+ traverse(combinedSchema).forEach(function (element) {
24
+ let path = "/" + this.path.join("/");
25
+ if (path === "/") path = "";
26
+ if (keys.includes(this.key)) {
27
+ jp.set(returnSchema, path, element);
28
+ }
29
+ });
30
+
31
+ const fileName = `../schemas/v2/overlays/${overlay}.json`;
32
+ fs.writeFileSync(fileName, JSON.stringify(returnSchema, null, 2));
33
+ console.log(`Overlay ${overlay} written to ${overlay}`);
34
+
35
+ traverse(combinedSchema).forEach(function (element) {
36
+ if (keys.includes(this.key)) {
37
+ this.delete(true); // true = stop here
38
+ }
39
+ });
40
+
41
+ fs.writeFileSync(
42
+ "../schemas/v2/combined.json",
43
+ JSON.stringify(combinedSchema, null, 2)
44
+ );
@@ -0,0 +1,36 @@
1
+ const traverse = require("traverse");
2
+ const fs = require("fs");
3
+
4
+ const combinedSchema = require("../schemas/v3/combined.json");
5
+
6
+ const includeFields = [
7
+ "ntsRef",
8
+ "nts-sefRef",
9
+ "ntslRef",
10
+ "ta6Ref",
11
+ "ta7Ref",
12
+ "ta10Ref",
13
+ ];
14
+
15
+ let pathCsv = "";
16
+
17
+ traverse(combinedSchema).forEach(function (element) {
18
+ let path = "/" + this.path.join("/");
19
+ if (path === "/") path = "";
20
+ if (includeFields.some((field) => element[field]) && element.title) {
21
+ const filteredPath = path
22
+ .split("/")
23
+ .filter(
24
+ (segment) =>
25
+ segment !== "properties" &&
26
+ segment !== "oneOf" &&
27
+ segment !== "items" &&
28
+ isNaN(segment)
29
+ )
30
+ .join("/");
31
+ const line = `"/${filteredPath}", "${element.title}"\n`;
32
+ pathCsv += line;
33
+ }
34
+ });
35
+
36
+ fs.writeFileSync("./pathList.csv", pathCsv);
@@ -0,0 +1,85 @@
1
+ const fs = require("fs");
2
+
3
+ // Read the current skeleton
4
+ const skeleton = require("../schemas/v3/skeleton.json");
5
+
6
+ // Ultra-minimal format: use indentation only, no brackets
7
+ const toMinimal = (obj, prefix = "", isArrayItem = false) => {
8
+ const lines = [];
9
+
10
+ if (typeof obj === "string") {
11
+ // Type indicators - single letter
12
+ const typeMap = {
13
+ "string": "s",
14
+ "number": "n",
15
+ "integer": "i",
16
+ "boolean": "b",
17
+ "variant": "v"
18
+ };
19
+ return typeMap[obj] || obj;
20
+ }
21
+
22
+ if (Array.isArray(obj)) {
23
+ lines.push(prefix + "[]");
24
+ if (obj.length > 0) {
25
+ const itemLines = toMinimal(obj[0], prefix + " ", true);
26
+ lines.push(...(Array.isArray(itemLines) ? itemLines : [itemLines]));
27
+ }
28
+ return lines;
29
+ }
30
+
31
+ if (obj && typeof obj === "object") {
32
+ const keys = Object.keys(obj);
33
+ if (keys.length === 0) {
34
+ return prefix + "{}";
35
+ }
36
+
37
+ keys.forEach((key, index) => {
38
+ const val = obj[key];
39
+ const keyPrefix = prefix + key;
40
+
41
+ if (typeof val === "string") {
42
+ const type = toMinimal(val);
43
+ lines.push(keyPrefix + ":" + type);
44
+ } else if (Array.isArray(val)) {
45
+ const arrLines = toMinimal(val, keyPrefix);
46
+ lines.push(...arrLines);
47
+ } else if (val && typeof val === "object" && Object.keys(val).length > 0) {
48
+ lines.push(keyPrefix);
49
+ const subLines = toMinimal(val, prefix + " ");
50
+ lines.push(...(Array.isArray(subLines) ? subLines : [subLines]));
51
+ } else {
52
+ lines.push(keyPrefix);
53
+ }
54
+ });
55
+
56
+ return lines;
57
+ }
58
+
59
+ return prefix + String(obj);
60
+ };
61
+
62
+ // Generate minimal version
63
+ const minimalLines = toMinimal(skeleton);
64
+ const minimal = minimalLines.join("\n");
65
+
66
+ // Write minimal version
67
+ fs.writeFileSync("../schemas/v3/minimalSkeleton.txt", minimal);
68
+
69
+ console.log("Minimal skeleton written to ../schemas/v3/minimalSkeleton.txt");
70
+ console.log(`Size: ${minimal.length} bytes`);
71
+ console.log(`Lines: ${minimalLines.length}`);
72
+
73
+ // Count tokens
74
+ try {
75
+ const GPT3Encoder = require('gpt-3-encoder');
76
+ const encoded = GPT3Encoder.encode(minimal);
77
+ console.log(`Tokens (GPT-3): ${encoded.length}`);
78
+ console.log(`Reduction: ${((1 - encoded.length / 78734) * 100).toFixed(1)}% fewer tokens than JSON skeleton`);
79
+
80
+ // Show sample
81
+ console.log("\nFirst 20 lines:");
82
+ console.log(minimalLines.slice(0, 20).join("\n"));
83
+ } catch (e) {
84
+ console.log(`Estimated tokens: ~${Math.ceil(minimal.length / 4)}`);
85
+ }