@unispechq/unispec-core 0.3.0 → 0.3.2

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 (306) hide show
  1. package/dist/cjs/diff/annotators.js +36 -9
  2. package/dist/cjs/src/cache/cache-factory.js +72 -0
  3. package/dist/cjs/src/cache/cache-manager.js +128 -0
  4. package/dist/cjs/src/cache/constants.js +25 -0
  5. package/dist/cjs/src/cache/hash-utils.js +19 -0
  6. package/dist/cjs/src/cache/hashing.js +230 -0
  7. package/dist/cjs/src/cache/index.js +24 -0
  8. package/dist/cjs/src/cache/lru-cache.js +144 -0
  9. package/dist/cjs/src/cache/types.js +5 -0
  10. package/dist/cjs/src/diff/annotators.js +160 -0
  11. package/dist/cjs/src/diff/change-reports.js +369 -0
  12. package/dist/cjs/src/diff/core.js +158 -0
  13. package/dist/cjs/src/diff/enhanced-diff.js +65 -0
  14. package/dist/cjs/src/diff/impact-strategies-refactored.js +230 -0
  15. package/dist/cjs/src/diff/impact-strategies.js +219 -0
  16. package/dist/cjs/src/diff/index.js +27 -0
  17. package/dist/cjs/src/diff/metrics-calculator.js +69 -0
  18. package/dist/cjs/src/diff/risk-calculator.js +58 -0
  19. package/dist/cjs/src/diff/suggestion-generator.js +78 -0
  20. package/dist/cjs/src/diff/types.js +11 -0
  21. package/dist/cjs/src/errors/base-error.js +33 -0
  22. package/dist/cjs/src/errors/config-error.js +11 -0
  23. package/dist/cjs/src/errors/error-factory.js +48 -0
  24. package/dist/cjs/src/errors/index.js +19 -0
  25. package/dist/cjs/src/errors/loader-error.js +11 -0
  26. package/dist/cjs/src/errors/reference-error.js +11 -0
  27. package/dist/cjs/src/errors/schema-error.js +11 -0
  28. package/dist/cjs/src/errors/security-error.js +11 -0
  29. package/dist/cjs/src/errors/semantic-error.js +11 -0
  30. package/dist/cjs/src/generated-schemas.js +2100 -0
  31. package/dist/cjs/src/index.js +59 -0
  32. package/dist/cjs/src/loader/index.js +13 -0
  33. package/dist/cjs/src/loader/security-validator.js +53 -0
  34. package/dist/cjs/src/loader/types.js +11 -0
  35. package/dist/cjs/src/loader/unispec-loader.js +84 -0
  36. package/dist/cjs/src/loader/yaml-loader.js +76 -0
  37. package/dist/cjs/src/normalizer/core.js +37 -0
  38. package/dist/cjs/src/normalizer/graphql-normalizer.js +67 -0
  39. package/dist/cjs/src/normalizer/index.js +7 -0
  40. package/dist/cjs/src/normalizer/rest-normalizer.js +51 -0
  41. package/dist/cjs/src/normalizer/types.js +2 -0
  42. package/dist/cjs/src/normalizer/utils.js +49 -0
  43. package/dist/cjs/src/normalizer/websocket-normalizer.js +81 -0
  44. package/dist/cjs/src/optimizer/core.js +140 -0
  45. package/dist/cjs/src/optimizer/index.js +17 -0
  46. package/dist/cjs/src/optimizer/optimization-functions.js +185 -0
  47. package/dist/cjs/src/optimizer/types.js +2 -0
  48. package/dist/cjs/src/optimizer/utils.js +32 -0
  49. package/dist/cjs/src/schemas/dedupe.js +113 -0
  50. package/dist/cjs/src/schemas/index.js +14 -0
  51. package/dist/cjs/src/schemas/resolver.js +42 -0
  52. package/dist/cjs/src/schemas/utils.js +53 -0
  53. package/dist/cjs/src/types/index.js +2 -0
  54. package/dist/cjs/src/validator/ajv-validator.js +82 -0
  55. package/dist/cjs/src/validator/config-validator-main.js +34 -0
  56. package/dist/cjs/src/validator/config-validator.js +17 -0
  57. package/dist/cjs/src/validator/index.js +23 -0
  58. package/dist/cjs/src/validator/object-traversal.js +112 -0
  59. package/dist/cjs/src/validator/reference-validator.js +233 -0
  60. package/dist/cjs/src/validator/schema-references.js +116 -0
  61. package/dist/cjs/src/validator/semantic-validator.js +328 -0
  62. package/dist/cjs/src/validator/tests-validator.js +16 -0
  63. package/dist/cjs/src/validator/types.js +2 -0
  64. package/dist/cjs/src/validator/unispec-validator.js +80 -0
  65. package/dist/cjs/src/validator/validator-factory.js +77 -0
  66. package/dist/cjs/src/versions.js +147 -0
  67. package/dist/cjs/tests/cache/cache.test.js +274 -0
  68. package/dist/cjs/tests/cache/utils.js +32 -0
  69. package/dist/cjs/tests/concurrency-normalizer-optimizer.test.js +1 -0
  70. package/dist/cjs/tests/diff/diff-annotators.test.js +280 -0
  71. package/dist/cjs/tests/diff/diff-comprehensive.test.js +262 -0
  72. package/dist/cjs/tests/diff/diff-extended.test.js +235 -0
  73. package/dist/cjs/tests/diff/diff.test.js +189 -0
  74. package/dist/cjs/tests/diff/utils.js +8 -0
  75. package/dist/cjs/tests/errors/errors-integration.test.js +173 -0
  76. package/dist/cjs/tests/errors/errors.test.js +280 -0
  77. package/dist/cjs/tests/errors/utils.js +7 -0
  78. package/dist/cjs/tests/loader/integration.test.js +216 -0
  79. package/dist/cjs/tests/loader/loader.test.js +341 -0
  80. package/dist/cjs/tests/normalizer/normalizer-comprehensive.test.js +648 -0
  81. package/dist/cjs/tests/normalizer/normalizer-invalid.test.js +258 -0
  82. package/dist/cjs/tests/normalizer/normalizer-valid.test.js +238 -0
  83. package/dist/cjs/tests/normalizer/utils.js +47 -0
  84. package/dist/cjs/tests/optimizer/compress-references.test.js +304 -0
  85. package/dist/cjs/tests/optimizer/deduplication.test.js +132 -0
  86. package/dist/cjs/tests/optimizer/integration.test.js +131 -0
  87. package/dist/cjs/tests/optimizer/optimization-report.test.js +222 -0
  88. package/dist/cjs/tests/optimizer/optimize-document.test.js +187 -0
  89. package/dist/cjs/tests/optimizer/orphaned-schemas.test.js +194 -0
  90. package/dist/cjs/tests/optimizer/sort-schemas.test.js +131 -0
  91. package/dist/cjs/tests/optimizer/utils.js +209 -0
  92. package/dist/cjs/tests/schemas/schemas-edge-cases.test.js +223 -0
  93. package/dist/cjs/tests/schemas/schemas.test.js +400 -0
  94. package/dist/cjs/tests/schemas/utils.js +7 -0
  95. package/dist/cjs/tests/utils.js +131 -0
  96. package/dist/cjs/tests/validator/config-validator.test.js +78 -0
  97. package/dist/cjs/tests/validator/debug-config.js +1 -0
  98. package/dist/cjs/tests/validator/debug-missing-service.js +1 -0
  99. package/dist/cjs/tests/validator/debug-other-configs.js +1 -0
  100. package/dist/cjs/tests/validator/debug-references.js +1 -0
  101. package/dist/cjs/tests/validator/unispec-validator.test.js +103 -0
  102. package/dist/cjs/tests/validator/utils.js +25 -0
  103. package/dist/diff/annotators.js +36 -9
  104. package/dist/src/cache/cache-factory.d.ts +31 -0
  105. package/dist/src/cache/cache-factory.js +65 -0
  106. package/dist/src/cache/cache-manager.d.ts +62 -0
  107. package/dist/src/cache/cache-manager.js +124 -0
  108. package/dist/src/cache/constants.d.ts +21 -0
  109. package/dist/src/cache/constants.js +22 -0
  110. package/dist/src/cache/hash-utils.d.ts +11 -0
  111. package/dist/src/cache/hash-utils.js +15 -0
  112. package/dist/src/cache/hashing.d.ts +28 -0
  113. package/dist/src/cache/hashing.js +193 -0
  114. package/dist/src/cache/index.d.ts +6 -0
  115. package/dist/src/cache/index.js +10 -0
  116. package/dist/src/cache/lru-cache.d.ts +44 -0
  117. package/dist/src/cache/lru-cache.js +140 -0
  118. package/dist/src/cache/types.d.ts +24 -0
  119. package/dist/src/cache/types.js +4 -0
  120. package/dist/src/diff/annotators.d.ts +4 -0
  121. package/dist/src/diff/annotators.js +155 -0
  122. package/dist/src/diff/change-reports.d.ts +37 -0
  123. package/dist/src/diff/change-reports.js +366 -0
  124. package/dist/src/diff/core.d.ts +26 -0
  125. package/dist/src/diff/core.js +155 -0
  126. package/dist/src/diff/enhanced-diff.d.ts +51 -0
  127. package/dist/src/diff/enhanced-diff.js +62 -0
  128. package/dist/src/diff/impact-strategies-refactored.d.ts +69 -0
  129. package/dist/src/diff/impact-strategies-refactored.js +223 -0
  130. package/dist/src/diff/impact-strategies.d.ts +41 -0
  131. package/dist/src/diff/impact-strategies.js +212 -0
  132. package/dist/src/diff/index.d.ts +8 -0
  133. package/dist/src/diff/index.js +11 -0
  134. package/dist/src/diff/metrics-calculator.d.ts +23 -0
  135. package/dist/src/diff/metrics-calculator.js +65 -0
  136. package/dist/src/diff/risk-calculator.d.ts +23 -0
  137. package/dist/src/diff/risk-calculator.js +55 -0
  138. package/dist/src/diff/suggestion-generator.d.ts +18 -0
  139. package/dist/src/diff/suggestion-generator.js +74 -0
  140. package/dist/src/diff/types.d.ts +24 -0
  141. package/dist/src/diff/types.js +8 -0
  142. package/dist/src/errors/base-error.d.ts +20 -0
  143. package/dist/src/errors/base-error.js +29 -0
  144. package/dist/src/errors/config-error.d.ts +4 -0
  145. package/dist/src/errors/config-error.js +7 -0
  146. package/dist/src/errors/error-factory.d.ts +22 -0
  147. package/dist/src/errors/error-factory.js +45 -0
  148. package/dist/src/errors/index.d.ts +8 -0
  149. package/dist/src/errors/index.js +8 -0
  150. package/dist/src/errors/loader-error.d.ts +4 -0
  151. package/dist/src/errors/loader-error.js +7 -0
  152. package/dist/src/errors/reference-error.d.ts +4 -0
  153. package/dist/src/errors/reference-error.js +7 -0
  154. package/dist/src/errors/schema-error.d.ts +4 -0
  155. package/dist/src/errors/schema-error.js +7 -0
  156. package/dist/src/errors/security-error.d.ts +4 -0
  157. package/dist/src/errors/security-error.js +7 -0
  158. package/dist/src/errors/semantic-error.d.ts +4 -0
  159. package/dist/src/errors/semantic-error.js +7 -0
  160. package/dist/src/generated-schemas.d.ts +2073 -0
  161. package/dist/src/generated-schemas.js +2097 -0
  162. package/dist/src/index.d.ts +13 -0
  163. package/dist/src/index.js +43 -0
  164. package/dist/src/loader/index.d.ts +5 -0
  165. package/dist/src/loader/index.js +5 -0
  166. package/dist/src/loader/security-validator.d.ts +5 -0
  167. package/dist/src/loader/security-validator.js +50 -0
  168. package/dist/src/loader/types.d.ts +30 -0
  169. package/dist/src/loader/types.js +8 -0
  170. package/dist/src/loader/unispec-loader.d.ts +10 -0
  171. package/dist/src/loader/unispec-loader.js +81 -0
  172. package/dist/src/loader/yaml-loader.d.ts +10 -0
  173. package/dist/src/loader/yaml-loader.js +39 -0
  174. package/dist/src/normalizer/core.d.ts +24 -0
  175. package/dist/src/normalizer/core.js +34 -0
  176. package/dist/src/normalizer/graphql-normalizer.d.ts +8 -0
  177. package/dist/src/normalizer/graphql-normalizer.js +64 -0
  178. package/dist/src/normalizer/index.d.ts +2 -0
  179. package/dist/src/normalizer/index.js +3 -0
  180. package/dist/src/normalizer/rest-normalizer.d.ts +8 -0
  181. package/dist/src/normalizer/rest-normalizer.js +48 -0
  182. package/dist/src/normalizer/types.d.ts +7 -0
  183. package/dist/src/normalizer/types.js +1 -0
  184. package/dist/src/normalizer/utils.d.ts +17 -0
  185. package/dist/src/normalizer/utils.js +45 -0
  186. package/dist/src/normalizer/websocket-normalizer.d.ts +8 -0
  187. package/dist/src/normalizer/websocket-normalizer.js +78 -0
  188. package/dist/src/optimizer/core.d.ts +17 -0
  189. package/dist/src/optimizer/core.js +136 -0
  190. package/dist/src/optimizer/index.d.ts +4 -0
  191. package/dist/src/optimizer/index.js +7 -0
  192. package/dist/src/optimizer/optimization-functions.d.ts +32 -0
  193. package/dist/src/optimizer/optimization-functions.js +179 -0
  194. package/dist/src/optimizer/types.d.ts +28 -0
  195. package/dist/src/optimizer/types.js +1 -0
  196. package/dist/src/optimizer/utils.d.ts +7 -0
  197. package/dist/src/optimizer/utils.js +29 -0
  198. package/dist/src/schemas/dedupe.d.ts +9 -0
  199. package/dist/src/schemas/dedupe.js +110 -0
  200. package/dist/src/schemas/index.d.ts +3 -0
  201. package/dist/src/schemas/index.js +6 -0
  202. package/dist/src/schemas/resolver.d.ts +19 -0
  203. package/dist/src/schemas/resolver.js +38 -0
  204. package/dist/src/schemas/utils.d.ts +20 -0
  205. package/dist/src/schemas/utils.js +49 -0
  206. package/dist/src/types/index.d.ts +434 -0
  207. package/dist/src/types/index.js +1 -0
  208. package/dist/src/validator/ajv-validator.d.ts +15 -0
  209. package/dist/src/validator/ajv-validator.js +75 -0
  210. package/dist/src/validator/config-validator-main.d.ts +10 -0
  211. package/dist/src/validator/config-validator-main.js +31 -0
  212. package/dist/src/validator/config-validator.d.ts +5 -0
  213. package/dist/src/validator/config-validator.js +14 -0
  214. package/dist/src/validator/index.d.ts +10 -0
  215. package/dist/src/validator/index.js +11 -0
  216. package/dist/src/validator/object-traversal.d.ts +52 -0
  217. package/dist/src/validator/object-traversal.js +104 -0
  218. package/dist/src/validator/reference-validator.d.ts +31 -0
  219. package/dist/src/validator/reference-validator.js +230 -0
  220. package/dist/src/validator/schema-references.d.ts +23 -0
  221. package/dist/src/validator/schema-references.js +111 -0
  222. package/dist/src/validator/semantic-validator.d.ts +26 -0
  223. package/dist/src/validator/semantic-validator.js +325 -0
  224. package/dist/src/validator/tests-validator.d.ts +9 -0
  225. package/dist/src/validator/tests-validator.js +13 -0
  226. package/dist/src/validator/types.d.ts +29 -0
  227. package/dist/src/validator/types.js +1 -0
  228. package/dist/src/validator/unispec-validator.d.ts +15 -0
  229. package/dist/src/validator/unispec-validator.js +77 -0
  230. package/dist/src/validator/validator-factory.d.ts +10 -0
  231. package/dist/src/validator/validator-factory.js +73 -0
  232. package/dist/src/versions.d.ts +10 -0
  233. package/dist/src/versions.js +143 -0
  234. package/dist/tests/cache/cache.test.d.ts +1 -0
  235. package/dist/tests/cache/cache.test.js +269 -0
  236. package/dist/tests/cache/utils.d.ts +4 -0
  237. package/dist/tests/cache/utils.js +24 -0
  238. package/dist/tests/concurrency-normalizer-optimizer.test.d.ts +0 -0
  239. package/dist/tests/concurrency-normalizer-optimizer.test.js +1 -0
  240. package/dist/tests/diff/diff-annotators.test.d.ts +1 -0
  241. package/dist/tests/diff/diff-annotators.test.js +275 -0
  242. package/dist/tests/diff/diff-comprehensive.test.d.ts +1 -0
  243. package/dist/tests/diff/diff-comprehensive.test.js +257 -0
  244. package/dist/tests/diff/diff-extended.test.d.ts +1 -0
  245. package/dist/tests/diff/diff-extended.test.js +230 -0
  246. package/dist/tests/diff/diff.test.d.ts +1 -0
  247. package/dist/tests/diff/diff.test.js +184 -0
  248. package/dist/tests/diff/utils.d.ts +2 -0
  249. package/dist/tests/diff/utils.js +3 -0
  250. package/dist/tests/errors/errors-integration.test.d.ts +1 -0
  251. package/dist/tests/errors/errors-integration.test.js +168 -0
  252. package/dist/tests/errors/errors.test.d.ts +1 -0
  253. package/dist/tests/errors/errors.test.js +275 -0
  254. package/dist/tests/errors/utils.d.ts +2 -0
  255. package/dist/tests/errors/utils.js +3 -0
  256. package/dist/tests/loader/integration.test.d.ts +1 -0
  257. package/dist/tests/loader/integration.test.js +211 -0
  258. package/dist/tests/loader/loader.test.d.ts +1 -0
  259. package/dist/tests/loader/loader.test.js +336 -0
  260. package/dist/tests/normalizer/normalizer-comprehensive.test.d.ts +1 -0
  261. package/dist/tests/normalizer/normalizer-comprehensive.test.js +643 -0
  262. package/dist/tests/normalizer/normalizer-invalid.test.d.ts +1 -0
  263. package/dist/tests/normalizer/normalizer-invalid.test.js +253 -0
  264. package/dist/tests/normalizer/normalizer-valid.test.d.ts +1 -0
  265. package/dist/tests/normalizer/normalizer-valid.test.js +233 -0
  266. package/dist/tests/normalizer/utils.d.ts +18 -0
  267. package/dist/tests/normalizer/utils.js +36 -0
  268. package/dist/tests/optimizer/compress-references.test.d.ts +1 -0
  269. package/dist/tests/optimizer/compress-references.test.js +299 -0
  270. package/dist/tests/optimizer/deduplication.test.d.ts +1 -0
  271. package/dist/tests/optimizer/deduplication.test.js +127 -0
  272. package/dist/tests/optimizer/integration.test.d.ts +1 -0
  273. package/dist/tests/optimizer/integration.test.js +126 -0
  274. package/dist/tests/optimizer/optimization-report.test.d.ts +1 -0
  275. package/dist/tests/optimizer/optimization-report.test.js +217 -0
  276. package/dist/tests/optimizer/optimize-document.test.d.ts +1 -0
  277. package/dist/tests/optimizer/optimize-document.test.js +182 -0
  278. package/dist/tests/optimizer/orphaned-schemas.test.d.ts +1 -0
  279. package/dist/tests/optimizer/orphaned-schemas.test.js +189 -0
  280. package/dist/tests/optimizer/sort-schemas.test.d.ts +1 -0
  281. package/dist/tests/optimizer/sort-schemas.test.js +126 -0
  282. package/dist/tests/optimizer/utils.d.ts +8 -0
  283. package/dist/tests/optimizer/utils.js +199 -0
  284. package/dist/tests/schemas/schemas-edge-cases.test.d.ts +1 -0
  285. package/dist/tests/schemas/schemas-edge-cases.test.js +218 -0
  286. package/dist/tests/schemas/schemas.test.d.ts +1 -0
  287. package/dist/tests/schemas/schemas.test.js +395 -0
  288. package/dist/tests/schemas/utils.d.ts +2 -0
  289. package/dist/tests/schemas/utils.js +3 -0
  290. package/dist/tests/utils.d.ts +10 -0
  291. package/dist/tests/utils.js +118 -0
  292. package/dist/tests/validator/config-validator.test.d.ts +1 -0
  293. package/dist/tests/validator/config-validator.test.js +73 -0
  294. package/dist/tests/validator/debug-config.d.ts +0 -0
  295. package/dist/tests/validator/debug-config.js +1 -0
  296. package/dist/tests/validator/debug-missing-service.d.ts +0 -0
  297. package/dist/tests/validator/debug-missing-service.js +1 -0
  298. package/dist/tests/validator/debug-other-configs.d.ts +0 -0
  299. package/dist/tests/validator/debug-other-configs.js +1 -0
  300. package/dist/tests/validator/debug-references.d.ts +0 -0
  301. package/dist/tests/validator/debug-references.js +1 -0
  302. package/dist/tests/validator/unispec-validator.test.d.ts +1 -0
  303. package/dist/tests/validator/unispec-validator.test.js +98 -0
  304. package/dist/tests/validator/utils.d.ts +6 -0
  305. package/dist/tests/validator/utils.js +20 -0
  306. package/package.json +4 -3
