@dxos/echo 0.8.4-main.5ea62a8 → 0.8.4-main.66e292d

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 (328) hide show
  1. package/dist/lib/browser/chunk-7GH6RXJ3.mjs +3683 -0
  2. package/dist/lib/browser/chunk-7GH6RXJ3.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-E4UTVJNF.mjs +1111 -0
  4. package/dist/lib/browser/chunk-E4UTVJNF.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +24 -1
  6. package/dist/lib/browser/internal/index.mjs +336 -0
  7. package/dist/lib/browser/internal/index.mjs.map +7 -0
  8. package/dist/lib/browser/meta.json +1 -1
  9. package/dist/lib/browser/testing/index.mjs +289 -31
  10. package/dist/lib/browser/testing/index.mjs.map +4 -4
  11. package/dist/lib/node-esm/chunk-JE5RXM2I.mjs +1111 -0
  12. package/dist/lib/node-esm/chunk-JE5RXM2I.mjs.map +7 -0
  13. package/dist/lib/node-esm/chunk-M4B6BMD2.mjs +3683 -0
  14. package/dist/lib/node-esm/chunk-M4B6BMD2.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +24 -1
  16. package/dist/lib/node-esm/internal/index.mjs +336 -0
  17. package/dist/lib/node-esm/internal/index.mjs.map +7 -0
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/testing/index.mjs +289 -31
  20. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  21. package/dist/types/src/Annotation.d.ts +2 -0
  22. package/dist/types/src/Annotation.d.ts.map +1 -0
  23. package/dist/types/src/Database.d.ts +137 -0
  24. package/dist/types/src/Database.d.ts.map +1 -0
  25. package/dist/types/src/Entity.d.ts +36 -0
  26. package/dist/types/src/Entity.d.ts.map +1 -0
  27. package/dist/types/src/Format.d.ts +4 -0
  28. package/dist/types/src/Format.d.ts.map +1 -0
  29. package/dist/types/src/JsonSchema.d.ts +9 -0
  30. package/dist/types/src/JsonSchema.d.ts.map +1 -0
  31. package/dist/types/src/Key.d.ts +1 -0
  32. package/dist/types/src/Key.d.ts.map +1 -1
  33. package/dist/types/src/Obj.d.ts +121 -50
  34. package/dist/types/src/Obj.d.ts.map +1 -1
  35. package/dist/types/src/Ref.d.ts +10 -10
  36. package/dist/types/src/Ref.d.ts.map +1 -1
  37. package/dist/types/src/Relation.d.ts +18 -14
  38. package/dist/types/src/Relation.d.ts.map +1 -1
  39. package/dist/types/src/Tag.d.ts +17 -0
  40. package/dist/types/src/Tag.d.ts.map +1 -0
  41. package/dist/types/src/Type.d.ts +39 -50
  42. package/dist/types/src/Type.d.ts.map +1 -1
  43. package/dist/types/src/errors.d.ts +68 -0
  44. package/dist/types/src/errors.d.ts.map +1 -0
  45. package/dist/types/src/index.d.ts +9 -3
  46. package/dist/types/src/index.d.ts.map +1 -1
  47. package/dist/types/src/internal/annotations/annotations.d.ts +174 -0
  48. package/dist/types/src/internal/annotations/annotations.d.ts.map +1 -0
  49. package/dist/types/src/internal/annotations/annotations.test.d.ts +2 -0
  50. package/dist/types/src/internal/annotations/annotations.test.d.ts.map +1 -0
  51. package/dist/types/src/internal/annotations/index.d.ts +3 -0
  52. package/dist/types/src/internal/annotations/index.d.ts.map +1 -0
  53. package/dist/types/src/internal/annotations/util.d.ts +26 -0
  54. package/dist/types/src/internal/annotations/util.d.ts.map +1 -0
  55. package/dist/types/src/internal/entities/entity.d.ts +10 -0
  56. package/dist/types/src/internal/entities/entity.d.ts.map +1 -0
  57. package/dist/types/src/internal/entities/expando.d.ts +16 -0
  58. package/dist/types/src/internal/entities/expando.d.ts.map +1 -0
  59. package/dist/types/src/internal/entities/index.d.ts +6 -0
  60. package/dist/types/src/internal/entities/index.d.ts.map +1 -0
  61. package/dist/types/src/internal/entities/model.d.ts +70 -0
  62. package/dist/types/src/internal/entities/model.d.ts.map +1 -0
  63. package/dist/types/src/internal/entities/object.d.ts +11 -0
  64. package/dist/types/src/internal/entities/object.d.ts.map +1 -0
  65. package/dist/types/src/internal/entities/relation.d.ts +55 -0
  66. package/dist/types/src/internal/entities/relation.d.ts.map +1 -0
  67. package/dist/types/src/internal/entities/util.d.ts +2 -0
  68. package/dist/types/src/internal/entities/util.d.ts.map +1 -0
  69. package/dist/types/src/internal/formats/date.d.ts +63 -0
  70. package/dist/types/src/internal/formats/date.d.ts.map +1 -0
  71. package/dist/types/src/internal/formats/date.test.d.ts +2 -0
  72. package/dist/types/src/internal/formats/date.test.d.ts.map +1 -0
  73. package/dist/types/src/internal/formats/format.d.ts +32 -0
  74. package/dist/types/src/internal/formats/format.d.ts.map +1 -0
  75. package/dist/types/src/internal/formats/format.test.d.ts +2 -0
  76. package/dist/types/src/internal/formats/format.test.d.ts.map +1 -0
  77. package/dist/types/src/internal/formats/index.d.ts +8 -0
  78. package/dist/types/src/internal/formats/index.d.ts.map +1 -0
  79. package/dist/types/src/internal/formats/number.d.ts +31 -0
  80. package/dist/types/src/internal/formats/number.d.ts.map +1 -0
  81. package/dist/types/src/internal/formats/object.d.ts +35 -0
  82. package/dist/types/src/internal/formats/object.d.ts.map +1 -0
  83. package/dist/types/src/internal/formats/select.d.ts +11 -0
  84. package/dist/types/src/internal/formats/select.d.ts.map +1 -0
  85. package/dist/types/src/internal/formats/string.d.ts +38 -0
  86. package/dist/types/src/internal/formats/string.d.ts.map +1 -0
  87. package/dist/types/src/internal/formats/types.d.ts +68 -0
  88. package/dist/types/src/internal/formats/types.d.ts.map +1 -0
  89. package/dist/types/src/internal/index.d.ts +11 -0
  90. package/dist/types/src/internal/index.d.ts.map +1 -0
  91. package/dist/types/src/internal/json-schema/annotations.d.ts +19 -0
  92. package/dist/types/src/internal/json-schema/annotations.d.ts.map +1 -0
  93. package/dist/types/src/internal/json-schema/effect-schema.test.d.ts +2 -0
  94. package/dist/types/src/internal/json-schema/effect-schema.test.d.ts.map +1 -0
  95. package/dist/types/src/internal/json-schema/index.d.ts +5 -0
  96. package/dist/types/src/internal/json-schema/index.d.ts.map +1 -0
  97. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts +7 -0
  98. package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +1 -0
  99. package/dist/types/src/internal/json-schema/json-schema-type.d.ts +250 -0
  100. package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +1 -0
  101. package/dist/types/src/internal/json-schema/json-schema.d.ts +29 -0
  102. package/dist/types/src/internal/json-schema/json-schema.d.ts.map +1 -0
  103. package/dist/types/src/internal/json-schema/json-schema.test.d.ts +2 -0
  104. package/dist/types/src/internal/json-schema/json-schema.test.d.ts.map +1 -0
  105. package/dist/types/src/internal/object/common.d.ts +18 -0
  106. package/dist/types/src/internal/object/common.d.ts.map +1 -0
  107. package/dist/types/src/internal/object/create-object.d.ts +39 -0
  108. package/dist/types/src/internal/object/create-object.d.ts.map +1 -0
  109. package/dist/types/src/internal/object/create-object.test.d.ts +2 -0
  110. package/dist/types/src/internal/object/create-object.test.d.ts.map +1 -0
  111. package/dist/types/src/internal/object/deleted.d.ts +6 -0
  112. package/dist/types/src/internal/object/deleted.d.ts.map +1 -0
  113. package/dist/types/src/internal/object/ids.d.ts +6 -0
  114. package/dist/types/src/internal/object/ids.d.ts.map +1 -0
  115. package/dist/types/src/internal/object/index.d.ts +8 -0
  116. package/dist/types/src/internal/object/index.d.ts.map +1 -0
  117. package/dist/types/src/internal/object/inspect.d.ts +2 -0
  118. package/dist/types/src/internal/object/inspect.d.ts.map +1 -0
  119. package/dist/types/src/internal/object/json-serializer.d.ts +31 -0
  120. package/dist/types/src/internal/object/json-serializer.d.ts.map +1 -0
  121. package/dist/types/src/internal/object/json-serializer.test.d.ts +2 -0
  122. package/dist/types/src/internal/object/json-serializer.test.d.ts.map +1 -0
  123. package/dist/types/src/internal/object/schema-validator.d.ts +15 -0
  124. package/dist/types/src/internal/object/schema-validator.d.ts.map +1 -0
  125. package/dist/types/src/internal/object/schema-validator.test.d.ts +2 -0
  126. package/dist/types/src/internal/object/schema-validator.test.d.ts.map +1 -0
  127. package/dist/types/src/internal/object/typed-object.d.ts +31 -0
  128. package/dist/types/src/internal/object/typed-object.d.ts.map +1 -0
  129. package/dist/types/src/internal/object/typed-object.test.d.ts +2 -0
  130. package/dist/types/src/internal/object/typed-object.test.d.ts.map +1 -0
  131. package/dist/types/src/internal/proxy/handler.test.d.ts +2 -0
  132. package/dist/types/src/internal/proxy/handler.test.d.ts.map +1 -0
  133. package/dist/types/src/internal/proxy/index.d.ts +3 -0
  134. package/dist/types/src/internal/proxy/index.d.ts.map +1 -0
  135. package/dist/types/src/internal/proxy/make-object.d.ts +16 -0
  136. package/dist/types/src/internal/proxy/make-object.d.ts.map +1 -0
  137. package/dist/types/src/internal/proxy/schema.test.d.ts +2 -0
  138. package/dist/types/src/internal/proxy/schema.test.d.ts.map +1 -0
  139. package/dist/types/src/internal/proxy/typed-handler.d.ts +44 -0
  140. package/dist/types/src/internal/proxy/typed-handler.d.ts.map +1 -0
  141. package/dist/types/src/internal/proxy/typed-handler.test.d.ts +2 -0
  142. package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +1 -0
  143. package/dist/types/src/internal/proxy/typed-object.test.d.ts +2 -0
  144. package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +1 -0
  145. package/dist/types/src/internal/ref/index.d.ts +3 -0
  146. package/dist/types/src/internal/ref/index.d.ts.map +1 -0
  147. package/dist/types/src/internal/ref/ref-array.d.ts +21 -0
  148. package/dist/types/src/internal/ref/ref-array.d.ts.map +1 -0
  149. package/dist/types/src/internal/ref/ref.d.ts +209 -0
  150. package/dist/types/src/internal/ref/ref.d.ts.map +1 -0
  151. package/dist/types/src/internal/ref/ref.test.d.ts +2 -0
  152. package/dist/types/src/internal/ref/ref.test.d.ts.map +1 -0
  153. package/dist/types/src/internal/schema/compose.d.ts +6 -0
  154. package/dist/types/src/internal/schema/compose.d.ts.map +1 -0
  155. package/dist/types/src/internal/schema/compose.test.d.ts +2 -0
  156. package/dist/types/src/internal/schema/compose.test.d.ts.map +1 -0
  157. package/dist/types/src/internal/schema/echo-schema.d.ts +168 -0
  158. package/dist/types/src/internal/schema/echo-schema.d.ts.map +1 -0
  159. package/dist/types/src/internal/schema/index.d.ts +6 -0
  160. package/dist/types/src/internal/schema/index.d.ts.map +1 -0
  161. package/dist/types/src/internal/schema/manipulation.d.ts +10 -0
  162. package/dist/types/src/internal/schema/manipulation.d.ts.map +1 -0
  163. package/dist/types/src/internal/schema/persistent-schema.d.ts +18 -0
  164. package/dist/types/src/internal/schema/persistent-schema.d.ts.map +1 -0
  165. package/dist/types/src/internal/schema/runtime-schema-registry.d.ts +18 -0
  166. package/dist/types/src/internal/schema/runtime-schema-registry.d.ts.map +1 -0
  167. package/dist/types/src/internal/schema/snapshot.d.ts +6 -0
  168. package/dist/types/src/internal/schema/snapshot.d.ts.map +1 -0
  169. package/dist/types/src/internal/types/base.d.ts +37 -0
  170. package/dist/types/src/internal/types/base.d.ts.map +1 -0
  171. package/dist/types/src/internal/types/entity.d.ts +12 -0
  172. package/dist/types/src/internal/types/entity.d.ts.map +1 -0
  173. package/dist/types/src/internal/types/index.d.ts +6 -0
  174. package/dist/types/src/internal/types/index.d.ts.map +1 -0
  175. package/dist/types/src/internal/types/meta.d.ts +40 -0
  176. package/dist/types/src/internal/types/meta.d.ts.map +1 -0
  177. package/dist/types/src/internal/types/typename.d.ts +13 -0
  178. package/dist/types/src/internal/types/typename.d.ts.map +1 -0
  179. package/dist/types/src/internal/types/version.d.ts +15 -0
  180. package/dist/types/src/internal/types/version.d.ts.map +1 -0
  181. package/dist/types/src/query/filter.d.ts +167 -0
  182. package/dist/types/src/query/filter.d.ts.map +1 -0
  183. package/dist/types/src/query/index.d.ts +4 -1
  184. package/dist/types/src/query/index.d.ts.map +1 -1
  185. package/dist/types/src/query/order.d.ts +12 -0
  186. package/dist/types/src/query/order.d.ts.map +1 -0
  187. package/dist/types/src/query/query.d.ts +112 -0
  188. package/dist/types/src/query/query.d.ts.map +1 -0
  189. package/dist/types/src/query/query.test.d.ts +2 -0
  190. package/dist/types/src/query/query.test.d.ts.map +1 -0
  191. package/dist/types/src/query/testing.d.ts +51 -0
  192. package/dist/types/src/query/testing.d.ts.map +1 -0
  193. package/dist/types/src/query/types.d.ts +17 -0
  194. package/dist/types/src/query/types.d.ts.map +1 -0
  195. package/dist/types/src/query/util.d.ts +8 -0
  196. package/dist/types/src/query/util.d.ts.map +1 -0
  197. package/dist/types/src/{test → testing}/api.test.d.ts.map +1 -1
  198. package/dist/types/src/testing/index.d.ts +3 -1
  199. package/dist/types/src/testing/index.d.ts.map +1 -1
  200. package/dist/types/src/testing/test-data.d.ts +18 -0
  201. package/dist/types/src/testing/test-data.d.ts.map +1 -0
  202. package/dist/types/src/testing/test-schema.d.ts +337 -0
  203. package/dist/types/src/testing/test-schema.d.ts.map +1 -0
  204. package/dist/types/src/testing/util.d.ts +16 -0
  205. package/dist/types/src/testing/util.d.ts.map +1 -0
  206. package/dist/types/tsconfig.tsbuildinfo +1 -1
  207. package/package.json +49 -29
  208. package/src/Annotation.ts +17 -0
  209. package/src/Database.ts +189 -0
  210. package/src/Entity.ts +51 -0
  211. package/src/Format.ts +11 -0
  212. package/src/JsonSchema.ts +16 -0
  213. package/src/Key.ts +3 -0
  214. package/src/Obj.ts +353 -107
  215. package/src/Ref.ts +9 -10
  216. package/src/Relation.ts +68 -43
  217. package/src/Tag.ts +40 -0
  218. package/src/Type.ts +97 -85
  219. package/src/errors.ts +18 -0
  220. package/src/index.ts +13 -4
  221. package/src/internal/README.md +83 -0
  222. package/src/internal/annotations/annotations.test.ts +96 -0
  223. package/src/internal/annotations/annotations.ts +463 -0
  224. package/src/internal/annotations/index.ts +6 -0
  225. package/src/internal/annotations/util.ts +70 -0
  226. package/src/internal/entities/entity.ts +109 -0
  227. package/src/internal/entities/expando.ts +23 -0
  228. package/src/internal/entities/index.ts +9 -0
  229. package/src/internal/entities/model.ts +129 -0
  230. package/src/internal/entities/object.ts +45 -0
  231. package/src/internal/entities/relation.ts +155 -0
  232. package/src/internal/entities/util.ts +33 -0
  233. package/src/internal/formats/date.test.ts +56 -0
  234. package/src/internal/formats/date.ts +217 -0
  235. package/src/internal/formats/format.test.ts +77 -0
  236. package/src/internal/formats/format.ts +55 -0
  237. package/src/internal/formats/index.ts +12 -0
  238. package/src/internal/formats/number.ts +89 -0
  239. package/src/internal/formats/object.ts +80 -0
  240. package/src/internal/formats/select.ts +16 -0
  241. package/src/internal/formats/string.ts +76 -0
  242. package/src/internal/formats/types.ts +180 -0
  243. package/src/internal/index.ts +38 -0
  244. package/src/internal/json-schema/annotations.ts +50 -0
  245. package/src/internal/json-schema/effect-schema.test.ts +143 -0
  246. package/src/internal/json-schema/index.ts +8 -0
  247. package/src/internal/json-schema/json-schema-normalize.ts +109 -0
  248. package/src/internal/json-schema/json-schema-type.ts +404 -0
  249. package/src/internal/json-schema/json-schema.test.ts +859 -0
  250. package/src/internal/json-schema/json-schema.ts +528 -0
  251. package/src/internal/object/common.ts +75 -0
  252. package/src/internal/object/create-object.test.ts +116 -0
  253. package/src/internal/object/create-object.ts +95 -0
  254. package/src/internal/object/deleted.ts +19 -0
  255. package/src/internal/object/ids.ts +12 -0
  256. package/src/internal/object/index.ts +11 -0
  257. package/src/internal/object/inspect.ts +46 -0
  258. package/src/internal/object/json-serializer.test.ts +94 -0
  259. package/src/internal/object/json-serializer.ts +230 -0
  260. package/src/internal/object/schema-validator.test.ts +186 -0
  261. package/src/internal/object/schema-validator.ts +242 -0
  262. package/src/internal/object/typed-object.test.ts +34 -0
  263. package/src/internal/object/typed-object.ts +94 -0
  264. package/src/internal/proxy/handler.test.ts +173 -0
  265. package/src/internal/proxy/index.ts +6 -0
  266. package/src/internal/proxy/make-object.ts +113 -0
  267. package/src/internal/proxy/schema.test.ts +137 -0
  268. package/src/internal/proxy/typed-handler.test.ts +102 -0
  269. package/src/internal/proxy/typed-handler.ts +233 -0
  270. package/src/internal/proxy/typed-object.test.ts +105 -0
  271. package/src/internal/ref/index.ts +6 -0
  272. package/src/internal/ref/ref-array.ts +39 -0
  273. package/src/internal/ref/ref.test.ts +101 -0
  274. package/src/internal/ref/ref.ts +525 -0
  275. package/src/internal/schema/compose.test.ts +42 -0
  276. package/src/internal/schema/compose.ts +37 -0
  277. package/src/internal/schema/echo-schema.ts +385 -0
  278. package/src/internal/schema/index.ts +9 -0
  279. package/src/internal/schema/manipulation.ts +92 -0
  280. package/src/internal/schema/persistent-schema.ts +28 -0
  281. package/src/internal/schema/runtime-schema-registry.ts +78 -0
  282. package/src/internal/schema/snapshot.ts +25 -0
  283. package/src/internal/types/base.ts +58 -0
  284. package/src/internal/types/entity.ts +23 -0
  285. package/src/internal/types/index.ts +9 -0
  286. package/src/internal/types/meta.ts +76 -0
  287. package/src/internal/types/typename.ts +45 -0
  288. package/src/internal/types/version.ts +20 -0
  289. package/src/query/filter.ts +455 -0
  290. package/src/query/index.ts +5 -1
  291. package/src/query/order.ts +34 -0
  292. package/src/query/query.test.ts +334 -0
  293. package/src/query/query.ts +303 -0
  294. package/src/query/testing.ts +64 -0
  295. package/src/query/types.ts +23 -0
  296. package/src/query/util.ts +25 -0
  297. package/src/testing/api.test.ts +100 -0
  298. package/src/testing/index.ts +3 -1
  299. package/src/testing/test-data.ts +130 -0
  300. package/src/testing/test-schema.ts +213 -0
  301. package/src/testing/util.ts +78 -0
  302. package/dist/lib/browser/chunk-2KNTYMIW.mjs +0 -697
  303. package/dist/lib/browser/chunk-2KNTYMIW.mjs.map +0 -7
  304. package/dist/lib/node-esm/chunk-EXNNC62J.mjs +0 -697
  305. package/dist/lib/node-esm/chunk-EXNNC62J.mjs.map +0 -7
  306. package/dist/types/src/experimental/database.d.ts +0 -8
  307. package/dist/types/src/experimental/database.d.ts.map +0 -1
  308. package/dist/types/src/experimental/index.d.ts +0 -1
  309. package/dist/types/src/experimental/index.d.ts.map +0 -1
  310. package/dist/types/src/experimental/queue.d.ts +0 -8
  311. package/dist/types/src/experimental/queue.d.ts.map +0 -1
  312. package/dist/types/src/experimental/space.d.ts +0 -8
  313. package/dist/types/src/experimental/space.d.ts.map +0 -1
  314. package/dist/types/src/query/dsl.d.ts +0 -218
  315. package/dist/types/src/query/dsl.d.ts.map +0 -1
  316. package/dist/types/src/query/dsl.test.d.ts +0 -2
  317. package/dist/types/src/query/dsl.test.d.ts.map +0 -1
  318. package/dist/types/src/testing/types.d.ts +0 -113
  319. package/dist/types/src/testing/types.d.ts.map +0 -1
  320. package/src/experimental/database.ts +0 -11
  321. package/src/experimental/index.ts +0 -7
  322. package/src/experimental/queue.ts +0 -11
  323. package/src/experimental/space.ts +0 -11
  324. package/src/query/dsl.test.ts +0 -324
  325. package/src/query/dsl.ts +0 -646
  326. package/src/test/api.test.ts +0 -173
  327. package/src/testing/types.ts +0 -91
  328. /package/dist/types/src/{test → testing}/api.test.d.ts +0 -0
