@voxgig/sdkgen-langpack 0.0.1

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 (300) hide show
  1. package/.sdk/model/target/dart.aon +63 -0
  2. package/.sdk/model/target/haskell.aon +72 -0
  3. package/.sdk/model/target/lean.aon +91 -0
  4. package/.sdk/src/cmp/dart/Config_dart.ts +248 -0
  5. package/.sdk/src/cmp/dart/EntityBase_dart.ts +34 -0
  6. package/.sdk/src/cmp/dart/EntityOperation_dart.ts +43 -0
  7. package/.sdk/src/cmp/dart/EntityTypes_dart.ts +207 -0
  8. package/.sdk/src/cmp/dart/Entity_dart.ts +87 -0
  9. package/.sdk/src/cmp/dart/Gitignore_dart.ts +34 -0
  10. package/.sdk/src/cmp/dart/MainEntity_dart.ts +33 -0
  11. package/.sdk/src/cmp/dart/Main_dart.ts +178 -0
  12. package/.sdk/src/cmp/dart/Package_dart.ts +82 -0
  13. package/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +177 -0
  14. package/.sdk/src/cmp/dart/ReadmeExamplesTest_dart.ts +238 -0
  15. package/.sdk/src/cmp/dart/ReadmeExplanation_dart.ts +53 -0
  16. package/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +152 -0
  17. package/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +59 -0
  18. package/.sdk/src/cmp/dart/ReadmeIntro_dart.ts +65 -0
  19. package/.sdk/src/cmp/dart/ReadmeModel_dart.ts +151 -0
  20. package/.sdk/src/cmp/dart/ReadmeOptions_dart.ts +63 -0
  21. package/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +225 -0
  22. package/.sdk/src/cmp/dart/ReadmeRef_dart.ts +397 -0
  23. package/.sdk/src/cmp/dart/ReadmeTopHowto_dart.ts +24 -0
  24. package/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +106 -0
  25. package/.sdk/src/cmp/dart/ReadmeTopTest_dart.ts +78 -0
  26. package/.sdk/src/cmp/dart/SdkError_dart.ts +42 -0
  27. package/.sdk/src/cmp/dart/TestDirect_dart.ts +516 -0
  28. package/.sdk/src/cmp/dart/TestEntity_dart.ts +628 -0
  29. package/.sdk/src/cmp/dart/Test_dart.ts +138 -0
  30. package/.sdk/src/cmp/dart/fragment/Config.data.fragment.dart +98 -0
  31. package/.sdk/src/cmp/dart/fragment/Config.fragment.dart +70 -0
  32. package/.sdk/src/cmp/dart/fragment/Direct.test.fragment.dart +25 -0
  33. package/.sdk/src/cmp/dart/fragment/Entity.fragment.dart +29 -0
  34. package/.sdk/src/cmp/dart/fragment/Entity.test.fragment.dart +28 -0
  35. package/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +302 -0
  36. package/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +98 -0
  37. package/.sdk/src/cmp/dart/fragment/EntityListOp.fragment.dart +90 -0
  38. package/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +102 -0
  39. package/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +108 -0
  40. package/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +102 -0
  41. package/.sdk/src/cmp/dart/fragment/Main.fragment.dart +339 -0
  42. package/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +26 -0
  43. package/.sdk/src/cmp/dart/tsconfig.json +15 -0
  44. package/.sdk/src/cmp/dart/utility_dart.ts +155 -0
  45. package/.sdk/src/cmp/haskell/Config_haskell.ts +98 -0
  46. package/.sdk/src/cmp/haskell/Entity_haskell.ts +13 -0
  47. package/.sdk/src/cmp/haskell/Gitignore_haskell.ts +27 -0
  48. package/.sdk/src/cmp/haskell/Main_haskell.ts +123 -0
  49. package/.sdk/src/cmp/haskell/Package_haskell.ts +60 -0
  50. package/.sdk/src/cmp/haskell/ReadmeEntity_haskell.ts +186 -0
  51. package/.sdk/src/cmp/haskell/ReadmeExamplesTest_haskell.ts +135 -0
  52. package/.sdk/src/cmp/haskell/ReadmeExplanation_haskell.ts +48 -0
  53. package/.sdk/src/cmp/haskell/ReadmeHowto_haskell.ts +168 -0
  54. package/.sdk/src/cmp/haskell/ReadmeInstall_haskell.ts +51 -0
  55. package/.sdk/src/cmp/haskell/ReadmeIntro_haskell.ts +67 -0
  56. package/.sdk/src/cmp/haskell/ReadmeModel_haskell.ts +162 -0
  57. package/.sdk/src/cmp/haskell/ReadmeOptions_haskell.ts +74 -0
  58. package/.sdk/src/cmp/haskell/ReadmeQuick_haskell.ts +241 -0
  59. package/.sdk/src/cmp/haskell/ReadmeRef_haskell.ts +408 -0
  60. package/.sdk/src/cmp/haskell/ReadmeTopHowto_haskell.ts +31 -0
  61. package/.sdk/src/cmp/haskell/ReadmeTopQuick_haskell.ts +104 -0
  62. package/.sdk/src/cmp/haskell/ReadmeTopTest_haskell.ts +80 -0
  63. package/.sdk/src/cmp/haskell/Test_haskell.ts +297 -0
  64. package/.sdk/src/cmp/haskell/tsconfig.json +15 -0
  65. package/.sdk/src/cmp/haskell/utility_haskell.ts +166 -0
  66. package/.sdk/src/cmp/lean/Config_lean.ts +93 -0
  67. package/.sdk/src/cmp/lean/Entity_lean.ts +9 -0
  68. package/.sdk/src/cmp/lean/Gitignore_lean.ts +18 -0
  69. package/.sdk/src/cmp/lean/Main_lean.ts +120 -0
  70. package/.sdk/src/cmp/lean/Package_lean.ts +93 -0
  71. package/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +29 -0
  72. package/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +19 -0
  73. package/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +25 -0
  74. package/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +39 -0
  75. package/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +25 -0
  76. package/.sdk/src/cmp/lean/ReadmeModel_lean.ts +24 -0
  77. package/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +22 -0
  78. package/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +50 -0
  79. package/.sdk/src/cmp/lean/ReadmeRef_lean.ts +40 -0
  80. package/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +16 -0
  81. package/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +23 -0
  82. package/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +19 -0
  83. package/.sdk/src/cmp/lean/Test_lean.ts +261 -0
  84. package/.sdk/src/cmp/lean/utility_lean.ts +129 -0
  85. package/.sdk/tm/dart/LICENSE +22 -0
  86. package/.sdk/tm/dart/Makefile +50 -0
  87. package/.sdk/tm/dart/lib/Context.dart +150 -0
  88. package/.sdk/tm/dart/lib/Control.dart +15 -0
  89. package/.sdk/tm/dart/lib/Operation.dart +31 -0
  90. package/.sdk/tm/dart/lib/Point.dart +51 -0
  91. package/.sdk/tm/dart/lib/Response.dart +32 -0
  92. package/.sdk/tm/dart/lib/Result.dart +39 -0
  93. package/.sdk/tm/dart/lib/Spec.dart +49 -0
  94. package/.sdk/tm/dart/lib/feature/audit/AuditFeature.dart +103 -0
  95. package/.sdk/tm/dart/lib/feature/base/BaseFeature.dart +76 -0
  96. package/.sdk/tm/dart/lib/feature/cache/CacheFeature.dart +152 -0
  97. package/.sdk/tm/dart/lib/feature/clienttrack/ClienttrackFeature.dart +104 -0
  98. package/.sdk/tm/dart/lib/feature/cost/CostFeature.dart +446 -0
  99. package/.sdk/tm/dart/lib/feature/debug/DebugFeature.dart +153 -0
  100. package/.sdk/tm/dart/lib/feature/idempotency/IdempotencyFeature.dart +92 -0
  101. package/.sdk/tm/dart/lib/feature/log/LogFeature.dart +85 -0
  102. package/.sdk/tm/dart/lib/feature/metrics/MetricsFeature.dart +103 -0
  103. package/.sdk/tm/dart/lib/feature/netsim/NetsimFeature.dart +186 -0
  104. package/.sdk/tm/dart/lib/feature/paging/PagingFeature.dart +240 -0
  105. package/.sdk/tm/dart/lib/feature/proxy/ProxyFeature.dart +118 -0
  106. package/.sdk/tm/dart/lib/feature/ratelimit/RatelimitFeature.dart +103 -0
  107. package/.sdk/tm/dart/lib/feature/rbac/RbacFeature.dart +121 -0
  108. package/.sdk/tm/dart/lib/feature/retry/RetryFeature.dart +155 -0
  109. package/.sdk/tm/dart/lib/feature/secrets/SecretsFeature.dart +649 -0
  110. package/.sdk/tm/dart/lib/feature/secrets/plugin/capability.dart +105 -0
  111. package/.sdk/tm/dart/lib/feature/secrets/plugin/catalog.dart +46 -0
  112. package/.sdk/tm/dart/lib/feature/secrets/plugin/config.dart +297 -0
  113. package/.sdk/tm/dart/lib/feature/secrets/plugin/depend.dart +198 -0
  114. package/.sdk/tm/dart/lib/feature/secrets/plugin/env.dart +144 -0
  115. package/.sdk/tm/dart/lib/feature/secrets/plugin/export.dart +58 -0
  116. package/.sdk/tm/dart/lib/feature/secrets/plugin/graph.dart +160 -0
  117. package/.sdk/tm/dart/lib/feature/secrets/plugin/host.dart +1067 -0
  118. package/.sdk/tm/dart/lib/feature/secrets/plugin/order.dart +172 -0
  119. package/.sdk/tm/dart/lib/feature/secrets/plugin/plugin.dart +23 -0
  120. package/.sdk/tm/dart/lib/feature/secrets/plugin/point.dart +117 -0
  121. package/.sdk/tm/dart/lib/feature/secrets/plugin/ref.dart +105 -0
  122. package/.sdk/tm/dart/lib/feature/secrets/plugin/resolve.dart +58 -0
  123. package/.sdk/tm/dart/lib/feature/secrets/plugin/types.dart +201 -0
  124. package/.sdk/tm/dart/lib/feature/secrets/plugin/version.dart +116 -0
  125. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/aws.dart +285 -0
  126. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/azuresecrets.dart +178 -0
  127. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/boru.dart +145 -0
  128. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/crypto.dart +194 -0
  129. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/doppler.dart +101 -0
  130. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/gcpsecrets.dart +143 -0
  131. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/hashicorp.dart +190 -0
  132. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/httpjson.dart +363 -0
  133. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/infisical.dart +149 -0
  134. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/onepassword.dart +146 -0
  135. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/secretspec.dart +116 -0
  136. package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/sigv4.dart +237 -0
  137. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/addr.dart +138 -0
  138. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/json.dart +276 -0
  139. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/provider.dart +31 -0
  140. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/providers.dart +243 -0
  141. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/sekreto.dart +730 -0
  142. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/spec.dart +200 -0
  143. package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/support.dart +217 -0
  144. package/.sdk/tm/dart/lib/feature/streaming/StreamingFeature.dart +97 -0
  145. package/.sdk/tm/dart/lib/feature/telemetry/TelemetryFeature.dart +136 -0
  146. package/.sdk/tm/dart/lib/feature/test/TestFeature.dart +328 -0
  147. package/.sdk/tm/dart/lib/feature/timeout/TimeoutFeature.dart +104 -0
  148. package/.sdk/tm/dart/lib/utility/CleanUtility.dart +12 -0
  149. package/.sdk/tm/dart/lib/utility/DoneUtility.dart +18 -0
  150. package/.sdk/tm/dart/lib/utility/ErrUtility.dart +46 -0
  151. package/.sdk/tm/dart/lib/utility/FeatureAddUtility.dart +35 -0
  152. package/.sdk/tm/dart/lib/utility/FeatureHookUtility.dart +20 -0
  153. package/.sdk/tm/dart/lib/utility/FeatureInitUtility.dart +9 -0
  154. package/.sdk/tm/dart/lib/utility/FetcherUtility.dart +104 -0
  155. package/.sdk/tm/dart/lib/utility/GraphqlUtility.dart +162 -0
  156. package/.sdk/tm/dart/lib/utility/MakeContextUtility.dart +6 -0
  157. package/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +71 -0
  158. package/.sdk/tm/dart/lib/utility/MakeFetchDefUtility.dart +42 -0
  159. package/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +233 -0
  160. package/.sdk/tm/dart/lib/utility/MakePointUtility.dart +130 -0
  161. package/.sdk/tm/dart/lib/utility/MakeRequestUtility.dart +66 -0
  162. package/.sdk/tm/dart/lib/utility/MakeResponseUtility.dart +59 -0
  163. package/.sdk/tm/dart/lib/utility/MakeResultUtility.dart +49 -0
  164. package/.sdk/tm/dart/lib/utility/MakeSpecUtility.dart +77 -0
  165. package/.sdk/tm/dart/lib/utility/MakeUrlUtility.dart +51 -0
  166. package/.sdk/tm/dart/lib/utility/ParamUtility.dart +56 -0
  167. package/.sdk/tm/dart/lib/utility/PrepareAuthUtility.dart +46 -0
  168. package/.sdk/tm/dart/lib/utility/PrepareBodyUtility.dart +19 -0
  169. package/.sdk/tm/dart/lib/utility/PrepareHeadersUtility.dart +11 -0
  170. package/.sdk/tm/dart/lib/utility/PrepareMethodUtility.dart +30 -0
  171. package/.sdk/tm/dart/lib/utility/PrepareParamsUtility.dart +23 -0
  172. package/.sdk/tm/dart/lib/utility/PreparePathUtility.dart +9 -0
  173. package/.sdk/tm/dart/lib/utility/PrepareQueryUtility.dart +18 -0
  174. package/.sdk/tm/dart/lib/utility/ResultBasicUtility.dart +29 -0
  175. package/.sdk/tm/dart/lib/utility/ResultBodyUtility.dart +15 -0
  176. package/.sdk/tm/dart/lib/utility/ResultHeadersUtility.dart +18 -0
  177. package/.sdk/tm/dart/lib/utility/StructUtility.dart +127 -0
  178. package/.sdk/tm/dart/lib/utility/TransformRequestUtility.dart +28 -0
  179. package/.sdk/tm/dart/lib/utility/TransformResponseUtility.dart +44 -0
  180. package/.sdk/tm/dart/lib/utility/Utility.dart +239 -0
  181. package/.sdk/tm/dart/lib/utility/voxgig_struct.dart +2462 -0
  182. package/.sdk/tm/dart/src/feature/README.md +3 -0
  183. package/.sdk/tm/dart/src/feature/audit/.gitkeep +0 -0
  184. package/.sdk/tm/dart/src/feature/base/.gitkeep +0 -0
  185. package/.sdk/tm/dart/src/feature/cache/.gitkeep +0 -0
  186. package/.sdk/tm/dart/src/feature/clienttrack/.gitkeep +0 -0
  187. package/.sdk/tm/dart/src/feature/cost/.gitkeep +0 -0
  188. package/.sdk/tm/dart/src/feature/debug/.gitkeep +0 -0
  189. package/.sdk/tm/dart/src/feature/idempotency/.gitkeep +0 -0
  190. package/.sdk/tm/dart/src/feature/log/.gitkeep +0 -0
  191. package/.sdk/tm/dart/src/feature/metrics/.gitkeep +0 -0
  192. package/.sdk/tm/dart/src/feature/netsim/.gitkeep +0 -0
  193. package/.sdk/tm/dart/src/feature/paging/.gitkeep +0 -0
  194. package/.sdk/tm/dart/src/feature/proxy/.gitkeep +0 -0
  195. package/.sdk/tm/dart/src/feature/ratelimit/.gitkeep +0 -0
  196. package/.sdk/tm/dart/src/feature/rbac/.gitkeep +0 -0
  197. package/.sdk/tm/dart/src/feature/retry/.gitkeep +0 -0
  198. package/.sdk/tm/dart/src/feature/secrets/.gitkeep +0 -0
  199. package/.sdk/tm/dart/src/feature/streaming/.gitkeep +0 -0
  200. package/.sdk/tm/dart/src/feature/telemetry/.gitkeep +0 -0
  201. package/.sdk/tm/dart/src/feature/test/.gitkeep +0 -0
  202. package/.sdk/tm/dart/src/feature/timeout/.gitkeep +0 -0
  203. package/.sdk/tm/dart/test/custom_test.dart +65 -0
  204. package/.sdk/tm/dart/test/exists_test.dart +12 -0
  205. package/.sdk/tm/dart/test/feature/harness.dart +347 -0
  206. package/.sdk/tm/dart/test/feature/secrets/secrets_test.dart +1107 -0
  207. package/.sdk/tm/dart/test/feature_test.dart +1193 -0
  208. package/.sdk/tm/dart/test/harness.dart +153 -0
  209. package/.sdk/tm/dart/test/netsim_test.dart +48 -0
  210. package/.sdk/tm/dart/test/omni.dart +520 -0
  211. package/.sdk/tm/dart/test/omni_smoke_test.dart +143 -0
  212. package/.sdk/tm/dart/test/pipeline_test.dart +608 -0
  213. package/.sdk/tm/dart/test/primary_test.dart +476 -0
  214. package/.sdk/tm/dart/test/sdk-test-control.json +19 -0
  215. package/.sdk/tm/dart/test/struct_test.dart +468 -0
  216. package/.sdk/tm/dart/test/utility.dart +198 -0
  217. package/.sdk/tm/dart/test/vendor/omni/omni.dart +7 -0
  218. package/.sdk/tm/dart/test/vendor/omni/runner.dart +653 -0
  219. package/.sdk/tm/dart/test/vendor/omni/util.dart +232 -0
  220. package/.sdk/tm/haskell/LICENSE +21 -0
  221. package/.sdk/tm/haskell/Makefile +22 -0
  222. package/.sdk/tm/haskell/VERSION +1 -0
  223. package/.sdk/tm/haskell/src/SdkFeatures.hs +1440 -0
  224. package/.sdk/tm/haskell/src/SdkHelpers.hs +337 -0
  225. package/.sdk/tm/haskell/src/SdkJson.hs +111 -0
  226. package/.sdk/tm/haskell/src/SdkRuntime.hs +1279 -0
  227. package/.sdk/tm/haskell/src/SdkTypes.hs +195 -0
  228. package/.sdk/tm/haskell/src/VoxgigStruct.hs +2299 -0
  229. package/.sdk/tm/haskell/src/Vregex.hs +237 -0
  230. package/.sdk/tm/haskell/src/feature/README.md +5 -0
  231. package/.sdk/tm/haskell/src/feature/audit/.gitkeep +0 -0
  232. package/.sdk/tm/haskell/src/feature/base/.gitkeep +0 -0
  233. package/.sdk/tm/haskell/src/feature/cache/.gitkeep +0 -0
  234. package/.sdk/tm/haskell/src/feature/clienttrack/.gitkeep +0 -0
  235. package/.sdk/tm/haskell/src/feature/debug/.gitkeep +0 -0
  236. package/.sdk/tm/haskell/src/feature/idempotency/.gitkeep +0 -0
  237. package/.sdk/tm/haskell/src/feature/log/.gitkeep +0 -0
  238. package/.sdk/tm/haskell/src/feature/metrics/.gitkeep +0 -0
  239. package/.sdk/tm/haskell/src/feature/netsim/.gitkeep +0 -0
  240. package/.sdk/tm/haskell/src/feature/paging/.gitkeep +0 -0
  241. package/.sdk/tm/haskell/src/feature/proxy/.gitkeep +0 -0
  242. package/.sdk/tm/haskell/src/feature/ratelimit/.gitkeep +0 -0
  243. package/.sdk/tm/haskell/src/feature/rbac/.gitkeep +0 -0
  244. package/.sdk/tm/haskell/src/feature/retry/.gitkeep +0 -0
  245. package/.sdk/tm/haskell/src/feature/streaming/.gitkeep +0 -0
  246. package/.sdk/tm/haskell/src/feature/telemetry/.gitkeep +0 -0
  247. package/.sdk/tm/haskell/src/feature/test/.gitkeep +0 -0
  248. package/.sdk/tm/haskell/src/feature/timeout/.gitkeep +0 -0
  249. package/.sdk/tm/haskell/test/Harness.hs +281 -0
  250. package/.sdk/tm/haskell/test/OmniResolver.hs +252 -0
  251. package/.sdk/tm/haskell/test/Runner.hs +49 -0
  252. package/.sdk/tm/haskell/test/StructCorpus.hs +449 -0
  253. package/.sdk/tm/haskell/test/TCustomUtility.hs +38 -0
  254. package/.sdk/tm/haskell/test/TFeature.hs +794 -0
  255. package/.sdk/tm/haskell/test/TNetsim.hs +50 -0
  256. package/.sdk/tm/haskell/test/TPipeline.hs +334 -0
  257. package/.sdk/tm/haskell/test/TPrimaryCorpus.hs +263 -0
  258. package/.sdk/tm/haskell/test/TPrimaryUtility.hs +386 -0
  259. package/.sdk/tm/haskell/test/Testutil.hs +59 -0
  260. package/.sdk/tm/haskell/test/vendor/omni/Omni.hs +1147 -0
  261. package/.sdk/tm/lean/LICENSE +21 -0
  262. package/.sdk/tm/lean/Makefile +32 -0
  263. package/.sdk/tm/lean/VERSION +1 -0
  264. package/.sdk/tm/lean/src/SdkFeature.lean +171 -0
  265. package/.sdk/tm/lean/src/SdkFeatures.lean +787 -0
  266. package/.sdk/tm/lean/src/SdkJson.lean +134 -0
  267. package/.sdk/tm/lean/src/SdkRuntime.lean +374 -0
  268. package/.sdk/tm/lean/src/SdkUtility.lean +809 -0
  269. package/.sdk/tm/lean/src/VoxgigStruct.lean +2880 -0
  270. package/.sdk/tm/lean/src/Vregex.lean +412 -0
  271. package/.sdk/tm/lean/src/feature/README.md +5 -0
  272. package/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
  273. package/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
  274. package/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
  275. package/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
  276. package/.sdk/tm/lean/src/feature/cost/.gitkeep +0 -0
  277. package/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
  278. package/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
  279. package/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
  280. package/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
  281. package/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
  282. package/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
  283. package/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
  284. package/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
  285. package/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
  286. package/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
  287. package/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
  288. package/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
  289. package/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
  290. package/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
  291. package/.sdk/tm/lean/test/OmniResolver.lean +358 -0
  292. package/.sdk/tm/lean/test/OmniSmoke.lean +174 -0
  293. package/.sdk/tm/lean/test/StructCorpus.lean +368 -0
  294. package/.sdk/tm/lean/test/TFeature.lean +281 -0
  295. package/.sdk/tm/lean/test/TPrimaryUtility.lean +227 -0
  296. package/.sdk/tm/lean/test/vendor/omni/Omni.lean +997 -0
  297. package/LICENSE +21 -0
  298. package/README.md +104 -0
  299. package/package.json +78 -0
  300. package/sdkgen-package.json +22 -0
