@planet-matrix/mobius-model 0.5.0 → 0.9.0

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 (379) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +123 -36
  3. package/dist/index.js +715 -4
  4. package/dist/index.js.map +981 -13
  5. package/oxlint.config.ts +6 -0
  6. package/package.json +36 -18
  7. package/src/abort/README.md +92 -0
  8. package/src/abort/abort-manager.ts +278 -0
  9. package/src/abort/abort-signal-listener-manager.ts +81 -0
  10. package/src/abort/index.ts +2 -0
  11. package/src/ai/README.md +1 -0
  12. package/src/ai/ai.ts +107 -0
  13. package/src/ai/chat-completion-ai/aihubmix-chat-completion.ts +78 -0
  14. package/src/ai/chat-completion-ai/chat-completion-ai.ts +270 -0
  15. package/src/ai/chat-completion-ai/chat-completion.ts +189 -0
  16. package/src/ai/chat-completion-ai/index.ts +7 -0
  17. package/src/ai/chat-completion-ai/lingyiwanwu-chat-completion.ts +78 -0
  18. package/src/ai/chat-completion-ai/ohmygpt-chat-completion.ts +78 -0
  19. package/src/ai/chat-completion-ai/openai-next-chat-completion.ts +78 -0
  20. package/src/ai/embedding-ai/embedding-ai.ts +63 -0
  21. package/src/ai/embedding-ai/embedding.ts +50 -0
  22. package/src/ai/embedding-ai/index.ts +4 -0
  23. package/src/ai/embedding-ai/openai-next-embedding.ts +23 -0
  24. package/src/ai/index.ts +4 -0
  25. package/src/aio/README.md +100 -0
  26. package/src/aio/content.ts +141 -0
  27. package/src/aio/index.ts +3 -0
  28. package/src/aio/json.ts +127 -0
  29. package/src/aio/prompt.ts +246 -0
  30. package/src/basic/README.md +72 -116
  31. package/src/basic/error.ts +19 -5
  32. package/src/basic/function.ts +83 -64
  33. package/src/basic/index.ts +1 -0
  34. package/src/basic/is.ts +152 -71
  35. package/src/basic/promise.ts +29 -8
  36. package/src/basic/schedule.ts +111 -0
  37. package/src/basic/stream.ts +135 -25
  38. package/src/basic/string.ts +2 -33
  39. package/src/color/README.md +105 -0
  40. package/src/color/index.ts +3 -0
  41. package/src/color/internal.ts +42 -0
  42. package/src/color/rgb/analyze.ts +236 -0
  43. package/src/color/rgb/construct.ts +130 -0
  44. package/src/color/rgb/convert.ts +227 -0
  45. package/src/color/rgb/derive.ts +303 -0
  46. package/src/color/rgb/index.ts +6 -0
  47. package/src/color/rgb/internal.ts +208 -0
  48. package/src/color/rgb/parse.ts +302 -0
  49. package/src/color/rgb/serialize.ts +144 -0
  50. package/src/color/types.ts +57 -0
  51. package/src/color/xyz/analyze.ts +80 -0
  52. package/src/color/xyz/construct.ts +19 -0
  53. package/src/color/xyz/convert.ts +71 -0
  54. package/src/color/xyz/index.ts +3 -0
  55. package/src/color/xyz/internal.ts +23 -0
  56. package/src/credential/README.md +107 -0
  57. package/src/credential/api-key.ts +158 -0
  58. package/src/credential/bearer.ts +73 -0
  59. package/src/credential/index.ts +4 -0
  60. package/src/credential/json-web-token.ts +96 -0
  61. package/src/credential/password.ts +170 -0
  62. package/src/cron/README.md +86 -0
  63. package/src/cron/cron.ts +87 -0
  64. package/src/cron/index.ts +1 -0
  65. package/src/css/README.md +93 -0
  66. package/src/css/class.ts +559 -0
  67. package/src/css/index.ts +1 -0
  68. package/src/drizzle/README.md +1 -0
  69. package/src/drizzle/drizzle.ts +1 -0
  70. package/src/drizzle/helper.ts +47 -0
  71. package/src/drizzle/index.ts +5 -0
  72. package/src/drizzle/infer.ts +52 -0
  73. package/src/drizzle/kysely.ts +8 -0
  74. package/src/drizzle/pagination.ts +200 -0
  75. package/src/email/README.md +1 -0
  76. package/src/email/index.ts +1 -0
  77. package/src/email/resend.ts +25 -0
  78. package/src/encoding/README.md +66 -79
  79. package/src/encoding/base64.ts +13 -4
  80. package/src/environment/README.md +97 -0
  81. package/src/environment/basic.ts +26 -0
  82. package/src/environment/device.ts +311 -0
  83. package/src/environment/feature.ts +285 -0
  84. package/src/environment/geo.ts +337 -0
  85. package/src/environment/index.ts +7 -0
  86. package/src/environment/runtime.ts +400 -0
  87. package/src/environment/snapshot.ts +60 -0
  88. package/src/environment/variable.ts +239 -0
  89. package/src/event/README.md +90 -0
  90. package/src/event/class-event-proxy.ts +229 -0
  91. package/src/event/common.ts +29 -0
  92. package/src/event/event-manager.ts +203 -0
  93. package/src/event/index.ts +4 -0
  94. package/src/event/instance-event-proxy.ts +187 -0
  95. package/src/event/internal.ts +24 -0
  96. package/src/exception/README.md +96 -0
  97. package/src/exception/browser.ts +219 -0
  98. package/src/exception/index.ts +4 -0
  99. package/src/exception/nodejs.ts +169 -0
  100. package/src/exception/normalize.ts +106 -0
  101. package/src/exception/types.ts +99 -0
  102. package/src/form/README.md +25 -0
  103. package/src/form/index.ts +1 -0
  104. package/src/form/inputor-controller/base.ts +874 -0
  105. package/src/form/inputor-controller/boolean.ts +39 -0
  106. package/src/form/inputor-controller/file.ts +39 -0
  107. package/src/form/inputor-controller/form.ts +181 -0
  108. package/src/form/inputor-controller/helper.ts +117 -0
  109. package/src/form/inputor-controller/index.ts +17 -0
  110. package/src/form/inputor-controller/multi-select.ts +99 -0
  111. package/src/form/inputor-controller/number.ts +116 -0
  112. package/src/form/inputor-controller/select.ts +109 -0
  113. package/src/form/inputor-controller/text.ts +82 -0
  114. package/src/http/READMD.md +1 -0
  115. package/src/http/api/api-core.ts +84 -0
  116. package/src/http/api/api-handler.ts +79 -0
  117. package/src/http/api/api-host.ts +47 -0
  118. package/src/http/api/api-result.ts +56 -0
  119. package/src/http/api/api-schema.ts +154 -0
  120. package/src/http/api/api-server.ts +130 -0
  121. package/src/http/api/api-test.ts +142 -0
  122. package/src/http/api/api-type.ts +37 -0
  123. package/src/http/api/api.ts +81 -0
  124. package/src/http/api/index.ts +11 -0
  125. package/src/http/api-adapter/api-core-node-http.ts +260 -0
  126. package/src/http/api-adapter/api-host-node-http.ts +156 -0
  127. package/src/http/api-adapter/api-result-arktype.ts +297 -0
  128. package/src/http/api-adapter/api-result-zod.ts +286 -0
  129. package/src/http/api-adapter/index.ts +5 -0
  130. package/src/http/bin/gen-api-list/gen-api-list.ts +126 -0
  131. package/src/http/bin/gen-api-list/index.ts +1 -0
  132. package/src/http/bin/gen-api-test/gen-api-test.ts +136 -0
  133. package/src/http/bin/gen-api-test/index.ts +1 -0
  134. package/src/http/bin/gen-api-type/calc-code.ts +25 -0
  135. package/src/http/bin/gen-api-type/gen-api-type.ts +127 -0
  136. package/src/http/bin/gen-api-type/index.ts +2 -0
  137. package/src/http/bin/index.ts +2 -0
  138. package/src/http/index.ts +3 -0
  139. package/src/huawei/README.md +1 -0
  140. package/src/huawei/index.ts +2 -0
  141. package/src/huawei/moderation/index.ts +1 -0
  142. package/src/huawei/moderation/moderation.ts +355 -0
  143. package/src/huawei/obs/esdk-obs-nodejs.d.ts +87 -0
  144. package/src/huawei/obs/index.ts +1 -0
  145. package/src/huawei/obs/obs.ts +42 -0
  146. package/src/identifier/README.md +92 -0
  147. package/src/identifier/id.ts +119 -0
  148. package/src/identifier/index.ts +2 -0
  149. package/src/identifier/uuid.ts +187 -0
  150. package/src/index.ts +33 -1
  151. package/src/json/README.md +92 -0
  152. package/src/json/index.ts +1 -0
  153. package/src/json/repair.ts +18 -0
  154. package/src/log/README.md +79 -0
  155. package/src/log/index.ts +5 -0
  156. package/src/log/log-emitter.ts +72 -0
  157. package/src/log/log-record.ts +10 -0
  158. package/src/log/log-scheduler.ts +74 -0
  159. package/src/log/log-type.ts +8 -0
  160. package/src/log/logger.ts +554 -0
  161. package/src/openai/README.md +1 -0
  162. package/src/openai/index.ts +1 -0
  163. package/src/openai/openai.ts +510 -0
  164. package/src/orchestration/README.md +91 -0
  165. package/src/orchestration/coordination/barrier.ts +214 -0
  166. package/src/orchestration/coordination/count-down-latch.ts +215 -0
  167. package/src/orchestration/coordination/errors.ts +98 -0
  168. package/src/orchestration/coordination/index.ts +16 -0
  169. package/src/orchestration/coordination/internal/wait-constraints.ts +95 -0
  170. package/src/orchestration/coordination/internal/wait-queue.ts +109 -0
  171. package/src/orchestration/coordination/keyed-lock.ts +168 -0
  172. package/src/orchestration/coordination/mutex.ts +257 -0
  173. package/src/orchestration/coordination/permit.ts +127 -0
  174. package/src/orchestration/coordination/read-write-lock.ts +444 -0
  175. package/src/orchestration/coordination/semaphore.ts +280 -0
  176. package/src/orchestration/dispatching/dispatcher.ts +83 -0
  177. package/src/orchestration/dispatching/index.ts +2 -0
  178. package/src/orchestration/dispatching/selector/base-selector.ts +39 -0
  179. package/src/orchestration/dispatching/selector/down-count-selector.ts +119 -0
  180. package/src/orchestration/dispatching/selector/index.ts +2 -0
  181. package/src/orchestration/index.ts +3 -0
  182. package/src/orchestration/scheduling/index.ts +2 -0
  183. package/src/orchestration/scheduling/scheduler.ts +103 -0
  184. package/src/orchestration/scheduling/task.ts +32 -0
  185. package/src/random/README.md +56 -86
  186. package/src/random/base.ts +66 -0
  187. package/src/random/index.ts +5 -1
  188. package/src/random/random-boolean.ts +40 -0
  189. package/src/random/random-integer.ts +60 -0
  190. package/src/random/random-number.ts +72 -0
  191. package/src/random/random-string.ts +66 -0
  192. package/src/reactor/README.md +4 -0
  193. package/src/reactor/reactor-core/primitive.ts +9 -9
  194. package/src/reactor/reactor-core/reactive-system.ts +5 -5
  195. package/src/request/README.md +108 -0
  196. package/src/request/fetch/base.ts +108 -0
  197. package/src/request/fetch/browser.ts +285 -0
  198. package/src/request/fetch/general.ts +20 -0
  199. package/src/request/fetch/index.ts +4 -0
  200. package/src/request/fetch/nodejs.ts +285 -0
  201. package/src/request/index.ts +2 -0
  202. package/src/request/request/base.ts +250 -0
  203. package/src/request/request/general.ts +64 -0
  204. package/src/request/request/index.ts +3 -0
  205. package/src/request/request/resource.ts +68 -0
  206. package/src/result/README.md +4 -0
  207. package/src/result/controller.ts +54 -0
  208. package/src/result/either.ts +193 -0
  209. package/src/result/index.ts +2 -0
  210. package/src/route/README.md +105 -0
  211. package/src/route/adapter/browser.ts +122 -0
  212. package/src/route/adapter/driver.ts +56 -0
  213. package/src/route/adapter/index.ts +2 -0
  214. package/src/route/index.ts +3 -0
  215. package/src/route/router/index.ts +2 -0
  216. package/src/route/router/route.ts +630 -0
  217. package/src/route/router/router.ts +1642 -0
  218. package/src/route/uri/hash.ts +308 -0
  219. package/src/route/uri/index.ts +7 -0
  220. package/src/route/uri/pathname.ts +376 -0
  221. package/src/route/uri/search.ts +413 -0
  222. package/src/singleton/README.md +79 -0
  223. package/src/singleton/factory.ts +55 -0
  224. package/src/singleton/index.ts +2 -0
  225. package/src/singleton/manager.ts +204 -0
  226. package/src/socket/README.md +105 -0
  227. package/src/socket/client/index.ts +2 -0
  228. package/src/socket/client/socket-unit.ts +660 -0
  229. package/src/socket/client/socket.ts +203 -0
  230. package/src/socket/common/index.ts +2 -0
  231. package/src/socket/common/socket-unit-common.ts +23 -0
  232. package/src/socket/common/socket-unit-heartbeat.ts +427 -0
  233. package/src/socket/index.ts +3 -0
  234. package/src/socket/server/index.ts +3 -0
  235. package/src/socket/server/server.ts +183 -0
  236. package/src/socket/server/socket-unit.ts +449 -0
  237. package/src/socket/server/socket.ts +264 -0
  238. package/src/storage/README.md +107 -0
  239. package/src/storage/index.ts +1 -0
  240. package/src/storage/table.ts +449 -0
  241. package/src/timer/README.md +86 -0
  242. package/src/timer/expiration/expiration-manager.ts +594 -0
  243. package/src/timer/expiration/index.ts +3 -0
  244. package/src/timer/expiration/min-heap.ts +208 -0
  245. package/src/timer/expiration/remaining-manager.ts +241 -0
  246. package/src/timer/index.ts +1 -0
  247. package/src/tube/README.md +99 -0
  248. package/src/tube/helper.ts +138 -0
  249. package/src/tube/index.ts +2 -0
  250. package/src/tube/tube.ts +880 -0
  251. package/src/type/README.md +54 -307
  252. package/src/type/class.ts +2 -2
  253. package/src/type/index.ts +14 -14
  254. package/src/type/is.ts +265 -2
  255. package/src/type/object.ts +37 -0
  256. package/src/type/string.ts +7 -2
  257. package/src/type/tuple.ts +6 -6
  258. package/src/type/union.ts +16 -0
  259. package/src/web/README.md +77 -0
  260. package/src/web/capture.ts +35 -0
  261. package/src/web/clipboard.ts +97 -0
  262. package/src/web/dom.ts +117 -0
  263. package/src/web/download.ts +16 -0
  264. package/src/web/event.ts +46 -0
  265. package/src/web/index.ts +10 -0
  266. package/src/web/local-storage.ts +113 -0
  267. package/src/web/location.ts +28 -0
  268. package/src/web/permission.ts +172 -0
  269. package/src/web/script-loader.ts +432 -0
  270. package/src/weixin/README.md +1 -0
  271. package/src/weixin/index.ts +2 -0
  272. package/src/weixin/official-account/authorization.ts +159 -0
  273. package/src/weixin/official-account/index.ts +2 -0
  274. package/src/weixin/official-account/js-api.ts +134 -0
  275. package/src/weixin/open/index.ts +1 -0
  276. package/src/weixin/open/oauth2.ts +133 -0
  277. package/tests/unit/abort/abort-manager.spec.ts +225 -0
  278. package/tests/unit/abort/abort-signal-listener-manager.spec.ts +62 -0
  279. package/tests/unit/ai/ai.spec.ts +85 -0
  280. package/tests/unit/aio/content.spec.ts +105 -0
  281. package/tests/unit/aio/json.spec.ts +147 -0
  282. package/tests/unit/aio/prompt.spec.ts +111 -0
  283. package/tests/unit/basic/array.spec.ts +1 -1
  284. package/tests/unit/basic/error.spec.ts +16 -4
  285. package/tests/unit/basic/schedule.spec.ts +74 -0
  286. package/tests/unit/basic/stream.spec.ts +91 -38
  287. package/tests/unit/basic/string.spec.ts +0 -9
  288. package/tests/unit/color/rgb/analyze.spec.ts +110 -0
  289. package/tests/unit/color/rgb/construct.spec.ts +56 -0
  290. package/tests/unit/color/rgb/convert.spec.ts +60 -0
  291. package/tests/unit/color/rgb/derive.spec.ts +103 -0
  292. package/tests/unit/color/rgb/parse.spec.ts +66 -0
  293. package/tests/unit/color/rgb/serialize.spec.ts +46 -0
  294. package/tests/unit/color/xyz/analyze.spec.ts +33 -0
  295. package/tests/unit/color/xyz/construct.spec.ts +10 -0
  296. package/tests/unit/color/xyz/convert.spec.ts +18 -0
  297. package/tests/unit/credential/api-key.spec.ts +37 -0
  298. package/tests/unit/credential/bearer.spec.ts +23 -0
  299. package/tests/unit/credential/json-web-token.spec.ts +23 -0
  300. package/tests/unit/credential/password.spec.ts +41 -0
  301. package/tests/unit/cron/cron.spec.ts +84 -0
  302. package/tests/unit/css/class.spec.ts +157 -0
  303. package/tests/unit/environment/basic.spec.ts +20 -0
  304. package/tests/unit/environment/device.spec.ts +146 -0
  305. package/tests/unit/environment/feature.spec.ts +388 -0
  306. package/tests/unit/environment/geo.spec.ts +111 -0
  307. package/tests/unit/environment/runtime.spec.ts +364 -0
  308. package/tests/unit/environment/snapshot.spec.ts +4 -0
  309. package/tests/unit/environment/variable.spec.ts +190 -0
  310. package/tests/unit/event/class-event-proxy.spec.ts +225 -0
  311. package/tests/unit/event/event-manager.spec.ts +246 -0
  312. package/tests/unit/event/instance-event-proxy.spec.ts +187 -0
  313. package/tests/unit/exception/browser.spec.ts +213 -0
  314. package/tests/unit/exception/nodejs.spec.ts +144 -0
  315. package/tests/unit/exception/normalize.spec.ts +57 -0
  316. package/tests/unit/form/inputor-controller/base.spec.ts +458 -0
  317. package/tests/unit/form/inputor-controller/boolean.spec.ts +30 -0
  318. package/tests/unit/form/inputor-controller/file.spec.ts +27 -0
  319. package/tests/unit/form/inputor-controller/form.spec.ts +120 -0
  320. package/tests/unit/form/inputor-controller/helper.spec.ts +67 -0
  321. package/tests/unit/form/inputor-controller/multi-select.spec.ts +34 -0
  322. package/tests/unit/form/inputor-controller/number.spec.ts +36 -0
  323. package/tests/unit/form/inputor-controller/select.spec.ts +49 -0
  324. package/tests/unit/form/inputor-controller/text.spec.ts +34 -0
  325. package/tests/unit/http/api/api-core-host.spec.ts +207 -0
  326. package/tests/unit/http/api/api-schema.spec.ts +120 -0
  327. package/tests/unit/http/api/api-server.spec.ts +363 -0
  328. package/tests/unit/http/api/api-test.spec.ts +117 -0
  329. package/tests/unit/http/api/api.spec.ts +121 -0
  330. package/tests/unit/http/api-adapter/node-http.spec.ts +191 -0
  331. package/tests/unit/identifier/id.spec.ts +71 -0
  332. package/tests/unit/identifier/uuid.spec.ts +85 -0
  333. package/tests/unit/json/repair.spec.ts +11 -0
  334. package/tests/unit/log/log-emitter.spec.ts +33 -0
  335. package/tests/unit/log/log-scheduler.spec.ts +40 -0
  336. package/tests/unit/log/log-type.spec.ts +7 -0
  337. package/tests/unit/log/logger.spec.ts +237 -0
  338. package/tests/unit/openai/openai.spec.ts +64 -0
  339. package/tests/unit/orchestration/coordination/barrier.spec.ts +96 -0
  340. package/tests/unit/orchestration/coordination/count-down-latch.spec.ts +63 -0
  341. package/tests/unit/orchestration/coordination/errors.spec.ts +29 -0
  342. package/tests/unit/orchestration/coordination/keyed-lock.spec.ts +109 -0
  343. package/tests/unit/orchestration/coordination/mutex.spec.ts +132 -0
  344. package/tests/unit/orchestration/coordination/permit.spec.ts +43 -0
  345. package/tests/unit/orchestration/coordination/read-write-lock.spec.ts +154 -0
  346. package/tests/unit/orchestration/coordination/semaphore.spec.ts +135 -0
  347. package/tests/unit/orchestration/dispatching/dispatcher.spec.ts +41 -0
  348. package/tests/unit/orchestration/dispatching/selector/down-count-selector.spec.ts +81 -0
  349. package/tests/unit/orchestration/scheduling/scheduler.spec.ts +103 -0
  350. package/tests/unit/random/base.spec.ts +58 -0
  351. package/tests/unit/random/random-boolean.spec.ts +25 -0
  352. package/tests/unit/random/random-integer.spec.ts +32 -0
  353. package/tests/unit/random/random-number.spec.ts +33 -0
  354. package/tests/unit/random/random-string.spec.ts +22 -0
  355. package/tests/unit/reactor/alien-signals-effect.spec.ts +11 -10
  356. package/tests/unit/reactor/preact-signal.spec.ts +1 -2
  357. package/tests/unit/request/fetch/browser.spec.ts +222 -0
  358. package/tests/unit/request/fetch/general.spec.ts +43 -0
  359. package/tests/unit/request/fetch/nodejs.spec.ts +225 -0
  360. package/tests/unit/request/request/base.spec.ts +385 -0
  361. package/tests/unit/request/request/general.spec.ts +161 -0
  362. package/tests/unit/route/router/route.spec.ts +431 -0
  363. package/tests/unit/route/router/router.spec.ts +407 -0
  364. package/tests/unit/route/uri/hash.spec.ts +72 -0
  365. package/tests/unit/route/uri/pathname.spec.ts +147 -0
  366. package/tests/unit/route/uri/search.spec.ts +107 -0
  367. package/tests/unit/singleton/singleton.spec.ts +49 -0
  368. package/tests/unit/socket/client.spec.ts +208 -0
  369. package/tests/unit/socket/server.spec.ts +135 -0
  370. package/tests/unit/socket/socket-unit-heartbeat.spec.ts +214 -0
  371. package/tests/unit/storage/table.spec.ts +620 -0
  372. package/tests/unit/timer/expiration/expiration-manager.spec.ts +464 -0
  373. package/tests/unit/timer/expiration/min-heap.spec.ts +71 -0
  374. package/tests/unit/timer/expiration/remaining-manager.spec.ts +234 -0
  375. package/tests/unit/tube/helper.spec.ts +139 -0
  376. package/tests/unit/tube/tube.spec.ts +501 -0
  377. package/.oxlintrc.json +0 -5
  378. package/src/random/uuid.ts +0 -103
  379. package/tests/unit/random/uuid.spec.ts +0 -37