@@ -0,0 +1,859 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import * as Option from 'effect/Option';
6
+ import * as Schema from 'effect/Schema';
7
+ import * as SchemaAST from 'effect/SchemaAST';
8
+ import { describe, expect, test } from 'vitest';
9
+
10
+ import { type JsonProp, findAnnotation } from '@dxos/effect';
11
+ import { ObjectId } from '@dxos/keys';
12
+ import { log } from '@dxos/log';
13
+
14
+ import { TestSchema, prepareAstForCompare } from '../../testing';
15
+ import * as Type from '../../Type';
16
+ import {
17
+ FieldLookupAnnotationId,
18
+ GeneratorAnnotation,
19
+ LabelAnnotation,
20
+ PropertyMeta,
21
+ getTypeAnnotation,
22
+ getTypeIdentifierAnnotation,
23
+ } from '../annotations';
24
+ import { EchoObjectSchema } from '../entities';
25
+ import { Email, FormatAnnotation, TypeFormat } from '../formats';
26
+ import { JsonSchemaType, getNormalizedEchoAnnotations, getSchemaProperty, setSchemaProperty } from '../json-schema';
27
+ import { Ref, createSchemaReference, getReferenceAst, getSchemaReference } from '../ref';
28
+ import { PersistentSchema } from '../schema';
29
+ import { EntityKind } from '../types';
30
+
31
+ import { toEffectSchema, toJsonSchema } from './json-schema';
32
+
33
+ const EXAMPLE_NAMESPACE = '@example';
34
+
35
+ describe('effect-to-json', () => {
36
+ test('type annotation', () => {
37
+ const Test = Schema.Struct({ name: Schema.String }).pipe(
38
+ Type.Obj({
39
+ typename: 'example.com/type/Test',
40
+ version: '0.1.0',
41
+ }),
42
+ );
43
+ const jsonSchema = toJsonSchema(Test);
44
+ expect((jsonSchema as any).$id).toEqual('dxn:type:example.com/type/Test');
45
+ expect((jsonSchema as any).version).toEqual('0.1.0');
46
+ });
47
+
48
+ test('property meta annotation', () => {
49
+ const meta = { maxLength: 0 };
50
+ const Test = Schema.Struct({
51
+ name: Schema.String.pipe(PropertyMeta(EXAMPLE_NAMESPACE, meta)),
52
+ }).pipe(
53
+ Type.Obj({
54
+ typename: 'example.com/type/Test',
55
+ version: '0.1.0',
56
+ }),
57
+ );
58
+ const jsonSchema = toJsonSchema(Test);
59
+ expect(getNormalizedEchoAnnotations(jsonSchema.properties!.name!)!.meta![EXAMPLE_NAMESPACE]).to.deep.eq(meta);
60
+ });
61
+
62
+ test('reference annotation', () => {
63
+ const Nested = Schema.Struct({
64
+ name: Schema.String,
65
+ }).pipe(
66
+ Type.Obj({
67
+ typename: 'example.com/type/TestNested',
68
+ version: '0.1.0',
69
+ }),
70
+ );
71
+ const Test = Schema.Struct({
72
+ name: Ref(Nested),
73
+ }).pipe(
74
+ Type.Obj({
75
+ typename: 'example.com/type/Test',
76
+ version: '0.1.0',
77
+ }),
78
+ );
79
+ const jsonSchema = toJsonSchema(Test);
80
+ // log.info('schema', { jsonSchema });
81
+ const nested = jsonSchema.properties!.name;
82
+ expectReferenceAnnotation(nested);
83
+ });
84
+
85
+ // TODO(ZaymonFC): @dmaretskyi we still need to fix this.
86
+ // TODO(dmaretskyi): Remove FieldLookupAnnotationId.
87
+ test.skip('reference annotation with lookup property', () => {
88
+ const Nested = Schema.Struct({
89
+ name: Schema.String,
90
+ }).pipe(
91
+ Type.Obj({
92
+ typename: 'example.com/type/TestNested',
93
+ version: '0.1.0',
94
+ }),
95
+ );
96
+ const Test = Schema.Struct({
97
+ name: Ref(Nested).annotations({ [FieldLookupAnnotationId]: 'name' }),
98
+ }).pipe(
99
+ Type.Obj({
100
+ typename: 'example.com/type/Test',
101
+ version: '0.1.0',
102
+ }),
103
+ );
104
+ const jsonSchema = toJsonSchema(Test);
105
+ const effectSchema = toEffectSchema(jsonSchema);
106
+
107
+ const annotation = findAnnotation<string>(effectSchema.ast, FieldLookupAnnotationId);
108
+ expect(annotation).to.not.toBeUndefined();
109
+ });
110
+
111
+ test('array of references', () => {
112
+ const Nested = Schema.Struct({
113
+ name: Schema.String,
114
+ }).pipe(
115
+ Type.Obj({
116
+ typename: 'example.com/type/TestNested',
117
+ version: '0.1.0',
118
+ }),
119
+ );
120
+ const Test = Schema.Struct({
121
+ name: Schema.Array(Ref(Nested)),
122
+ }).pipe(
123
+ Type.Obj({
124
+ typename: 'example.com/type/Test',
125
+ version: '0.1.0',
126
+ }),
127
+ );
128
+
129
+ const jsonSchema = toJsonSchema(Test);
130
+ expectReferenceAnnotation((jsonSchema.properties!.name as any).items);
131
+ });
132
+
133
+ test('optional references', () => {
134
+ const Nested = Schema.Struct({
135
+ name: Schema.String,
136
+ }).pipe(
137
+ Type.Obj({
138
+ typename: 'example.com/type/TestNested',
139
+ version: '0.1.0',
140
+ }),
141
+ );
142
+ const Test = Schema.Struct({
143
+ name: Schema.optional(Ref(Nested)),
144
+ }).pipe(
145
+ Type.Obj({
146
+ typename: 'example.com/type/Test',
147
+ version: '0.1.0',
148
+ }),
149
+ );
150
+ const jsonSchema = toJsonSchema(Test);
151
+ expectReferenceAnnotation(jsonSchema.properties!.name);
152
+ });
153
+
154
+ test('regular objects are not annotated', () => {
155
+ const object = Schema.Struct({ name: Schema.Struct({ name: Schema.String }) });
156
+ const jsonSchema = toJsonSchema(object);
157
+ expect(getNormalizedEchoAnnotations(jsonSchema)).to.be.undefined;
158
+ expect(getNormalizedEchoAnnotations(jsonSchema.properties!.name!)).to.be.undefined;
159
+ });
160
+
161
+ test('annotations', () => {
162
+ const TempSchema = Schema.Struct({
163
+ name: Schema.String.annotations({ description: 'Person name', title: 'Name' }),
164
+ email: Schema.String.pipe(FormatAnnotation.set(TypeFormat.Email)).annotations({
165
+ description: 'Email address',
166
+ }),
167
+ }).pipe(
168
+ Type.Obj({
169
+ typename: 'example.com/type/Person',
170
+ version: '0.1.0',
171
+ }),
172
+ );
173
+
174
+ const jsonSchema = toJsonSchema(TempSchema);
175
+ expect(jsonSchema).to.deep.eq({
176
+ $schema: 'http://json-schema.org/draft-07/schema#',
177
+ $id: 'dxn:type:example.com/type/Person',
178
+
179
+ entityKind: EntityKind.Object,
180
+ typename: 'example.com/type/Person',
181
+ version: '0.1.0',
182
+
183
+ type: 'object',
184
+ required: ['name', 'email', 'id'],
185
+ properties: {
186
+ id: { type: 'string' },
187
+ name: { type: 'string', title: 'Name', description: 'Person name' },
188
+ email: {
189
+ type: 'string',
190
+
191
+ description: 'Email address',
192
+ format: 'email',
193
+ },
194
+ },
195
+ propertyOrder: ['name', 'email', 'id'],
196
+ additionalProperties: false,
197
+ });
198
+ });
199
+
200
+ test('handles suspend -- Contact schema serialization', () => {
201
+ const schema = toJsonSchema(TestSchema.Person);
202
+ expect(Object.keys(schema.properties!)).toEqual([
203
+ 'id',
204
+ 'name',
205
+ 'username',
206
+ 'email',
207
+ 'tasks',
208
+ 'employer',
209
+ 'address',
210
+ ]);
211
+ });
212
+
213
+ test('reference property by ref', () => {
214
+ const Organization = Schema.Struct({
215
+ field: Schema.String,
216
+ }).pipe(
217
+ Type.Obj({
218
+ typename: 'example.com/type/Organization',
219
+ version: '0.1.0',
220
+ }),
221
+ );
222
+
223
+ const Contact = Schema.Struct({
224
+ name: Schema.String,
225
+ organization: Ref(Organization).annotations({ description: 'Contact organization' }),
226
+ }).pipe(
227
+ Type.Obj({
228
+ typename: 'example.com/type/Person',
229
+ version: '0.1.0',
230
+ }),
231
+ );
232
+
233
+ // log.info('Contact', { ast: Contact.ast });
234
+
235
+ const jsonSchema = toJsonSchema(Contact);
236
+ expect(jsonSchema).toEqual({
237
+ $schema: 'http://json-schema.org/draft-07/schema#',
238
+ $id: 'dxn:type:example.com/type/Person',
239
+
240
+ entityKind: EntityKind.Object,
241
+ typename: 'example.com/type/Person',
242
+ version: '0.1.0',
243
+
244
+ type: 'object',
245
+ additionalProperties: false,
246
+
247
+ properties: {
248
+ id: {
249
+ type: 'string',
250
+ },
251
+ name: {
252
+ type: 'string',
253
+ },
254
+ organization: {
255
+ allOf: [
256
+ {
257
+ $id: '/schemas/echo/ref',
258
+ $ref: '/schemas/echo/ref',
259
+ reference: {
260
+ schema: {
261
+ $ref: 'dxn:type:example.com/type/Organization',
262
+ },
263
+ schemaVersion: '0.1.0',
264
+ },
265
+ },
266
+ ],
267
+ description: 'Contact organization',
268
+ },
269
+ },
270
+ required: ['name', 'organization', 'id'],
271
+ propertyOrder: ['name', 'organization', 'id'],
272
+ });
273
+ });
274
+
275
+ test('add reference property', () => {
276
+ const Organization = Schema.Struct({
277
+ field: Schema.String,
278
+ }).pipe(
279
+ Type.Obj({
280
+ typename: 'example.com/type/Organization',
281
+ version: '0.1.0',
282
+ }),
283
+ );
284
+
285
+ const Contact = Schema.Struct({
286
+ name: Schema.String,
287
+ organization: Ref(Organization).annotations({ description: 'Contact organization' }),
288
+ }).pipe(
289
+ Type.Obj({
290
+ typename: 'example.com/type/Person',
291
+ version: '0.1.0',
292
+ }),
293
+ );
294
+
295
+ const jsonSchema = toJsonSchema(Contact);
296
+ setSchemaProperty(jsonSchema, 'organization' as JsonProp, createSchemaReference(Organization.typename));
297
+ const { typename } = getSchemaReference(getSchemaProperty(jsonSchema, 'organization' as JsonProp) ?? {}) ?? {};
298
+ expect(typename).to.eq(Organization.typename);
299
+ });
300
+
301
+ test('serialize circular schema (PersistentSchema)', () => {
302
+ const jsonSchema = toJsonSchema(PersistentSchema);
303
+ expect(Object.keys(jsonSchema.properties!).length).toBeGreaterThan(0);
304
+
305
+ // TODO(dmaretskyi): Currently unable to deserialize.
306
+ // const effectSchema = toEffectSchema(jsonSchema);
307
+ log('schema', { jsonSchema });
308
+ });
309
+
310
+ test('tuple schema with description', () => {
311
+ const schema = Schema.Struct({
312
+ args: Schema.Tuple(
313
+ Schema.String.annotations({ description: 'The source currency' }),
314
+ Schema.String.annotations({ description: 'The target currency' }),
315
+ ),
316
+ });
317
+ const jsonSchema = toJsonSchema(schema);
318
+ log('schema', { jsonSchema });
319
+
320
+ (Schema.asserts(JsonSchemaType) as any)(jsonSchema);
321
+ });
322
+
323
+ test('reference with title annotation', () => {
324
+ const schema = Schema.Struct({
325
+ contact: Ref(TestSchema.Person).annotations({ title: 'Custom Title' }),
326
+ });
327
+
328
+ // log.info('schema before', { ast: schema.ast });
329
+
330
+ const jsonSchema = toJsonSchema(schema);
331
+ // log.info('json schema', { jsonSchema });
332
+
333
+ const effectSchema = toEffectSchema(jsonSchema);
334
+ // log.info('effect schema', { ast: effectSchema.ast });
335
+
336
+ expect(
337
+ effectSchema.pipe(
338
+ Schema.pluck('contact'),
339
+ Schema.typeSchema,
340
+ (s) => s.ast,
341
+ SchemaAST.getAnnotation(SchemaAST.TitleAnnotationId),
342
+ Option.getOrUndefined,
343
+ ),
344
+ ).to.eq('Custom Title');
345
+ });
346
+
347
+ test('relation schema', () => {
348
+ const schema = TestSchema.EmployedBy;
349
+ const jsonSchema = toJsonSchema(schema);
350
+ expect(jsonSchema).toEqual({
351
+ $id: 'dxn:type:example.com/type/EmployedBy',
352
+ $schema: 'http://json-schema.org/draft-07/schema#',
353
+ entityKind: 'relation',
354
+ typename: 'example.com/type/EmployedBy',
355
+ version: '0.1.0',
356
+ relationSource: {
357
+ // TODO(dmaretskyi): Should those point to specific schema version?
358
+ $ref: 'dxn:type:example.com/type/Person',
359
+ },
360
+ relationTarget: {
361
+ // TODO(dmaretskyi): Should those point to specific schema version?
362
+ $ref: 'dxn:type:example.com/type/Organization',
363
+ },
364
+ type: 'object',
365
+ properties: {
366
+ id: {
367
+ type: 'string',
368
+ },
369
+ role: {
370
+ type: 'string',
371
+ },
372
+ since: {
373
+ type: 'string',
374
+ },
375
+ },
376
+ propertyOrder: ['role', 'since', 'id'],
377
+ required: ['role', 'id'],
378
+ additionalProperties: false,
379
+ });
380
+ });
381
+
382
+ test('label prop', () => {
383
+ const Organization = Schema.Struct({
384
+ id: ObjectId,
385
+ name: Schema.String,
386
+ }).pipe(
387
+ EchoObjectSchema({
388
+ typename: 'example.com/type/Organization',
389
+ version: '0.1.0',
390
+ }),
391
+ LabelAnnotation.set(['name']),
392
+ );
393
+
394
+ const jsonSchema = toJsonSchema(Organization);
395
+ expect(jsonSchema).toEqual({
396
+ $id: 'dxn:type:example.com/type/Organization',
397
+ $schema: 'http://json-schema.org/draft-07/schema#',
398
+ typename: 'example.com/type/Organization',
399
+ version: '0.1.0',
400
+ entityKind: 'object',
401
+ type: 'object',
402
+ properties: {
403
+ id: {
404
+ type: 'string',
405
+ pattern: '^[0-7][0-9A-HJKMNP-TV-Z]{25}$',
406
+ description: 'A Universally Unique Lexicographically Sortable Identifier',
407
+ },
408
+ name: {
409
+ type: 'string',
410
+ },
411
+ },
412
+ annotations: {
413
+ labelProp: ['name'],
414
+ },
415
+ propertyOrder: ['id', 'name'],
416
+ required: ['id', 'name'],
417
+ additionalProperties: false,
418
+ });
419
+ });
420
+
421
+ test('object id with description', () => {
422
+ const schema = Schema.Struct({
423
+ id: ObjectId.annotations({ description: 'The id' }),
424
+ });
425
+ // log.info('schema', { schema: ObjectId.ast });
426
+ const jsonSchema = toJsonSchema(schema);
427
+ expect(jsonSchema).toMatchInlineSnapshot(`
428
+ {
429
+ "$schema": "http://json-schema.org/draft-07/schema#",
430
+ "additionalProperties": false,
431
+ "properties": {
432
+ "id": {
433
+ "description": "The id",
434
+ "pattern": "^[0-7][0-9A-HJKMNP-TV-Z]{25}$",
435
+ "type": "string",
436
+ },
437
+ },
438
+ "propertyOrder": [
439
+ "id",
440
+ ],
441
+ "required": [
442
+ "id",
443
+ ],
444
+ "type": "object",
445
+ }
446
+ `);
447
+ });
448
+
449
+ test('email schema', () => {
450
+ const schema = Email;
451
+ const jsonSchema = toJsonSchema(schema);
452
+ expect(jsonSchema).toMatchInlineSnapshot(`
453
+ {
454
+ "$schema": "http://json-schema.org/draft-07/schema#",
455
+ "description": "Email address",
456
+ "format": "email",
457
+ "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
458
+ "title": "Email",
459
+ "type": "string",
460
+ }
461
+ `);
462
+ const effectSchema = toEffectSchema(jsonSchema);
463
+ expect(prepareAstForCompare(effectSchema.ast)).to.deep.eq(prepareAstForCompare(schema.ast));
464
+ });
465
+
466
+ const expectReferenceAnnotation = (object: JsonSchemaType) => {
467
+ expect(object.reference).to.deep.eq({
468
+ schema: {
469
+ $ref: 'dxn:type:example.com/type/TestNested',
470
+ },
471
+ schemaVersion: '0.1.0',
472
+ });
473
+ };
474
+ });
475
+
476
+ describe('json-to-effect', () => {
477
+ describe('field schema', () => {
478
+ test('email', () => {
479
+ const schema = Email;
480
+ expect(toJsonSchema(schema)).to.deep.eq({
481
+ $schema: 'http://json-schema.org/draft-07/schema#',
482
+ type: 'string',
483
+ format: 'email',
484
+ title: 'Email',
485
+ description: 'Email address',
486
+ // TODO(dmaretskyi): omit pattern.
487
+ pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
488
+ });
489
+ });
490
+ });
491
+
492
+ for (const partial of [false, true]) {
493
+ test(`deserialized equals original ${partial ? 'with partial' : ''}`, () => {
494
+ const Organization = Schema.Struct({
495
+ field: Schema.String,
496
+ }).pipe(
497
+ Type.Obj({
498
+ typename: 'example.com/type/Organization',
499
+ version: '0.1.0',
500
+ }),
501
+ );
502
+
503
+ const fields = {
504
+ string: Schema.String,
505
+ number: Schema.Number.pipe(PropertyMeta(EXAMPLE_NAMESPACE, { is_date: true })),
506
+ boolean: Schema.Boolean,
507
+ array: Schema.Array(Schema.String),
508
+ twoDArray: Schema.Array(Schema.Array(Schema.String)),
509
+ record: Schema.Record({ key: Schema.String, value: Schema.Number }),
510
+ object: Schema.Struct({ id: Schema.String, field: Ref(Organization) }),
511
+ echoObject: Ref(Organization),
512
+ echoObjectArray: Schema.Array(Ref(Organization)),
513
+ email: Schema.String.pipe(FormatAnnotation.set(TypeFormat.Email)),
514
+ null: Schema.Null,
515
+ } as const;
516
+
517
+ const Test = (partial ? Schema.partial(Schema.Struct(fields)) : Schema.Struct(fields)).pipe(
518
+ Type.Obj({
519
+ typename: 'example.com/type/Test',
520
+ version: '0.1.0',
521
+ }),
522
+ );
523
+
524
+ const jsonSchema = toJsonSchema(Test);
525
+ // log.info('schema', { jsonSchema });
526
+
527
+ const schema = toEffectSchema(jsonSchema);
528
+
529
+ expect(() => expect(schema.ast).to.deep.eq(Test.ast)).to.throw();
530
+ expect(() => expect(prepareAstForCompare(Test.ast)).to.deep.eq(Test.ast)).to.throw();
531
+ expect(() => expect(schema.ast).to.deep.eq(prepareAstForCompare(Test.ast))).to.throw();
532
+ // log.info('', { original: prepareAstForCompare(Schema.ast), deserialized: prepareAstForCompare(schema.ast) });
533
+ expect(prepareAstForCompare(schema.ast)).to.deep.eq(prepareAstForCompare(Test.ast));
534
+
535
+ // TODO(dmaretskyi): Fix.
536
+ // expect(
537
+ // SchemaAST.getPropertySignatures(schema.ast).find((prop) => prop.name === 'email')!.type.annotations[
538
+ // FormatAnnotationId
539
+ // ],
540
+ // ).toEqual('email');
541
+ });
542
+ }
543
+
544
+ test('legacy schema with dxn:type $id gets decoded', () => {
545
+ const jsonSchema: JsonSchemaType = {
546
+ $id: 'dxn:type:example.com/type/Project',
547
+ $schema: 'http://json-schema.org/draft-07/schema#',
548
+ additionalProperties: false,
549
+ echo: {
550
+ type: {
551
+ schemaId: '01JERV1HQCQZDQ4NVCJ42QB38F',
552
+ typename: 'example.com/type/Project',
553
+ version: '0.1.0',
554
+ },
555
+ },
556
+ properties: {
557
+ description: {
558
+ type: 'string',
559
+ },
560
+ id: {
561
+ type: 'string',
562
+ },
563
+ name: {
564
+ echo: {
565
+ generator: 'commerce.productName',
566
+ },
567
+ type: 'string',
568
+ },
569
+ },
570
+ required: ['id'],
571
+ type: 'object',
572
+ version: '0.1.0',
573
+ };
574
+
575
+ const schema = toEffectSchema(jsonSchema);
576
+ expect(getTypeAnnotation(schema)).to.deep.eq({
577
+ kind: EntityKind.Object,
578
+ typename: 'example.com/type/Project',
579
+ version: '0.1.0',
580
+ });
581
+ expect(getTypeIdentifierAnnotation(schema)).to.deep.eq('dxn:echo:@:01JERV1HQCQZDQ4NVCJ42QB38F');
582
+ });
583
+
584
+ test('symbol annotations get compared', () => {
585
+ const schema1 = Schema.String.pipe(FormatAnnotation.set(TypeFormat.Email));
586
+ const schema2 = Schema.String.pipe(FormatAnnotation.set(TypeFormat.Currency));
587
+ expect(prepareAstForCompare(schema1.ast)).not.to.deep.eq(prepareAstForCompare(schema2.ast));
588
+ });
589
+
590
+ test('description gets preserved', () => {
591
+ const schema = Schema.Struct({
592
+ name: Schema.String.annotations({ description: 'Name' }),
593
+ });
594
+ const jsonSchema = toJsonSchema(schema);
595
+ const effectSchema = toEffectSchema(jsonSchema);
596
+ const jsonSchema2 = toJsonSchema(effectSchema);
597
+ expect(jsonSchema2.properties!.name.description).to.eq('Name');
598
+ });
599
+
600
+ test('relation schema roundtrip', () => {
601
+ const schema = TestSchema.HasManager;
602
+ const jsonSchema = toJsonSchema(schema);
603
+ const effectSchema = toEffectSchema(jsonSchema);
604
+ expect(prepareAstForCompare(effectSchema.ast)).to.deep.eq(prepareAstForCompare(schema.ast));
605
+ });
606
+
607
+ test('generator annotation', () => {
608
+ const schema = Schema.Struct({
609
+ name: Schema.String.pipe(GeneratorAnnotation.set('commerce.productName')),
610
+ });
611
+ const jsonSchema = toJsonSchema(schema);
612
+ expect(jsonSchema).toMatchInlineSnapshot(`
613
+ {
614
+ "$schema": "http://json-schema.org/draft-07/schema#",
615
+ "additionalProperties": false,
616
+ "properties": {
617
+ "name": {
618
+ "annotations": {
619
+ "generator": "commerce.productName",
620
+ },
621
+ "type": "string",
622
+ },
623
+ },
624
+ "propertyOrder": [
625
+ "name",
626
+ ],
627
+ "required": [
628
+ "name",
629
+ ],
630
+ "type": "object",
631
+ }
632
+ `);
633
+ });
634
+
635
+ // test('generator annotation on object', () => {
636
+ // const schema = Schema.Struct({
637
+ // });
638
+ // const jsonSchema = toJsonSchema(schema);
639
+ // expect(jsonSchema).toMatchInlineSnapshot();
640
+ // });
641
+
642
+ test('default annotation ', () => {
643
+ const schema = Schema.Struct({
644
+ str: Schema.String.annotations({
645
+ default: 'foo',
646
+ }),
647
+ arr: Schema.Array(Schema.String).annotations({
648
+ default: [],
649
+ }),
650
+ obj: Schema.Struct({
651
+ foo: Schema.optional(Schema.String).annotations({
652
+ default: 'bar',
653
+ }),
654
+ }),
655
+ });
656
+ const jsonSchema = toJsonSchema(schema);
657
+ expect(jsonSchema).toMatchInlineSnapshot(`
658
+ {
659
+ "$schema": "http://json-schema.org/draft-07/schema#",
660
+ "additionalProperties": false,
661
+ "properties": {
662
+ "arr": {
663
+ "default": [],
664
+ "items": {
665
+ "type": "string",
666
+ },
667
+ "type": "array",
668
+ },
669
+ "obj": {
670
+ "additionalProperties": false,
671
+ "properties": {
672
+ "foo": {
673
+ "default": "bar",
674
+ "type": "string",
675
+ },
676
+ },
677
+ "propertyOrder": [
678
+ "foo",
679
+ ],
680
+ "required": [],
681
+ "type": "object",
682
+ },
683
+ "str": {
684
+ "default": "foo",
685
+ "type": "string",
686
+ },
687
+ },
688
+ "propertyOrder": [
689
+ "str",
690
+ "arr",
691
+ "obj",
692
+ ],
693
+ "required": [
694
+ "str",
695
+ "arr",
696
+ "obj",
697
+ ],
698
+ "type": "object",
699
+ }
700
+ `);
701
+ });
702
+
703
+ test('schema with optional referece', () => {
704
+ const TempSchema = Schema.Struct({ contact: Schema.optional(Ref(TestSchema.Person)) });
705
+ const jsonSchema = toJsonSchema(TempSchema);
706
+ expect(jsonSchema).toMatchInlineSnapshot(`
707
+ {
708
+ "$schema": "http://json-schema.org/draft-07/schema#",
709
+ "additionalProperties": false,
710
+ "properties": {
711
+ "contact": {
712
+ "$id": "/schemas/echo/ref",
713
+ "$ref": "/schemas/echo/ref",
714
+ "reference": {
715
+ "schema": {
716
+ "$ref": "dxn:type:example.com/type/Person",
717
+ },
718
+ "schemaVersion": "0.1.0",
719
+ },
720
+ },
721
+ },
722
+ "propertyOrder": [
723
+ "contact",
724
+ ],
725
+ "required": [],
726
+ "type": "object",
727
+ }
728
+ `);
729
+
730
+ const effectSchema = toEffectSchema(jsonSchema);
731
+ expect(prepareAstForCompare(effectSchema.ast)).to.deep.eq(prepareAstForCompare(TempSchema.ast));
732
+ });
733
+
734
+ test('object nested inside another struct', () => {
735
+ const Contact = Schema.Struct({
736
+ name: Schema.String,
737
+ }).pipe(EchoObjectSchema({ typename: 'example.com/type/Person', version: '0.1.0' }));
738
+ const input = Schema.Struct({
739
+ contact: Contact,
740
+ });
741
+ const jsonSchema = toJsonSchema(input);
742
+ expect(jsonSchema).toMatchInlineSnapshot(`
743
+ {
744
+ "$schema": "http://json-schema.org/draft-07/schema#",
745
+ "additionalProperties": false,
746
+ "properties": {
747
+ "contact": {
748
+ "$id": "dxn:type:example.com/type/Person",
749
+ "additionalProperties": false,
750
+ "entityKind": "object",
751
+ "properties": {
752
+ "id": {
753
+ "type": "string",
754
+ },
755
+ "name": {
756
+ "type": "string",
757
+ },
758
+ },
759
+ "propertyOrder": [
760
+ "name",
761
+ "id",
762
+ ],
763
+ "required": [
764
+ "name",
765
+ "id",
766
+ ],
767
+ "type": "object",
768
+ "typename": "example.com/type/Person",
769
+ "version": "0.1.0",
770
+ },
771
+ },
772
+ "propertyOrder": [
773
+ "contact",
774
+ ],
775
+ "required": [
776
+ "contact",
777
+ ],
778
+ "type": "object",
779
+ }
780
+ `);
781
+
782
+ const effectSchema = toEffectSchema(jsonSchema);
783
+ expect(prepareAstForCompare(effectSchema.ast)).to.deep.eq(prepareAstForCompare(input.ast));
784
+ });
785
+ });
786
+
787
+ describe('reference', () => {
788
+ test('reference annotation', () => {
789
+ const schema = Ref(TestSchema.Person);
790
+ const jsonSchema = toJsonSchema(schema);
791
+ expect(jsonSchema).toEqual({
792
+ $id: '/schemas/echo/ref',
793
+ $ref: '/schemas/echo/ref',
794
+ $schema: 'http://json-schema.org/draft-07/schema#',
795
+ reference: {
796
+ schema: {
797
+ $ref: 'dxn:type:example.com/type/Person',
798
+ },
799
+ schemaVersion: '0.1.0',
800
+ },
801
+ });
802
+ });
803
+
804
+ test('title annotation', () => {
805
+ const schema = Ref(TestSchema.Person).annotations({ title: 'My custom title' });
806
+ const jsonSchema = toJsonSchema(schema);
807
+ expect(jsonSchema).toEqual({
808
+ $schema: 'http://json-schema.org/draft-07/schema#',
809
+ allOf: [
810
+ {
811
+ $id: '/schemas/echo/ref',
812
+ $ref: '/schemas/echo/ref',
813
+ reference: {
814
+ schema: {
815
+ $ref: 'dxn:type:example.com/type/Person',
816
+ },
817
+ schemaVersion: '0.1.0',
818
+ },
819
+ },
820
+ ],
821
+ title: 'My custom title',
822
+ });
823
+ });
824
+
825
+ test('description annotation', () => {
826
+ const schema = Ref(TestSchema.Person).annotations({ description: 'My custom description' });
827
+ const jsonSchema = toJsonSchema(schema);
828
+ expect(jsonSchema).toEqual({
829
+ $schema: 'http://json-schema.org/draft-07/schema#',
830
+ allOf: [
831
+ {
832
+ $id: '/schemas/echo/ref',
833
+ $ref: '/schemas/echo/ref',
834
+ reference: {
835
+ schema: {
836
+ $ref: 'dxn:type:example.com/type/Person',
837
+ },
838
+ schemaVersion: '0.1.0',
839
+ },
840
+ },
841
+ ],
842
+ description: 'My custom description',
843
+ });
844
+
845
+ const effectSchema = toEffectSchema(jsonSchema);
846
+ expect(prepareAstForCompare(effectSchema.ast)).to.deep.eq(prepareAstForCompare(schema.ast));
847
+ });
848
+
849
+ test('serialize and deserialize', () => {
850
+ const schema = Ref(TestSchema.Person);
851
+ const jsonSchema = toJsonSchema(schema);
852
+ const deserializedSchema = toEffectSchema(jsonSchema);
853
+ const refAst = getReferenceAst(deserializedSchema.ast);
854
+ expect(refAst).toEqual({
855
+ typename: TestSchema.Person.typename,
856
+ version: TestSchema.Person.version,
857
+ });
858
+ });
859
+ });