@@ -0,0 +1,304 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const node_test_1 = require("node:test");
8
+ const optimization_functions_1 = require("../../src/optimizer/optimization-functions.js");
9
+ const utils_1 = require("./utils.js");
10
+ (0, node_test_1.describe)("compressSchemaReferences", () => {
11
+ (0, node_test_1.it)("should compress JSON Pointer references", () => {
12
+ const doc = (0, utils_1.createDocumentWithLongReferences)();
13
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(doc);
14
+ node_assert_1.default.strictEqual(compressedCount, 1);
15
+ // Check that reference was compressed
16
+ const route = doc.service?.protocols?.rest?.routes?.[0];
17
+ const schemaRef = route?.responses?.["200"]?.content?.["application/json"]?.schemaRef;
18
+ node_assert_1.default.strictEqual(schemaRef, "TestSchema");
19
+ });
20
+ (0, node_test_1.it)("should compress hash references", () => {
21
+ const doc = {
22
+ unispecVersion: "1.0.0",
23
+ service: {
24
+ name: "test",
25
+ schemas: {
26
+ TestSchema: {
27
+ name: "TestSchema",
28
+ description: "Test schema",
29
+ jsonSchema: { type: "string" },
30
+ },
31
+ },
32
+ protocols: {
33
+ rest: {
34
+ routes: [
35
+ {
36
+ name: "testRoute",
37
+ method: "GET",
38
+ path: "/test",
39
+ responses: {
40
+ "200": {
41
+ description: "Success",
42
+ content: {
43
+ "application/json": {
44
+ schemaRef: "#TestSchema", // Hash format
45
+ },
46
+ },
47
+ },
48
+ },
49
+ },
50
+ ],
51
+ },
52
+ },
53
+ },
54
+ };
55
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(doc);
56
+ node_assert_1.default.strictEqual(compressedCount, 1);
57
+ const route = doc.service?.protocols?.rest?.routes?.[0];
58
+ const schemaRef = route?.responses?.["200"]?.content?.["application/json"]?.schemaRef;
59
+ node_assert_1.default.strictEqual(schemaRef, "TestSchema");
60
+ });
61
+ (0, node_test_1.it)("should compress path references", () => {
62
+ const doc = {
63
+ unispecVersion: "1.0.0",
64
+ service: {
65
+ name: "test",
66
+ schemas: {
67
+ TestSchema: {
68
+ name: "TestSchema",
69
+ description: "Test schema",
70
+ jsonSchema: { type: "string" },
71
+ },
72
+ },
73
+ protocols: {
74
+ rest: {
75
+ routes: [
76
+ {
77
+ name: "testRoute",
78
+ method: "GET",
79
+ path: "/test",
80
+ responses: {
81
+ "200": {
82
+ description: "Success",
83
+ content: {
84
+ "application/json": {
85
+ schemaRef: "path/to/TestSchema", // Path format
86
+ },
87
+ },
88
+ },
89
+ },
90
+ },
91
+ ],
92
+ },
93
+ },
94
+ },
95
+ };
96
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(doc);
97
+ node_assert_1.default.strictEqual(compressedCount, 1);
98
+ const route = doc.service?.protocols?.rest?.routes?.[0];
99
+ const schemaRef = route?.responses?.["200"]?.content?.["application/json"]?.schemaRef;
100
+ node_assert_1.default.strictEqual(schemaRef, "TestSchema");
101
+ });
102
+ (0, node_test_1.it)("should not compress already simple references", () => {
103
+ const doc = {
104
+ unispecVersion: "1.0.0",
105
+ service: {
106
+ name: "test",
107
+ schemas: {
108
+ TestSchema: {
109
+ name: "TestSchema",
110
+ description: "Test schema",
111
+ jsonSchema: { type: "string" },
112
+ },
113
+ },
114
+ protocols: {
115
+ rest: {
116
+ routes: [
117
+ {
118
+ name: "testRoute",
119
+ method: "GET",
120
+ path: "/test",
121
+ responses: {
122
+ "200": {
123
+ description: "Success",
124
+ content: {
125
+ "application/json": {
126
+ schemaRef: "TestSchema", // Already simple
127
+ },
128
+ },
129
+ },
130
+ },
131
+ },
132
+ ],
133
+ },
134
+ },
135
+ },
136
+ };
137
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(doc);
138
+ node_assert_1.default.strictEqual(compressedCount, 0);
139
+ const route = doc.service?.protocols?.rest?.routes?.[0];
140
+ const schemaRef = route?.responses?.["200"]?.content?.["application/json"]?.schemaRef;
141
+ node_assert_1.default.strictEqual(schemaRef, "TestSchema");
142
+ });
143
+ (0, node_test_1.it)("should handle multiple references", () => {
144
+ const doc = {
145
+ unispecVersion: "1.0.0",
146
+ service: {
147
+ name: "test",
148
+ schemas: {
149
+ TestSchema: {
150
+ name: "TestSchema",
151
+ description: "Test schema",
152
+ jsonSchema: { type: "string" },
153
+ },
154
+ },
155
+ protocols: {
156
+ rest: {
157
+ routes: [
158
+ {
159
+ name: "testRoute1",
160
+ method: "GET",
161
+ path: "/test1",
162
+ responses: {
163
+ "200": {
164
+ description: "Success",
165
+ content: {
166
+ "application/json": {
167
+ schemaRef: "#/service/schemas/TestSchema",
168
+ },
169
+ },
170
+ },
171
+ },
172
+ },
173
+ {
174
+ name: "testRoute2",
175
+ method: "POST",
176
+ path: "/test2",
177
+ requestBody: {
178
+ content: {
179
+ "application/json": {
180
+ schemaRef: "#TestSchema",
181
+ },
182
+ },
183
+ },
184
+ responses: {
185
+ "201": {
186
+ description: "Created",
187
+ content: {
188
+ "application/json": {
189
+ schemaRef: "path/to/TestSchema",
190
+ },
191
+ },
192
+ },
193
+ },
194
+ },
195
+ ],
196
+ },
197
+ },
198
+ },
199
+ };
200
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(doc);
201
+ node_assert_1.default.strictEqual(compressedCount, 3);
202
+ // Check all references were compressed
203
+ const routes = doc.service?.protocols?.rest?.routes || [];
204
+ const ref1 = routes[0]?.responses?.["200"]?.content?.["application/json"]?.schemaRef;
205
+ const ref2 = routes[1]?.requestBody?.content?.["application/json"]?.schemaRef;
206
+ const ref3 = routes[1]?.responses?.["201"]?.content?.["application/json"]?.schemaRef;
207
+ node_assert_1.default.strictEqual(ref1, "TestSchema");
208
+ node_assert_1.default.strictEqual(ref2, "TestSchema");
209
+ node_assert_1.default.strictEqual(ref3, "TestSchema");
210
+ });
211
+ (0, node_test_1.it)("should handle documents without schemas", () => {
212
+ const doc = { unispecVersion: "1.0.0", service: { name: "test" } };
213
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(doc);
214
+ node_assert_1.default.strictEqual(compressedCount, 0);
215
+ });
216
+ (0, node_test_1.it)("should handle empty references", () => {
217
+ const doc = {
218
+ unispecVersion: "1.0.0",
219
+ service: {
220
+ name: "test",
221
+ protocols: {
222
+ rest: {
223
+ routes: [
224
+ {
225
+ name: "testRoute",
226
+ method: "GET",
227
+ path: "/test",
228
+ responses: {
229
+ "200": {
230
+ description: "Success",
231
+ content: {
232
+ "application/json": {
233
+ schemaRef: "",
234
+ },
235
+ },
236
+ },
237
+ },
238
+ },
239
+ ],
240
+ },
241
+ },
242
+ },
243
+ };
244
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(doc);
245
+ node_assert_1.default.strictEqual(compressedCount, 0);
246
+ });
247
+ (0, node_test_1.it)("should work with real examples from node_modules", () => {
248
+ const doc = (0, utils_1.loadExample)((0, utils_1.getExamplePath)("valid", "spec", "mixed-complete.json"));
249
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(JSON.parse(JSON.stringify(doc)));
250
+ // mixed-complete.json uses simple references, so nothing should be compressed
251
+ node_assert_1.default.strictEqual(compressedCount, 0);
252
+ });
253
+ (0, node_test_1.it)("should find references in nested structures", () => {
254
+ const doc = {
255
+ unispecVersion: "1.0.0",
256
+ service: {
257
+ name: "test",
258
+ schemas: {
259
+ TestSchema: {
260
+ name: "TestSchema",
261
+ description: "Test schema",
262
+ jsonSchema: { type: "string" },
263
+ },
264
+ },
265
+ protocols: {
266
+ rest: {
267
+ routes: [
268
+ {
269
+ name: "testRoute",
270
+ method: "GET",
271
+ path: "/test",
272
+ responses: {
273
+ "200": {
274
+ description: "Success",
275
+ content: {
276
+ "application/json": {
277
+ schemaRef: "#/service/schemas/TestSchema",
278
+ },
279
+ },
280
+ },
281
+ },
282
+ },
283
+ ],
284
+ },
285
+ websocket: {
286
+ channels: [
287
+ {
288
+ name: "testChannel",
289
+ messages: [
290
+ {
291
+ name: "testMessage",
292
+ schemaRef: "#/service/schemas/TestSchema",
293
+ },
294
+ ],
295
+ },
296
+ ],
297
+ },
298
+ },
299
+ },
300
+ };
301
+ const compressedCount = (0, optimization_functions_1.compressSchemaReferences)(doc);
302
+ node_assert_1.default.strictEqual(compressedCount, 2); // One in REST response, one in WebSocket
303
+ });
304
+ });
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const node_test_1 = require("node:test");
8
+ const optimization_functions_1 = require("../../src/optimizer/optimization-functions.js");
9
+ const utils_1 = require("./utils.js");
10
+ (0, node_test_1.describe)("deduplicateSchemas", () => {
11
+ (0, node_test_1.it)("should remove duplicate schemas and update references", () => {
12
+ const doc = (0, utils_1.createDocumentWithDuplicateSchemas)();
13
+ const result = (0, optimization_functions_1.deduplicateSchemas)(doc);
14
+ node_assert_1.default.strictEqual(result.removedSchemas.length, 1);
15
+ node_assert_1.default.ok(result.removedSchemas.includes("Person") ||
16
+ result.removedSchemas.includes("User"));
17
+ node_assert_1.default.strictEqual(result.updatedReferences, 0);
18
+ // Check that only one of the duplicate schemas remains
19
+ const remainingSchemas = Object.keys(doc.service?.schemas || {});
20
+ node_assert_1.default.ok(remainingSchemas.includes("User") || remainingSchemas.includes("Person"));
21
+ node_assert_1.default.strictEqual(remainingSchemas.filter((name) => name === "User" || name === "Person")
22
+ .length, 1);
23
+ node_assert_1.default.ok(remainingSchemas.includes("Profile"));
24
+ });
25
+ (0, node_test_1.it)("should prefer referenced schema over unreferenced one", () => {
26
+ const doc = (0, utils_1.createDocumentWithDuplicateSchemas)();
27
+ // Add reference to User schema
28
+ if (doc.service?.protocols?.rest?.routes?.[0]) {
29
+ doc.service.protocols.rest.routes[0].responses = {
30
+ "200": {
31
+ description: "Success",
32
+ content: {
33
+ "application/json": {
34
+ schemaRef: "User",
35
+ },
36
+ },
37
+ },
38
+ };
39
+ }
40
+ const result = (0, optimization_functions_1.deduplicateSchemas)(doc);
41
+ node_assert_1.default.strictEqual(result.removedSchemas.length, 1);
42
+ node_assert_1.default.ok(result.removedSchemas.includes("Person"));
43
+ node_assert_1.default.ok(!result.removedSchemas.includes("User"));
44
+ node_assert_1.default.ok(doc.service?.schemas?.User);
45
+ node_assert_1.default.ok(!doc.service?.schemas?.Person);
46
+ });
47
+ (0, node_test_1.it)("should handle documents without schemas", () => {
48
+ const doc = { unispecVersion: "1.0.0", service: { name: "test" } };
49
+ const result = (0, optimization_functions_1.deduplicateSchemas)(doc);
50
+ node_assert_1.default.strictEqual(result.removedSchemas.length, 0);
51
+ node_assert_1.default.strictEqual(result.updatedReferences, 0);
52
+ });
53
+ (0, node_test_1.it)("should handle documents without service", () => {
54
+ const doc = { unispecVersion: "1.0.0", service: { name: "test" } };
55
+ const result = (0, optimization_functions_1.deduplicateSchemas)(doc);
56
+ node_assert_1.default.strictEqual(result.removedSchemas.length, 0);
57
+ node_assert_1.default.strictEqual(result.updatedReferences, 0);
58
+ });
59
+ (0, node_test_1.it)("should handle empty schemas object", () => {
60
+ const doc = {
61
+ unispecVersion: "1.0.0",
62
+ service: { name: "test", schemas: {} },
63
+ };
64
+ const result = (0, optimization_functions_1.deduplicateSchemas)(doc);
65
+ node_assert_1.default.strictEqual(result.removedSchemas.length, 0);
66
+ node_assert_1.default.strictEqual(result.updatedReferences, 0);
67
+ });
68
+ (0, node_test_1.it)("should update schema references when removing duplicates", () => {
69
+ // Test case where reference points to Person (which will be kept)
70
+ const doc = (0, utils_1.createDocumentWithDuplicateSchemas)();
71
+ if (doc.service?.protocols?.rest?.routes?.[0]) {
72
+ doc.service.protocols.rest.routes[0].responses = {
73
+ "200": {
74
+ description: "Success",
75
+ content: {
76
+ "application/json": {
77
+ schemaRef: "Person", // This will be kept, User will be removed
78
+ },
79
+ },
80
+ },
81
+ };
82
+ }
83
+ const result = (0, optimization_functions_1.deduplicateSchemas)(doc);
84
+ // Should remove User (no reference update needed since Person stays)
85
+ node_assert_1.default.strictEqual(result.removedSchemas.length, 1);
86
+ node_assert_1.default.ok(result.removedSchemas.includes("User"));
87
+ node_assert_1.default.strictEqual(result.updatedReferences, 0);
88
+ // Check that Person still exists and reference points to it
89
+ node_assert_1.default.ok(doc.service?.schemas?.Person);
90
+ node_assert_1.default.ok(!doc.service?.schemas?.User);
91
+ const route = doc.service?.protocols?.rest?.routes?.[0];
92
+ const schemaRef = route?.responses?.["200"]?.content?.["application/json"]?.schemaRef;
93
+ node_assert_1.default.strictEqual(schemaRef, "Person");
94
+ });
95
+ (0, node_test_1.it)("should work with real examples from node_modules", () => {
96
+ const doc = (0, utils_1.loadExample)((0, utils_1.getExamplePath)("valid", "spec", "mixed-complete.json"));
97
+ const result = (0, optimization_functions_1.deduplicateSchemas)(JSON.parse(JSON.stringify(doc)));
98
+ // mixed-complete.json has no duplicates, so nothing should be removed
99
+ node_assert_1.default.strictEqual(result.removedSchemas.length, 0);
100
+ node_assert_1.default.strictEqual(result.updatedReferences, 0);
101
+ });
102
+ (0, node_test_1.it)("should handle schemas with null jsonSchema", () => {
103
+ const doc = {
104
+ unispecVersion: "1.0.0",
105
+ service: {
106
+ name: "test",
107
+ schemas: {
108
+ Schema1: {
109
+ name: "Schema1",
110
+ description: "Schema 1",
111
+ jsonSchema: {},
112
+ },
113
+ Schema2: {
114
+ name: "Schema2",
115
+ description: "Schema 2",
116
+ jsonSchema: {},
117
+ },
118
+ Schema3: {
119
+ name: "Schema3",
120
+ description: "Schema 3",
121
+ jsonSchema: { type: "string" },
122
+ },
123
+ },
124
+ },
125
+ };
126
+ const result = (0, optimization_functions_1.deduplicateSchemas)(doc);
127
+ // Two schemas with empty jsonSchema should be considered duplicates
128
+ node_assert_1.default.strictEqual(result.removedSchemas.length, 1);
129
+ node_assert_1.default.strictEqual(result.updatedReferences, 0);
130
+ node_assert_1.default.strictEqual(Object.keys(doc.service?.schemas || {}).length, 2);
131
+ });
132
+ });
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const node_test_1 = require("node:test");
8
+ const core_1 = require("../../src/optimizer/core.js");
9
+ const optimization_functions_1 = require("../../src/optimizer/optimization-functions.js");
10
+ const utils_1 = require("./utils.js");
11
+ (0, node_test_1.describe)("Optimizer Integration Tests", () => {
12
+ (0, node_test_1.it)("should work with real examples from node_modules", () => {
13
+ const doc = (0, utils_1.loadExample)((0, utils_1.getExamplePath)("valid", "spec", "mixed-complete.json"));
14
+ // Test individual functions
15
+ const dedupResult = (0, optimization_functions_1.deduplicateSchemas)(JSON.parse(JSON.stringify(doc)));
16
+ node_assert_1.default.ok(dedupResult.removedSchemas.length >= 0);
17
+ const orphanedResult = (0, optimization_functions_1.removeOrphanedSchemas)(JSON.parse(JSON.stringify(doc)));
18
+ node_assert_1.default.ok(orphanedResult.length >= 0);
19
+ const sortResult = (0, optimization_functions_1.sortSchemas)(JSON.parse(JSON.stringify(doc)));
20
+ node_assert_1.default.ok(sortResult >= 0);
21
+ const compressResult = (0, optimization_functions_1.compressSchemaReferences)(JSON.parse(JSON.stringify(doc)));
22
+ node_assert_1.default.ok(compressResult >= 0);
23
+ // Test optimizeDocument
24
+ const optimizeResult = (0, core_1.optimizeDocument)(JSON.parse(JSON.stringify(doc)));
25
+ node_assert_1.default.ok(optimizeResult.document);
26
+ node_assert_1.default.ok(optimizeResult.statistics);
27
+ node_assert_1.default.ok(Array.isArray(optimizeResult.changes));
28
+ // Test generateOptimizationReport
29
+ const report = (0, core_1.generateOptimizationReport)(JSON.parse(JSON.stringify(doc)));
30
+ node_assert_1.default.ok(report.recommendations);
31
+ node_assert_1.default.ok(report.potentialSavings);
32
+ });
33
+ (0, node_test_1.it)("should handle edge cases gracefully", () => {
34
+ // Empty document
35
+ const emptyDoc = { unispecVersion: "1.0.0", service: { name: "test" } };
36
+ const optimizeResult = (0, core_1.optimizeDocument)(emptyDoc);
37
+ node_assert_1.default.strictEqual(optimizeResult.statistics.originalSchemas, 0);
38
+ node_assert_1.default.strictEqual(optimizeResult.statistics.optimizedSchemas, 0);
39
+ const report = (0, core_1.generateOptimizationReport)(emptyDoc);
40
+ node_assert_1.default.strictEqual(report.recommendations.length, 0);
41
+ node_assert_1.default.strictEqual(report.potentialSavings.schemaReduction, 0);
42
+ });
43
+ (0, node_test_1.it)("should preserve document integrity", () => {
44
+ const doc = (0, utils_1.loadExample)((0, utils_1.getExamplePath)("valid", "spec", "rest-simple.json"));
45
+ const result = (0, core_1.optimizeDocument)(JSON.parse(JSON.stringify(doc)));
46
+ // Should preserve required fields
47
+ node_assert_1.default.strictEqual(result.document.unispecVersion, doc.unispecVersion);
48
+ node_assert_1.default.strictEqual(result.document.service?.name, doc.service?.name);
49
+ node_assert_1.default.ok(result.document.service?.protocols);
50
+ node_assert_1.default.ok(result.document.service?.schemas);
51
+ });
52
+ (0, node_test_1.it)("should handle complex optimization scenarios", () => {
53
+ const doc = {
54
+ unispecVersion: "1.0.0",
55
+ service: {
56
+ name: "test",
57
+ schemas: {
58
+ // Duplicate schemas
59
+ User: {
60
+ description: "User schema",
61
+ jsonSchema: {
62
+ type: "object",
63
+ properties: { id: { type: "string" } },
64
+ },
65
+ },
66
+ Person: {
67
+ description: "Person schema",
68
+ jsonSchema: {
69
+ type: "object",
70
+ properties: { id: { type: "string" } },
71
+ },
72
+ },
73
+ // Orphaned schema
74
+ Orphaned: {
75
+ description: "Orphaned schema",
76
+ jsonSchema: { type: "string" },
77
+ },
78
+ // Referenced schema
79
+ Profile: {
80
+ description: "Profile schema",
81
+ jsonSchema: {
82
+ type: "object",
83
+ properties: { profileId: { type: "string" } },
84
+ },
85
+ },
86
+ },
87
+ protocols: {
88
+ rest: {
89
+ routes: [
90
+ {
91
+ name: "testRoute",
92
+ method: "GET",
93
+ path: "/test",
94
+ responses: {
95
+ "200": {
96
+ description: "Success",
97
+ content: {
98
+ "application/json": {
99
+ schemaRef: "#/service/schemas/Person", // Long reference to duplicate
100
+ },
101
+ },
102
+ },
103
+ },
104
+ },
105
+ ],
106
+ },
107
+ },
108
+ },
109
+ };
110
+ const result = (0, core_1.optimizeDocument)(doc, {
111
+ dedupeSchemas: true,
112
+ sortSchemas: true,
113
+ removeUnusedSchemas: true,
114
+ compressReferences: true,
115
+ });
116
+ // Should optimize correctly
117
+ node_assert_1.default.strictEqual(result.statistics.originalSchemas, 4);
118
+ node_assert_1.default.strictEqual(result.statistics.optimizedSchemas, 1); // Person (Profile is orphaned)
119
+ node_assert_1.default.strictEqual(result.statistics.removedSchemas, 3); // User + Orphaned + Profile
120
+ node_assert_1.default.strictEqual(result.statistics.deduplicatedSchemas, 1);
121
+ // Should have changes recorded
122
+ node_assert_1.default.ok(result.changes.length >= 3);
123
+ // Check final state
124
+ const schemas = Object.keys(result.document.service?.schemas || {});
125
+ node_assert_1.default.deepStrictEqual(schemas, ["Person"]); // Only Person remains
126
+ // Check reference was updated and compressed
127
+ const route = result.document.service?.protocols?.rest?.routes?.[0];
128
+ const schemaRef = route?.responses?.["200"]?.content?.["application/json"]?.schemaRef;
129
+ node_assert_1.default.strictEqual(schemaRef, "Person");
130
+ });
131
+ });