@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,341 @@
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_fs_1 = __importDefault(require("node:fs"));
8
+ const node_test_1 = require("node:test");
9
+ const utils_1 = require("../../tests/utils.js");
10
+ const loader_1 = require("../../src/loader/index.js");
11
+ (0, node_test_1.describe)("loader", () => {
12
+ (0, node_test_1.describe)("loadUniSpec", () => {
13
+ (0, node_test_1.it)("should load valid JSON UniSpec document", async () => {
14
+ const validSpecPath = (0, utils_1.getExamplePath)("valid", "spec", "rest-simple.json");
15
+ const jsonContent = node_fs_1.default.readFileSync(validSpecPath, "utf-8");
16
+ const result = await (0, loader_1.loadUniSpec)(jsonContent);
17
+ node_assert_1.default.strictEqual(result.unispecVersion, "1.0.0");
18
+ node_assert_1.default.strictEqual(result.service.name, "user-service");
19
+ node_assert_1.default.strictEqual(result.service.protocols?.rest?.routes?.length, 2);
20
+ });
21
+ (0, node_test_1.it)("should load valid UniSpec document as object", async () => {
22
+ const validSpec = {
23
+ unispecVersion: "1.0.0",
24
+ service: {
25
+ name: "test-service",
26
+ description: "Test service",
27
+ protocols: {
28
+ rest: {
29
+ routes: [
30
+ {
31
+ name: "testRoute",
32
+ path: "/test",
33
+ method: "GET",
34
+ responses: {
35
+ "200": { description: "OK" },
36
+ },
37
+ },
38
+ ],
39
+ },
40
+ },
41
+ },
42
+ };
43
+ const result = await (0, loader_1.loadUniSpec)(validSpec);
44
+ node_assert_1.default.strictEqual(result.service.name, "test-service");
45
+ node_assert_1.default.strictEqual(result.unispecVersion, "1.0.0");
46
+ });
47
+ (0, node_test_1.it)("should load valid YAML UniSpec document", async () => {
48
+ const yamlContent = `
49
+ unispecVersion: "1.0.0"
50
+ service:
51
+ name: "yaml-service"
52
+ description: "YAML based service"
53
+ protocols:
54
+ rest:
55
+ routes:
56
+ - name: "getUsers"
57
+ path: "/users"
58
+ method: "GET"
59
+ responses:
60
+ "200":
61
+ description: "Success"
62
+ `;
63
+ const result = await (0, loader_1.loadUniSpec)(yamlContent);
64
+ node_assert_1.default.strictEqual(result.service.name, "yaml-service");
65
+ node_assert_1.default.strictEqual(result.unispecVersion, "1.0.0");
66
+ });
67
+ (0, node_test_1.it)("should reject empty string input", async () => {
68
+ try {
69
+ await (0, loader_1.loadUniSpec)(" ");
70
+ node_assert_1.default.fail("Should have thrown an error");
71
+ }
72
+ catch (error) {
73
+ node_assert_1.default.ok(error instanceof Error);
74
+ node_assert_1.default.ok(error.message.includes("empty"));
75
+ }
76
+ });
77
+ (0, node_test_1.it)("should reject invalid JSON and YAML", async () => {
78
+ const invalidContent = "{ invalid json syntax: [unclosed array";
79
+ try {
80
+ await (0, loader_1.loadUniSpec)(invalidContent);
81
+ node_assert_1.default.fail("Should have thrown an error");
82
+ }
83
+ catch (error) {
84
+ node_assert_1.default.ok(error instanceof Error);
85
+ node_assert_1.default.ok(error.message.includes("Failed to parse"));
86
+ }
87
+ });
88
+ (0, node_test_1.it)("should enforce document size limit", async () => {
89
+ const largeContent = "x".repeat(11 * 1024 * 1024); // 11MB
90
+ try {
91
+ await (0, loader_1.loadUniSpec)(largeContent, { maxDocumentSize: 10 * 1024 * 1024 });
92
+ node_assert_1.default.fail("Should have thrown an error");
93
+ }
94
+ catch (error) {
95
+ node_assert_1.default.ok(error instanceof Error);
96
+ node_assert_1.default.ok(error.message.includes("Document size"));
97
+ }
98
+ });
99
+ (0, node_test_1.it)("should load valid examples from schema package", async () => {
100
+ const validExamples = [
101
+ "valid/spec/rest-simple.json",
102
+ "valid/spec/graphql-simple.json",
103
+ "valid/spec/websocket-simple.json",
104
+ "valid/spec/mixed-complete.json",
105
+ ];
106
+ for (const example of validExamples) {
107
+ const examplePath = (0, utils_1.getExamplePath)(...example.split("/"));
108
+ const content = node_fs_1.default.readFileSync(examplePath, "utf-8");
109
+ const result = await (0, loader_1.loadUniSpec)(content);
110
+ node_assert_1.default.ok(result.unispecVersion);
111
+ node_assert_1.default.ok(result.service.name);
112
+ node_assert_1.default.ok(result.service.protocols);
113
+ }
114
+ });
115
+ (0, node_test_1.it)("should handle invalid examples appropriately", async () => {
116
+ const invalidExamples = [
117
+ "invalid/spec/missing-service-name.json",
118
+ "invalid/spec/missing-unispec-version.json",
119
+ "invalid/spec/invalid-identifier.json",
120
+ ];
121
+ for (const example of invalidExamples) {
122
+ const examplePath = (0, utils_1.getExamplePath)(...example.split("/"));
123
+ const content = node_fs_1.default.readFileSync(examplePath, "utf-8");
124
+ // Note: loader only handles parsing, not validation
125
+ // Invalid schema examples should still parse as JSON/YAML
126
+ const result = await (0, loader_1.loadUniSpec)(content);
127
+ // Should parse successfully but validation errors would be caught elsewhere
128
+ node_assert_1.default.ok(typeof result === "object");
129
+ }
130
+ });
131
+ });
132
+ (0, node_test_1.describe)("validateDocumentSecurity", () => {
133
+ const defaultOptions = {
134
+ maxDepth: 100,
135
+ maxKeys: 10000,
136
+ allowedTags: ["str", "int", "float", "bool", "null", "seq", "map"],
137
+ maxDocumentSize: 10 * 1024 * 1024,
138
+ strictYamlTags: false,
139
+ };
140
+ (0, node_test_1.it)("should pass validation for normal documents", () => {
141
+ const doc = {
142
+ level1: {
143
+ level2: {
144
+ level3: "value",
145
+ },
146
+ },
147
+ };
148
+ (0, loader_1.validateDocumentSecurity)(doc, defaultOptions);
149
+ // Should not throw
150
+ });
151
+ (0, node_test_1.it)("should reject documents exceeding max depth", () => {
152
+ const doc = {};
153
+ let current = doc;
154
+ // Create nested structure exceeding max depth
155
+ for (let i = 0; i < 105; i++) {
156
+ current.next = {};
157
+ current = current.next;
158
+ }
159
+ try {
160
+ (0, loader_1.validateDocumentSecurity)(doc, { ...defaultOptions, maxDepth: 100 });
161
+ node_assert_1.default.fail("Should have thrown an error");
162
+ }
163
+ catch (error) {
164
+ node_assert_1.default.ok(error instanceof Error);
165
+ node_assert_1.default.ok(error.message.includes("depth"));
166
+ }
167
+ });
168
+ (0, node_test_1.it)("should reject documents exceeding max keys", () => {
169
+ const doc = {};
170
+ // Create object with many keys
171
+ for (let i = 0; i < 105; i++) {
172
+ doc[`key${i}`] = `value${i}`;
173
+ }
174
+ try {
175
+ (0, loader_1.validateDocumentSecurity)(doc, { ...defaultOptions, maxKeys: 100 });
176
+ node_assert_1.default.fail("Should have thrown an error");
177
+ }
178
+ catch (error) {
179
+ node_assert_1.default.ok(error instanceof Error);
180
+ node_assert_1.default.ok(error.message.includes("key count"));
181
+ }
182
+ });
183
+ (0, node_test_1.it)("should handle arrays correctly", () => {
184
+ const doc = {
185
+ array: [{ item: 1 }, { item: 2 }, { nested: { deep: "value" } }],
186
+ };
187
+ (0, loader_1.validateDocumentSecurity)(doc, defaultOptions);
188
+ // Should not throw
189
+ });
190
+ (0, node_test_1.it)("should handle mixed structures", () => {
191
+ const doc = {
192
+ strings: ["a", "b", "c"],
193
+ objects: {
194
+ nested: {
195
+ array: [1, 2, 3],
196
+ },
197
+ },
198
+ number: 42,
199
+ boolean: true,
200
+ null: null,
201
+ };
202
+ (0, loader_1.validateDocumentSecurity)(doc, defaultOptions);
203
+ // Should not throw
204
+ });
205
+ });
206
+ (0, node_test_1.describe)("getYamlModule", () => {
207
+ (0, node_test_1.it)("should load and validate YAML module", async () => {
208
+ const yamlModule = await (0, loader_1.getYamlModule)();
209
+ node_assert_1.default.ok(yamlModule);
210
+ node_assert_1.default.strictEqual(typeof yamlModule.load, "function");
211
+ node_assert_1.default.ok(yamlModule.FAILSAFE_SCHEMA);
212
+ });
213
+ (0, node_test_1.it)("should cache YAML module", async () => {
214
+ const module1 = await (0, loader_1.getYamlModule)();
215
+ const module2 = await (0, loader_1.getYamlModule)();
216
+ node_assert_1.default.strictEqual(module1, module2);
217
+ });
218
+ });
219
+ (0, node_test_1.describe)("validateYamlModule", () => {
220
+ (0, node_test_1.it)("should validate correct YAML module", () => {
221
+ const mockYamlModule = {
222
+ load: () => { },
223
+ FAILSAFE_SCHEMA: {},
224
+ other: "property",
225
+ };
226
+ // Should not throw
227
+ (0, loader_1.validateYamlModule)(mockYamlModule);
228
+ });
229
+ (0, node_test_1.it)("should reject non-object modules", () => {
230
+ try {
231
+ (0, loader_1.validateYamlModule)("not an object");
232
+ node_assert_1.default.fail("Should have thrown an error");
233
+ }
234
+ catch (error) {
235
+ node_assert_1.default.ok(error instanceof Error);
236
+ node_assert_1.default.ok(error.message.includes("must be an object"));
237
+ }
238
+ });
239
+ (0, node_test_1.it)("should reject modules without load function", () => {
240
+ const invalidModule = {
241
+ FAILSAFE_SCHEMA: {},
242
+ };
243
+ try {
244
+ (0, loader_1.validateYamlModule)(invalidModule);
245
+ node_assert_1.default.fail("Should have thrown an error");
246
+ }
247
+ catch (error) {
248
+ node_assert_1.default.ok(error instanceof Error);
249
+ node_assert_1.default.ok(error.message.includes("missing load function"));
250
+ }
251
+ });
252
+ (0, node_test_1.it)("should reject modules without FAILSAFE_SCHEMA", () => {
253
+ const invalidModule = {
254
+ load: () => { },
255
+ };
256
+ try {
257
+ (0, loader_1.validateYamlModule)(invalidModule);
258
+ node_assert_1.default.fail("Should have thrown an error");
259
+ }
260
+ catch (error) {
261
+ node_assert_1.default.ok(error instanceof Error);
262
+ node_assert_1.default.ok(error.message.includes("FAILSAFE_SCHEMA"));
263
+ }
264
+ });
265
+ });
266
+ (0, node_test_1.describe)("security constraints", () => {
267
+ (0, node_test_1.it)("should respect custom security options", async () => {
268
+ const doc = {
269
+ unispecVersion: "1.0.0",
270
+ service: {
271
+ name: "test",
272
+ protocols: {},
273
+ },
274
+ };
275
+ // Should work with relaxed constraints
276
+ await (0, loader_1.loadUniSpec)(doc, {
277
+ maxDepth: 1000,
278
+ maxKeys: 100000,
279
+ maxDocumentSize: 100 * 1024 * 1024,
280
+ });
281
+ });
282
+ (0, node_test_1.it)("should handle circular references gracefully", async () => {
283
+ const doc = { name: "test" };
284
+ doc.self = doc;
285
+ try {
286
+ await (0, loader_1.loadUniSpec)(doc);
287
+ // Circular references in JavaScript objects are handled by the security validation
288
+ // which uses iteration instead of recursion
289
+ }
290
+ catch (error) {
291
+ // Should not cause stack overflow
292
+ node_assert_1.default.ok(error instanceof Error);
293
+ node_assert_1.default.ok(!error.message.includes("stack"));
294
+ }
295
+ });
296
+ });
297
+ (0, node_test_1.describe)("edge cases", () => {
298
+ (0, node_test_1.it)("should handle null and undefined values", async () => {
299
+ const doc = {
300
+ unispecVersion: "1.0.0",
301
+ service: {
302
+ name: "test",
303
+ description: null,
304
+ tags: undefined,
305
+ protocols: {},
306
+ },
307
+ };
308
+ const result = await (0, loader_1.loadUniSpec)(doc);
309
+ node_assert_1.default.strictEqual(result.service.name, "test");
310
+ node_assert_1.default.strictEqual(result.service.description, null);
311
+ });
312
+ (0, node_test_1.it)("should handle empty objects and arrays", async () => {
313
+ const doc = {
314
+ unispecVersion: "1.0.0",
315
+ service: {
316
+ name: "test",
317
+ protocols: {
318
+ rest: {
319
+ routes: [],
320
+ schemas: {},
321
+ },
322
+ },
323
+ },
324
+ };
325
+ const result = await (0, loader_1.loadUniSpec)(doc);
326
+ node_assert_1.default.strictEqual(result.service.protocols?.rest?.routes?.length, 0);
327
+ });
328
+ (0, node_test_1.it)("should handle special characters in strings", async () => {
329
+ const doc = {
330
+ unispecVersion: "1.0.0",
331
+ service: {
332
+ name: "test-service-特殊字符-🚀",
333
+ description: 'Description with "quotes" and \n newlines',
334
+ protocols: {},
335
+ },
336
+ };
337
+ const result = await (0, loader_1.loadUniSpec)(doc);
338
+ node_assert_1.default.strictEqual(result.service.name, "test-service-特殊字符-🚀");
339
+ });
340
+ });
341
+ });