@@ -0,0 +1,127 @@
1
+ import { randomUUID } from "node:crypto"
2
+ import fs, { existsSync, mkdirSync } from "node:fs"
3
+ import path from "node:path"
4
+ import ts from "typescript"
5
+
6
+ import { getGlobalLogger } from "#Source/log/index.ts"
7
+
8
+ import { getCalcCode } from "./calc-code.ts"
9
+
10
+ export interface GenerateApiTypeOptions {
11
+ importFrom: string
12
+ /**
13
+ * Path to tsconfig.json file.
14
+ */
15
+ tsconfigFilePath: string
16
+ /**
17
+ * Path to Api folder.
18
+ */
19
+ apiFolderPath: string
20
+ /**
21
+ * Path to output file.
22
+ */
23
+ outputFilePath: string
24
+ }
25
+ const toAbsolutePath = (options: GenerateApiTypeOptions): GenerateApiTypeOptions => {
26
+ const { tsconfigFilePath, apiFolderPath, outputFilePath } = options
27
+ const absoluteTsconfigFilePath = path.resolve(tsconfigFilePath)
28
+ const absoluteApiFolderPath = path.resolve(apiFolderPath)
29
+ const absoluteOutputFilePath = path.resolve(outputFilePath)
30
+ console.log("tsconfigFilePath:", absoluteTsconfigFilePath)
31
+ console.log("apiFolderPath:", absoluteApiFolderPath)
32
+ console.log("outputFilePath:", absoluteOutputFilePath)
33
+ return {
34
+ ...options,
35
+ tsconfigFilePath: absoluteTsconfigFilePath,
36
+ apiFolderPath: absoluteApiFolderPath,
37
+ outputFilePath: absoluteOutputFilePath,
38
+ }
39
+ }
40
+ export const generateApiType = (options: GenerateApiTypeOptions): void => {
41
+ const {
42
+ importFrom,
43
+ tsconfigFilePath,
44
+ apiFolderPath,
45
+ outputFilePath,
46
+ } = toAbsolutePath(options)
47
+ const logger = getGlobalLogger()
48
+
49
+ const tsconfigJson = ts.parseConfigFileTextToJson(tsconfigFilePath, fs.readFileSync(tsconfigFilePath, "utf8"))
50
+ if (tsconfigJson.error) {
51
+ throw new Error("无法解析 tsconfig.json")
52
+ }
53
+ const parsedTsconfig = ts.parseJsonConfigFileContent(tsconfigJson.config, ts.sys, path.resolve(tsconfigFilePath, ".."))
54
+ logger.debug("成功解析 tsconfig 文件...")
55
+
56
+ const projectHost = ts.createCompilerHost(parsedTsconfig.options)
57
+ const project = ts.createProgram(parsedTsconfig.fileNames, parsedTsconfig.options, projectHost)
58
+ logger.debug("成功读取项目...")
59
+
60
+ const allSourceFiles = project.getSourceFiles()
61
+ const apiSourceFiles = allSourceFiles.filter((sourceFile) => {
62
+ // 我们约定接口蓝图必须名为 type.ts
63
+ // oxlint-disable-next-line no-useless-escape unicorn/prefer-string-raw
64
+ return new RegExp(`${apiFolderPath.replaceAll("\\", "\\\\")}.*type\.ts`).test(path.resolve(sourceFile.fileName))
65
+ })
66
+ logger.debug(`找到 ${apiSourceFiles.length} 个接口...`)
67
+
68
+ // 为每一个接口文件生成一个虚拟计算文件
69
+ const apiTypeCalcFileNames = apiSourceFiles.map(sourceFile => sourceFile.fileName.replace("type.ts", `type-calculate-${randomUUID()}.ts`))
70
+ const calcCode = getCalcCode({ importFrom })
71
+ const apiTypeCalcFiles = apiTypeCalcFileNames.map((filename) => {
72
+ return {
73
+ name: filename,
74
+ sourceFile: ts.createSourceFile(filename, calcCode, ts.ScriptTarget.Latest),
75
+ }
76
+ })
77
+ logger.debug("成功生成虚拟计算文件...")
78
+
79
+ const newProject = ts.createProgram({
80
+ rootNames: [...parsedTsconfig.fileNames, ...apiTypeCalcFileNames],
81
+ options: parsedTsconfig.options,
82
+ host: {
83
+ ...projectHost,
84
+ getSourceFile: (filename) => {
85
+ const apiTypeCalcSourceFile = apiTypeCalcFiles.find(apiTypeCalcSourceFile => apiTypeCalcSourceFile.name === filename)
86
+ if (apiTypeCalcSourceFile !== undefined) {
87
+ return apiTypeCalcSourceFile.sourceFile
88
+ }
89
+ return project.getSourceFile(filename)
90
+ },
91
+ },
92
+ oldProgram: project,
93
+ })
94
+ logger.debug("成功生成虚拟项目...")
95
+
96
+ const check = newProject.getTypeChecker()
97
+ logger.debug("成功生成虚拟项目类型检查器...")
98
+
99
+ const result: string[] = []
100
+ apiSourceFiles.forEach((apiSourceFile, index) => {
101
+ logger.info(`处理(${index + 1} / ${apiSourceFiles.length}):${apiSourceFile.fileName}`)
102
+
103
+ const apiCalcSourceFile = apiTypeCalcFiles[index]?.sourceFile
104
+ if (apiCalcSourceFile === undefined) {
105
+ throw new Error("非预期的数组越界")
106
+ }
107
+
108
+ for (const node of apiCalcSourceFile.statements) {
109
+ if (ts.isExportAssignment(node) && node.isExportEquals === undefined) {
110
+ const apiType = check.getTypeAtLocation(node.expression)
111
+ const typeString = check.typeToString(apiType, undefined, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope)
112
+ result.push(typeString)
113
+ }
114
+ }
115
+ })
116
+ logger.debug("成功处理所有接口...")
117
+
118
+ const outputPathAbs = path.resolve(outputFilePath)
119
+ const outDir = path.dirname(outputPathAbs)
120
+
121
+ if (!existsSync(outDir)) {
122
+ mkdirSync(outDir, { recursive: true })
123
+ }
124
+
125
+ fs.writeFileSync(outputPathAbs, `export type ApiType = [${result.join(",")}]\n`)
126
+ logger.debug(`生成成功:${outputPathAbs}`)
127
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./calc-code.ts"
2
+ export * from "./gen-api-type.ts"
@@ -0,0 +1,2 @@
1
+ export * from "./gen-api-list/index.ts"
2
+ export * from "./gen-api-type/index.ts"
@@ -0,0 +1,3 @@
1
+ export * from "./api/index.ts"
2
+ export * from "./api-adapter/index.ts"
3
+ export * from "./bin/index.ts"
@@ -0,0 +1 @@
1
+ # Huawei
@@ -0,0 +1,2 @@
1
+ export * from "./moderation/index.ts"
2
+ export * from "./obs/index.ts"
@@ -0,0 +1 @@
1
+ export * from "./moderation.ts"
@@ -0,0 +1,355 @@
1
+ import { fetch } from "undici"
2
+ import { type } from "arktype"
3
+
4
+ import type { LoggerFriendly, LoggerFriendlyOptions } from "#Source/log/index.ts"
5
+ import { Logger } from "#Source/log/index.ts"
6
+
7
+ type TextEventType =
8
+ | "nickname" // 昵称
9
+ | "title" // 标题
10
+ | "article" // 帖子
11
+ | "comment" // 评论
12
+ | "barrage" // 弹幕
13
+ | "search" // 搜索栏
14
+ | "profile" // 个人简介
15
+ type ImageEventType =
16
+ | "head_image" // 头像
17
+ | "album" // 相册
18
+ | "dynamic" // 动态
19
+ | "article" // 帖子
20
+ | "comment" // 评论
21
+ | "room_cover" // 房间封面
22
+ | "group_message" // 群聊图片
23
+ | "message" // 私聊图片
24
+ | "product" // 商品图片
25
+ type ImageCategories =
26
+ | "terrorism" // 暴恐元素的检测
27
+ | "porn" // 涉黄元素的检测
28
+ | "image_text" // 广告图文的检测
29
+ const SUGGESTION_TYPE = {
30
+ block: "block", // 包含敏感信息,不通过
31
+ pass: "pass", // 不包含敏感信息,通过
32
+ review: "review", // 需要人工复检
33
+ } as const
34
+ type SuggestionType = typeof SUGGESTION_TYPE[keyof typeof SUGGESTION_TYPE]
35
+ const suggestionTypeSchema = type.or("'block'", "'pass'", "'review'")
36
+
37
+ const textModerationResponseSchema = type({
38
+ result: type({
39
+ suggestion: suggestionTypeSchema,
40
+ }),
41
+ })
42
+ export interface ModerationTextOptions {
43
+ input: string
44
+ eventType: TextEventType
45
+ }
46
+ export interface ModerationTextResult {
47
+ suggestion: SuggestionType
48
+ }
49
+ const imageModerationResponseSchema = type({
50
+ result: type({
51
+ suggestion: suggestionTypeSchema,
52
+ }),
53
+ })
54
+ export interface ModerationImageOptions {
55
+ mode: "base64" | "url"
56
+ input: string
57
+ eventType: ImageEventType
58
+ categories: ImageCategories[]
59
+ }
60
+ export interface ModerationImageResult {
61
+ suggestion: SuggestionType
62
+ }
63
+
64
+ export interface ModerationOptions extends LoggerFriendlyOptions {
65
+ userName: string
66
+ userPwd: string
67
+ domainName: string
68
+ projectName: string
69
+ projectId: string
70
+ endpoint: string
71
+ /**
72
+ * token 有效期,单位:毫秒,默认 11 小时
73
+ */
74
+ tokenValidTime?: number | undefined
75
+ }
76
+ interface ResolvedModerationOptions {
77
+ userName: string
78
+ userPwd: string
79
+ domainName: string
80
+ projectName: string
81
+ projectId: string
82
+ endpoint: string
83
+ tokenValidTime: number
84
+ }
85
+ export class Moderation implements LoggerFriendly {
86
+ readonly options: ResolvedModerationOptions
87
+
88
+ readonly logger: Logger
89
+
90
+ protected tokenGetTime: number | null = null
91
+ protected token: string | null = null
92
+
93
+ constructor(options: ModerationOptions) {
94
+ this.options = {
95
+ ...options,
96
+ // token 有效期 12 小时,保险起见,我们超过 11 小时就重写获取一次,以免调用到一半忽然失效
97
+ // 请求新 token 并不会造成旧 token 失效,所以想象中的问题不会发生
98
+ tokenValidTime: options.tokenValidTime ?? (11 * 60 * 60 * 1_000),
99
+ }
100
+
101
+ this.logger = Logger.fromOptions(options).setDefaultName("Moderation")
102
+ }
103
+
104
+ /**
105
+ * {@link https://support.huaweicloud.com/api-moderation/moderation_03_0003.html}
106
+ * {@link https://support.huaweicloud.com/api-iam/iam_30_0001.html}
107
+ */
108
+ protected async getNewToken(): Promise<string> {
109
+ const {
110
+ userName,
111
+ userPwd,
112
+ domainName,
113
+ projectName,
114
+ } = this.options
115
+ const logger = this.logger
116
+
117
+ try {
118
+ logger.log("准备获取 token...")
119
+
120
+ const response = await fetch(
121
+ `https://iam.${projectName}.myhuaweicloud.com/v3/auth/tokens`,
122
+ {
123
+ method: "POST",
124
+ headers: { "Content-Type": "application/json" },
125
+ body: JSON.stringify({
126
+ auth: {
127
+ identity: {
128
+ methods: ["password"],
129
+ password: {
130
+ user: {
131
+ name: userName,
132
+ password: userPwd,
133
+ domain: {
134
+ name: domainName,
135
+ },
136
+ },
137
+ },
138
+ },
139
+ scope: {
140
+ project: {
141
+ name: projectName,
142
+ },
143
+ },
144
+ },
145
+ }),
146
+ }
147
+ )
148
+
149
+ const responseText = await response.text()
150
+ const responseBody = responseText === ""
151
+ ? null
152
+ : (() => {
153
+ try {
154
+ return JSON.parse(responseText) as unknown
155
+ }
156
+ catch {
157
+ return responseText
158
+ }
159
+ })()
160
+ const errorMessage = typeof responseBody === "string"
161
+ ? responseBody
162
+ : (() => {
163
+ try {
164
+ return JSON.stringify(responseBody)
165
+ }
166
+ catch {
167
+ return String(responseBody)
168
+ }
169
+ })()
170
+
171
+ if (response.ok === false) {
172
+ throw new Error(errorMessage)
173
+ }
174
+
175
+ const token = response.headers.get("x-subject-token")
176
+ if (token === null || token === undefined) {
177
+ throw new Error(errorMessage)
178
+ }
179
+
180
+ logger.log("获取 token 成功")
181
+ this.token = token
182
+ this.tokenGetTime = Date.now()
183
+ return token
184
+ } catch (exception) {
185
+ logger.error(`获取 toekn 失败:${String(exception)}`)
186
+ throw exception
187
+ }
188
+ }
189
+
190
+ protected async getToken(): Promise<string> {
191
+ const token = this.token
192
+ const tokenGetTime = this.tokenGetTime
193
+ const { tokenValidTime } = this.options
194
+
195
+ if (
196
+ token === null
197
+ || tokenGetTime === null
198
+ || tokenGetTime + tokenValidTime < Date.now()
199
+ ) {
200
+ return await this.getNewToken()
201
+ } else {
202
+ return await Promise.resolve(token)
203
+ }
204
+ }
205
+
206
+ /**
207
+ * @see {@link https://support.huaweicloud.com/api-moderation/moderation_03_0069.html}
208
+ */
209
+ async text(
210
+ options: ModerationTextOptions
211
+ ): Promise<ModerationTextResult> {
212
+ const { input, eventType } = options
213
+ const { endpoint, projectId } = this.options
214
+ const logger = this.logger
215
+
216
+ // empty string is always safe
217
+ if (input === "") {
218
+ return { suggestion: "pass" }
219
+ }
220
+
221
+ try {
222
+ logger.log(`开始调用 text 检查,输入:${input},类型:${eventType}`)
223
+
224
+ const token = await this.getToken()
225
+ const responseRaw = await fetch(
226
+ `https://${endpoint}/v3/${projectId}/moderation/text`,
227
+ {
228
+ method: "POST",
229
+ headers: {
230
+ "Content-Type": "application/json",
231
+ "X-Auth-Token": token,
232
+ },
233
+ body: JSON.stringify({
234
+ event_type: eventType,
235
+ data: {
236
+ language: "zh",
237
+ text: input,
238
+ },
239
+ glossary_names: [],
240
+ white_glossary_names: [],
241
+ categories: ["terrorism", "porn", "ban", "abuse"],
242
+ }),
243
+ }
244
+ )
245
+ const responseText = await responseRaw.text()
246
+ const response = responseText === ""
247
+ ? null
248
+ : (() => {
249
+ try {
250
+ return JSON.parse(responseText) as unknown
251
+ }
252
+ catch {
253
+ return responseText
254
+ }
255
+ })()
256
+
257
+ if (responseRaw.ok === false) {
258
+ throw new Error(typeof response === "string" ? response : JSON.stringify(response))
259
+ }
260
+
261
+ const validateResult = await textModerationResponseSchema["~standard"].validate(response)
262
+ if (validateResult.issues !== undefined) {
263
+ logger.error(`非预期的返回结果:${JSON.stringify(response)}`)
264
+ throw new Error("非预期的返回结果")
265
+ }
266
+
267
+ logger.log(`调用成功:${JSON.stringify(validateResult)}`)
268
+ return validateResult.value.result
269
+ }
270
+ catch (exception) {
271
+ logger.error(`调用失败:${String(exception)}`)
272
+ throw exception
273
+ }
274
+ }
275
+
276
+ /**
277
+ * @see {@link https://support.huaweicloud.com/api-moderation/moderation_03_0086.html}
278
+ */
279
+ async image(
280
+ options: ModerationImageOptions
281
+ ): Promise<ModerationImageResult> {
282
+ const { mode, input, eventType, categories } = options
283
+ const { endpoint, projectId } = this.options
284
+ const logger = this.logger
285
+
286
+ try {
287
+ logger.log(`开始调用 image 检查,输入:${input},类型:${eventType}`)
288
+
289
+ const token = await this.getToken()
290
+
291
+ interface argType {
292
+ event_type: ImageEventType
293
+ categories: ImageCategories[]
294
+ image?: string | undefined
295
+ url?: string | undefined
296
+ }
297
+ const arg: argType = {
298
+ event_type: eventType,
299
+ categories,
300
+ image: mode === "base64" ? input : undefined,
301
+ url: mode === "url" ? input : undefined,
302
+ }
303
+
304
+ if (mode === "base64") {
305
+ arg.image = input
306
+ }
307
+ else if (mode === "url") {
308
+ arg.url = input
309
+ }
310
+ else {
311
+ throw new Error("意外的 mode")
312
+ }
313
+
314
+ const responseRaw = await fetch(
315
+ `https://${endpoint}/v3/${projectId}/moderation/image`,
316
+ {
317
+ method: "POST",
318
+ headers: {
319
+ "Content-Type": "application/json",
320
+ "X-Auth-Token": token,
321
+ },
322
+ body: JSON.stringify(arg),
323
+ }
324
+ )
325
+ const responseText = await responseRaw.text()
326
+ const response = responseText === ""
327
+ ? null
328
+ : (() => {
329
+ try {
330
+ return JSON.parse(responseText) as unknown
331
+ }
332
+ catch {
333
+ return responseText
334
+ }
335
+ })()
336
+
337
+ if (responseRaw.ok === false) {
338
+ throw new Error(typeof response === "string" ? response : JSON.stringify(response))
339
+ }
340
+
341
+ const validateResult = await imageModerationResponseSchema["~standard"].validate(response)
342
+ if (validateResult.issues !== undefined) {
343
+ logger.error(`非预期的返回结果:${JSON.stringify(response)}`)
344
+ throw new Error("非预期的返回结果")
345
+ }
346
+
347
+ logger.log(`调用成功:${JSON.stringify(validateResult.value)}`)
348
+ return validateResult.value.result
349
+ }
350
+ catch (exception) {
351
+ logger.error(`调用失败:${String(exception)}`)
352
+ throw exception
353
+ }
354
+ }
355
+ }
@@ -0,0 +1,87 @@
1
+ declare module "esdk-obs-nodejs" {
2
+ import type { Readable } from "node:stream"
3
+
4
+ interface CommonMsg {
5
+ Status: number
6
+ Code: string
7
+ Message: string
8
+ HostId: string
9
+ RequestId: string
10
+ Id2: string
11
+ Indicator: string
12
+ }
13
+
14
+ type ObsResult<InterfaceResult> = Promise<{
15
+ CommonMsg: CommonMsg
16
+ InterfaceResult: InterfaceResult
17
+ }>
18
+
19
+ export interface GetBucketMetadataOptions {
20
+ Bucket: string
21
+ }
22
+ export interface GetBucketMetadataInterfaceResult {
23
+ RequestId: string
24
+ StorageClass: string
25
+ Location: string
26
+ ObsVersion: string
27
+ AllowOrigin: string
28
+ AllowHeader: string
29
+ AllowMethod: string
30
+ ExposeHeader: string
31
+ MaxAgeSeconds: string
32
+ }
33
+ export type GetBucketMetadataResult = ObsResult<GetBucketMetadataInterfaceResult>
34
+
35
+ export interface PutObjectOptions {
36
+ Bucket: string
37
+ Key: string
38
+ Body: string | Readable
39
+ ContentType?: string | undefined
40
+ ProgressCallback?: ((count: number, objectTotalSize: number, time: number) => void) | undefined
41
+ }
42
+ export interface PutObjectInterfaceResult {
43
+ RequestId: string
44
+ ETag: string
45
+ VersionId: string
46
+ StorageClass: string
47
+ SseKms: string
48
+ SseKmsKey: string
49
+ SseC: string
50
+ SseCKeyMd5: string
51
+ }
52
+ export type PutObjectResult = ObsResult<PutObjectInterfaceResult>
53
+
54
+ export type DeleteObjectOptions = {
55
+ Bucket: string
56
+ Key: string
57
+ VersionId?: string | undefined
58
+ ProgressCallback?: ((count: number, objectTotalSize: number, time: number) => void) | undefined
59
+ }
60
+ export type DeleteObjectInterfaceResult = {
61
+ RequestId: string
62
+ DeleteMarker: string
63
+ VersionId: string
64
+ }
65
+ export type DeleteObjectResult = ObsResult<DeleteObjectInterfaceResult>
66
+
67
+ export interface ObsClientOptions {
68
+ access_key_id: string
69
+ secret_access_key: string
70
+ server: string
71
+ }
72
+ export class ObsClient {
73
+ constructor(options: ObsClientOptions)
74
+
75
+ GetBucketMetadata: (
76
+ options: GetBucketMetadataOptions
77
+ ) => GetBucketMetadataResult
78
+
79
+ putObject: (
80
+ options: PutObjectOptions
81
+ ) => PutObjectResult
82
+
83
+ deleteObject: (
84
+ options: DeleteObjectOptions
85
+ ) => DeleteObjectResult
86
+ }
87
+ }
@@ -0,0 +1 @@
1
+ export * from "./obs.ts"
@@ -0,0 +1,42 @@
1
+ import type { DeleteObjectOptions, DeleteObjectResult, PutObjectOptions, PutObjectResult } from "esdk-obs-nodejs"
2
+ import { ObsClient } from "esdk-obs-nodejs"
3
+
4
+ export interface ObsOptions {
5
+ accessKeyId: string
6
+ secretAccessKey: string
7
+ server: string
8
+ }
9
+ /**
10
+ * @see {@link https://www.huaweicloud.com/product/obs.html | 华为云对象存储服务}
11
+ */
12
+ export class Obs {
13
+ protected obsClient: ObsClient
14
+
15
+ constructor(options: ObsOptions) {
16
+ this.obsClient = new ObsClient({
17
+ access_key_id: options.accessKeyId,
18
+ secret_access_key: options.secretAccessKey,
19
+ server: options.server
20
+ })
21
+ }
22
+
23
+ async putObject(
24
+ options: PutObjectOptions
25
+ ): Promise<PutObjectResult> {
26
+ const result = await this.obsClient.putObject(options)
27
+ if (result.CommonMsg.Status >= 300) {
28
+ throw new Error(result.CommonMsg.Message)
29
+ }
30
+ return result
31
+ }
32
+
33
+ async deleteObject(
34
+ options: DeleteObjectOptions
35
+ ): Promise<DeleteObjectResult> {
36
+ const result = await this.obsClient.deleteObject(options)
37
+ if (result.CommonMsg.Status >= 300) {
38
+ throw new Error(result.CommonMsg.Message)
39
+ }
40
+ return result
41
+ }
42
+ }