@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,262 @@
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_path_1 = __importDefault(require("node:path"));
8
+ const node_test_1 = require("node:test");
9
+ const utils_1 = require("../../tests/utils.js");
10
+ const core_1 = require("../../src/diff/core.js");
11
+ (0, node_test_1.describe)("diff module - comprehensive schema examples", () => {
12
+ (0, node_test_1.describe)("valid spec examples", () => {
13
+ (0, node_test_1.it)("should handle rest-simple.json correctly", () => {
14
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
15
+ // Test self-comparison
16
+ const result = (0, core_1.diffUniSpec)(doc, doc);
17
+ node_assert_1.default.strictEqual(result.changes.length, 0);
18
+ // Test modifications
19
+ const modified = JSON.parse(JSON.stringify(doc));
20
+ modified.service.protocols.rest.routes.push({
21
+ name: "newRoute",
22
+ method: "DELETE",
23
+ path: "/users/{id}",
24
+ responses: { 204: { description: "No content" } },
25
+ });
26
+ const diffResult = (0, core_1.diffUniSpec)(doc, modified);
27
+ const newRoute = diffResult.changes.find((change) => change.path.includes("newRoute"));
28
+ node_assert_1.default.ok(newRoute);
29
+ node_assert_1.default.strictEqual(newRoute.protocol, "rest");
30
+ node_assert_1.default.strictEqual(newRoute.severity, "non-breaking");
31
+ });
32
+ (0, node_test_1.it)("should handle graphql-simple.json correctly", () => {
33
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "graphql-simple.json"));
34
+ // Test self-comparison
35
+ const result = (0, core_1.diffUniSpec)(doc, doc);
36
+ node_assert_1.default.strictEqual(result.changes.length, 0);
37
+ // Test schema change
38
+ const modified = JSON.parse(JSON.stringify(doc));
39
+ modified.service.protocols.graphql.schema +=
40
+ " type NewType { field: String! }";
41
+ const diffResult = (0, core_1.diffUniSpec)(doc, modified);
42
+ const schemaChange = diffResult.changes.find((change) => change.path.includes("schema"));
43
+ node_assert_1.default.ok(schemaChange);
44
+ node_assert_1.default.strictEqual(schemaChange.description, "Value changed");
45
+ });
46
+ (0, node_test_1.it)("should handle websocket-simple.json correctly", () => {
47
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "websocket-simple.json"));
48
+ // Test self-comparison
49
+ const result = (0, core_1.diffUniSpec)(doc, doc);
50
+ node_assert_1.default.strictEqual(result.changes.length, 0);
51
+ // Test channel addition
52
+ const modified = JSON.parse(JSON.stringify(doc));
53
+ modified.service.protocols.websocket.channels.push({
54
+ name: "newChannel",
55
+ description: "New channel",
56
+ messages: [],
57
+ });
58
+ const diffResult = (0, core_1.diffUniSpec)(doc, modified);
59
+ const newChannel = diffResult.changes.find((change) => change.path.includes("newChannel"));
60
+ node_assert_1.default.ok(newChannel);
61
+ node_assert_1.default.strictEqual(newChannel.protocol, "websocket");
62
+ node_assert_1.default.strictEqual(newChannel.severity, "non-breaking");
63
+ });
64
+ (0, node_test_1.it)("should handle mixed-complete.json correctly", () => {
65
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "mixed-complete.json"));
66
+ // Test self-comparison
67
+ const result = (0, core_1.diffUniSpec)(doc, doc);
68
+ node_assert_1.default.strictEqual(result.changes.length, 0);
69
+ // Test multiple protocol changes
70
+ const modified = JSON.parse(JSON.stringify(doc));
71
+ // Add REST route
72
+ if (modified.service.protocols.rest) {
73
+ modified.service.protocols.rest.routes.push({
74
+ name: "mixedRoute",
75
+ method: "PATCH",
76
+ path: "/mixed",
77
+ responses: { 200: { description: "OK" } },
78
+ });
79
+ }
80
+ // Add GraphQL query
81
+ if (modified.service.protocols.graphql?.queries) {
82
+ modified.service.protocols.graphql.queries.push({
83
+ name: "mixedQuery",
84
+ description: "Mixed query",
85
+ args: [],
86
+ returnType: "String",
87
+ });
88
+ }
89
+ const diffResult = (0, core_1.diffUniSpec)(doc, modified);
90
+ // Should have both REST and GraphQL changes
91
+ const restChanges = diffResult.changes.filter((change) => change.protocol === "rest");
92
+ const graphqlChanges = diffResult.changes.filter((change) => change.protocol === "graphql");
93
+ node_assert_1.default.ok(restChanges.length > 0);
94
+ node_assert_1.default.ok(graphqlChanges.length > 0);
95
+ });
96
+ });
97
+ (0, node_test_1.describe)("valid config examples", () => {
98
+ (0, node_test_1.it)("should handle complete-enterprise.json correctly", () => {
99
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "config", "complete-enterprise.json"));
100
+ // Test self-comparison
101
+ const result = (0, core_1.diffUniSpec)(doc, doc);
102
+ node_assert_1.default.strictEqual(result.changes.length, 0);
103
+ // Test modification
104
+ const modified = JSON.parse(JSON.stringify(doc));
105
+ if (Array.isArray(modified.services)) {
106
+ modified.services.push({
107
+ name: "new-service",
108
+ baseUrl: "https://new-service.example.com",
109
+ });
110
+ }
111
+ const diffResult = (0, core_1.diffUniSpec)(doc, modified);
112
+ node_assert_1.default.ok(diffResult.changes.length > 0);
113
+ });
114
+ (0, node_test_1.it)("should handle registry-based.json correctly", () => {
115
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "config", "registry-based.json"));
116
+ // Test self-comparison
117
+ const result = (0, core_1.diffUniSpec)(doc, doc);
118
+ node_assert_1.default.strictEqual(result.changes.length, 0);
119
+ });
120
+ (0, node_test_1.it)("should handle simple-multi-service.json correctly", () => {
121
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "config", "simple-multi-service.json"));
122
+ // Test self-comparison
123
+ const result = (0, core_1.diffUniSpec)(doc, doc);
124
+ node_assert_1.default.strictEqual(result.changes.length, 0);
125
+ });
126
+ });
127
+ (0, node_test_1.describe)("invalid spec examples", () => {
128
+ (0, node_test_1.it)("should handle graphql-missing-arg-type.json without crashing", () => {
129
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "graphql-missing-arg-type.json"));
130
+ // Should not crash on invalid documents
131
+ const result = (0, core_1.diffUniSpec)(doc, doc);
132
+ node_assert_1.default.strictEqual(result.changes.length, 0);
133
+ // Should handle modifications
134
+ const modified = JSON.parse(JSON.stringify(doc));
135
+ modified.unispecVersion = "1.0.1";
136
+ const diffResult = (0, core_1.diffUniSpec)(doc, modified);
137
+ const versionChange = diffResult.changes.find((change) => change.path === "/unispecVersion");
138
+ node_assert_1.default.ok(versionChange);
139
+ });
140
+ (0, node_test_1.it)("should handle graphql-missing-name.json without crashing", () => {
141
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "graphql-missing-name.json"));
142
+ const result = (0, core_1.diffUniSpec)(doc, doc);
143
+ node_assert_1.default.strictEqual(result.changes.length, 0);
144
+ });
145
+ (0, node_test_1.it)("should handle invalid-identifier.json without crashing", () => {
146
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "invalid-identifier.json"));
147
+ const result = (0, core_1.diffUniSpec)(doc, doc);
148
+ node_assert_1.default.strictEqual(result.changes.length, 0);
149
+ });
150
+ (0, node_test_1.it)("should handle invalid-rest-method.json without crashing", () => {
151
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "invalid-rest-method.json"));
152
+ const result = (0, core_1.diffUniSpec)(doc, doc);
153
+ node_assert_1.default.strictEqual(result.changes.length, 0);
154
+ });
155
+ (0, node_test_1.it)("should handle missing-service-name.json without crashing", () => {
156
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "missing-service-name.json"));
157
+ const result = (0, core_1.diffUniSpec)(doc, doc);
158
+ node_assert_1.default.strictEqual(result.changes.length, 0);
159
+ });
160
+ (0, node_test_1.it)("should handle missing-unispec-version.json without crashing", () => {
161
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "missing-unispec-version.json"));
162
+ const result = (0, core_1.diffUniSpec)(doc, doc);
163
+ node_assert_1.default.strictEqual(result.changes.length, 0);
164
+ });
165
+ });
166
+ (0, node_test_1.describe)("invalid config examples", () => {
167
+ (0, node_test_1.it)("should handle empty-services-array.json without crashing", () => {
168
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "empty-services-array.json"));
169
+ const result = (0, core_1.diffUniSpec)(doc, doc);
170
+ node_assert_1.default.strictEqual(result.changes.length, 0);
171
+ });
172
+ (0, node_test_1.it)("should handle invalid-spec-reference.json without crashing", () => {
173
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "invalid-spec-reference.json"));
174
+ const result = (0, core_1.diffUniSpec)(doc, doc);
175
+ node_assert_1.default.strictEqual(result.changes.length, 0);
176
+ });
177
+ (0, node_test_1.it)("should handle missing-services.json without crashing", () => {
178
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "missing-services.json"));
179
+ const result = (0, core_1.diffUniSpec)(doc, doc);
180
+ node_assert_1.default.strictEqual(result.changes.length, 0);
181
+ });
182
+ });
183
+ (0, node_test_1.describe)("cross-example comparisons", () => {
184
+ (0, node_test_1.it)("should handle comparing different valid specs", () => {
185
+ const restDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
186
+ const graphqlDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "graphql-simple.json"));
187
+ // Should detect many differences between different specs
188
+ const result = (0, core_1.diffUniSpec)(restDoc, graphqlDoc);
189
+ node_assert_1.default.ok(result.changes.length > 0);
190
+ // Most changes will be structural and not protocol-specific
191
+ // since the documents have completely different structures
192
+ const structuralChanges = result.changes.filter((change) => change.protocol === undefined);
193
+ // Should have some structural changes
194
+ node_assert_1.default.ok(structuralChanges.length > 0);
195
+ // May have some protocol-specific changes if paths overlap
196
+ const restChanges = result.changes.filter((change) => change.protocol === "rest");
197
+ const graphqlChanges = result.changes.filter((change) => change.protocol === "graphql");
198
+ // At least one of them should have changes
199
+ node_assert_1.default.ok(restChanges.length > 0 ||
200
+ graphqlChanges.length > 0 ||
201
+ structuralChanges.length > 0);
202
+ });
203
+ (0, node_test_1.it)("should handle comparing valid and invalid specs", () => {
204
+ const validDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
205
+ const invalidDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "spec", "missing-service-name.json"));
206
+ // Should handle comparisons without crashing
207
+ const result = (0, core_1.diffUniSpec)(validDoc, invalidDoc);
208
+ node_assert_1.default.ok(result.changes.length > 0);
209
+ });
210
+ (0, node_test_1.it)("should handle comparing config and spec files", () => {
211
+ const configDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "config", "simple-multi-service.json"));
212
+ const specDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
213
+ // Should handle completely different structures
214
+ const result = (0, core_1.diffUniSpec)(configDoc, specDoc);
215
+ node_assert_1.default.ok(result.changes.length > 0);
216
+ });
217
+ });
218
+ (0, node_test_1.describe)("edge cases with real examples", () => {
219
+ (0, node_test_1.it)("should handle deeply nested changes in complex examples", () => {
220
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "mixed-complete.json"));
221
+ const modified = JSON.parse(JSON.stringify(doc));
222
+ // Make a deep nested change - find the first route with requestBody
223
+ if (modified.service?.protocols?.rest?.routes) {
224
+ const routeWithBody = modified.service.protocols.rest.routes.find((route) => route.requestBody?.content?.["application/json"]?.schemaRef);
225
+ if (routeWithBody) {
226
+ routeWithBody.requestBody.content["application/json"].schemaRef =
227
+ "NewSchemaRef";
228
+ }
229
+ }
230
+ const result = (0, core_1.diffUniSpec)(doc, modified);
231
+ // Should have some changes
232
+ node_assert_1.default.ok(result.changes.length > 0);
233
+ // Look for any schema-related change
234
+ const schemaChange = result.changes.find((change) => change.path.includes("schemaRef"));
235
+ // If we found a route with schemaRef, it should be detected
236
+ if (doc.service?.protocols?.rest?.routes?.some((route) => route.requestBody?.content?.["application/json"]?.schemaRef)) {
237
+ node_assert_1.default.ok(schemaChange);
238
+ node_assert_1.default.strictEqual(schemaChange.description, "Value changed");
239
+ }
240
+ else {
241
+ // If no route had schemaRef, we should still have some changes
242
+ node_assert_1.default.ok(result.changes.length > 0);
243
+ }
244
+ });
245
+ (0, node_test_1.it)("should handle array operations in named collections correctly", () => {
246
+ const doc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
247
+ const modified = JSON.parse(JSON.stringify(doc));
248
+ // Reorder routes array
249
+ if (modified.service.protocols.rest.routes.length >= 2) {
250
+ const temp = modified.service.protocols.rest.routes[0];
251
+ modified.service.protocols.rest.routes[0] =
252
+ modified.service.protocols.rest.routes[1];
253
+ modified.service.protocols.rest.routes[1] = temp;
254
+ }
255
+ const result = (0, core_1.diffUniSpec)(doc, modified);
256
+ // Named collections should compare by name, not index
257
+ // So reordering should not produce changes
258
+ const routeChanges = result.changes.filter((change) => change.path.includes("/routes/"));
259
+ node_assert_1.default.strictEqual(routeChanges.length, 0);
260
+ });
261
+ });
262
+ });
@@ -0,0 +1,235 @@
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_path_1 = __importDefault(require("node:path"));
8
+ const node_test_1 = require("node:test");
9
+ const utils_1 = require("../../tests/utils.js");
10
+ const core_1 = require("../../src/diff/core.js");
11
+ (0, node_test_1.describe)("diff module - extended tests", () => {
12
+ (0, node_test_1.describe)("handling of invalid examples", () => {
13
+ (0, node_test_1.it)("should handle empty services array without crashing", () => {
14
+ const invalidDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "empty-services-array.json"));
15
+ // Should not crash when processing invalid documents
16
+ const result = (0, core_1.diffUniSpec)(invalidDoc, invalidDoc);
17
+ node_assert_1.default.strictEqual(result.changes.length, 0);
18
+ });
19
+ (0, node_test_1.it)("should handle missing service name", () => {
20
+ const invalidDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "missing-service-name.json"));
21
+ const modifiedDoc = JSON.parse(JSON.stringify(invalidDoc));
22
+ // This is a config file, not a spec, so it has different structure
23
+ modifiedDoc.version = 2;
24
+ const result = (0, core_1.diffUniSpec)(invalidDoc, modifiedDoc);
25
+ node_assert_1.default.ok(result.changes.length > 0);
26
+ const versionChange = result.changes.find((change) => change.path === "/version");
27
+ node_assert_1.default.ok(versionChange);
28
+ node_assert_1.default.strictEqual(versionChange.description, "Value changed");
29
+ });
30
+ (0, node_test_1.it)("should handle missing version", () => {
31
+ const invalidDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "invalid", "config", "missing-version.json"));
32
+ const modifiedDoc = JSON.parse(JSON.stringify(invalidDoc));
33
+ modifiedDoc.service = {
34
+ ...modifiedDoc.service,
35
+ description: "Added description",
36
+ };
37
+ const result = (0, core_1.diffUniSpec)(invalidDoc, modifiedDoc);
38
+ node_assert_1.default.ok(result.changes.length > 0);
39
+ });
40
+ });
41
+ (0, node_test_1.describe)("complex scenarios with valid examples", () => {
42
+ (0, node_test_1.it)("should handle mixed protocol changes", () => {
43
+ const baseDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "mixed-complete.json"));
44
+ const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
45
+ // Add REST route
46
+ modifiedDoc.service.protocols.rest.routes.push({
47
+ name: "newRoute",
48
+ summary: "New route",
49
+ path: "/new",
50
+ method: "GET",
51
+ responses: { 200: { description: "Success" } },
52
+ });
53
+ // Add GraphQL query
54
+ if (modifiedDoc.service.protocols.graphql) {
55
+ modifiedDoc.service.protocols.graphql.queries.push({
56
+ name: "newQuery",
57
+ description: "New query",
58
+ args: [],
59
+ returnType: "String",
60
+ });
61
+ }
62
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
63
+ const restChange = result.changes.find((change) => change.path.includes("newRoute") && change.protocol === "rest");
64
+ node_assert_1.default.ok(restChange);
65
+ node_assert_1.default.strictEqual(restChange.severity, "non-breaking");
66
+ if (modifiedDoc.service.protocols.graphql) {
67
+ const graphqlChange = result.changes.find((change) => change.path.includes("newQuery") && change.protocol === "graphql");
68
+ node_assert_1.default.ok(graphqlChange);
69
+ }
70
+ });
71
+ (0, node_test_1.it)("should detect breaking changes in REST", () => {
72
+ const baseDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "rest-simple.json"));
73
+ const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
74
+ // Remove a route (breaking change)
75
+ modifiedDoc.service.protocols.rest.routes =
76
+ modifiedDoc.service.protocols.rest.routes.filter((route) => route.name !== "getUsers");
77
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
78
+ const removedRoute = result.changes.find((change) => change.path === "/service/protocols/rest/routes/getUsers");
79
+ node_assert_1.default.ok(removedRoute);
80
+ node_assert_1.default.strictEqual(removedRoute.severity, "breaking");
81
+ node_assert_1.default.strictEqual(removedRoute.kind, "rest.route.removed");
82
+ });
83
+ });
84
+ (0, node_test_1.describe)("edge cases and boundary conditions", () => {
85
+ (0, node_test_1.it)("should handle null vs undefined values", () => {
86
+ const baseDoc = {
87
+ unispecVersion: "1.0.0",
88
+ service: {
89
+ name: "test-service",
90
+ description: undefined,
91
+ },
92
+ };
93
+ const modifiedDoc = {
94
+ unispecVersion: "1.0.0",
95
+ service: {
96
+ name: "test-service",
97
+ description: "A description",
98
+ },
99
+ };
100
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
101
+ const descriptionChange = result.changes.find((change) => change.path === "/service/description");
102
+ node_assert_1.default.ok(descriptionChange);
103
+ node_assert_1.default.strictEqual(descriptionChange.description, "Value changed");
104
+ });
105
+ (0, node_test_1.it)("should handle empty objects and arrays", () => {
106
+ const baseDoc = {
107
+ unispecVersion: "1.0.0",
108
+ service: {
109
+ name: "test-service",
110
+ protocols: {
111
+ rest: {
112
+ routes: [],
113
+ },
114
+ },
115
+ },
116
+ };
117
+ const modifiedDoc = {
118
+ unispecVersion: "1.0.0",
119
+ service: {
120
+ name: "test-service",
121
+ protocols: {
122
+ rest: {
123
+ routes: [
124
+ {
125
+ name: "newRoute",
126
+ method: "GET",
127
+ path: "/test",
128
+ responses: { 200: { description: "OK" } },
129
+ },
130
+ ],
131
+ },
132
+ },
133
+ },
134
+ };
135
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
136
+ const routeChange = result.changes.find((change) => change.path === "/service/protocols/rest/routes/newRoute");
137
+ node_assert_1.default.ok(routeChange);
138
+ node_assert_1.default.strictEqual(routeChange.description, "Item added");
139
+ node_assert_1.default.strictEqual(routeChange.protocol, "rest");
140
+ });
141
+ (0, node_test_1.it)("should handle deeply nested structures", () => {
142
+ const baseDoc = {
143
+ unispecVersion: "1.0.0",
144
+ service: {
145
+ name: "test-service",
146
+ metadata: {
147
+ tags: [{ name: "api", version: "1.0" }],
148
+ info: {
149
+ contact: {
150
+ email: "test@example.com",
151
+ },
152
+ },
153
+ },
154
+ },
155
+ };
156
+ const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
157
+ modifiedDoc.service.metadata.tags[0].version = "2.0";
158
+ modifiedDoc.service.metadata.info.contact.phone = "+1234567890";
159
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
160
+ const versionChange = result.changes.find((change) => change.path === "/service/metadata/tags/0/version");
161
+ node_assert_1.default.ok(versionChange);
162
+ node_assert_1.default.strictEqual(versionChange.description, "Value changed");
163
+ const phoneChange = result.changes.find((change) => change.path === "/service/metadata/info/contact/phone");
164
+ node_assert_1.default.ok(phoneChange);
165
+ node_assert_1.default.strictEqual(phoneChange.description, "Field added");
166
+ });
167
+ });
168
+ (0, node_test_1.describe)("array handling", () => {
169
+ (0, node_test_1.it)("should handle regular arrays (non-named collections)", () => {
170
+ const baseDoc = {
171
+ unispecVersion: "1.0.0",
172
+ service: {
173
+ name: "test-service",
174
+ tags: ["api", "v1"],
175
+ },
176
+ };
177
+ const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
178
+ modifiedDoc.service.tags = ["api", "v2", "production"];
179
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
180
+ // Should detect changes at index level for regular arrays
181
+ const indexChange = result.changes.find((change) => change.path === "/service/tags/1");
182
+ node_assert_1.default.ok(indexChange);
183
+ node_assert_1.default.strictEqual(indexChange.description, "Value changed");
184
+ const addedChange = result.changes.find((change) => change.path === "/service/tags/2");
185
+ node_assert_1.default.ok(addedChange);
186
+ node_assert_1.default.strictEqual(addedChange.description, "Item added");
187
+ });
188
+ (0, node_test_1.it)("should handle arrays without name property", () => {
189
+ const baseDoc = {
190
+ unispecVersion: "1.0.0",
191
+ service: {
192
+ name: "test-service",
193
+ items: [
194
+ { id: 1, value: "first" },
195
+ { id: 2, value: "second" },
196
+ ],
197
+ },
198
+ };
199
+ const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
200
+ modifiedDoc.service.items[0].value = "updated";
201
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
202
+ // Should use index-based comparison for arrays without name property
203
+ const itemChange = result.changes.find((change) => change.path === "/service/items/0/value");
204
+ node_assert_1.default.ok(itemChange);
205
+ node_assert_1.default.strictEqual(itemChange.description, "Value changed");
206
+ });
207
+ });
208
+ (0, node_test_1.describe)("protocol-specific behavior", () => {
209
+ (0, node_test_1.it)("should handle WebSocket messages correctly", () => {
210
+ const baseDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "websocket-simple.json"));
211
+ const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
212
+ // Add message to existing channel
213
+ if (modifiedDoc.service.protocols.websocket.channels[0]) {
214
+ modifiedDoc.service.protocols.websocket.channels[0].messages.push({
215
+ name: "newMessage",
216
+ description: "New message type",
217
+ direction: "publish",
218
+ });
219
+ }
220
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
221
+ const messageChange = result.changes.find((change) => change.path.includes("newMessage") && change.protocol === "websocket");
222
+ node_assert_1.default.ok(messageChange);
223
+ });
224
+ (0, node_test_1.it)("should handle GraphQL schema changes", () => {
225
+ const baseDoc = (0, utils_1.loadExample)(node_path_1.default.join(utils_1.examplesDir, "valid", "spec", "graphql-simple.json"));
226
+ const modifiedDoc = JSON.parse(JSON.stringify(baseDoc));
227
+ // Change schema string
228
+ modifiedDoc.service.protocols.graphql.schema = `${baseDoc.service.protocols?.graphql?.schema} type NewType { field: String! }`;
229
+ const result = (0, core_1.diffUniSpec)(baseDoc, modifiedDoc);
230
+ const schemaChange = result.changes.find((change) => change.path === "/service/protocols/graphql/schema");
231
+ node_assert_1.default.ok(schemaChange);
232
+ node_assert_1.default.strictEqual(schemaChange.description, "Value changed");
233
+ });
234
+ });
235
+ });