@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,1279 @@
1
+ -- ProjectName SDK runtime: the operation pipeline.
2
+ --
3
+ -- The context builder, all the `*Util` pipeline utilities (the dynamic donors'
4
+ -- utility/ layer), the utility bundle constructor, make_options and the
5
+ -- innermost transport (fetcher). Utilities are top-level IO functions that call
6
+ -- each other directly; the two members that vary per client — the transport
7
+ -- (`uFetcher`, wrapped by features) and `uParam` — are IORef cells so features
8
+ -- and tests can rebind them. Everything runs in IO because struct nodes are
9
+ -- IORef-backed and reference-stable.
10
+
11
+ module SdkRuntime where
12
+
13
+ import Control.Exception (throwIO)
14
+ import Control.Monad (forM_, when)
15
+ import Data.Bits ((.&.))
16
+ import Data.Char (isAlphaNum, toUpper)
17
+ import Data.IORef
18
+ import qualified Data.Map.Strict as Map
19
+ import Data.Maybe (isNothing)
20
+ import System.IO.Unsafe (unsafePerformIO)
21
+ import Text.Printf (printf)
22
+
23
+ import VoxgigStruct
24
+ ( Value (..), InjArg (..), emptyList, emptyMap, mkList, mkMap
25
+ , getprop, getpropAlt, setprop, delprop, getpath, getelem, keysof, listItems
26
+ , items, clone, merge, validate, transform, select, size, isempty
27
+ , isnode, ismap, islist, isfunc, isNoval, isNullish, vint
28
+ , escurl, escre, stringify, walk, join )
29
+ import SdkTypes
30
+ import SdkHelpers
31
+
32
+ -- ------------------------------------------------------------------
33
+ -- random ids (no external dep; LCG)
34
+ -- ------------------------------------------------------------------
35
+
36
+ {-# NOINLINE randSeed #-}
37
+ randSeed :: IORef Int
38
+ randSeed = unsafePerformIO (newIORef 123456789)
39
+
40
+ randInt :: Int -> IO Int
41
+ randInt n
42
+ | n <= 0 = pure 0
43
+ | otherwise = do
44
+ s <- readIORef randSeed
45
+ let s' = (s * 1103515245 + 12345) .&. 0x7fffffff
46
+ writeIORef randSeed s'
47
+ pure (s' `mod` n)
48
+
49
+ randHex4 :: IO String
50
+ randHex4 = printf "%04x" <$> randInt 0x10000
51
+
52
+ randId16 :: IO String
53
+ randId16 = concat <$> sequence [randHex4, randHex4, randHex4, randHex4]
54
+
55
+ nextCtxId :: IO String
56
+ nextCtxId = do n <- randInt 90000000; pure ("C" ++ show (10000000 + n))
57
+
58
+ escurlS :: String -> IO String
59
+ escurlS s = do r <- escurl (VStr s); pure (case r of VStr x -> x; _ -> s)
60
+
61
+ escreS :: String -> IO String
62
+ escreS s = do r <- escre (VStr s); pure (case r of VStr x -> x; _ -> s)
63
+
64
+ valEqScalar :: Value -> Value -> Bool
65
+ valEqScalar a b = case (a, b) of
66
+ (VNoval, VNoval) -> True
67
+ (VNull, VNull) -> True
68
+ (VNoval, VNull) -> True
69
+ (VNull, VNoval) -> True
70
+ (VStr x, VStr y) -> x == y
71
+ (VNum x, VNum y) -> x == y
72
+ (VBool x, VBool y) -> x == y
73
+ _ -> False
74
+
75
+ -- ------------------------------------------------------------------
76
+ -- context builder
77
+ -- ------------------------------------------------------------------
78
+
79
+ clientOptionsMap :: Client -> IO Value
80
+ clientOptionsMap cl = do
81
+ o <- readIORef (clOptions cl)
82
+ c <- clone o
83
+ case c of VMap _ -> pure c; _ -> emptyMap
84
+
85
+ resolveOp :: Context -> String -> IO Operation
86
+ resolveOp ctx opname = do
87
+ ment <- readIORef (cEntity ctx)
88
+ let entname = maybe "_" eName ment
89
+ cacheKey = opCacheKey entname opname
90
+ m <- readIORef (cOpmap ctx)
91
+ case Map.lookup cacheKey m of
92
+ Just op -> pure op
93
+ Nothing ->
94
+ if opname == ""
95
+ then newOperation =<< emptyMap
96
+ else do
97
+ cfg <- readIORef (cConfig ctx)
98
+ opcfg <- getpathS cfg ("entity." ++ entname ++ ".op." ++ opname)
99
+ let inpt = if opname == "update" || opname == "create" then "data" else "match"
100
+ pts <- case opcfg of
101
+ VMap _ -> do p <- getp opcfg "points"; case p of VList _ -> pure p; _ -> emptyList
102
+ _ -> emptyList
103
+ opm <- jo [("entity", VStr entname), ("name", VStr opname), ("input", VStr inpt), ("points", pts)]
104
+ op <- newOperation opm
105
+ modifyIORef' (cOpmap ctx) (Map.insert cacheKey op)
106
+ pure op
107
+
108
+ makeContextImpl :: CtxSpec -> Maybe Context -> IO Context
109
+ makeContextImpl cs basectx = do
110
+ cid <- nextCtxId
111
+
112
+ client <- case csClient cs of
113
+ Just c -> pure (Just c)
114
+ Nothing -> maybe (pure Nothing) (readIORef . cClient) basectx
115
+
116
+ utility <- case csUtility cs of
117
+ Just u -> pure (Just u)
118
+ Nothing -> maybe (pure Nothing) (readIORef . cUtility) basectx
119
+
120
+ ctrl <- case csCtrl cs of
121
+ Just cr@(VMap _) -> do
122
+ c <- newControl
123
+ thr <- getp cr "throw_err"
124
+ case thr of
125
+ VBool b -> setp c "throw" (VBool b)
126
+ _ -> do t2 <- getp cr "throw"; case t2 of VBool b -> setp c "throw" (VBool b); _ -> pure ()
127
+ ex <- getp cr "explain"; case ex of VMap _ -> setp c "explain" ex; _ -> pure ()
128
+ ac <- getp cr "actor"; case ac of VNoval -> pure (); _ -> setp c "actor" ac
129
+ pg <- getp cr "paging"; case pg of VMap _ -> setp c "paging" pg; _ -> pure ()
130
+ pure c
131
+ _ -> maybe newControl (readIORef . cCtrl) basectx
132
+
133
+ meta <- case csMeta cs of
134
+ Just m@(VMap _) -> pure m
135
+ _ -> case basectx of
136
+ Just b -> do mv <- readIORef (cMeta b); case mv of VMap _ -> pure mv; _ -> emptyMap
137
+ Nothing -> emptyMap
138
+
139
+ config <- inheritMap (csConfig cs) (cConfig <$> basectx) VNoval
140
+ entopts <- inheritMap (csEntopts cs) (cEntopts <$> basectx) VNoval
141
+ options <- inheritMap (csOptions cs) (cOptions <$> basectx) VNoval
142
+
143
+ entity <- case csEntity cs of
144
+ Just e -> pure (Just e)
145
+ Nothing -> maybe (pure Nothing) (readIORef . cEntity) basectx
146
+
147
+ shared <- case csShared cs of
148
+ Just m@(VMap _) -> pure m
149
+ _ -> maybe (pure VNoval) (readIORef . cShared) basectx
150
+
151
+ opmapRef <- case csOpmap cs of
152
+ Just r -> pure r
153
+ Nothing -> case basectx of Just b -> pure (cOpmap b); Nothing -> newIORef Map.empty
154
+
155
+ dat <- mapOf (csData cs)
156
+ reqdata <- mapOf (csReqdata cs)
157
+ mtch <- mapOf (csMatch cs)
158
+ reqmatch <- mapOf (csReqmatch cs)
159
+
160
+ point <- case csPoint cs of
161
+ Just m@(VMap _) -> pure m
162
+ _ -> maybe (pure VNoval) (readIORef . cPoint) basectx
163
+
164
+ spec <- inheritObj (csSpec cs) (cSpec <$> basectx)
165
+ result <- inheritObj (csResult cs) (cResult <$> basectx)
166
+ response <- inheritObj (csResponse cs) (cResponse <$> basectx)
167
+
168
+ op0 <- newOperation =<< emptyMap
169
+ scratch <- emptyMap
170
+ out <- emptyMap
171
+
172
+ cOutR <- newIORef out
173
+ cCtrlR <- newIORef ctrl
174
+ cMetaR <- newIORef meta
175
+ cClientR <- newIORef client
176
+ cUtilR <- newIORef utility
177
+ cOpR <- newIORef op0
178
+ cPointR <- newIORef point
179
+ cConfigR <- newIORef config
180
+ cEntoptsR <- newIORef entopts
181
+ cOptionsR <- newIORef options
182
+ cResponseR <- newIORef response
183
+ cResultR <- newIORef result
184
+ cSpecR <- newIORef spec
185
+ cDataR <- newIORef dat
186
+ cReqdataR <- newIORef reqdata
187
+ cMatchR <- newIORef mtch
188
+ cReqmatchR <- newIORef reqmatch
189
+ cEntityR <- newIORef entity
190
+ cSharedR <- newIORef shared
191
+ cScratchR <- newIORef scratch
192
+
193
+ let ctx = Context
194
+ { cId = cid, cOut = cOutR, cCtrl = cCtrlR, cMeta = cMetaR
195
+ , cClient = cClientR, cUtility = cUtilR, cOp = cOpR, cPoint = cPointR
196
+ , cConfig = cConfigR, cEntopts = cEntoptsR, cOptions = cOptionsR
197
+ , cOpmap = opmapRef, cResponse = cResponseR, cResult = cResultR
198
+ , cSpec = cSpecR, cData = cDataR, cReqdata = cReqdataR, cMatch = cMatchR
199
+ , cReqmatch = cReqmatchR, cEntity = cEntityR, cShared = cSharedR
200
+ , cScratch = cScratchR }
201
+
202
+ let opname = maybe "" id (csOpname cs)
203
+ op <- resolveOp ctx opname
204
+ writeIORef cOpR op
205
+ pure ctx
206
+ where
207
+ inheritMap mcs mbfield dflt = case mcs of
208
+ Just m@(VMap _) -> pure m
209
+ _ -> case mbfield of Just r -> readIORef r; Nothing -> pure dflt
210
+ inheritObj mcs mbfield = case mcs of
211
+ Just v -> pure v
212
+ _ -> case mbfield of Just r -> readIORef r; Nothing -> pure VNoval
213
+ mapOf mv = case mv of
214
+ Just d -> case toMap d of VMap _ -> pure d; _ -> emptyMap
215
+ Nothing -> emptyMap
216
+
217
+ -- ------------------------------------------------------------------
218
+ -- utilities
219
+ -- ------------------------------------------------------------------
220
+
221
+ cleanUtil :: Context -> Value -> IO Value
222
+ cleanUtil _ v = pure v
223
+
224
+ makeErrorUtil :: Context -> Maybe Value -> IO Value
225
+ makeErrorUtil ctx merr = do
226
+ op <- readIORef (cOp ctx)
227
+ let opname0 = opName op
228
+ opname = if opname0 == "" || opname0 == "_" then "unknown operation" else opname0
229
+ resultV <- readIORef (cResult ctx)
230
+ result <- case resultV of VMap _ -> pure resultV; _ -> newResult =<< emptyMap
231
+ setp result "ok" (VBool False)
232
+ err <- case merr of
233
+ Just e -> pure e
234
+ Nothing -> do
235
+ re <- getp result "err"; isE <- isErr re
236
+ if isE then pure re else mkErr "unknown" "unknown error"
237
+ em <- errMsg err
238
+ let msg = "ProjectNameSDK: " ++ opname ++ ": " ++ em
239
+ setp result "err" VNoval
240
+ ctrl <- readIORef (cCtrl ctx)
241
+ explain <- getp ctrl "explain"
242
+ case explain of
243
+ VMap _ -> do e2 <- jo [("message", VStr msg)]; setp explain "err" e2
244
+ _ -> pure ()
245
+ ecode <- errCode err
246
+ rv <- resultToValue result
247
+ specV <- readIORef (cSpec ctx)
248
+ sv <- case specV of VMap _ -> specToValue specV; _ -> pure VNoval
249
+ sdkErr <- jo [ ("__sdkerr__", VBool True), ("code", VStr ecode), ("message", VStr msg)
250
+ , ("result", rv), ("spec", sv) ]
251
+ setp ctrl "err" sdkErr
252
+ -- Fire PreUnexpected so observability features (metrics, telemetry, audit,
253
+ -- debug) close/record error paths that never reach PreDone (e.g. a PrePoint
254
+ -- rbac short-circuit). Fires after ctrl err is set so hooks can read the
255
+ -- error; features guard against double-recording when PreDone already fired.
256
+ featureHookUtil ctx "PreUnexpected"
257
+ thr <- getp ctrl "throw"
258
+ case thr of
259
+ VBool False -> getp result "resdata"
260
+ _ -> throwIO (SdkException sdkErr)
261
+
262
+ doneUtil :: Context -> IO Value
263
+ doneUtil ctx = do
264
+ ctrl <- readIORef (cCtrl ctx)
265
+ explain <- getp ctrl "explain"
266
+ case explain of
267
+ VMap _ -> do
268
+ er <- getp explain "result"
269
+ case er of VMap _ -> delp er "err"; _ -> pure ()
270
+ _ -> pure ()
271
+ resultV <- readIORef (cResult ctx)
272
+ case resultV of
273
+ VMap _ -> do
274
+ ok <- getp resultV "ok"
275
+ if isTrueV ok then getp resultV "resdata" else makeErrorUtil ctx Nothing
276
+ _ -> makeErrorUtil ctx Nothing
277
+
278
+ -- ----- feature utilities -----
279
+
280
+ featureHookUtil :: Context -> String -> IO ()
281
+ featureHookUtil ctx name = do
282
+ mcl <- readIORef (cClient ctx)
283
+ case mcl of
284
+ Nothing -> pure ()
285
+ Just cl -> do fs <- readIORef (clFeatures cl); mapM_ (\f -> fHook f name ctx) fs
286
+
287
+ featureAddUtil :: Context -> Feature -> IO ()
288
+ featureAddUtil ctx f = do
289
+ cl <- cc ctx
290
+ fopts <- readIORef (fOptions f)
291
+ let posOpt k = do
292
+ v <- case fopts of VMap _ -> getp fopts k; _ -> pure VNoval
293
+ pure (case v of VStr s -> Just s; _ -> Nothing)
294
+ before <- posOpt "__before__"
295
+ after <- posOpt "__after__"
296
+ replace <- posOpt "__replace__"
297
+ feats <- readIORef (clFeatures cl)
298
+ let hasPos = before /= Nothing || after /= Nothing || replace /= Nothing
299
+ go _ [] = Nothing
300
+ go acc (ef : rest)
301
+ | before == Just (fName ef) = Just (reverse acc ++ (f : ef : rest))
302
+ | after == Just (fName ef) = Just (reverse acc ++ (ef : f : rest))
303
+ | replace == Just (fName ef) = Just (reverse acc ++ (f : rest))
304
+ | otherwise = go (ef : acc) rest
305
+ positioned = if hasPos then go [] feats else Nothing
306
+ case positioned of
307
+ Just l -> writeIORef (clFeatures cl) l
308
+ Nothing -> writeIORef (clFeatures cl) (feats ++ [f])
309
+
310
+ featureInitUtil :: Context -> Feature -> IO ()
311
+ featureInitUtil ctx f = do
312
+ let fname = fName f
313
+ opts <- readIORef (cOptions ctx)
314
+ fo <- getp opts "feature"
315
+ fopts <- case fo of
316
+ VMap _ -> do foo <- getp fo fname; case foo of VMap _ -> pure foo; _ -> emptyMap
317
+ _ -> emptyMap
318
+ active <- getp fopts "active"
319
+ when (isTrueV active) (fInit f ctx fopts)
320
+
321
+ -- ----- prepare / param -----
322
+
323
+ -- The API definition is authoritative: a POST-only or PATCH-based API
324
+ -- exposes `update` as POST or PATCH, not the PUT the op name implies. Only
325
+ -- fall back to the op-name convention when the point has no method.
326
+ prepareMethodUtil :: Context -> IO String
327
+ prepareMethodUtil ctx = do
328
+ point <- readIORef (cPoint ctx)
329
+ pm <- getp point "method"
330
+ case pm of
331
+ VStr m | not (null m) -> pure (map toUpper m)
332
+ _ -> do
333
+ op <- readIORef (cOp ctx)
334
+ pure $ case opName op of
335
+ "create" -> "POST"; "update" -> "PUT"; "load" -> "GET"
336
+ "list" -> "GET"; "remove" -> "DELETE"; "patch" -> "PATCH"
337
+ -- NO CATCH-ALL GET. The ts reference returns methodMap[key], which is
338
+ -- undefined for an op the map does not name — the request is then
339
+ -- rejected rather than silently issued. A `_ -> "GET"` here turned
340
+ -- every unrecognised op into a GET, which is both a divergence from
341
+ -- the corpus (which expects no method for opname "bad") and the more
342
+ -- dangerous of the two behaviours: a mistyped or unsupported op
343
+ -- quietly fetched. Found by the primary corpus on its first run.
344
+ _ -> ""
345
+
346
+ prepareHeadersUtil :: Context -> IO Value
347
+ prepareHeadersUtil ctx = do
348
+ cl <- cc ctx
349
+ options <- clientOptionsMap cl
350
+ h <- getp options "headers"
351
+ case h of
352
+ VNoval -> emptyMap
353
+ _ -> do c <- clone h; case c of VMap _ -> pure c; _ -> emptyMap
354
+
355
+ paramUtil :: Context -> Value -> IO Value
356
+ paramUtil ctx paramdef = do
357
+ point <- readIORef (cPoint ctx)
358
+ specV <- readIORef (cSpec ctx)
359
+ mtch <- readIORef (cMatch ctx)
360
+ reqmatch <- readIORef (cReqmatch ctx)
361
+ dat <- readIORef (cData ctx)
362
+ reqdata <- readIORef (cReqdata ctx)
363
+ key <- case paramdef of VStr s -> pure s; _ -> getStrD paramdef "name" ""
364
+ aliasV <- getp point "alias"
365
+ akey <- case aliasV of VMap _ -> getStrD aliasV key ""; _ -> pure ""
366
+ let orElse v act = if isNoval v then act else pure v
367
+ v1 <- getp reqmatch key
368
+ v2 <- orElse v1 (getp mtch key)
369
+ v3 <- if isNoval v2 && not (null akey)
370
+ then do
371
+ case specV of
372
+ VMap _ -> do sa <- getp specV "alias"; setp sa akey (VStr key)
373
+ _ -> pure ()
374
+ getp reqmatch akey
375
+ else pure v2
376
+ v4 <- orElse v3 (getp reqdata key)
377
+ v5 <- orElse v4 (getp dat key)
378
+ if isNoval v5 && not (null akey)
379
+ then do a <- getp reqdata akey; orElse a (getp dat akey)
380
+ else pure v5
381
+
382
+ prepareParamsUtil :: Context -> IO Value
383
+ prepareParamsUtil ctx = do
384
+ point <- readIORef (cPoint ctx)
385
+ args <- getp point "args"
386
+ params <- case args of
387
+ VMap _ -> do p <- getp args "params"; case p of VList _ -> listItems p; _ -> pure []
388
+ _ -> pure []
389
+ out <- emptyMap
390
+ u <- cu ctx
391
+ pfn <- readIORef (uParam u)
392
+ forM_ params $ \pd -> do
393
+ v <- pfn ctx pd
394
+ when (not (isNoval v)) $
395
+ case pd of
396
+ VMap _ -> do nm <- getStrD pd "name" ""; when (nm /= "") (setp out nm v)
397
+ _ -> pure ()
398
+ pure out
399
+
400
+ preparePathUtil :: Context -> IO String
401
+ preparePathUtil ctx = do
402
+ point <- readIORef (cPoint ctx)
403
+ p <- getp point "parts"
404
+ parts <- case p of VList _ -> pure p; _ -> emptyList
405
+ join_ parts
406
+
407
+ prepareQueryUtil :: Context -> IO Value
408
+ prepareQueryUtil ctx = do
409
+ point <- readIORef (cPoint ctx)
410
+ rmV <- readIORef (cReqmatch ctx)
411
+ reqmatch <- case rmV of VMap _ -> pure rmV; _ -> emptyMap
412
+ pl <- getp point "params"
413
+ params <- case pl of VList _ -> listItems pl; _ -> pure []
414
+ let containsParam s = any (\v -> case v of VStr x -> x == s; _ -> False) params
415
+ out <- emptyMap
416
+ ks <- keysof reqmatch
417
+ forM_ ks $ \k -> do
418
+ v <- getp reqmatch k
419
+ when (not (isNoval v) && not (containsParam k)) (setp out k v)
420
+ pure out
421
+
422
+ prepareBodyUtil :: Context -> IO Value
423
+ prepareBodyUtil ctx = do
424
+ op <- readIORef (cOp ctx)
425
+ if opInput op == "data" then transformRequestUtil ctx else pure VNoval
426
+
427
+ -- ------------------------------------------------------------------
428
+ -- graphql (transport)
429
+ --
430
+ -- GraphQL transport. API-INDEPENDENT: every GraphQL SDK this generator
431
+ -- produces uses this code unchanged. The API-specific part — which
432
+ -- operations exist and what each one's document is — is model data, computed
433
+ -- once by apidef and emitted into Config.
434
+ --
435
+ -- Two jobs:
436
+ --
437
+ -- graphqlBodyUtil — build { query, variables } for a point, binding the
438
+ -- op's arguments to the document's declared variables.
439
+ --
440
+ -- graphqlErrorsUtil — lift a GraphQL failure into an SDK error. GraphQL
441
+ -- reports failures as a top-level `errors` array under
442
+ -- HTTP 200, so the status-driven path in resultBasic
443
+ -- never sees them.
444
+ -- ------------------------------------------------------------------
445
+
446
+ -- Content type every GraphQL-over-HTTP request uses.
447
+ graphqlContentType :: String
448
+ graphqlContentType = "application/json"
449
+
450
+ -- Map a GraphQL error to the same error codes the HTTP path produces, so a
451
+ -- caller handles auth or rate limiting identically on both transports.
452
+ -- Servers put the machine-readable code in `extensions.code`; Linear-style
453
+ -- APIs use `extensions.type`.
454
+ graphqlErrorCode :: Value -> IO String
455
+ graphqlErrorCode gqlerr = do
456
+ ext <- getp gqlerr "extensions"
457
+ c0 <- getStrD ext "code" ""
458
+ code <- if null c0 then getStrD ext "type" "" else pure c0
459
+ let raw = map toUpper code
460
+ pure $
461
+ if substrContains raw "AUTH" || substrContains raw "FORBIDDEN"
462
+ || substrContains raw "UNAUTHENTICATED"
463
+ then "request_auth"
464
+ else if substrContains raw "RATELIMIT" || substrContains raw "RATE_LIMIT"
465
+ || substrContains raw "TOO_MANY"
466
+ then "request_ratelimit"
467
+ else if substrContains raw "BAD_USER_INPUT"
468
+ || substrContains raw "VALIDATION"
469
+ || substrContains raw "INVALID"
470
+ then "request_invalid"
471
+ else "request_graphql"
472
+
473
+ -- Build the request body for a GraphQL point.
474
+ --
475
+ -- Variables come from the op's own arguments: a named variable binds to the
476
+ -- like-named argument (`from`), and the input-object variable (empty `from`)
477
+ -- takes the request data as a whole — which is what makes a generated
478
+ -- create/update call look exactly like its REST equivalent.
479
+ graphqlBodyUtil :: Context -> IO Value
480
+ graphqlBodyUtil ctx = do
481
+ point <- readIORef (cPoint ctx)
482
+ gql <- getp point "graphql"
483
+ case gql of
484
+ VMap _ -> do
485
+ -- reqmatch/reqdata hold the caller's arguments for THIS call;
486
+ -- data/match hold the entity's current state. Which pair depends on
487
+ -- whether the op takes match or data input. A named variable falls
488
+ -- back to the current state, so updating a loaded entity with just
489
+ -- {title} still binds the stored id the mutation requires.
490
+ op <- readIORef (cOp ctx)
491
+ let datainput = opInput op == "data"
492
+ rsV <- readIORef (if datainput then cReqdata ctx else cReqmatch ctx)
493
+ dsV <- readIORef (if datainput then cData ctx else cMatch ctx)
494
+ reqsrc <- case rsV of VMap _ -> pure rsV; _ -> emptyMap
495
+ datasrc <- case dsV of VMap _ -> pure dsV; _ -> emptyMap
496
+ variables <- emptyMap
497
+ vl <- getp gql "vars"
498
+ varlist <- case vl of VList _ -> listItems vl; _ -> pure []
499
+ forM_ varlist $ \spec -> case spec of
500
+ VMap _ -> do
501
+ name <- getStrD spec "name" ""
502
+ from <- getStrD spec "from" ""
503
+ when (not (null name)) $
504
+ if null from
505
+ then do
506
+ -- The input object IS the request body. Strip the action
507
+ -- selector, which is an SDK-side point discriminator, not an
508
+ -- API field.
509
+ body <- emptyMap
510
+ ks <- keysof reqsrc
511
+ forM_ ks $ \k -> when (k /= "$action") $ do
512
+ v <- getp reqsrc k
513
+ setp body k v
514
+ setp variables name body
515
+ else do
516
+ -- Only send variables the caller actually supplied: sending
517
+ -- an explicit null would clear a field on many APIs.
518
+ v0 <- getp reqsrc from
519
+ val <- if isNullish v0 then getp datasrc from else pure v0
520
+ when (not (isNullish val)) (setp variables name val)
521
+ _ -> pure ()
522
+ doc <- getp gql "doc"
523
+ jo [("query", doc), ("variables", variables)]
524
+ _ -> pure VNoval
525
+
526
+ -- Inspect a decoded GraphQL response body and record a failure when the
527
+ -- server reported one. Returns True when an error was recorded.
528
+ --
529
+ -- Partial data (`data` alongside `errors`) is treated as failure: the REST
530
+ -- surface has no partial-success concept, and silently returning half an
531
+ -- object would be worse than failing.
532
+ graphqlErrorsUtil :: Context -> IO Bool
533
+ graphqlErrorsUtil ctx = do
534
+ resultV <- readIORef (cResult ctx)
535
+ point <- readIORef (cPoint ctx)
536
+ kind <- getStrD point "kind" ""
537
+ case resultV of
538
+ VMap _ | kind == "graphql" -> do
539
+ body <- getp resultV "body"
540
+ ev <- getp body "errors"
541
+ errors <- case ev of VList _ -> listItems ev; _ -> pure []
542
+ if null errors
543
+ then pure False
544
+ else do
545
+ let firsterr = head errors
546
+ n = length errors
547
+ m0 <- getStrD firsterr "message" ""
548
+ let m1 = if null m0 then "graphql error" else m0
549
+ msg = if 1 < n then m1 ++ " (+" ++ show (n - 1) ++ " more)" else m1
550
+ code <- graphqlErrorCode firsterr
551
+ e <- mkErr code ("graphql: " ++ msg)
552
+ setp resultV "err" e
553
+ setp resultV "ok" (VBool False)
554
+ pure True
555
+ _ -> pure False
556
+
557
+ prepareAuthUtil :: Context -> UResult
558
+ prepareAuthUtil ctx = do
559
+ specV <- readIORef (cSpec ctx)
560
+ case specV of
561
+ VMap _ -> do
562
+ headers <- getp specV "headers"
563
+ cl <- cc ctx
564
+ options <- clientOptionsMap cl
565
+ authv <- getp options "auth"
566
+ case authv of
567
+ VNoval -> do delp headers "authorization"; pure (specV, Nothing)
568
+ VNull -> do delp headers "authorization"; pure (specV, Nothing)
569
+ _ -> do
570
+ apikey <- getpropAlt (VStr "__NOTFOUND__") options (VStr "apikey")
571
+ let isNotFound = case apikey of VStr "__NOTFOUND__" -> True; _ -> False
572
+ apikeyStr = case apikey of VStr s -> s; _ -> ""
573
+ if isNotFound || isNoval apikey || apikeyStr == ""
574
+ then do delp headers "authorization"; pure (specV, Nothing)
575
+ else do
576
+ apV <- getpathS options "auth.prefix"
577
+ let authPrefix = case apV of VStr s -> s; _ -> ""
578
+ authval = if authPrefix /= "" then authPrefix ++ " " ++ apikeyStr else apikeyStr
579
+ setp headers "authorization" (VStr authval)
580
+ pure (specV, Nothing)
581
+ _ -> do e <- mkErr "auth_no_spec" "Expected context spec property to be defined."; pure (VNoval, Just e)
582
+
583
+ -- ----- transforms / result helpers -----
584
+
585
+ transformRequestUtil :: Context -> IO Value
586
+ transformRequestUtil ctx = do
587
+ specV <- readIORef (cSpec ctx)
588
+ case specV of VMap _ -> setp specV "step" (VStr "reqform"); _ -> pure ()
589
+ point <- readIORef (cPoint ctx)
590
+ reqdata <- readIORef (cReqdata ctx)
591
+ tr <- toMap <$> getp point "transform"
592
+ case tr of
593
+ VMap _ -> do
594
+ reqform <- getp tr "req"
595
+ case reqform of
596
+ VNoval -> pure reqdata
597
+ _ -> do input <- jo [("reqdata", reqdata)]; transform INone input reqform
598
+ _ -> pure reqdata
599
+
600
+ transformResponseUtil :: Context -> IO Value
601
+ transformResponseUtil ctx = do
602
+ specV <- readIORef (cSpec ctx)
603
+ case specV of VMap _ -> setp specV "step" (VStr "resform"); _ -> pure ()
604
+ resultV <- readIORef (cResult ctx)
605
+ case resultV of
606
+ VMap _ -> do
607
+ ok <- getp resultV "ok"
608
+ if not (isTrueV ok) then pure VNoval
609
+ else do
610
+ point <- readIORef (cPoint ctx)
611
+ tr <- toMap <$> getp point "transform"
612
+ case tr of
613
+ VMap _ -> do
614
+ resform <- getp tr "res"
615
+ case resform of
616
+ VNoval -> pure VNoval
617
+ _ -> do
618
+ status <- getp resultV "status"
619
+ st <- getp resultV "statusText"
620
+ hdr <- getp resultV "headers"
621
+ body <- getp resultV "body"
622
+ errv <- getp resultV "err"
623
+ isE <- isErr errv
624
+ errOut <- if isE then do m <- getp errv "message"; jo [("message", m)] else pure VNoval
625
+ resdata <- getp resultV "resdata"
626
+ resmatch <- getp resultV "resmatch"
627
+ input <- jo [ ("ok", ok), ("status", status), ("statusText", st)
628
+ , ("headers", hdr), ("body", body), ("err", errOut)
629
+ , ("resdata", resdata), ("resmatch", resmatch) ]
630
+ rd <- transform INone input resform
631
+ setp resultV "resdata" rd
632
+ pure rd
633
+ _ -> pure VNoval
634
+ _ -> pure VNoval
635
+
636
+ resultBasicUtil :: Context -> IO ()
637
+ resultBasicUtil ctx = do
638
+ responseV <- readIORef (cResponse ctx)
639
+ resultV <- readIORef (cResult ctx)
640
+ case (responseV, resultV) of
641
+ (VMap _, VMap _) -> do
642
+ st <- getp responseV "status"
643
+ stt <- getp responseV "statusText"
644
+ setp resultV "status" st
645
+ setp resultV "statusText" stt
646
+ let status = toInt st
647
+ sttext = case stt of VStr s -> s; _ -> ""
648
+ if status >= 400
649
+ then do
650
+ let msg = "request: " ++ show status ++ ": " ++ sttext
651
+ prev <- getp resultV "err"
652
+ isE <- isErr prev
653
+ if isE
654
+ then do pm <- errMsg prev; e <- mkErr "request_status" (pm ++ ": " ++ msg); setp resultV "err" e
655
+ else do e <- mkErr "request_status" msg; setp resultV "err" e
656
+ else do
657
+ re <- getp responseV "err"
658
+ isE <- isErr re
659
+ when isE (setp resultV "err" re)
660
+ _ -> pure ()
661
+
662
+ resultBodyUtil :: Context -> IO ()
663
+ resultBodyUtil ctx = do
664
+ responseV <- readIORef (cResponse ctx)
665
+ resultV <- readIORef (cResult ctx)
666
+ case (responseV, resultV) of
667
+ (VMap _, VMap _) -> do
668
+ jsn <- getp responseV "json"
669
+ body <- getp responseV "body"
670
+ when (isCallable jsn && not (isNoval body)) $ do
671
+ d <- callJson jsn
672
+ setp resultV "body" d
673
+ _ -> pure ()
674
+
675
+ resultHeadersUtil :: Context -> IO ()
676
+ resultHeadersUtil ctx = do
677
+ resultV <- readIORef (cResult ctx)
678
+ case resultV of
679
+ VMap _ -> do
680
+ responseV <- readIORef (cResponse ctx)
681
+ case responseV of
682
+ VMap _ -> do
683
+ h <- getp responseV "headers"
684
+ case h of VMap _ -> setp resultV "headers" h; _ -> do em <- emptyMap; setp resultV "headers" em
685
+ _ -> do em <- emptyMap; setp resultV "headers" em
686
+ _ -> pure ()
687
+
688
+ -- ----- make_* pipeline stages -----
689
+
690
+ makePointUtil :: Context -> UResult
691
+ makePointUtil ctx = do
692
+ out <- readIORef (cOut ctx)
693
+ pre <- getp out "point"
694
+ isE <- isErr pre
695
+ if isE then pure (VNoval, Just pre)
696
+ else case pre of
697
+ VMap _ -> do writeIORef (cPoint ctx) pre; pure (pre, Nothing)
698
+ _ -> do
699
+ op <- readIORef (cOp ctx)
700
+ options <- readIORef (cOptions ctx)
701
+ av <- getpathS options "allow.op"
702
+ let allowOp = case av of VStr s -> s; _ -> ""
703
+ if not (substrContains allowOp (opName op))
704
+ then do
705
+ e <- mkErr "point_op_allow"
706
+ ("Operation \"" ++ opName op ++ "\" not allowed by SDK option allow.op value: \"" ++ allowOp ++ "\"")
707
+ pure (VNoval, Just e)
708
+ else do
709
+ pts <- listItems (opPoints op)
710
+ case pts of
711
+ [] -> do e <- mkErr "point_no_points" ("Operation \"" ++ opName op ++ "\" has no endpoint definitions."); pure (VNoval, Just e)
712
+ [single] -> do writeIORef (cPoint ctx) single; pure (single, Nothing)
713
+ _ -> do
714
+ (reqsel, sel) <- if opInput op == "data"
715
+ then (,) <$> readIORef (cReqdata ctx) <*> readIORef (cData ctx)
716
+ else (,) <$> readIORef (cReqmatch ctx) <*> readIORef (cMatch ctx)
717
+ let isFound pt = do
718
+ selectDef <- toMap <$> getp pt "select"
719
+ existOk <- case selectDef of
720
+ VMap _ -> do
721
+ exist <- getp selectDef "exist"
722
+ case exist of
723
+ VList _ -> do
724
+ eks <- listItems exist
725
+ let chk found ek = if not found then pure False else do
726
+ let existkey = vstring ek
727
+ rv <- getp reqsel existkey; sv <- getp sel existkey
728
+ pure (not (isNoval rv && isNoval sv))
729
+ foldMB True chk eks
730
+ _ -> pure True
731
+ _ -> pure True
732
+ if not existOk then pure False
733
+ else do
734
+ reqAction <- getp reqsel "$action"
735
+ selectAction <- getp selectDef "$action"
736
+ pure (valEqScalar reqAction selectAction)
737
+ findMatch [] = pure Nothing
738
+ findMatch (pt : rest) = do
739
+ f <- isFound pt
740
+ if f then pure (Just pt) else findMatch rest
741
+ -- A record route ends in the record's identifier
742
+ -- (/boards/{id}); a cross-reference that also returns the
743
+ -- entity ends in the relationship's name
744
+ -- (/posts/{id}/author). That, then fewest segments, tells
745
+ -- the entity's own route from a cross-reference. The same
746
+ -- rule runs at generation time, in helpers/opShape.ts —
747
+ -- both sides must move together.
748
+ ptsLen pt = do
749
+ parts <- getp pt "parts"
750
+ case parts of
751
+ VList _ -> length <$> listItems parts
752
+ _ -> pure (0 :: Int)
753
+ terminalParam pt = do
754
+ parts <- getp pt "parts"
755
+ case parts of
756
+ VList _ -> do
757
+ items <- listItems parts
758
+ pure (case reverse items of
759
+ (lastp : _) -> case vstring lastp of
760
+ ('{' : _) -> True
761
+ _ -> False
762
+ [] -> False)
763
+ _ -> pure False
764
+ betterOwn cand best = do
765
+ ct <- terminalParam cand
766
+ bt <- terminalParam best
767
+ if ct /= bt
768
+ then pure ct
769
+ else do
770
+ cl <- ptsLen cand
771
+ bl <- ptsLen best
772
+ pure (cl < bl)
773
+ ownPoint [] = pure VNoval
774
+ ownPoint (p0 : rest0) = go p0 rest0
775
+ where go best [] = pure best
776
+ go best (c : cs) = do
777
+ b <- betterOwn c best
778
+ go (if b then c else best) cs
779
+ matched <- findMatch pts
780
+ reqAction <- getp reqsel "$action"
781
+ chosen <- maybe (ownPoint pts) pure matched
782
+ -- select.exist can list more than the params needed to pick a
783
+ -- point, so nothing matched. A request naming an action gets
784
+ -- here only because that action's own point failed its exist
785
+ -- test, so it is unbuildable whatever we pick — refuse it
786
+ -- BEFORE the guard below, which compares the chosen point's
787
+ -- $action and would wave the request through whenever the
788
+ -- fallback lands on the action point itself.
789
+ if isNothing matched && not (isNoval reqAction)
790
+ then do
791
+ e <- mkErr "point_action_invalid" ("Operation \"" ++ opName op ++ "\" action \"" ++ vstring reqAction ++ "\" is not valid.")
792
+ pure (VNoval, Just e)
793
+ else if not (isNoval reqAction) && not (isNoval chosen)
794
+ then do
795
+ pointSelect <- toMap <$> getp chosen "select"
796
+ pointAction <- getp pointSelect "$action"
797
+ if not (valEqScalar reqAction pointAction)
798
+ then do e <- mkErr "point_action_invalid" ("Operation \"" ++ opName op ++ "\" action \"" ++ vstring reqAction ++ "\" is not valid."); pure (VNoval, Just e)
799
+ else do writeIORef (cPoint ctx) chosen; pure (chosen, Nothing)
800
+ else do writeIORef (cPoint ctx) chosen; pure (chosen, Nothing)
801
+
802
+ foldMB :: Bool -> (Bool -> a -> IO Bool) -> [a] -> IO Bool
803
+ foldMB acc _ [] = pure acc
804
+ foldMB acc f (x : xs) = do acc' <- f acc x; foldMB acc' f xs
805
+
806
+ makeSpecUtil :: Context -> UResult
807
+ makeSpecUtil ctx = do
808
+ out <- readIORef (cOut ctx)
809
+ pre <- getp out "spec"
810
+ isE <- isErr pre
811
+ if isE then pure (VNoval, Just pre)
812
+ else case pre of
813
+ VMap _ -> do writeIORef (cSpec ctx) pre; pure (pre, Nothing)
814
+ _ -> do
815
+ options <- readIORef (cOptions ctx)
816
+ base <- getStrD options "base" ""
817
+ prefix <- getStrD options "prefix" ""
818
+ suffix <- getStrD options "suffix" ""
819
+ point <- readIORef (cPoint ctx)
820
+ p <- getp point "parts"
821
+ parts <- case p of VList _ -> pure p; _ -> emptyList
822
+ specm <- jo [("base", VStr base), ("prefix", VStr prefix), ("parts", parts), ("suffix", VStr suffix), ("step", VStr "start")]
823
+ sp <- newSpec specm
824
+ writeIORef (cSpec ctx) sp
825
+ method <- prepareMethodUtil ctx
826
+ setp sp "method" (VStr method)
827
+ amv <- getpathS options "allow.method"
828
+ let allowMethod = case amv of VStr s -> s; _ -> ""
829
+ if not (substrContains allowMethod method)
830
+ then do e <- mkErr "spec_method_allow" ("Method \"" ++ method ++ "\" not allowed by SDK option allow.method value: \"" ++ allowMethod ++ "\""); pure (VNoval, Just e)
831
+ else do
832
+ params <- prepareParamsUtil ctx; setp sp "params" params
833
+ query <- prepareQueryUtil ctx; setp sp "query" query
834
+ headers <- prepareHeadersUtil ctx; setp sp "headers" headers
835
+ kind <- getStrD point "kind" ""
836
+ if kind == "graphql"
837
+ -- GraphQL addresses one endpoint: no path parts, no query string,
838
+ -- and the body carries the operation. prepareBody is skipped
839
+ -- deliberately — it only emits a body for data-input ops, whereas
840
+ -- every GraphQL op posts one, including load/list/remove.
841
+ then do
842
+ body <- graphqlBodyUtil ctx; setp sp "body" body
843
+ setp sp "path" (VStr "")
844
+ -- prepareQuery already copied the op's match arguments into the
845
+ -- query string. Those same values are bound as operation
846
+ -- variables, so leaving them would send /graphql?id=i1.
847
+ emptyq <- emptyMap; setp sp "query" emptyq
848
+ setp headers "content-type" (VStr graphqlContentType)
849
+ else do
850
+ body <- prepareBodyUtil ctx; setp sp "body" body
851
+ path <- preparePathUtil ctx; setp sp "path" (VStr path)
852
+ ctrl <- readIORef (cCtrl ctx)
853
+ explain <- getp ctrl "explain"
854
+ case explain of { VMap _ -> do { snap <- specToValue sp; setp explain "spec" snap }; _ -> pure () }
855
+ (sp2, merr) <- prepareAuthUtil ctx
856
+ case merr of
857
+ Just e -> pure (VNoval, Just e)
858
+ Nothing -> do writeIORef (cSpec ctx) sp2; pure (sp2, Nothing)
859
+
860
+ makeUrlUtil :: Context -> UResult
861
+ makeUrlUtil ctx = do
862
+ specV <- readIORef (cSpec ctx)
863
+ resultV <- readIORef (cResult ctx)
864
+ case specV of
865
+ VMap _ -> case resultV of
866
+ VMap _ -> do
867
+ base <- getStrD specV "base" ""
868
+ prefix <- getStrD specV "prefix" ""
869
+ path <- getStrD specV "path" ""
870
+ suffix <- getStrD specV "suffix" ""
871
+ arr <- ja [VStr base, VStr prefix, VStr path, VStr suffix]
872
+ url0 <- join_ arr
873
+ resmatch <- emptyMap
874
+ params <- getp specV "params"
875
+ pks <- keysof params
876
+ url1 <- foldMS url0 pks $ \u k -> do
877
+ v <- getp params k
878
+ if isNoval v then pure u
879
+ else do enc <- escurlS (vstring v); setp resmatch k v; pure (strReplaceAll u ("{" ++ k ++ "}") enc)
880
+ query <- getp specV "query"
881
+ qks <- keysof query
882
+ (url2, _) <- foldMS2 (url1, "?") qks $ \(u, qsep) k -> do
883
+ v <- getp query k
884
+ if isNoval v then pure (u, qsep)
885
+ else do ek <- escurlS k; ev <- escurlS (vstring v); setp resmatch k v; pure (u ++ qsep ++ ek ++ "=" ++ ev, "&")
886
+ setp resultV "resmatch" resmatch
887
+ pure (VStr url2, Nothing)
888
+ _ -> do e <- mkErr "url_no_result" "Expected context result property to be defined."; pure (VStr "", Just e)
889
+ _ -> do e <- mkErr "url_no_spec" "Expected context spec property to be defined."; pure (VStr "", Just e)
890
+
891
+ foldMS :: b -> [a] -> (b -> a -> IO b) -> IO b
892
+ foldMS z xs f = go z xs where go acc [] = pure acc; go acc (y : ys) = do acc' <- f acc y; go acc' ys
893
+
894
+ foldMS2 :: (b, c) -> [a] -> ((b, c) -> a -> IO (b, c)) -> IO (b, c)
895
+ foldMS2 z xs f = go z xs where go acc [] = pure acc; go acc (y : ys) = do acc' <- f acc y; go acc' ys
896
+
897
+ makeFetchDefUtil :: Context -> UResult
898
+ makeFetchDefUtil ctx = do
899
+ specV <- readIORef (cSpec ctx)
900
+ case specV of
901
+ VMap _ -> do
902
+ resultV <- readIORef (cResult ctx)
903
+ case resultV of VMap _ -> pure (); _ -> do r <- newResult =<< emptyMap; writeIORef (cResult ctx) r
904
+ setp specV "step" (VStr "prepare")
905
+ (urlV, merr) <- makeUrlUtil ctx
906
+ case merr of
907
+ Just e -> pure (VNoval, Just e)
908
+ Nothing -> do
909
+ let url = vstring urlV
910
+ setp specV "url" (VStr url)
911
+ method <- getStrD specV "method" "GET"
912
+ headers <- getp specV "headers"
913
+ fetchdef <- jo [("url", VStr url), ("method", VStr method), ("headers", headers)]
914
+ body <- getp specV "body"
915
+ case body of
916
+ VNoval -> pure ()
917
+ VMap _ -> do bs <- jsonifyCompact body; setp fetchdef "body" (VStr bs)
918
+ _ -> setp fetchdef "body" body
919
+ pure (fetchdef, Nothing)
920
+ _ -> do e <- mkErr "fetchdef_no_spec" "Expected context spec property to be defined."; pure (VNoval, Just e)
921
+
922
+ makeRequestUtil :: Context -> UResult
923
+ makeRequestUtil ctx = do
924
+ out <- readIORef (cOut ctx)
925
+ pre <- getp out "request"
926
+ isE <- isErr pre
927
+ if isE then pure (VNoval, Just pre)
928
+ else case pre of
929
+ VMap _ -> pure (pre, Nothing)
930
+ _ -> do
931
+ response0 <- newResponse =<< emptyMap
932
+ result <- newResult =<< emptyMap
933
+ writeIORef (cResult ctx) result
934
+ specV <- readIORef (cSpec ctx)
935
+ case specV of
936
+ VMap _ -> do
937
+ (fetchdef, merr) <- makeFetchDefUtil ctx
938
+ case merr of
939
+ Just e -> do
940
+ setp response0 "err" e
941
+ writeIORef (cResponse ctx) response0
942
+ setp specV "step" (VStr "postrequest")
943
+ pure (response0, Nothing)
944
+ Nothing -> do
945
+ ctrl <- readIORef (cCtrl ctx)
946
+ explain <- getp ctrl "explain"
947
+ case explain of VMap _ -> setp explain "fetchdef" fetchdef; _ -> pure ()
948
+ setp specV "step" (VStr "prerequest")
949
+ url <- getStrD fetchdef "url" ""
950
+ u <- cu ctx
951
+ fetcher <- readIORef (uFetcher u)
952
+ (fetched, fetchErr) <- fetcher ctx url fetchdef
953
+ response <- case fetchErr of
954
+ Just fe -> do setp response0 "err" fe; pure response0
955
+ Nothing ->
956
+ if isNoval fetched || isNullV fetched
957
+ then do r <- newResponse =<< emptyMap; e <- mkErr "request_no_response" "response: undefined"; setp r "err" e; pure r
958
+ else case fetched of
959
+ VMap _ -> newResponse fetched
960
+ _ -> do setp response0 "err" =<< mkErr "request_invalid_response" "response: invalid type"; pure response0
961
+ setp specV "step" (VStr "postrequest")
962
+ writeIORef (cResponse ctx) response
963
+ pure (response, Nothing)
964
+ _ -> do e <- mkErr "request_no_spec" "Expected context spec property to be defined."; pure (VNoval, Just e)
965
+
966
+ isNullV :: Value -> Bool
967
+ isNullV VNull = True
968
+ isNullV _ = False
969
+
970
+ makeResponseUtil :: Context -> UResult
971
+ makeResponseUtil ctx = do
972
+ out <- readIORef (cOut ctx)
973
+ pre <- getp out "response"
974
+ isE <- isErr pre
975
+ if isE then pure (VNoval, Just pre)
976
+ else case pre of
977
+ VMap _ -> pure (pre, Nothing)
978
+ _ -> do
979
+ specV <- readIORef (cSpec ctx)
980
+ responseV <- readIORef (cResponse ctx)
981
+ resultV <- readIORef (cResult ctx)
982
+ case specV of
983
+ VMap _ -> case responseV of
984
+ VMap _ -> case resultV of
985
+ VMap _ -> do
986
+ setp specV "step" (VStr "response")
987
+ resultBasicUtil ctx; resultHeadersUtil ctx; resultBodyUtil ctx
988
+ -- GraphQL reports failures as a top-level `errors` array under
989
+ -- HTTP 200, so resultBasic's status check never sees them. Lift
990
+ -- them here, before the response transform tries to unwrap data
991
+ -- that is not there.
992
+ _ <- graphqlErrorsUtil ctx
993
+ _ <- transformResponseUtil ctx
994
+ errv <- getp resultV "err"
995
+ isErrR <- isErr errv
996
+ when (not isErrR) (setp resultV "ok" (VBool True))
997
+ ctrl <- readIORef (cCtrl ctx)
998
+ explain <- getp ctrl "explain"
999
+ case explain of { VMap _ -> do { snap <- resultToValue resultV; setp explain "result" snap }; _ -> pure () }
1000
+ pure (responseV, Nothing)
1001
+ _ -> do e <- mkErr "response_no_result" "Expected context result property to be defined."; pure (VNoval, Just e)
1002
+ _ -> do e <- mkErr "response_no_response" "Expected context response property to be defined."; pure (VNoval, Just e)
1003
+ _ -> do e <- mkErr "response_no_spec" "Expected context spec property to be defined."; pure (VNoval, Just e)
1004
+
1005
+ makeResultUtil :: Context -> UResult
1006
+ makeResultUtil ctx = do
1007
+ out <- readIORef (cOut ctx)
1008
+ pre <- getp out "result"
1009
+ isE <- isErr pre
1010
+ if isE then pure (VNoval, Just pre)
1011
+ else case pre of
1012
+ VMap _ -> pure (pre, Nothing)
1013
+ _ -> do
1014
+ op <- readIORef (cOp ctx)
1015
+ specV <- readIORef (cSpec ctx)
1016
+ resultV <- readIORef (cResult ctx)
1017
+ case specV of
1018
+ VMap _ -> case resultV of
1019
+ VMap _ -> do
1020
+ setp specV "step" (VStr "result")
1021
+ _ <- transformResponseUtil ctx
1022
+ when (opName op == "list") $ do
1023
+ resdata <- getp resultV "resdata"
1024
+ el <- emptyList
1025
+ setp resultV "resdata" el
1026
+ ment <- readIORef (cEntity ctx)
1027
+ case (resdata, ment) of
1028
+ (VList _, Just entity) -> do
1029
+ items0 <- listItems resdata
1030
+ entries <- mapM (\entry -> do
1031
+ ent <- eMake entity
1032
+ case entry of VMap _ -> eDataSet ent entry; _ -> pure ()
1033
+ pure entry) items0
1034
+ el2 <- mkList entries
1035
+ setp resultV "resdata" el2
1036
+ _ -> pure ()
1037
+ ctrl <- readIORef (cCtrl ctx)
1038
+ explain <- getp ctrl "explain"
1039
+ case explain of { VMap _ -> do { snap <- resultToValue resultV; setp explain "result" snap }; _ -> pure () }
1040
+ pure (resultV, Nothing)
1041
+ _ -> do e <- mkErr "result_no_result" "Expected context result property to be defined."; pure (VNoval, Just e)
1042
+ _ -> do e <- mkErr "result_no_spec" "Expected context spec property to be defined."; pure (VNoval, Just e)
1043
+
1044
+ -- ----- fetcher (innermost transport) -----
1045
+
1046
+ fetcherUtil :: Context -> String -> Value -> IO (Value, Maybe Value)
1047
+ fetcherUtil ctx fullurl fetchdef = do
1048
+ cl <- cc ctx
1049
+ mode <- readIORef (clMode cl)
1050
+ if mode /= "live"
1051
+ then do e <- mkErr "fetch_mode_block" ("Request blocked by mode: \"" ++ mode ++ "\" (URL was: \"" ++ fullurl ++ "\")"); pure (VNoval, Just e)
1052
+ else do
1053
+ options <- clientOptionsMap cl
1054
+ testActive <- getpathS options "feature.test.active"
1055
+ if isTrueV testActive
1056
+ then do e <- mkErr "fetch_test_block" ("Request blocked as test feature is active (URL was: \"" ++ fullurl ++ "\")"); pure (VNoval, Just e)
1057
+ else do
1058
+ sysFetch <- getpathS options "system.fetch"
1059
+ case sysFetch of
1060
+ VFunc _ -> do
1061
+ argsL <- ja [VStr fullurl, fetchdef]
1062
+ out <- callVfn sysFetch argsL
1063
+ errStr <- getStr out "__err__"
1064
+ case errStr of
1065
+ Just msg -> do e <- mkErr "fetch_system" msg; pure (VNoval, Just e)
1066
+ Nothing -> pure (out, Nothing)
1067
+ VNoval -> do e <- mkErr "fetch_no_transport" "No live HTTP transport in this build; provide options.system.fetch."; pure (VNoval, Just e)
1068
+ VNull -> do e <- mkErr "fetch_no_transport" "No live HTTP transport in this build; provide options.system.fetch."; pure (VNoval, Just e)
1069
+ _ -> do e <- mkErr "fetch_invalid" "system.fetch is not a valid function"; pure (VNoval, Just e)
1070
+
1071
+ -- ------------------------------------------------------------------
1072
+ -- make_options
1073
+ -- ------------------------------------------------------------------
1074
+
1075
+ optSpecValue :: IO Value
1076
+ optSpecValue = do
1077
+ auth <- jo [("prefix", VStr ""), ("basic", VBool False)]
1078
+ hdrs <- jo [("`$CHILD`", VStr "`$STRING`")]
1079
+ -- OpenAPI server-variable defaults, carried by the generated config whenever
1080
+ -- the spec's server URL is templated. Accepted here so validation does not
1081
+ -- reject the SDK's own config; the {name} substitution into base is a
1082
+ -- separate concern.
1083
+ srv <- jo [("`$CHILD`", VStr "")]
1084
+ allow <- jo [("method", VStr "GET,PUT,POST,PATCH,DELETE,OPTIONS"), ("op", VStr "create,update,load,list,remove,command,direct,graphql")]
1085
+ entChild <- do a <- emptyMap; jo [("`$OPEN`", VBool True), ("active", VBool False), ("alias", a)]
1086
+ ent <- jo [("`$CHILD`", entChild)]
1087
+ featChild <- jo [("`$OPEN`", VBool True), ("active", VBool False)]
1088
+ feat <- jo [("`$CHILD`", featChild)]
1089
+ utilm <- emptyMap
1090
+ sysm <- emptyMap
1091
+ testEnt <- jo [("`$OPEN`", VBool True)]
1092
+ test <- jo [("active", VBool False), ("entity", testEnt)]
1093
+ clean <- jo [("keys", VStr "key,token,id")]
1094
+ jo [ ("apikey", VStr ""), ("base", VStr "http://localhost:8000"), ("prefix", VStr ""), ("suffix", VStr "")
1095
+ , ("auth", auth), ("headers", hdrs), ("server", srv), ("allow", allow), ("entity", ent), ("feature", feat)
1096
+ , ("utility", utilm), ("system", sysm), ("test", test), ("clean", clean) ]
1097
+
1098
+ makeOptionsUtil :: Context -> IO Value
1099
+ makeOptionsUtil ctx = do
1100
+ optionsV <- readIORef (cOptions ctx)
1101
+ options <- case optionsV of VNoval -> emptyMap; v -> pure v
1102
+ customUtils <- getp options "utility"
1103
+ case customUtils of
1104
+ VMap _ -> do
1105
+ mu <- readIORef (cUtility ctx)
1106
+ case mu of
1107
+ Just u -> do ks <- keysof customUtils; forM_ ks $ \k -> do v <- getp customUtils k; c <- readIORef (uCustom u); setp c k v
1108
+ Nothing -> pure ()
1109
+ _ -> pure ()
1110
+ optsC <- clone options
1111
+ opts0 <- case optsC of VMap _ -> pure optsC; _ -> emptyMap
1112
+ -- Feature add-order. options.feature may be given as an ordered LIST of
1113
+ -- {name, active, ...opts} entries (list position = add order) or a
1114
+ -- {name => {opts}} map. Normalize a list to a map (so merge/validate/init
1115
+ -- are unchanged) and remember the explicit order; a map defaults to
1116
+ -- test-first so the `test` mock transport is the base of the wrapper chain.
1117
+ featureRaw <- getp opts0 "feature"
1118
+ explicitOrder <- case featureRaw of
1119
+ VList ref -> do
1120
+ entries <- readIORef ref
1121
+ fmap' <- emptyMap
1122
+ order <- fmap concat $ mapM (\entry -> case entry of
1123
+ VMap _ -> do
1124
+ nm <- getp entry "name"
1125
+ case nm of
1126
+ VStr name -> do
1127
+ fopts <- clone entry
1128
+ _ <- delprop fopts (VStr "name")
1129
+ setp fmap' name fopts
1130
+ pure [name]
1131
+ _ -> pure []
1132
+ _ -> pure []) entries
1133
+ setp opts0 "feature" fmap'
1134
+ pure (Just order)
1135
+ _ -> pure Nothing
1136
+ configV <- readIORef (cConfig ctx)
1137
+ config <- case configV of VMap _ -> pure configV; _ -> emptyMap
1138
+ cfgoptsV <- toMap <$> getp config "options"
1139
+ cfgopts <- case cfgoptsV of VMap _ -> pure cfgoptsV; _ -> emptyMap
1140
+ optspec <- optSpecValue
1141
+ sysFetch <- getpathS opts0 "system.fetch"
1142
+ em <- emptyMap
1143
+ mlist <- ja [em, cfgopts, opts0]
1144
+ merged <- merge mlist
1145
+ validated <- validate INone merged optspec
1146
+ opts <- case validated of VMap _ -> pure validated; _ -> emptyMap
1147
+ -- Resolve a templated base URL (e.g. https://{tenant_id}.hanko.io).
1148
+ -- Every placeholder must resolve to a non-empty value: from options.server
1149
+ -- (user), else the Config default. A placeholder that resolves to "" is a
1150
+ -- construction ERROR in live mode - the URL cannot work - but in test mode
1151
+ -- substitutes the deterministic value "test-<name>" so offline tests need no
1152
+ -- configuration. The SDK constructor has no error return, so a missing
1153
+ -- required variable THROWS: construction-time misconfiguration.
1154
+ baseV <- getp opts "base"
1155
+ case baseV of
1156
+ VStr base | '{' `elem` base -> do
1157
+ taV <- getpathS opts "test.active"
1158
+ faV <- getpathS opts "feature.test.active"
1159
+ -- Value has no Eq instance: match the constructor.
1160
+ let isTrue v = case v of VBool b -> b; _ -> False
1161
+ testmode = isTrue taV || isTrue faV
1162
+ server <- getp opts "server"
1163
+ mnV <- getpathS config "main.name"
1164
+ let sdkname = case mnV of VStr s | not (null s) -> s; _ -> "SDK"
1165
+
1166
+ -- Scanned by hand: a placeholder is `{` followed by [A-Za-z0-9_]+ and
1167
+ -- `}`; anything else is literal text, so a stray brace is left alone.
1168
+ let resolve [] = pure []
1169
+ resolve ('{' : rest) =
1170
+ let (name, tail') = span (\c -> isAlphaNum c || '_' == c) rest
1171
+ in case tail' of
1172
+ ('}' : more) | not (null name) -> do
1173
+ valV <- case server of VMap _ -> getp server name; _ -> pure VNoval
1174
+ let val = case valV of VStr s -> s; _ -> ""
1175
+ sub <- if not (null val)
1176
+ then pure val
1177
+ else if testmode
1178
+ then pure ("test-" ++ name)
1179
+ else do
1180
+ e <- jo [ ("code", VStr "server_var_required")
1181
+ , ("msg", VStr (sdkname ++ ": the server variable '" ++
1182
+ name ++ "' is required: the API base URL is '" ++
1183
+ base ++ "' - pass server = { \"" ++ name ++
1184
+ "\": \"...\" } in the SDK options"))
1185
+ , ("sdk", VStr "ProjectName") ]
1186
+ throwIO (SdkException e)
1187
+ more' <- resolve more
1188
+ pure (sub ++ more')
1189
+ _ -> do r <- resolve rest; pure ('{' : r)
1190
+ resolve (c : rest) = do r <- resolve rest; pure (c : r)
1191
+ resolved <- resolve base
1192
+ setp opts "base" (VStr resolved)
1193
+ _ -> pure ()
1194
+
1195
+ when (not (isNoval sysFetch)) $ do
1196
+ sys <- getp opts "system"
1197
+ case sys of
1198
+ VMap _ -> setp sys "fetch" sysFetch
1199
+ _ -> do s <- jo [("fetch", sysFetch)]; setp opts "system" s
1200
+ ckv <- getpathS opts "clean.keys"
1201
+ let cleanKeys = case ckv of VStr s -> s; _ -> "key,token,id"
1202
+ parts <- fmap concat $ mapM (\p -> let t = strip p in if t == "" then pure [] else do e <- escreS t; pure [e]) (splitOnChar ',' cleanKeys)
1203
+ let keyre = intercalate' "|" parts
1204
+ cleanEmpty <- emptyMap
1205
+ derived <- jo [("clean", cleanEmpty)]
1206
+ when (keyre /= "") $ do cm <- jo [("keyre", VStr keyre)]; setp derived "clean" cm
1207
+ -- Resolve the feature add-order: an explicit list order (above) wins;
1208
+ -- otherwise order the map test-first, then the remaining names sorted
1209
+ -- (keysof returns sorted keys), so the result is deterministic.
1210
+ featureOrder <- case explicitOrder of
1211
+ Just ord -> pure ord
1212
+ Nothing -> do
1213
+ fmapV <- getp opts "feature"
1214
+ names <- case fmapV of VMap _ -> keysof fmapV; _ -> pure []
1215
+ pure $ if "test" `elem` names then "test" : filter (/= "test") names else names
1216
+ orderList <- ja (map VStr featureOrder)
1217
+ setp derived "featureorder" orderList
1218
+ setp opts "__derived__" derived
1219
+ pure opts
1220
+
1221
+ intercalate' :: String -> [String] -> String
1222
+ intercalate' _ [] = ""
1223
+ intercalate' _ [x] = x
1224
+ intercalate' sep (x : xs) = x ++ sep ++ intercalate' sep xs
1225
+
1226
+ -- ------------------------------------------------------------------
1227
+ -- struct api exposure (utility.struct)
1228
+ -- ------------------------------------------------------------------
1229
+
1230
+ structApiInstance :: StructApi
1231
+ structApiInstance = StructApi
1232
+ { sGetprop = getprop
1233
+ , sSetprop = setprop
1234
+ , sGetpath = getpath INone
1235
+ , sGetelem = getelem
1236
+ , sClone = clone
1237
+ , sMerge = \l -> mkList l >>= merge
1238
+ , sItems = items
1239
+ , sKeysof = keysof
1240
+ , sSize = size
1241
+ , sIsempty = isempty
1242
+ , sStringify = stringify
1243
+ , sJsonify = jsonifyCompact
1244
+ , sEscurl = escurlS . vstring
1245
+ , sEscre = escreS . vstring
1246
+ , sTransform = transform INone
1247
+ , sValidate = validate INone
1248
+ , sSelect = select
1249
+ , sWalk = \fn v -> walk (Just fn) Nothing VNoval v
1250
+ }
1251
+
1252
+ -- ------------------------------------------------------------------
1253
+ -- utility construction
1254
+ -- ------------------------------------------------------------------
1255
+
1256
+ newUtility :: IO Utility
1257
+ newUtility = do
1258
+ custom <- newIORef =<< emptyMap
1259
+ fetcher <- newIORef fetcherUtil
1260
+ param <- newIORef paramUtil
1261
+ pure Utility { uCustom = custom, uStruct = structApiInstance, uFetcher = fetcher, uParam = param }
1262
+
1263
+ copyUtility :: Utility -> IO Utility
1264
+ copyUtility src = do
1265
+ f <- readIORef (uFetcher src)
1266
+ p <- readIORef (uParam src)
1267
+ fetcher <- newIORef f
1268
+ param <- newIORef p
1269
+ srcCustom <- readIORef (uCustom src)
1270
+ custom <- emptyMap
1271
+ case srcCustom of
1272
+ VMap _ -> do ks <- keysof srcCustom; forM_ ks $ \k -> do v <- getp srcCustom k; setp custom k v
1273
+ _ -> pure ()
1274
+ customR <- newIORef custom
1275
+ pure Utility { uCustom = customR, uStruct = uStruct src, uFetcher = fetcher, uParam = param }
1276
+
1277
+ -- struct join helper: join parts with "/" as a URL path
1278
+ join_ :: Value -> IO String
1279
+ join_ arr = join arr (VStr "/") True