@@ -0,0 +1,997 @@
1
+ -- VENDORED: @voxgig/omni sdk-20260908-1556-0 (lean/Omni.lean)
2
+ -- Source: https://github.com/voxgig/omni @ 274708cc2d12b21707d975543953f845f8444be0 [tag: sdk-20260908-1556-0]
3
+ -- License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
4
+ /-
5
+ Omni: the shared multi-language test runner (Lean 4 port).
6
+
7
+ A test spec is plain JSON. The same spec file drives the same tests in
8
+ every language that ships an omni port.
9
+
10
+ Port of the canonical TypeScript implementation
11
+ (typescript/src/Runner.ts). Behaviour must match, case for case.
12
+
13
+ Lean has no exceptions in pure code, so a subject reports failure as
14
+ `Except.error message`, and a failing check is returned the same way.
15
+ -/
16
+
17
+ import Lean.Data.Json
18
+
19
+ open Lean
20
+
21
+ namespace Omni
22
+
23
+ /-- Value is JSON null. -/
24
+ def nullmark : String := "__NULL__"
25
+ /-- Value is not present. -/
26
+ def undefmark : String := "__UNDEF__"
27
+ /-- Value exists (not undefined). -/
28
+ def existsmark : String := "__EXISTS__"
29
+
30
+ /-- A JSON value, or absence. `none` is the marker for "no value at all",
31
+ as distinct from `some Json.null`.
32
+
33
+ `Lean.Json` stores objects in a SORTED tree, so key order is not preserved:
34
+ a spec whose maps are written out of key order reaches a consumer reordered.
35
+ Every map in voxgig/struct's corpus happens to be key-sorted, so nothing
36
+ notices today - but a consumer whose own maps are insertion-ordered (most
37
+ are) cannot rely on that. omni-swift carried the same defect and its value
38
+ model was its own to change (#32); this one is Lean's. -/
39
+ abbrev Val := Option Json
40
+
41
+ def ismap (val : Val) : Bool :=
42
+ match val with
43
+ | some (.obj _) => true
44
+ | _ => false
45
+
46
+ def islist (val : Val) : Bool :=
47
+ match val with
48
+ | some (.arr _) => true
49
+ | _ => false
50
+
51
+ def isnode (val : Val) : Bool := ismap val || islist val
52
+
53
+ def isabsent (val : Val) : Bool := val.isNone
54
+
55
+ def isnull (val : Val) : Bool :=
56
+ match val with
57
+ | some .null => true
58
+ | _ => false
59
+
60
+ def isnone (val : Val) : Bool := isabsent val || isnull val
61
+
62
+ def isnum (val : Val) : Bool :=
63
+ match val with
64
+ | some (.num _) => true
65
+ | _ => false
66
+
67
+ def isstr (val : Val) : Bool :=
68
+ match val with
69
+ | some (.str _) => true
70
+ | _ => false
71
+
72
+ def asnum (val : Val) : Option Float :=
73
+ match val with
74
+ | some (.num n) => some n.toFloat
75
+ | _ => none
76
+
77
+ def asstr (val : Val) : Option String :=
78
+ match val with
79
+ | some (.str s) => some s
80
+ | _ => none
81
+
82
+ def aslist (val : Val) : Option (Array Json) :=
83
+ match val with
84
+ | some (.arr a) => some a
85
+ | _ => none
86
+
87
+ def asmap (val : Val) : Option (List (String × Json)) :=
88
+ match val with
89
+ | some (.obj kvs) => some (kvs.toArray.map (fun kv => (kv.1, kv.2))).toList
90
+ | _ => none
91
+
92
+ /-- Read a map entry. Returns `none` (absent) when missing.
93
+
94
+ `getObjVal?` rather than reaching into the `.obj` payload directly: the
95
+ container behind it is Lean's own business and it has already changed once
96
+ (`RBNode` through v4.16, `Std.TreeMap.Raw` by v4.32), taking `find`'s
97
+ signature with it. A consumer pinned to a newer toolchain than this one -
98
+ struct/lean is on v4.32 - could not compile the runner at all. -/
99
+ def jget (val : Val) (key : String) : Val :=
100
+ match val with
101
+ | some json => (json.getObjVal? key).toOption
102
+ | _ => none
103
+
104
+ /-- Is a map key present at all (even with a null value)? -/
105
+ def jhas (val : Val) (key : String) : Bool := (jget val key).isSome
106
+
107
+ /-- A copy of a map with one entry set (no-op for non-maps). -/
108
+ def jset (val : Json) (key : String) (entry : Json) : Json :=
109
+ match val with
110
+ | .obj _ => val.setObjVal! key entry
111
+ | other => other
112
+
113
+ def jnum (val : Int) : Json := Json.num (JsonNumber.fromInt val)
114
+ def jstr (val : String) : Json := Json.str val
115
+ def jbool (val : Bool) : Json := Json.bool val
116
+ def jlist (entries : List Json) : Json := Json.arr entries.toArray
117
+ def jmap (entries : List (String × Json)) : Json := Json.mkObj entries
118
+
119
+ /-- Render a number the same way in every port: 5.0 prints as 5. -/
120
+ def numstr (val : Float) : String :=
121
+ if val.isNaN || val.isInf then "null"
122
+ else
123
+ -- Lean prints a Float as "5.000000"; trim to the shortest exact form,
124
+ -- so that 5.0 renders as 5 in every port.
125
+ let text := toString val
126
+ if text.contains '.' then
127
+ let trimmed := text.dropRightWhile (· == '0')
128
+ if trimmed.endsWith "." then trimmed.dropRight 1 else trimmed
129
+ else text
130
+
131
+ /-- Render a string as a JSON string literal. -/
132
+ def quote (val : String) : String :=
133
+ let escape (ch : Char) : String :=
134
+ if ch == '"' then "\\\""
135
+ else if ch == '\\' then "\\\\"
136
+ else if ch == '\n' then "\\n"
137
+ else if ch == '\r' then "\\r"
138
+ else if ch == '\t' then "\\t"
139
+ else if ch.toNat < 0x20 then "\\u00" ++ (Nat.toDigits 16 ch.toNat).asString
140
+ else ch.toString
141
+ "\"" ++ (val.toList.map escape |> String.join) ++ "\""
142
+
143
+ /-- Compact JSON text with map keys sorted, identical in every port. -/
144
+ partial def jsonstr (val : Val) : String :=
145
+ match val with
146
+ | none => "undefined"
147
+ | some .null => "null"
148
+ | some (.bool flag) => if flag then "true" else "false"
149
+ | some (.num n) => numstr n.toFloat
150
+ | some (.str text) => quote text
151
+ | some (.arr entries) =>
152
+ "[" ++ String.intercalate "," (entries.toList.map (fun e => jsonstr (some e))) ++ "]"
153
+ | some (.obj kvs) =>
154
+ -- Lean's object is key-ordered already, which is what omni wants.
155
+ let pairs := kvs.toArray.toList.map (fun kv => quote kv.1 ++ ":" ++ jsonstr (some kv.2))
156
+ "{" ++ String.intercalate "," pairs ++ "}"
157
+
158
+ /-- Strings verbatim, everything else as compact JSON. -/
159
+ def stringify (val : Val) : String :=
160
+ match asstr val with
161
+ | some text => text
162
+ | none => jsonstr val
163
+
164
+ /-- Render a path as a dotted string. -/
165
+ def pathify (path : List String) : String := String.intercalate "." path
166
+
167
+ /-- Deep copy a JSON value (Lean values are immutable). -/
168
+ def clone (val : Val) : Val := val
169
+
170
+ /-- Deep structural equality: numbers by value, bools never numbers. -/
171
+ partial def deepequal (a b : Val) : Bool :=
172
+ match a, b with
173
+ | none, none => true
174
+ | some x, some y =>
175
+ match x, y with
176
+ | .null, .null => true
177
+ | .bool p, .bool q => p == q
178
+ | .num p, .num q => p.toFloat == q.toFloat
179
+ | .str p, .str q => p == q
180
+ | .arr p, .arr q =>
181
+ p.size == q.size &&
182
+ (List.range p.size).all (fun index => deepequal (some p[index]!) (some q[index]!))
183
+ | .obj p, .obj q =>
184
+ let pl := p.toArray.toList
185
+ let ql := q.toArray.toList
186
+ pl.length == ql.length &&
187
+ pl.all (fun kv =>
188
+ match (Json.obj q).getObjVal? kv.1 with
189
+ | .ok other => deepequal (some kv.2) (some other)
190
+ | .error _ => false)
191
+ | _, _ => false
192
+ | _, _ => false
193
+
194
+ /-- Read a value by path. Returns `none` (absent) when a step is missing. -/
195
+ def getpath (val : Val) (path : List String) : Val :=
196
+ path.foldl
197
+ (fun current part =>
198
+ match current with
199
+ | some (.arr entries) =>
200
+ match part.toNat? with
201
+ | some index => if index < entries.size then some entries[index]! else none
202
+ | none => none
203
+ | some (.obj _) => jget current part
204
+ | _ => none)
205
+ val
206
+
207
+ /-- Depth-first walk: children first, then the containing node. -/
208
+ partial def walk (val : Json) (apply : Json → List String → Json)
209
+ (path : List String := []) : Json :=
210
+ let next :=
211
+ match val with
212
+ | .arr entries =>
213
+ Json.arr (entries.mapIdx (fun index entry => walk entry apply (path ++ [toString index])))
214
+ | .obj kvs =>
215
+ Json.mkObj (kvs.toArray.toList.map (fun kv => (kv.1, walk kv.2 apply (path ++ [kv.1]))))
216
+ | other => other
217
+ apply next path
218
+
219
+ /-- Nulls (and absent values) become NULLMARK. Always a fresh copy. -/
220
+ partial def fixjson (val : Val) (donull : Bool) : Val :=
221
+ if isnone val then
222
+ -- Canonical returns the value UNCHANGED when donull is false
223
+ -- (typescript/src/Runner.ts): absent stays absent and null stays null.
224
+ -- Answering `Json.null` for both collapsed two states the corpus
225
+ -- distinguishes - and the old return type, `Json`, could not say
226
+ -- "absent" at all. Same defect the other ports carried (#17, #23, #25,
227
+ -- #26, #27, #28, #32).
228
+ (if donull then some (jstr nullmark) else val)
229
+ else
230
+ match val with
231
+ | some (.arr entries) =>
232
+ some (Json.arr (entries.map (fun entry => (fixjson (some entry) donull).getD Json.null)))
233
+ | some (.obj kvs) =>
234
+ some (Json.mkObj (kvs.toArray.toList.map
235
+ (fun kv => (kv.1, (fixjson (some kv.2) donull).getD Json.null))))
236
+ | some other => some other
237
+ | none => none
238
+
239
+ /-- The JSON form of an error: always at least {name,message}. -/
240
+ def errify (message : String) : Json :=
241
+ jmap [("name", jstr "Error"), ("message", jstr message)]
242
+
243
+ /- ---- regex engine --------------------------------------------------
244
+
245
+ Omni specs match error messages with `/pattern/` expectations, so every
246
+ port needs a regex. Lean has none in its standard library, so omni carries
247
+ this engine, a direct port of the Rust one (rust/src/regex.rs). -/
248
+
249
+ inductive ClassItem : Type where
250
+ | char (ch : Char)
251
+ | range (low high : Char)
252
+ | digit (invert : Bool)
253
+ | word (invert : Bool)
254
+ | space (invert : Bool)
255
+
256
+ inductive Node : Type where
257
+ | char (ch : Char)
258
+ | any
259
+ | cls (items : List ClassItem) (negated : Bool)
260
+ | start
261
+ | stop
262
+ | seq (nodes : List Node)
263
+ | alt (branches : List Node)
264
+ | repeat (inner : Node) (min : Nat) (max : Option Nat) (greedy : Bool)
265
+
266
+ instance : Inhabited Node := ⟨.any⟩
267
+ instance : Inhabited ClassItem := ⟨.char 'x'⟩
268
+
269
+ private def escapeNode (escape : Char) : Node :=
270
+ match escape with
271
+ | 'd' => Node.cls [ClassItem.digit false] false
272
+ | 'D' => Node.cls [ClassItem.digit false] true
273
+ | 'w' => Node.cls [ClassItem.word false] false
274
+ | 'W' => Node.cls [ClassItem.word false] true
275
+ | 's' => Node.cls [ClassItem.space false] false
276
+ | 'S' => Node.cls [ClassItem.space false] true
277
+ | 'n' => Node.char '\n'
278
+ | 'r' => Node.char '\r'
279
+ | 't' => Node.char '\t'
280
+ | other => Node.char other
281
+
282
+ private partial def parseClass (chars : List Char) : Option (Node × List Char) :=
283
+ let (negated, rest) :=
284
+ match chars with
285
+ | '^' :: more => (true, more)
286
+ | _ => (false, chars)
287
+ let rec collect (acc : List ClassItem) (first : Bool) (left : List Char)
288
+ : Option (Node × List Char) :=
289
+ match left with
290
+ | [] => none
291
+ | ']' :: more => if first then collect (ClassItem.char ']' :: acc) false more
292
+ else some (Node.cls acc.reverse negated, more)
293
+ | '\\' :: escape :: more =>
294
+ let item :=
295
+ match escape with
296
+ | 'd' => ClassItem.digit false
297
+ | 'w' => ClassItem.word false
298
+ | 's' => ClassItem.space false
299
+ | 'n' => ClassItem.char '\n'
300
+ | 'r' => ClassItem.char '\r'
301
+ | 't' => ClassItem.char '\t'
302
+ | other => ClassItem.char other
303
+ collect (item :: acc) false more
304
+ | low :: '-' :: high :: more =>
305
+ if high == ']' then collect (ClassItem.char low :: acc) false ('-' :: high :: more)
306
+ else collect (ClassItem.range low high :: acc) false more
307
+ | ch :: more => collect (ClassItem.char ch :: acc) false more
308
+ collect [] true rest
309
+
310
+ private partial def parseCount (chars : List Char) : Option (Nat × Option Nat × List Char) :=
311
+ let digits := chars.takeWhile Char.isDigit
312
+ let rest := chars.dropWhile Char.isDigit
313
+ if digits.isEmpty then none
314
+ else
315
+ let low := digits.asString.toNat!
316
+ match rest with
317
+ | '}' :: more => some (low, some low, more)
318
+ | ',' :: more =>
319
+ let highdigits := more.takeWhile Char.isDigit
320
+ let afterhigh := more.dropWhile Char.isDigit
321
+ match afterhigh with
322
+ | '}' :: final =>
323
+ some (low, (if highdigits.isEmpty then none else some highdigits.asString.toNat!), final)
324
+ | _ => none
325
+ | _ => none
326
+
327
+ mutual
328
+
329
+ private partial def parseAlt (chars : List Char) : Option (Node × List Char) := do
330
+ let (first, rest) ← parseSeq chars
331
+ let rec branches (acc : List Node) (left : List Char) : Option (Node × List Char) :=
332
+ match left with
333
+ | '|' :: more => do
334
+ let (branch, rest) ← parseSeq more
335
+ branches (branch :: acc) rest
336
+ | _ => some (if acc.length == 1 then acc.head! else .alt acc.reverse, left)
337
+ branches [first] rest
338
+
339
+ private partial def parseSeq (chars : List Char) : Option (Node × List Char) :=
340
+ let rec collect (acc : List Node) (left : List Char) : Option (Node × List Char) :=
341
+ match left with
342
+ | [] => some (.seq acc.reverse, [])
343
+ | '|' :: _ => some (.seq acc.reverse, left)
344
+ | ')' :: _ => some (.seq acc.reverse, left)
345
+ | _ => do
346
+ let (atom, rest) ← parseAtom left
347
+ let (node, more) ← parseRepeat atom rest
348
+ collect (node :: acc) more
349
+ collect [] chars
350
+
351
+ private partial def parseRepeat (atom : Node) (chars : List Char) : Option (Node × List Char) :=
352
+ let build (min : Nat) (max : Option Nat) (rest : List Char) : Option (Node × List Char) :=
353
+ match rest with
354
+ | '?' :: more => some (.repeat atom min max false, more)
355
+ | _ => some (.repeat atom min max true, rest)
356
+ match chars with
357
+ | '*' :: rest => build 0 none rest
358
+ | '+' :: rest => build 1 none rest
359
+ | '?' :: rest => build 0 (some 1) rest
360
+ | '{' :: rest =>
361
+ match parseCount rest with
362
+ | some (min, max, more) => build min max more
363
+ | none => some (atom, chars)
364
+ | _ => some (atom, chars)
365
+
366
+ private partial def parseAtom (chars : List Char) : Option (Node × List Char) :=
367
+ match chars with
368
+ | [] => none
369
+ | '(' :: rest => do
370
+ let inner := match rest with
371
+ | '?' :: ':' :: more => more
372
+ | _ => rest
373
+ let (node, more) ← parseAlt inner
374
+ match more with
375
+ | ')' :: final => some (node, final)
376
+ | _ => none
377
+ | '[' :: rest => parseClass rest
378
+ | '.' :: rest => some (.any, rest)
379
+ | '^' :: rest => some (.start, rest)
380
+ | '$' :: rest => some (.stop, rest)
381
+ | '\\' :: escape :: rest => some (escapeNode escape, rest)
382
+ | ch :: rest => some (.char ch, rest)
383
+
384
+ end
385
+
386
+ private def isWordChar (ch : Char) : Bool := ch.isAlphanum || ch == '_'
387
+
388
+ private def classMatch (items : List ClassItem) (negated : Bool) (ch : Char) : Bool :=
389
+ let hit := items.any fun item =>
390
+ match item with
391
+ | .char want => ch == want
392
+ | .range low high => low ≤ ch && ch ≤ high
393
+ | .digit invert => ch.isDigit != invert
394
+ | .word invert => isWordChar ch != invert
395
+ | .space invert => ch.isWhitespace != invert
396
+ hit != negated
397
+
398
+ mutual
399
+
400
+ private partial def matchNode (node : Node) (text : Array Char) (pos : Nat)
401
+ (cont : Nat → Bool) : Bool :=
402
+ match node with
403
+ | .char want => pos < text.size && text[pos]! == want && cont (pos + 1)
404
+ | .any => pos < text.size && cont (pos + 1)
405
+ | .cls items negated =>
406
+ pos < text.size && classMatch items negated text[pos]! && cont (pos + 1)
407
+ | .start => pos == 0 && cont pos
408
+ | .stop => pos == text.size && cont pos
409
+ | .seq nodes => matchSeq nodes text pos cont
410
+ | .alt branches => branches.any (fun branch => matchNode branch text pos cont)
411
+ | .repeat inner min max greedy => matchRepeat inner min max greedy 0 text pos cont
412
+
413
+ private partial def matchSeq (nodes : List Node) (text : Array Char) (pos : Nat)
414
+ (cont : Nat → Bool) : Bool :=
415
+ match nodes with
416
+ | [] => cont pos
417
+ | head :: rest => matchNode head text pos (fun next => matchSeq rest text next cont)
418
+
419
+ private partial def matchRepeat (inner : Node) (min : Nat) (max : Option Nat) (greedy : Bool)
420
+ (count : Nat) (text : Array Char) (pos : Nat) (cont : Nat → Bool) : Bool :=
421
+ let canmore := match max with
422
+ | some limit => count < limit
423
+ | none => true
424
+ let takemore := fun _ =>
425
+ canmore && matchNode inner text pos (fun next =>
426
+ -- A zero-width repeat would loop forever.
427
+ next > pos && matchRepeat inner min max greedy (count + 1) text next cont)
428
+ let stopnow := fun _ => count >= min && cont pos
429
+ if greedy then takemore () || stopnow () else stopnow () || takemore ()
430
+
431
+ end
432
+
433
+ /-- Is the pattern found anywhere in the text? -/
434
+ def regexFind (pattern text : String) : Bool :=
435
+ match parseAlt pattern.toList with
436
+ | some (root, []) =>
437
+ let chars := text.toList.toArray
438
+ (List.range (chars.size + 1)).any (fun start => matchNode root chars start (fun _ => true))
439
+ | _ => false
440
+
441
+ /-- Match one leaf: /regex/ or case-insensitive substring for strings. -/
442
+ def matchval (check base : Val) : Bool :=
443
+ if deepequal check base then true
444
+ else
445
+ let want :=
446
+ match asstr check with
447
+ | some text => if text == undefmark || text == nullmark then none else check
448
+ | none => check
449
+ if isnone want then
450
+ isnone base || asstr base == some nullmark
451
+ else
452
+ match asstr want with
453
+ -- An empty want is not a wildcard: the empty string is a substring of
454
+ -- everything, so `match:{out:""}` (or `err:""`) would accept any value.
455
+ | some "" => asstr base == some ""
456
+ | some text =>
457
+ let basestr := stringify base
458
+ if text.length > 2 && text.startsWith "/" && text.endsWith "/" then
459
+ -- Through the char list rather than `dropRight`: that one is
460
+ -- deprecated by v4.32 and now answers a `String.Slice`, which is a
461
+ -- different type, so a consumer on a newer toolchain cannot build
462
+ -- this. `String.mk` and `List.dropLast` are stable across both.
463
+ regexFind (String.mk (text.toList.drop 1 |>.dropLast)) basestr
464
+ else
465
+ (basestr.toLower.splitOn text.toLower).length > 1
466
+ | none => deepequal want base
467
+
468
+ /-- Convert NULLMARK sentinels back into real nulls. -/
469
+ def nullmodifier (val : Val) : Val :=
470
+ match asstr val with
471
+ | some text =>
472
+ if text == nullmark then some Json.null
473
+ else some (jstr (String.intercalate "null" (text.splitOn nullmark)))
474
+ | none => val
475
+
476
+ /- ---- runner --------------------------------------------------------- -/
477
+
478
+ /-- The newest spec format version this runner understands. A spec with no
479
+ `OMNI` block is version 0: the original, lenient format, frozen forever.
480
+ Version 1 turns on strict entry validation (see `checkentry`). -/
481
+ def SPECVERSION : Nat := 1
482
+
483
+ /-- Capability strings this runner supports beyond the version baseline. A
484
+ spec's `OMNI.requires` list is checked against this: an unknown capability
485
+ refuses the spec loudly at load time, instead of a lagging port silently
486
+ mis-running it. (Empty today; future format features mint a string here.) -/
487
+ def CAPABILITIES : List String := []
488
+
489
+ /-- The complete set of fields an entry may carry. Under version 1 anything
490
+ else is an error: an unrecognised key is almost always a typo'd assertion,
491
+ and a typo'd assertion is a test that silently stopped testing. -/
492
+ private def ENTRYFIELDS : List String :=
493
+ ["in", "args", "ctx", "out", "err", "match", "client", "id", "doc"]
494
+
495
+ -- A capability that is not a string, or not in CAPABILITIES, is one this
496
+ -- runner does not recognise.
497
+ private def unsupportedcap (cap : Json) : Bool :=
498
+ match asstr (some cap) with
499
+ | some capstr => !(CAPABILITIES.contains capstr)
500
+ | none => true
501
+
502
+ /-- The `requires` half of `resolveversion`: a present-but-non-list is
503
+ malformed, and any listed capability this runner does not recognise
504
+ refuses the whole spec. An absent `requires` is fine - it only narrows,
505
+ never widens, what a version already permits. -/
506
+ private def checkrequires (requires : Val) (version : Nat) : Except String Nat :=
507
+ if isabsent requires then
508
+ pure version
509
+ else
510
+ match aslist requires with
511
+ | none => throw "omni: malformed OMNI requires list"
512
+ | some caps =>
513
+ match caps.toList.find? unsupportedcap with
514
+ | some badcap =>
515
+ throw s!"omni: spec requires unsupported capability: {stringify (some badcap)}"
516
+ | none => pure version
517
+
518
+ /-- Read the spec's format version from its optional top-level `OMNI`
519
+ block, and refuse a spec this runner cannot faithfully run: a version
520
+ newer than `SPECVERSION`, or a required capability not in `CAPABILITIES`.
521
+ These are runner refusals, never candidates for an `err` expectation.
522
+
523
+ Only a genuinely absent `OMNI` key is legacy; a present null (or anything
524
+ else that is not a map) is malformed - the presence/definedness
525
+ distinction the sentinel system exists to preserve applies to the
526
+ runner's own validation too. -/
527
+ def resolveversion (alltests : Json) : Except String Nat :=
528
+ -- Not `meta`: that became a reserved token by Lean v4.32, so the binding
529
+ -- fails to parse on a newer toolchain than this file pins.
530
+ let omniblock := jget (some alltests) "OMNI"
531
+ if isabsent omniblock then
532
+ pure 0
533
+ else
534
+ match omniblock with
535
+ | some (.obj _) =>
536
+ match asnum (jget omniblock "version") with
537
+ | some num =>
538
+ if num != num.floor then
539
+ throw "omni: malformed OMNI version block"
540
+ else if num < 0.0 || SPECVERSION.toFloat < num then
541
+ throw s!"omni: unsupported spec version: {numstr num}"
542
+ else
543
+ checkrequires (jget omniblock "requires") num.toUInt64.toNat
544
+ | none => throw "omni: malformed OMNI version block"
545
+ | _ => throw "omni: malformed OMNI version block"
546
+
547
+ /-- The function under test. Arguments arrive as `Val` - JSON values, or
548
+ absence - and failure is reported as `Except.error message`.
549
+
550
+ `Val`, not `Json`, on both sides. An entry that supplies no `in` means the
551
+ subject is called with NO argument, which the corpus distinguishes from one
552
+ called with null: struct's `minor/typify` has both `{in: null}` and `{}`
553
+ (register 4.12). And a subject that legitimately returns nothing needs to be
554
+ able to say so under `{null: false}`. -/
555
+ abbrev Subject : Type := List Val → Except String Val
556
+
557
+ /-- A subject that may REPLACE its arguments, which `match.args` can then
558
+ assert on. `minor/setpath` is the case in point: eight of its nine entries
559
+ assert that the store was rewritten in place, and `merge/integrity` all six.
560
+
561
+ Lean is pure, so a consumer's nodes are its own - struct/lean keeps them in a
562
+ heap threaded through `SIO` - and nothing it does is visible through this
563
+ runner's argument list. Returning the arguments alongside the result is the
564
+ only channel there is.
565
+
566
+ Separate from `Subject` rather than replacing it: a signature change would
567
+ break every consumer for a capability most subjects do not need. omni-rust,
568
+ -cpp, -ocaml, -elixir, -haskell, -clojure, -scala and -swift carry the same
569
+ pair, for the same reason. -/
570
+ abbrev SubjectArgs : Type := List Val → Except String (List Val × Val)
571
+
572
+ /-- Run-time options for a set of test entries. -/
573
+ structure Flags where
574
+ null : Bool := true
575
+ name : Option String := none
576
+
577
+ def Flags.nonull : Flags := { null := false }
578
+
579
+ /-- The host of the system under test. Every hook is optional.
580
+
581
+ A provider is recursive (a client hook yields another provider), so it is
582
+ an inductive rather than a structure. -/
583
+ inductive Provider : Type where
584
+ | mk (subject : Option (String → Option Subject))
585
+ (client : Option (Json → Provider))
586
+ (contextify : Option (Json → Json))
587
+ -- Build the `match.err` base from the failure, REPLACING `errify`.
588
+ --
589
+ -- Lean reaches this point with a message and nothing else, so a
590
+ -- library whose errors carry a code has no other way to put one in
591
+ -- the base. The hook receives that message and returns the base,
592
+ -- letting a spec assert `match: {err: {code: "x"}}` instead of
593
+ -- pattern-matching prose.
594
+ (errify : Option (String → Json))
595
+
596
+ def Provider.subject : Provider → Option (String → Option Subject)
597
+ | .mk found _ _ _ => found
598
+
599
+ def Provider.client : Provider → Option (Json → Provider)
600
+ | .mk _ found _ _ => found
601
+
602
+ def Provider.contextify : Provider → Option (Json → Json)
603
+ | .mk _ _ found _ => found
604
+
605
+ def Provider.errify : Provider → Option (String → Json)
606
+ | .mk _ _ _ found => found
607
+
608
+ /-- Build a provider from the hooks a host supplies. -/
609
+ def provider (subject : Option (String → Option Subject) := none)
610
+ (client : Option (Json → Provider) := none)
611
+ (contextify : Option (Json → Json) := none)
612
+ (errify : Option (String → Json) := none) : Provider :=
613
+ .mk subject client contextify errify
614
+
615
+ /-- A provider with no hooks. -/
616
+ def emptyProvider : Provider := provider
617
+
618
+ instance : Inhabited Provider := ⟨emptyProvider⟩
619
+
620
+ /-- Find `primary.<name>`, then `<name>`, then the whole spec. -/
621
+ def resolvespec (name : String) (alltests : Json) : Json :=
622
+ if name.isEmpty then alltests
623
+ else
624
+ match jget (jget (some alltests) "primary") name with
625
+ | some found => found
626
+ | none =>
627
+ match jget (some alltests) name with
628
+ | some found => found
629
+ | none => alltests
630
+
631
+ -- The spec-defined part of an entry (drop runner bookkeeping).
632
+ private def entrysummary (entry : Json) : Json :=
633
+ match entry with
634
+ | .obj kvs =>
635
+ Json.mkObj ((kvs.toArray.toList.map (fun kv => (kv.1, kv.2))).filter
636
+ (fun kv => kv.1 != "res" && kv.1 != "thrown" && kv.1 != "ctx"))
637
+ | other => other
638
+
639
+ -- The label of one entry, for failure messages.
640
+ private def entryref (label : String) (index : Nat) (entry : Json) : String :=
641
+ let id := jget (some entry) "id"
642
+ let idpart := if isabsent id then "" else s! " ({stringify id})"
643
+ s!"{label}[{index}]{idpart}"
644
+
645
+ private def failure (label : String) (index : Nat) (entry : Json) (reason : String)
646
+ (expected actual : Option String) : String :=
647
+ let head := s!"omni: {entryref label index entry}: {reason}"
648
+ let head := match expected with
649
+ | some text => head ++ s!"\n expected: {text}"
650
+ | none => head
651
+ let head := match actual with
652
+ | some text => head ++ s!"\n actual: {text}"
653
+ | none => head
654
+ head ++ s!"\n entry: {stringify (some (entrysummary entry))}"
655
+
656
+ -- Strict entry validation, applied when the spec declares version 1 or
657
+ -- later. The lenient format converts each of these mistakes into a silent
658
+ -- pass or a dead field; here they fail with the entry named.
659
+ private def checkentry (label : String) (index : Nat) (entry : Json) : Except String Unit := do
660
+ if !ismap (some entry) then
661
+ throw (failure label index entry "entry is not a map" none none)
662
+
663
+ let entrykeys := (asmap (some entry)).getD []
664
+ match entrykeys.find? (fun kv => !(ENTRYFIELDS.contains kv.1)) with
665
+ | some badkv => throw (failure label index entry s!"unknown entry field: {badkv.1}" none none)
666
+ | none => pure ()
667
+
668
+ let argsources := (["in", "args", "ctx"].filter (fun key => jhas (some entry) key)).length
669
+ if 1 < argsources then
670
+ throw (failure label index entry "entry has more than one of in, args, ctx" none none)
671
+
672
+ -- `err` must be present AND non-null; `out` only needs to be present -
673
+ -- an authored `out: null` still collides with an `err` expectation.
674
+ let errpresent := !isnone (jget (some entry) "err")
675
+ let outpresent := jhas (some entry) "out"
676
+ if errpresent && outpresent then
677
+ throw (failure label index entry "entry has both err and out" none none)
678
+
679
+ let idval := jget (some entry) "id"
680
+ if !isabsent idval && (asstr idval).isNone then
681
+ throw (failure label index entry "entry id is not a string" none none)
682
+ else
683
+ pure ()
684
+
685
+ -- Validate a version-1 group up front, against the AUTHORED entries -
686
+ -- null-normalisation would otherwise rewrite an authored null (e.g.
687
+ -- `id: null`) into a sentinel string and hide it from validation. A
688
+ -- malformed spec is a spec error, not a test result, so it fails before
689
+ -- any subject runs.
690
+ private def checkset (label : String) (testspec : Json) (normalset : Array Json)
691
+ : Except String Unit := do
692
+ let origset :=
693
+ match aslist (jget (some testspec) "set") with
694
+ | some entries => entries
695
+ | none => normalset
696
+
697
+ let emptyflag := match jget (some testspec) "empty" with
698
+ | some (.bool true) => true
699
+ | _ => false
700
+
701
+ if origset.size == 0 && !emptyflag then
702
+ throw s!"omni: empty test set: {label}"
703
+
704
+ for index in List.range origset.size do
705
+ checkentry label index origset[index]!
706
+
707
+ -- Check that every leaf of `check` is present, and matches, in `base`.
708
+ private partial def matchcheck (label : String) (index : Nat) (entry check base : Json)
709
+ (path : List String) : Except String Unit := do
710
+ let place := if path.isEmpty then "<root>" else pathify path
711
+ match check with
712
+ | .arr entries =>
713
+ for idx in List.range entries.size do
714
+ matchcheck label index entry entries[idx]! base (path ++ [toString idx])
715
+ | .obj kvs =>
716
+ for kv in kvs.toArray.toList do
717
+ matchcheck label index entry kv.2 base (path ++ [kv.1])
718
+ | leaf =>
719
+ let baseval := getpath (some base) path
720
+ let leafval := some leaf
721
+ -- The sentinels are tested BEFORE the identity check below. Otherwise
722
+ -- a subject returning the literal string "__UNDEF__" satisfies an
723
+ -- assertion that the key is absent - two mutually exclusive states
724
+ -- passing one check. A sentinel that accepts its own literal is not a
725
+ -- sentinel. (NULLMARK still accepts NULLMARK: under the default null
726
+ -- flag a real null has already been normalised to it, so the two are
727
+ -- genuinely indistinguishable here - that one needs a raw-value
728
+ -- escape, not an ordering change.)
729
+ -- Explicitly absent: satisfied only by a genuinely missing key, never
730
+ -- by a present null (the distinction the sentinels exist to keep).
731
+ if asstr leafval == some undefmark then
732
+ if isabsent baseval then pure ()
733
+ else throw (failure label index entry s!"expected absent at {place}"
734
+ (some "absent") (some (stringify baseval)))
735
+ -- Explicitly null: satisfied only by a present null.
736
+ else if asstr leafval == some nullmark then
737
+ if isnull baseval || asstr baseval == some nullmark then pure ()
738
+ else throw (failure label index entry s!"expected null at {place}"
739
+ (some "null") (some (stringify baseval)))
740
+ -- Explicitly present: any present value, including null.
741
+ else if asstr leafval == some existsmark then
742
+ if !isabsent baseval then pure ()
743
+ else throw (failure label index entry s!"expected present at {place}"
744
+ (some "present") (some "absent"))
745
+ -- Identical values match. This sits below the sentinel branches on
746
+ -- purpose - see the note above.
747
+ else if deepequal leafval baseval then
748
+ pure ()
749
+ -- A concrete expectation never matches a missing key - a match leaf
750
+ -- against an absent value must fail, not substring-match "undefined".
751
+ else if isabsent baseval then
752
+ throw (failure label index entry s!"match failed at {place}"
753
+ (some (stringify leafval)) (some "absent"))
754
+ else if matchval leafval baseval then
755
+ pure ()
756
+ else
757
+ throw (failure label index entry s!"match failed at {place}"
758
+ (some (stringify leafval)) (some (stringify baseval)))
759
+
760
+ private def checkresult (label : String) (index : Nat) (entry : Json) (args : List Val)
761
+ (res : Val) : Except String Unit := do
762
+ let entryerr := jget (some entry) "err"
763
+
764
+ if !isnone entryerr then
765
+ throw (failure label index entry "expected error did not occur"
766
+ (some (stringify entryerr)) (some (stringify res)))
767
+
768
+ let check := jget (some entry) "match"
769
+ let matched := !isnone check
770
+
771
+ if let some checkval := check then
772
+ let base := jmap [
773
+ ("in", (jget (some entry) "in").getD Json.null),
774
+ -- A match block reads arguments as JSON, and an absent one renders as
775
+ -- null there the way canonical's JSON round-trip does.
776
+ ("args", jlist (args.map (fun arg => arg.getD Json.null))),
777
+ ("out", (jget (some entry) "res").getD Json.null),
778
+ ("ctx", (jget (some entry) "ctx").getD Json.null)]
779
+ matchcheck label index entry checkval base []
780
+
781
+ let out := jget (some entry) "out"
782
+
783
+ if deepequal res out then
784
+ pure ()
785
+ -- NOTE: a match with no explicit out is a complete check on its own.
786
+ else if matched && (isnone out || asstr out == some nullmark) then
787
+ pure ()
788
+ else
789
+ throw (failure label index entry "result mismatch"
790
+ (some (stringify out)) (some (stringify res)))
791
+
792
+ /-- The error base a `match.err` sees: the provider's own, when it has one. -/
793
+ def errbase (message : String) (prov : Provider) : Json :=
794
+ match prov.errify with
795
+ | some hook => hook message
796
+ | none => errify message
797
+
798
+ private def handleerror (label : String) (index : Nat) (entry : Json) (message : String)
799
+ (prov : Provider) : Except String Unit := do
800
+ let entryerr := jget (some entry) "err"
801
+
802
+ if isnone entryerr then
803
+ throw (failure label index entry "unexpected error" none (some message))
804
+
805
+ let istrue := match entryerr with
806
+ | some (.bool true) => true
807
+ | _ => false
808
+
809
+ if istrue || matchval entryerr (some (jstr message)) then
810
+ if let some checkval := jget (some entry) "match" then
811
+ let base := jmap [
812
+ ("in", (jget (some entry) "in").getD Json.null),
813
+ ("out", (jget (some entry) "res").getD Json.null),
814
+ ("ctx", (jget (some entry) "ctx").getD Json.null),
815
+ ("err", errbase message prov)]
816
+ matchcheck label index entry checkval base []
817
+ pure ()
818
+ else
819
+ throw (failure label index entry "error mismatch"
820
+ (some (stringify entryerr)) (some message))
821
+
822
+ /-- What a runner returns for one named spec section. -/
823
+ structure RunPack where
824
+ spec : Json
825
+ subject : Option Subject
826
+ client : Provider
827
+ clients : List (String × Provider)
828
+ name : String
829
+ -- The spec's resolved format version (see `resolveversion`). 0 for a
830
+ -- legacy spec with no `OMNI` block, in which case strict validation
831
+ -- (`checkset`/`checkentry`) never runs.
832
+ specversion : Nat
833
+
834
+ /-- A named group of the resolved spec. -/
835
+ def RunPack.set (pack : RunPack) (setname : String) : Json :=
836
+ (jget (some pack.spec) setname).getD Json.null
837
+
838
+ /-- Run one set of test entries with flags, for a subject that may replace
839
+ its arguments. See `SubjectArgs`. -/
840
+ partial def RunPack.drive (pack : RunPack) (testspec : Json) (flags : Flags)
841
+ (testsubject : Option Subject) (argsubject : Option SubjectArgs)
842
+ : Except String Unit := do
843
+ let label := flags.name.getD (if pack.name.isEmpty then "set" else pack.name)
844
+
845
+ let usesubject ← match argsubject with
846
+ | some _ => pure none
847
+ | none =>
848
+ match testsubject.orElse (fun _ => pack.subject) with
849
+ | some found => pure (some found)
850
+ | none => throw s!"omni: no test subject for: {label}"
851
+
852
+ let testspecmap := fixjson (some testspec) flags.null
853
+
854
+ let testset ← match aslist (jget testspecmap "set") with
855
+ | some entries => pure entries
856
+ | none => throw s!"omni: test spec has no set: {label}"
857
+
858
+ -- Validate the AUTHORED group (testspec, not testspecmap) once, before
859
+ -- any subject runs - see checkset for why this must read the
860
+ -- pre-normalisation entries.
861
+ if 1 <= pack.specversion then
862
+ checkset label testspec testset
863
+
864
+ for index in List.range testset.size do
865
+ let rawentry := testset[index]!
866
+
867
+ if !ismap (some rawentry) then
868
+ throw s!"omni: {label}[{index}]: entry is not a map"
869
+
870
+ -- An entry with no `out` expects a null (or absent) result.
871
+ let entry :=
872
+ if flags.null && isnone (jget (some rawentry) "out") then
873
+ jset rawentry "out" (jstr nullmark)
874
+ else rawentry
875
+
876
+ let entrysubject ←
877
+ match usesubject, asstr (jget (some entry) "client") with
878
+ | none, _ => pure none
879
+ | some found, some clientname =>
880
+ match pack.clients.lookup clientname with
881
+ | none => throw s!"omni: unknown client: {clientname}"
882
+ | some client =>
883
+ match client.subject with
884
+ | some resolve => pure (some ((resolve pack.name).getD found))
885
+ | none => pure (some found)
886
+ | some found, none => pure (some found)
887
+
888
+ -- Build the argument list: `ctx`, `args`, or `in`.
889
+ let hasctx := jhas (some entry) "ctx"
890
+ let hasargs := jhas (some entry) "args"
891
+
892
+ -- `Val`, so an entry with no `in` reaches the subject as ABSENT rather
893
+ -- than as null - the distinction `minor/typify` asserts (register 4.12).
894
+ let args0 : List Val :=
895
+ if hasctx then [jget (some entry) "ctx"]
896
+ else if hasargs then
897
+ match aslist (jget (some entry) "args") with
898
+ | some list => list.toList.map some
899
+ | none => [jget (some entry) "args"]
900
+ else [jget (some entry) "in"]
901
+
902
+ let (args, entry) :=
903
+ if (hasctx || hasargs) && !args0.isEmpty && ismap args0.head! then
904
+ let head := args0.head!.getD Json.null
905
+ let contextified := match pack.client.contextify with
906
+ | some contextify => contextify head
907
+ | none => head
908
+ -- Canonical attaches the resolved client onto ctx/args[0]
909
+ -- (testpack.client) so a context subject can tell it was invoked
910
+ -- through one. Json has no case for a live Provider reference,
911
+ -- and the resolved client is never absent (it defaults to the
912
+ -- root provider), so a boolean marker carries the same
913
+ -- observable meaning the corpus checks for - presence, never
914
+ -- identity.
915
+ let first := jset contextified "client" (jbool true)
916
+ (some first :: args0.tail!, jset entry "ctx" first)
917
+ else (args0, entry)
918
+
919
+ -- An args-subject returns its arguments alongside the result, so
920
+ -- `match.args` sees what the subject actually did with them.
921
+ let outcome : Except String (List Val × Val) :=
922
+ match argsubject, entrysubject with
923
+ | some call, _ => call args
924
+ | none, some call => (call args).map (fun res => (args, res))
925
+ | none, none => throw s!"omni: no test subject for: {label}"
926
+
927
+ match outcome with
928
+ | .ok (callargs, rawres) =>
929
+ let res := fixjson rawres flags.null
930
+ let done := match res with
931
+ | some value => jset entry "res" value
932
+ | none => entry
933
+ checkresult label index done callargs res
934
+ | .error message => handleerror label index entry message pack.client
935
+
936
+ /-- Run one set of test entries with flags. Returns the failure message. -/
937
+ def RunPack.runsetflags (pack : RunPack) (testspec : Json) (flags : Flags)
938
+ (testsubject : Option Subject) : Except String Unit :=
939
+ pack.drive testspec flags testsubject none
940
+
941
+ /-- Everything `runsetflags` does, for a subject that may replace its
942
+ arguments. See `SubjectArgs`. -/
943
+ def RunPack.runsetflagsargs (pack : RunPack) (testspec : Json) (flags : Flags)
944
+ (argsubject : SubjectArgs) : Except String Unit :=
945
+ pack.drive testspec flags none (some argsubject)
946
+
947
+ /-- Run one set of test entries. Returns the failure message. -/
948
+ def RunPack.runset (pack : RunPack) (testspec : Json) (testsubject : Option Subject)
949
+ : Except String Unit :=
950
+ pack.runsetflags testspec {} testsubject
951
+
952
+ /-- Make a runner for a spec value and a provider. Resolves the spec's
953
+ format version first (see `resolveversion`) and refuses to build a runner
954
+ at all for a version this port cannot faithfully run - fail fast, before
955
+ any group or client is resolved. -/
956
+ def makeRunnerSpec (alltests : Json) (provider : Provider) (name : String)
957
+ : Except String RunPack := do
958
+ let specversion ← resolveversion alltests
959
+
960
+ let spec := resolvespec name alltests
961
+
962
+ -- A spec may define clients that a given test run never references.
963
+ let clients :=
964
+ match asmap (jget (jget (some spec) "DEF") "client"), provider.client with
965
+ | some entries, some clientmaker =>
966
+ entries.map (fun kv =>
967
+ let copts := (jget (jget (some kv.2) "test") "options").getD (jmap [])
968
+ (kv.1, clientmaker copts))
969
+ | _, _ => []
970
+
971
+ let subject :=
972
+ if name.isEmpty then none
973
+ else match provider.subject with
974
+ | some resolve => resolve name
975
+ | none => none
976
+
977
+ pure { spec := spec, subject := subject, client := provider, clients := clients,
978
+ name := name, specversion := specversion }
979
+
980
+ /-- Load a spec: a path to a JSON file. -/
981
+ def loadspec (path : String) : IO Json := do
982
+ let text ← IO.FS.readFile path
983
+ match Json.parse text with
984
+ | .ok value => pure value
985
+ | .error message => throw (IO.userError s!"omni: cannot parse spec: {path}: {message}")
986
+
987
+ /-- Make a runner for a spec file path and a provider. A version refusal
988
+ from `makeRunnerSpec` surfaces the same way a spec-load failure already
989
+ does: a thrown `IO.userError`, so a caller can guard one `makeRunner` call
990
+ regardless of which stage failed. -/
991
+ def makeRunner (path : String) (provider : Provider) (name : String) : IO RunPack := do
992
+ let alltests ← loadspec path
993
+ match makeRunnerSpec alltests provider name with
994
+ | .ok pack => pure pack
995
+ | .error message => throw (IO.userError message)
996
+
997
+ end Omni