@struktoai/mirage-browser 0.0.8-alpha.1 → 0.0.8

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 (289) hide show
  1. package/README.md +140 -46
  2. package/dist/core/opfs/append.d.ts +1 -2
  3. package/dist/core/opfs/append.d.ts.map +1 -1
  4. package/dist/core/opfs/append.js +2 -5
  5. package/dist/core/opfs/append.js.map +1 -1
  6. package/dist/core/opfs/capacity.d.ts +8 -0
  7. package/dist/core/opfs/capacity.d.ts.map +1 -0
  8. package/dist/core/opfs/capacity.js +42 -0
  9. package/dist/core/opfs/capacity.js.map +1 -0
  10. package/dist/core/opfs/stream.d.ts.map +1 -1
  11. package/dist/core/opfs/stream.js +2 -0
  12. package/dist/core/opfs/stream.js.map +1 -1
  13. package/dist/core/opfs/write.d.ts +1 -2
  14. package/dist/core/opfs/write.d.ts.map +1 -1
  15. package/dist/core/opfs/write.js +2 -5
  16. package/dist/core/opfs/write.js.map +1 -1
  17. package/dist/index.d.ts +79 -99
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +53 -91
  20. package/dist/index.js.map +1 -1
  21. package/dist/io/gateway.d.ts +8 -0
  22. package/dist/io/gateway.d.ts.map +1 -0
  23. package/dist/io/gateway.js +238 -0
  24. package/dist/io/gateway.js.map +1 -0
  25. package/dist/io/network.d.ts +21 -0
  26. package/dist/io/network.d.ts.map +1 -0
  27. package/dist/io/network.js +131 -0
  28. package/dist/io/network.js.map +1 -0
  29. package/dist/io/spool.d.ts +2 -0
  30. package/dist/io/spool.d.ts.map +1 -0
  31. package/dist/io/spool.js +68 -0
  32. package/dist/io/spool.js.map +1 -0
  33. package/dist/vfs/aliyun/aliyun.d.ts +4 -5
  34. package/dist/vfs/aliyun/aliyun.d.ts.map +1 -1
  35. package/dist/vfs/aliyun/aliyun.js +2 -4
  36. package/dist/vfs/aliyun/aliyun.js.map +1 -1
  37. package/dist/vfs/aliyun/config.d.ts +22 -11
  38. package/dist/vfs/aliyun/config.d.ts.map +1 -1
  39. package/dist/vfs/aliyun/config.js +2 -7
  40. package/dist/vfs/aliyun/config.js.map +1 -1
  41. package/dist/vfs/backblaze/backblaze.d.ts +4 -5
  42. package/dist/vfs/backblaze/backblaze.d.ts.map +1 -1
  43. package/dist/vfs/backblaze/backblaze.js +2 -4
  44. package/dist/vfs/backblaze/backblaze.js.map +1 -1
  45. package/dist/vfs/backblaze/config.d.ts +22 -11
  46. package/dist/vfs/backblaze/config.d.ts.map +1 -1
  47. package/dist/vfs/backblaze/config.js +2 -7
  48. package/dist/vfs/backblaze/config.js.map +1 -1
  49. package/dist/vfs/ceph/ceph.d.ts +4 -5
  50. package/dist/vfs/ceph/ceph.d.ts.map +1 -1
  51. package/dist/vfs/ceph/ceph.js +2 -4
  52. package/dist/vfs/ceph/ceph.js.map +1 -1
  53. package/dist/vfs/ceph/config.d.ts +22 -10
  54. package/dist/vfs/ceph/config.d.ts.map +1 -1
  55. package/dist/vfs/ceph/config.js +1 -7
  56. package/dist/vfs/ceph/config.js.map +1 -1
  57. package/dist/vfs/digitalocean/config.d.ts +22 -11
  58. package/dist/vfs/digitalocean/config.d.ts.map +1 -1
  59. package/dist/vfs/digitalocean/config.js +2 -7
  60. package/dist/vfs/digitalocean/config.js.map +1 -1
  61. package/dist/vfs/digitalocean/digitalocean.d.ts +4 -5
  62. package/dist/vfs/digitalocean/digitalocean.d.ts.map +1 -1
  63. package/dist/vfs/digitalocean/digitalocean.js +2 -4
  64. package/dist/vfs/digitalocean/digitalocean.js.map +1 -1
  65. package/dist/vfs/discord/config.d.ts +5 -14
  66. package/dist/vfs/discord/config.d.ts.map +1 -1
  67. package/dist/vfs/discord/config.js +11 -18
  68. package/dist/vfs/discord/config.js.map +1 -1
  69. package/dist/vfs/discord/discord.d.ts +7 -10
  70. package/dist/vfs/discord/discord.d.ts.map +1 -1
  71. package/dist/vfs/discord/discord.js +7 -11
  72. package/dist/vfs/discord/discord.js.map +1 -1
  73. package/dist/vfs/gcs/config.d.ts +34 -15
  74. package/dist/vfs/gcs/config.d.ts.map +1 -1
  75. package/dist/vfs/gcs/config.js +12 -6
  76. package/dist/vfs/gcs/config.js.map +1 -1
  77. package/dist/vfs/gcs/gcs.d.ts +4 -5
  78. package/dist/vfs/gcs/gcs.d.ts.map +1 -1
  79. package/dist/vfs/gcs/gcs.js +2 -4
  80. package/dist/vfs/gcs/gcs.js.map +1 -1
  81. package/dist/vfs/minio/config.d.ts +22 -10
  82. package/dist/vfs/minio/config.d.ts.map +1 -1
  83. package/dist/vfs/minio/config.js +1 -7
  84. package/dist/vfs/minio/config.js.map +1 -1
  85. package/dist/vfs/minio/minio.d.ts +4 -5
  86. package/dist/vfs/minio/minio.d.ts.map +1 -1
  87. package/dist/vfs/minio/minio.js +2 -4
  88. package/dist/vfs/minio/minio.js.map +1 -1
  89. package/dist/vfs/mongodb/http_driver.d.ts +2 -0
  90. package/dist/vfs/mongodb/http_driver.d.ts.map +1 -1
  91. package/dist/vfs/mongodb/http_driver.js +2 -1
  92. package/dist/vfs/mongodb/http_driver.js.map +1 -1
  93. package/dist/vfs/mongodb/mongodb.d.ts +10 -11
  94. package/dist/vfs/mongodb/mongodb.d.ts.map +1 -1
  95. package/dist/vfs/mongodb/mongodb.js +8 -7
  96. package/dist/vfs/mongodb/mongodb.js.map +1 -1
  97. package/dist/vfs/notion/config.d.ts +4 -15
  98. package/dist/vfs/notion/config.d.ts.map +1 -1
  99. package/dist/vfs/notion/config.js +7 -17
  100. package/dist/vfs/notion/config.js.map +1 -1
  101. package/dist/vfs/notion/notion.d.ts +7 -10
  102. package/dist/vfs/notion/notion.d.ts.map +1 -1
  103. package/dist/vfs/notion/notion.js +5 -10
  104. package/dist/vfs/notion/notion.js.map +1 -1
  105. package/dist/vfs/oci/config.d.ts +25 -11
  106. package/dist/vfs/oci/config.d.ts.map +1 -1
  107. package/dist/vfs/oci/config.js +7 -7
  108. package/dist/vfs/oci/config.js.map +1 -1
  109. package/dist/vfs/oci/oci.d.ts +4 -5
  110. package/dist/vfs/oci/oci.d.ts.map +1 -1
  111. package/dist/vfs/oci/oci.js +2 -4
  112. package/dist/vfs/oci/oci.js.map +1 -1
  113. package/dist/vfs/opfs/opfs.d.ts +18 -11
  114. package/dist/vfs/opfs/opfs.d.ts.map +1 -1
  115. package/dist/vfs/opfs/opfs.js +62 -38
  116. package/dist/vfs/opfs/opfs.js.map +1 -1
  117. package/dist/vfs/postgres/neon_driver.d.ts +3 -1
  118. package/dist/vfs/postgres/neon_driver.d.ts.map +1 -1
  119. package/dist/vfs/postgres/neon_driver.js +34 -3
  120. package/dist/vfs/postgres/neon_driver.js.map +1 -1
  121. package/dist/vfs/postgres/postgres.d.ts +10 -11
  122. package/dist/vfs/postgres/postgres.d.ts.map +1 -1
  123. package/dist/vfs/postgres/postgres.js +6 -7
  124. package/dist/vfs/postgres/postgres.js.map +1 -1
  125. package/dist/vfs/qingstor/config.d.ts +22 -11
  126. package/dist/vfs/qingstor/config.d.ts.map +1 -1
  127. package/dist/vfs/qingstor/config.js +2 -7
  128. package/dist/vfs/qingstor/config.js.map +1 -1
  129. package/dist/vfs/qingstor/qingstor.d.ts +4 -5
  130. package/dist/vfs/qingstor/qingstor.d.ts.map +1 -1
  131. package/dist/vfs/qingstor/qingstor.js +2 -4
  132. package/dist/vfs/qingstor/qingstor.js.map +1 -1
  133. package/dist/vfs/r2/config.d.ts +27 -11
  134. package/dist/vfs/r2/config.d.ts.map +1 -1
  135. package/dist/vfs/r2/config.js +11 -7
  136. package/dist/vfs/r2/config.js.map +1 -1
  137. package/dist/vfs/r2/r2.d.ts +4 -5
  138. package/dist/vfs/r2/r2.d.ts.map +1 -1
  139. package/dist/vfs/r2/r2.js +2 -4
  140. package/dist/vfs/r2/r2.js.map +1 -1
  141. package/dist/vfs/redis/redis.d.ts +5 -1
  142. package/dist/vfs/redis/redis.d.ts.map +1 -1
  143. package/dist/vfs/redis/redis.js +1 -1
  144. package/dist/vfs/redis/redis.js.map +1 -1
  145. package/dist/vfs/redis/store.d.ts +2 -0
  146. package/dist/vfs/redis/store.d.ts.map +1 -1
  147. package/dist/vfs/redis/store.js +24 -5
  148. package/dist/vfs/redis/store.js.map +1 -1
  149. package/dist/vfs/registry.d.ts.map +1 -1
  150. package/dist/vfs/registry.js +87 -85
  151. package/dist/vfs/registry.js.map +1 -1
  152. package/dist/vfs/s3/config.d.ts +17 -5
  153. package/dist/vfs/s3/config.d.ts.map +1 -1
  154. package/dist/vfs/s3/config.js +7 -7
  155. package/dist/vfs/s3/config.js.map +1 -1
  156. package/dist/vfs/s3/s3.d.ts +6 -9
  157. package/dist/vfs/s3/s3.d.ts.map +1 -1
  158. package/dist/vfs/s3/s3.js +5 -10
  159. package/dist/vfs/s3/s3.js.map +1 -1
  160. package/dist/vfs/s3_alias.d.ts +22 -32
  161. package/dist/vfs/s3_alias.d.ts.map +1 -1
  162. package/dist/vfs/s3_alias.js +35 -23
  163. package/dist/vfs/s3_alias.js.map +1 -1
  164. package/dist/vfs/scaleway/config.d.ts +22 -11
  165. package/dist/vfs/scaleway/config.d.ts.map +1 -1
  166. package/dist/vfs/scaleway/config.js +2 -7
  167. package/dist/vfs/scaleway/config.js.map +1 -1
  168. package/dist/vfs/scaleway/scaleway.d.ts +4 -5
  169. package/dist/vfs/scaleway/scaleway.d.ts.map +1 -1
  170. package/dist/vfs/scaleway/scaleway.js +2 -4
  171. package/dist/vfs/scaleway/scaleway.js.map +1 -1
  172. package/dist/vfs/seaweedfs/config.d.ts +22 -10
  173. package/dist/vfs/seaweedfs/config.d.ts.map +1 -1
  174. package/dist/vfs/seaweedfs/config.js +1 -7
  175. package/dist/vfs/seaweedfs/config.js.map +1 -1
  176. package/dist/vfs/seaweedfs/seaweedfs.d.ts +4 -5
  177. package/dist/vfs/seaweedfs/seaweedfs.d.ts.map +1 -1
  178. package/dist/vfs/seaweedfs/seaweedfs.js +2 -4
  179. package/dist/vfs/seaweedfs/seaweedfs.js.map +1 -1
  180. package/dist/vfs/slack/config.d.ts +5 -15
  181. package/dist/vfs/slack/config.d.ts.map +1 -1
  182. package/dist/vfs/slack/config.js +11 -21
  183. package/dist/vfs/slack/config.js.map +1 -1
  184. package/dist/vfs/slack/slack.d.ts +7 -10
  185. package/dist/vfs/slack/slack.d.ts.map +1 -1
  186. package/dist/vfs/slack/slack.js +7 -11
  187. package/dist/vfs/slack/slack.js.map +1 -1
  188. package/dist/vfs/supabase/config.d.ts +25 -11
  189. package/dist/vfs/supabase/config.d.ts.map +1 -1
  190. package/dist/vfs/supabase/config.js +7 -7
  191. package/dist/vfs/supabase/config.js.map +1 -1
  192. package/dist/vfs/supabase/supabase.d.ts +4 -5
  193. package/dist/vfs/supabase/supabase.d.ts.map +1 -1
  194. package/dist/vfs/supabase/supabase.js +2 -4
  195. package/dist/vfs/supabase/supabase.js.map +1 -1
  196. package/dist/vfs/tencent/config.d.ts +22 -11
  197. package/dist/vfs/tencent/config.d.ts.map +1 -1
  198. package/dist/vfs/tencent/config.js +2 -7
  199. package/dist/vfs/tencent/config.js.map +1 -1
  200. package/dist/vfs/tencent/tencent.d.ts +4 -5
  201. package/dist/vfs/tencent/tencent.d.ts.map +1 -1
  202. package/dist/vfs/tencent/tencent.js +2 -4
  203. package/dist/vfs/tencent/tencent.js.map +1 -1
  204. package/dist/vfs/wasabi/config.d.ts +32 -16
  205. package/dist/vfs/wasabi/config.d.ts.map +1 -1
  206. package/dist/vfs/wasabi/config.js +8 -7
  207. package/dist/vfs/wasabi/config.js.map +1 -1
  208. package/dist/vfs/wasabi/wasabi.d.ts +4 -5
  209. package/dist/vfs/wasabi/wasabi.d.ts.map +1 -1
  210. package/dist/vfs/wasabi/wasabi.js +2 -4
  211. package/dist/vfs/wasabi/wasabi.js.map +1 -1
  212. package/dist/workspace.d.ts +2 -3
  213. package/dist/workspace.d.ts.map +1 -1
  214. package/dist/workspace.js +10 -18
  215. package/dist/workspace.js.map +1 -1
  216. package/package.json +7 -10
  217. package/THIRD_PARTY_NOTICES +0 -66
  218. package/dist/core/opfs/constants.d.ts +0 -2
  219. package/dist/core/opfs/constants.d.ts.map +0 -1
  220. package/dist/core/opfs/constants.js +0 -15
  221. package/dist/core/opfs/constants.js.map +0 -1
  222. package/dist/generated/wasm.d.ts +0 -3
  223. package/dist/generated/wasm.d.ts.map +0 -1
  224. package/dist/generated/wasm.js +0 -7
  225. package/dist/generated/wasm.js.map +0 -1
  226. package/dist/vfs/aliyun/prompt.d.ts +0 -2
  227. package/dist/vfs/aliyun/prompt.d.ts.map +0 -1
  228. package/dist/vfs/aliyun/prompt.js +0 -19
  229. package/dist/vfs/aliyun/prompt.js.map +0 -1
  230. package/dist/vfs/backblaze/prompt.d.ts +0 -2
  231. package/dist/vfs/backblaze/prompt.d.ts.map +0 -1
  232. package/dist/vfs/backblaze/prompt.js +0 -19
  233. package/dist/vfs/backblaze/prompt.js.map +0 -1
  234. package/dist/vfs/ceph/prompt.d.ts +0 -2
  235. package/dist/vfs/ceph/prompt.d.ts.map +0 -1
  236. package/dist/vfs/ceph/prompt.js +0 -19
  237. package/dist/vfs/ceph/prompt.js.map +0 -1
  238. package/dist/vfs/digitalocean/prompt.d.ts +0 -2
  239. package/dist/vfs/digitalocean/prompt.d.ts.map +0 -1
  240. package/dist/vfs/digitalocean/prompt.js +0 -19
  241. package/dist/vfs/digitalocean/prompt.js.map +0 -1
  242. package/dist/vfs/gcs/prompt.d.ts +0 -2
  243. package/dist/vfs/gcs/prompt.d.ts.map +0 -1
  244. package/dist/vfs/gcs/prompt.js +0 -19
  245. package/dist/vfs/gcs/prompt.js.map +0 -1
  246. package/dist/vfs/minio/prompt.d.ts +0 -2
  247. package/dist/vfs/minio/prompt.d.ts.map +0 -1
  248. package/dist/vfs/minio/prompt.js +0 -19
  249. package/dist/vfs/minio/prompt.js.map +0 -1
  250. package/dist/vfs/oci/prompt.d.ts +0 -2
  251. package/dist/vfs/oci/prompt.d.ts.map +0 -1
  252. package/dist/vfs/oci/prompt.js +0 -19
  253. package/dist/vfs/oci/prompt.js.map +0 -1
  254. package/dist/vfs/opfs/prompt.d.ts +0 -2
  255. package/dist/vfs/opfs/prompt.d.ts.map +0 -1
  256. package/dist/vfs/opfs/prompt.js +0 -17
  257. package/dist/vfs/opfs/prompt.js.map +0 -1
  258. package/dist/vfs/qingstor/prompt.d.ts +0 -2
  259. package/dist/vfs/qingstor/prompt.d.ts.map +0 -1
  260. package/dist/vfs/qingstor/prompt.js +0 -19
  261. package/dist/vfs/qingstor/prompt.js.map +0 -1
  262. package/dist/vfs/r2/prompt.d.ts +0 -2
  263. package/dist/vfs/r2/prompt.d.ts.map +0 -1
  264. package/dist/vfs/r2/prompt.js +0 -19
  265. package/dist/vfs/r2/prompt.js.map +0 -1
  266. package/dist/vfs/s3/prompt.d.ts +0 -2
  267. package/dist/vfs/s3/prompt.d.ts.map +0 -1
  268. package/dist/vfs/s3/prompt.js +0 -19
  269. package/dist/vfs/s3/prompt.js.map +0 -1
  270. package/dist/vfs/scaleway/prompt.d.ts +0 -2
  271. package/dist/vfs/scaleway/prompt.d.ts.map +0 -1
  272. package/dist/vfs/scaleway/prompt.js +0 -19
  273. package/dist/vfs/scaleway/prompt.js.map +0 -1
  274. package/dist/vfs/seaweedfs/prompt.d.ts +0 -2
  275. package/dist/vfs/seaweedfs/prompt.d.ts.map +0 -1
  276. package/dist/vfs/seaweedfs/prompt.js +0 -19
  277. package/dist/vfs/seaweedfs/prompt.js.map +0 -1
  278. package/dist/vfs/supabase/prompt.d.ts +0 -2
  279. package/dist/vfs/supabase/prompt.d.ts.map +0 -1
  280. package/dist/vfs/supabase/prompt.js +0 -19
  281. package/dist/vfs/supabase/prompt.js.map +0 -1
  282. package/dist/vfs/tencent/prompt.d.ts +0 -2
  283. package/dist/vfs/tencent/prompt.d.ts.map +0 -1
  284. package/dist/vfs/tencent/prompt.js +0 -19
  285. package/dist/vfs/tencent/prompt.js.map +0 -1
  286. package/dist/vfs/wasabi/prompt.d.ts +0 -2
  287. package/dist/vfs/wasabi/prompt.d.ts.map +0 -1
  288. package/dist/vfs/wasabi/prompt.js +0 -19
  289. package/dist/vfs/wasabi/prompt.js.map +0 -1
@@ -0,0 +1,238 @@
1
+ // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
14
+ import { liveEgress, opened } from '@struktoai/mirage-core/io/gateway';
15
+ import { postNetworkGate, preNetworkGate, } from '@struktoai/mirage-core/policy/policies';
16
+ import { REACHING, portOf, routed, watchNetwork } from "./network.js";
17
+ let watching = false;
18
+ /**
19
+ * The bytes a request body holds, null for a form or a stream, whose size a
20
+ * page cannot know before it sends them.
21
+ */
22
+ function measured(body) {
23
+ if (body === null || body === undefined)
24
+ return 0;
25
+ if (typeof body === 'string')
26
+ return new TextEncoder().encode(body).byteLength;
27
+ if (body instanceof ArrayBuffer || ArrayBuffer.isView(body))
28
+ return body.byteLength;
29
+ if (body instanceof Blob)
30
+ return body.size;
31
+ if (body instanceof URLSearchParams)
32
+ return new TextEncoder().encode(body.toString()).byteLength;
33
+ return null;
34
+ }
35
+ /**
36
+ * The page's side of the gateway: each fetch a listening workspace's line
37
+ * makes asks every live workspace's preNetwork once, by host name, since a
38
+ * page resolves no address and cannot tell one task's binding from
39
+ * another's. Its body is counted and cut past the tightest Limit, an upload
40
+ * past it, or of a size the page cannot know, is refused before it is sent,
41
+ * and a redirect is refused, since a page cannot see where one goes before
42
+ * following it. postNetwork hears how it ended, once. The counts are the
43
+ * bodies' bytes, since a page never sees the wire. Mirrors Python's
44
+ * `_Gateway`.
45
+ */
46
+ async function through(send, input, init) {
47
+ const live = liveEgress();
48
+ const answers = await Promise.all(live.map((egress) => egress.hooked));
49
+ // A nested call binds the same workspace's egress again: each workspace
50
+ // judges a request once.
51
+ const owners = new Map();
52
+ live.forEach((egress, at) => {
53
+ if (answers[at] === true && egress.policies !== null)
54
+ owners.set(egress.policies, egress);
55
+ });
56
+ try {
57
+ input = routed(input);
58
+ }
59
+ catch (err) {
60
+ console.debug('gateway:', err);
61
+ throw new TypeError('Failed to fetch');
62
+ }
63
+ const target = new URL(input instanceof Request ? input.url : input, globalThis.location.href);
64
+ if (owners.size === 0 || !REACHING.has(target.protocol))
65
+ return send(input, init);
66
+ const host = target.hostname;
67
+ const port = portOf(target);
68
+ const started = Date.now();
69
+ const sent = init?.body !== undefined
70
+ ? measured(init.body)
71
+ : input instanceof Request && input.body !== null
72
+ ? null
73
+ : 0;
74
+ const tickets = [];
75
+ let over = false;
76
+ // Tell every workspace that let the request through how it went, once.
77
+ const ended = async (how, out, received) => {
78
+ if (over)
79
+ return;
80
+ over = true;
81
+ for (const { egress, ctx, passed } of tickets) {
82
+ if (egress.policies === null)
83
+ continue;
84
+ await postNetworkGate(egress.policies, {
85
+ ...ctx,
86
+ bytesSent: out,
87
+ bytesReceived: received,
88
+ seconds: (Date.now() - started) / 1000,
89
+ ended: how,
90
+ }, passed).catch((err) => {
91
+ console.debug('gateway: postNetwork failed:', err);
92
+ });
93
+ }
94
+ };
95
+ let cap = null;
96
+ let deadline = null;
97
+ for (const [policies, egress] of owners) {
98
+ const ctx = opened(host, '', port);
99
+ let answer;
100
+ try {
101
+ answer = await preNetworkGate(policies, ctx);
102
+ }
103
+ catch (err) {
104
+ console.debug('gateway: preNetwork failed:', err);
105
+ await ended('refused', 0, 0);
106
+ throw new TypeError('Failed to fetch');
107
+ }
108
+ tickets.push({ egress, ctx, passed: answer[0] });
109
+ const limit = answer[1];
110
+ if (limit?.maxBytes != null)
111
+ cap = Math.min(cap ?? limit.maxBytes, limit.maxBytes);
112
+ if (limit?.timeoutSeconds != null) {
113
+ deadline = Math.min(deadline ?? limit.timeoutSeconds, limit.timeoutSeconds);
114
+ }
115
+ }
116
+ if (cap !== null && (sent === null || sent > cap)) {
117
+ await ended('limit', 0, 0);
118
+ throw new TypeError('Failed to fetch');
119
+ }
120
+ const stop = new AbortController();
121
+ const timer = deadline === null
122
+ ? null
123
+ : setTimeout(() => {
124
+ stop.abort();
125
+ }, deadline * 1000);
126
+ const asked = init?.signal ?? (input instanceof Request ? input.signal : null);
127
+ const signal = asked == null ? stop.signal : AbortSignal.any([asked, stop.signal]);
128
+ // A redirect the page would follow goes where no policy saw, so it is not
129
+ // followed; one the caller handles itself is handed back as fetch gives it.
130
+ const redirect = init?.redirect ?? (input instanceof Request ? input.redirect : 'follow');
131
+ let response;
132
+ try {
133
+ response = await send(input, {
134
+ ...init,
135
+ signal,
136
+ redirect: redirect === 'follow' ? 'manual' : redirect,
137
+ });
138
+ }
139
+ catch (err) {
140
+ if (timer !== null)
141
+ clearTimeout(timer);
142
+ await ended(stop.signal.aborted ? 'limit' : 'error', sent ?? 0, 0);
143
+ throw err;
144
+ }
145
+ if (response.type === 'opaqueredirect' && redirect === 'follow') {
146
+ if (timer !== null)
147
+ clearTimeout(timer);
148
+ await ended('refused', sent ?? 0, 0);
149
+ throw new TypeError('Failed to fetch');
150
+ }
151
+ if (response.body === null || [204, 205, 304].includes(response.status)) {
152
+ if (timer !== null)
153
+ clearTimeout(timer);
154
+ await ended('closed', sent ?? 0, 0);
155
+ return response;
156
+ }
157
+ let received = 0;
158
+ const reader = response.body.getReader();
159
+ const counted = new ReadableStream({
160
+ async pull(controller) {
161
+ let step;
162
+ try {
163
+ step = await reader.read();
164
+ }
165
+ catch (err) {
166
+ if (timer !== null)
167
+ clearTimeout(timer);
168
+ await ended(stop.signal.aborted ? 'limit' : 'error', sent ?? 0, received);
169
+ controller.error(err);
170
+ return;
171
+ }
172
+ if (step.done) {
173
+ if (timer !== null)
174
+ clearTimeout(timer);
175
+ await ended('closed', sent ?? 0, received);
176
+ controller.close();
177
+ return;
178
+ }
179
+ if (cap !== null && (sent ?? 0) + received + step.value.byteLength > cap) {
180
+ const left = Math.max(cap - (sent ?? 0) - received, 0);
181
+ received += left;
182
+ controller.enqueue(step.value.subarray(0, left));
183
+ stop.abort();
184
+ if (timer !== null)
185
+ clearTimeout(timer);
186
+ await reader.cancel().catch((err) => {
187
+ console.debug('gateway: body cancel failed:', err);
188
+ });
189
+ await ended('limit', sent ?? 0, received);
190
+ controller.error(new TypeError('network error'));
191
+ return;
192
+ }
193
+ received += step.value.byteLength;
194
+ controller.enqueue(step.value);
195
+ },
196
+ async cancel(reason) {
197
+ if (timer !== null)
198
+ clearTimeout(timer);
199
+ await reader.cancel(reason);
200
+ await ended('closed', sent ?? 0, received);
201
+ },
202
+ });
203
+ const relayed = new Response(counted, {
204
+ status: response.status,
205
+ statusText: response.statusText,
206
+ headers: response.headers,
207
+ });
208
+ Object.defineProperties(relayed, {
209
+ url: { value: response.url },
210
+ redirected: { value: response.redirected },
211
+ type: { value: response.type },
212
+ });
213
+ return relayed;
214
+ }
215
+ /**
216
+ * Send every request the page makes through `through`, once; one with no
217
+ * listening egress goes on at once. A page cannot hold a WebSocket's
218
+ * handshake for an async answer, so while a policy listens for connections a
219
+ * WebSocket is refused. Mirrors Python's `_watch`.
220
+ */
221
+ export function watch() {
222
+ if (watching)
223
+ return;
224
+ watching = true;
225
+ watchNetwork();
226
+ const send = globalThis.fetch.bind(globalThis);
227
+ globalThis.fetch = (input, init) => through(send, input, init);
228
+ const Socket = globalThis.WebSocket;
229
+ globalThis.WebSocket = class extends Socket {
230
+ constructor(url, protocols) {
231
+ if (liveEgress().some((egress) => egress.listening !== false && egress.policies !== null)) {
232
+ throw new DOMException(`A policy listens for connections, so ${String(url)} is refused`, 'SecurityError');
233
+ }
234
+ super(url, protocols);
235
+ }
236
+ };
237
+ }
238
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src/io/gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export declare const REACHING: Set<string>;
2
+ /** The port a URL reaches, which it leaves unwritten for its scheme's own. */
3
+ export declare function portOf(target: URL): number;
4
+ /**
5
+ * `input` sent where the bound rule routes its host and port instead, and
6
+ * judged there; as it is when it routes nowhere. A page checks TLS against
7
+ * the URL it sends, so a secure route may change the port but not the host.
8
+ * Throws when it cannot be routed.
9
+ */
10
+ export declare function routed(input: RequestInfo | URL): RequestInfo | URL;
11
+ /**
12
+ * Start judging every request the page makes, once: fetch and WebSocket ask
13
+ * every live workspace's rule by host name, since a page resolves no
14
+ * address and cannot tell one task's binding from another's, so the
15
+ * strictest rule wins. A page cannot see where a redirect goes before it
16
+ * follows one, so under a rule fetch follows none: a request that asked to
17
+ * follow fails as fetch does. Called as the first workspace with a rule is
18
+ * built. Mirrors Python's `watch_network`.
19
+ */
20
+ export declare function watchNetwork(): void;
21
+ //# sourceMappingURL=network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/io/network.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,QAAQ,aAA8C,CAAA;AAInE,8EAA8E;AAC9E,wBAAgB,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAG1C;AAoCD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,GAAG,WAAW,GAAG,GAAG,CAiBlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAoCnC"}
@@ -0,0 +1,131 @@
1
+ // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
14
+ import { liveEgress } from '@struktoai/mirage-core/io/gateway';
15
+ import { networkBound, networkLets, networkRoute } from '@struktoai/mirage-core/io/network';
16
+ // The schemes that reach a host; data:, blob: and the like never leave the page.
17
+ export const REACHING = new Set(['http:', 'https:', 'ws:', 'wss:']);
18
+ let watching = false;
19
+ /** The port a URL reaches, which it leaves unwritten for its scheme's own. */
20
+ export function portOf(target) {
21
+ if (target.port !== '')
22
+ return Number(target.port);
23
+ return target.protocol === 'https:' || target.protocol === 'wss:' ? 443 : 80;
24
+ }
25
+ function lets(url) {
26
+ const target = new URL(url, globalThis.location.href);
27
+ return !REACHING.has(target.protocol) || networkLets(target.hostname, '', portOf(target));
28
+ }
29
+ // The schemes whose TLS checks the URL's own host name.
30
+ const SECURE = new Set(['https:', 'wss:']);
31
+ /**
32
+ * Where a page's request to `host` on `port` goes instead, null for nowhere
33
+ * else. A page cannot tell one task's binding from another's, so every live
34
+ * line and file op must route it alike, but for a file op of a session with
35
+ * a live line, which goes as that line does (a file call inside a line binds
36
+ * the workspace's own rule over the session's); throws when two do not.
37
+ */
38
+ function routeOf(host, port) {
39
+ const live = liveEgress();
40
+ if (live.length === 0)
41
+ return networkRoute(host, port);
42
+ // Whether a line of the session `egress` runs for is live in its workspace.
43
+ const lined = (egress) => egress.session !== null &&
44
+ live.some((line) => !line.op && line.session === egress.session && line.policies === egress.policies);
45
+ const answers = live
46
+ .filter((egress) => !egress.op || !lined(egress))
47
+ .map((egress) => egress.rule?.route(host, port) ?? null);
48
+ const first = answers[0] ?? null;
49
+ if (answers.some((answer) => answer?.join(':') !== first?.join(':'))) {
50
+ throw new Error(`network: live calls route ${host}:${String(port)} apart`);
51
+ }
52
+ return first;
53
+ }
54
+ /**
55
+ * `input` sent where the bound rule routes its host and port instead, and
56
+ * judged there; as it is when it routes nowhere. A page checks TLS against
57
+ * the URL it sends, so a secure route may change the port but not the host.
58
+ * Throws when it cannot be routed.
59
+ */
60
+ export function routed(input) {
61
+ const target = new URL(input instanceof Request ? input.url : input, globalThis.location.href);
62
+ if (!REACHING.has(target.protocol))
63
+ return input;
64
+ const route = routeOf(target.hostname, portOf(target));
65
+ if (route === null)
66
+ return input;
67
+ const bare = target.hostname
68
+ .replace(/^\[(.*)\]$/, '$1')
69
+ .replace(/\.$/, '')
70
+ .toLowerCase();
71
+ if (SECURE.has(target.protocol) && route[0] !== bare) {
72
+ throw new Error(`network: a page cannot route ${target.host} to another host and still check its TLS name`);
73
+ }
74
+ target.hostname = route[0].includes(':') ? `[${route[0]}]` : route[0];
75
+ target.port = String(route[1]);
76
+ return input instanceof Request ? new Request(target, input) : target;
77
+ }
78
+ /**
79
+ * Start judging every request the page makes, once: fetch and WebSocket ask
80
+ * every live workspace's rule by host name, since a page resolves no
81
+ * address and cannot tell one task's binding from another's, so the
82
+ * strictest rule wins. A page cannot see where a redirect goes before it
83
+ * follows one, so under a rule fetch follows none: a request that asked to
84
+ * follow fails as fetch does. Called as the first workspace with a rule is
85
+ * built. Mirrors Python's `watch_network`.
86
+ */
87
+ export function watchNetwork() {
88
+ if (watching)
89
+ return;
90
+ watching = true;
91
+ const send = globalThis.fetch.bind(globalThis);
92
+ globalThis.fetch = async (input, init) => {
93
+ if (networkBound() === null)
94
+ return send(input, init);
95
+ try {
96
+ input = routed(input);
97
+ }
98
+ catch (err) {
99
+ console.debug('network:', err);
100
+ throw new TypeError('Failed to fetch');
101
+ }
102
+ if (!lets(input instanceof Request ? input.url : input))
103
+ throw new TypeError('Failed to fetch');
104
+ const redirect = init?.redirect ?? (input instanceof Request ? input.redirect : 'follow');
105
+ if (redirect !== 'follow')
106
+ return send(input, init);
107
+ const response = await send(input, { ...init, redirect: 'manual' });
108
+ if (response.type === 'opaqueredirect')
109
+ throw new TypeError('Failed to fetch');
110
+ return response;
111
+ };
112
+ const Socket = globalThis.WebSocket;
113
+ globalThis.WebSocket = class extends Socket {
114
+ constructor(url, protocols) {
115
+ let target = url;
116
+ if (networkBound() !== null) {
117
+ try {
118
+ target = routed(url);
119
+ }
120
+ catch (err) {
121
+ throw new DOMException(String(err), 'SecurityError');
122
+ }
123
+ if (!lets(target)) {
124
+ throw new DOMException(`The network rule refuses ${String(target)}`, 'SecurityError');
125
+ }
126
+ }
127
+ super(target, protocols);
128
+ }
129
+ };
130
+ }
131
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/io/network.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool.d.ts","sourceRoot":"","sources":["../../src/io/spool.ts"],"names":[],"mappings":""}
@@ -0,0 +1,68 @@
1
+ // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
14
+ import { setSpoolFactory } from '@struktoai/mirage-core/io/spool';
15
+ /**
16
+ * A page's spool scratch: spilled bytes as fixed blocks of Blob, which the
17
+ * browser holds outside the JavaScript heap and may page to disk, so a spool
18
+ * past its memory limit no longer grows the heap. A write rebuilds only the
19
+ * blocks it touches, from slices of what they held. Mirrors Node's spool
20
+ * store.
21
+ */
22
+ function createStore() {
23
+ const BLOCK = 256 * 1024;
24
+ const blocks = [];
25
+ let length = 0;
26
+ return Promise.resolve({
27
+ write(at, data) {
28
+ let offset = 0;
29
+ while (offset < data.length) {
30
+ const index = Math.floor((at + offset) / BLOCK);
31
+ const start = (at + offset) % BLOCK;
32
+ const count = Math.min(BLOCK - start, data.length - offset);
33
+ const held = blocks[index] ?? new Blob();
34
+ const fresh = data.slice(offset, offset + count);
35
+ blocks[index] =
36
+ start === 0 && count >= held.size
37
+ ? new Blob([fresh])
38
+ : new Blob([
39
+ held.slice(0, start),
40
+ new Uint8Array(Math.max(0, start - held.size)),
41
+ fresh,
42
+ held.slice(start + count),
43
+ ]);
44
+ offset += count;
45
+ }
46
+ length = Math.max(length, at + data.length);
47
+ return Promise.resolve();
48
+ },
49
+ async read(offset, size) {
50
+ const end = Math.min(length, offset + size);
51
+ if (end <= offset)
52
+ return new Uint8Array();
53
+ const first = Math.floor(offset / BLOCK);
54
+ const window = new Blob(blocks.slice(first, Math.floor((end - 1) / BLOCK) + 1));
55
+ return new Uint8Array(await window.slice(offset - first * BLOCK, end - first * BLOCK).arrayBuffer());
56
+ },
57
+ body() {
58
+ return Promise.resolve(new Blob(blocks));
59
+ },
60
+ close() {
61
+ blocks.length = 0;
62
+ length = 0;
63
+ return Promise.resolve();
64
+ },
65
+ });
66
+ }
67
+ setSpoolFactory(createStore);
68
+ //# sourceMappingURL=spool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool.js","sourceRoot":"","sources":["../../src/io/spool.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,7 @@
1
- import { S3AliasVFS, type S3AliasVFSState } from '../s3_alias.ts';
2
- import { type AliyunConfig, type AliyunConfigRedacted } from './config.ts';
3
- export type AliyunVFSState = S3AliasVFSState<AliyunConfigRedacted>;
4
- export declare class AliyunVFS extends S3AliasVFS<AliyunConfig, AliyunConfigRedacted> {
5
- readonly prompt: string;
1
+ import type { RedactedSchema } from '@struktoai/mirage-core/vfs/secrets';
2
+ import { S3AliasVFS } from '../s3_alias.ts';
3
+ import { AliyunConfig } from './config.ts';
4
+ export declare class AliyunVFS extends S3AliasVFS<AliyunConfig, RedactedSchema<typeof AliyunConfig>> {
6
5
  constructor(config: AliyunConfig);
7
6
  }
8
7
  //# sourceMappingURL=aliyun.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aliyun.d.ts","sourceRoot":"","sources":["../../../src/vfs/aliyun/aliyun.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACjE,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAA;AAGpB,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC,oBAAoB,CAAC,CAAA;AAElE,qBAAa,SAAU,SAAQ,UAAU,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAC3E,SAAkB,MAAM,EAAE,MAAM,CAAS;gBAE7B,MAAM,EAAE,YAAY;CAGjC"}
1
+ {"version":3,"file":"aliyun.d.ts","sourceRoot":"","sources":["../../../src/vfs/aliyun/aliyun.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,qBAAa,SAAU,SAAQ,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC;gBAC9E,MAAM,EAAE,YAAY;CAGjC"}
@@ -13,12 +13,10 @@
13
13
  // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
14
14
  import { VFSName } from '@struktoai/mirage-core/types';
15
15
  import { S3AliasVFS } from "../s3_alias.js";
16
- import { aliyunToS3Config, redactAliyunConfig, } from "./config.js";
17
- import { PROMPT } from "./prompt.js";
16
+ import { AliyunConfig } from "./config.js";
18
17
  export class AliyunVFS extends S3AliasVFS {
19
- prompt = PROMPT;
20
18
  constructor(config) {
21
- super(VFSName.ALIYUN, config, aliyunToS3Config(config), redactAliyunConfig);
19
+ super(VFSName.ALIYUN, config, AliyunConfig);
22
20
  }
23
21
  }
24
22
  //# sourceMappingURL=aliyun.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"aliyun.js","sourceRoot":"","sources":["../../../src/vfs/aliyun/aliyun.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,uEAAuE;AAEvE,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AACtD,OAAO,EAAE,UAAU,EAAwB,MAAM,gBAAgB,CAAA;AACjE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GAGnB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAIpC,MAAM,OAAO,SAAU,SAAQ,UAA8C;IACzD,MAAM,GAAW,MAAM,CAAA;IAEzC,YAAY,MAAoB;QAC9B,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAA;IAC7E,CAAC;CACF"}
1
+ {"version":3,"file":"aliyun.js","sourceRoot":"","sources":["../../../src/vfs/aliyun/aliyun.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,uEAAuE;AAEvE,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,OAAO,SAAU,SAAQ,UAA6D;IAC1F,YAAY,MAAoB;QAC9B,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAA;IAC7C,CAAC;CACF"}
@@ -1,17 +1,28 @@
1
- import type { ConfigOf, RedactedConfig } from '@struktoai/mirage-core/vfs/secrets';
2
- declare const AliyunConfigSchema: import("zod").ZodObject<{
1
+ import type { ConfigOf } from '@struktoai/mirage-core/vfs/secrets';
2
+ export declare const AliyunConfig: import("zod").ZodObject<{
3
+ timeout: import("zod").ZodOptional<import("zod").ZodNumber>;
3
4
  bucket: import("zod").ZodString;
4
- presignedUrlProvider: import("zod").ZodCustom<import("@struktoai/mirage-core/vfs/s3/config").S3BrowserPresignedUrlProvider, import("@struktoai/mirage-core/vfs/s3/config").S3BrowserPresignedUrlProvider>;
5
+ presignedUrlProvider: import("@struktoai/mirage-core/vfs/secrets").SecretSchema<import("zod").ZodCustom<import("@struktoai/mirage-core/vfs/s3/config").S3BrowserPresignedUrlProvider, import("@struktoai/mirage-core/vfs/s3/config").S3BrowserPresignedUrlProvider>>;
5
6
  region: import("zod").ZodOptional<import("zod").ZodString>;
6
7
  endpoint: import("zod").ZodOptional<import("zod").ZodString>;
7
8
  defaultContentType: import("zod").ZodOptional<import("zod").ZodString>;
8
9
  keyPrefix: import("zod").ZodOptional<import("zod").ZodString>;
9
- }, import("zod/v4/core").$strip>;
10
- export type AliyunConfig = ConfigOf<typeof AliyunConfigSchema>;
11
- export type AliyunConfigRedacted = RedactedConfig<AliyunConfig, 'presignedUrlProvider'>;
12
- export declare const resolvedAliyunEndpoint: (config: AliyunConfig) => string | undefined;
13
- export declare const aliyunToS3Config: (config: AliyunConfig) => import("@struktoai/mirage-core/vfs/s3/config").S3Config;
14
- export declare const redactAliyunConfig: (config: AliyunConfig) => AliyunConfigRedacted;
15
- export declare const normalizeAliyunConfig: (input: Record<string, unknown>) => AliyunConfig;
16
- export {};
10
+ }, import("zod/v4/core").$strip> & import("../s3_alias.ts").BrowserAlias<ConfigOf<import("zod").ZodObject<{
11
+ timeout: import("zod").ZodOptional<import("zod").ZodNumber>;
12
+ bucket: import("zod").ZodString;
13
+ presignedUrlProvider: import("@struktoai/mirage-core/vfs/secrets").SecretSchema<import("zod").ZodCustom<import("@struktoai/mirage-core/vfs/s3/config").S3BrowserPresignedUrlProvider, import("@struktoai/mirage-core/vfs/s3/config").S3BrowserPresignedUrlProvider>>;
14
+ region: import("zod").ZodOptional<import("zod").ZodString>;
15
+ endpoint: import("zod").ZodOptional<import("zod").ZodString>;
16
+ defaultContentType: import("zod").ZodOptional<import("zod").ZodString>;
17
+ keyPrefix: import("zod").ZodOptional<import("zod").ZodString>;
18
+ }, import("zod/v4/core").$strip>> & import("../s3_alias.ts").S3BrowserAliasConfig, {
19
+ bucket: string;
20
+ presignedUrlProvider: "<REDACTED>";
21
+ timeout?: number;
22
+ region?: string;
23
+ endpoint?: string;
24
+ defaultContentType?: string;
25
+ keyPrefix?: string;
26
+ }, string | undefined>;
27
+ export type AliyunConfig = ConfigOf<typeof AliyunConfig>;
17
28
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/vfs/aliyun/config.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AAGlF,QAAA,MAAM,kBAAkB;;;;;;;gCAAyB,CAAA;AAEjD,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAE9D,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,YAAY,EAAE,sBAAsB,CAAC,CAAA;AAOvF,eAAO,MAAM,sBAAsB,8CAAyB,CAAA;AAC5D,eAAO,MAAM,gBAAgB,mFAAmB,CAAA;AAChD,eAAO,MAAM,kBAAkB,gDAAe,CAAA;AAC9C,eAAO,MAAM,qBAAqB,kDAAkB,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/vfs/aliyun/config.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAGlE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;sBAGvB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAA"}
@@ -12,13 +12,8 @@
12
12
  // limitations under the License.
13
13
  // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
14
14
  import { browserAliasSchema, derivedEndpoint, makeBrowserS3Alias } from "../s3_alias.js";
15
- const AliyunConfigSchema = browserAliasSchema({});
16
- const alias = makeBrowserS3Alias({
17
- schema: AliyunConfigSchema,
15
+ export const AliyunConfig = makeBrowserS3Alias({
16
+ schema: browserAliasSchema({}),
18
17
  endpointFor: derivedEndpoint('region', (region) => `https://s3.oss-${region}.aliyuncs.com`),
19
18
  });
20
- export const resolvedAliyunEndpoint = alias.resolvedEndpoint;
21
- export const aliyunToS3Config = alias.toS3Config;
22
- export const redactAliyunConfig = alias.redact;
23
- export const normalizeAliyunConfig = alias.normalize;
24
19
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/vfs/aliyun/config.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,uEAAuE;AAGvE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExF,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAA;AAMjD,MAAM,KAAK,GAAG,kBAAkB,CAAqC;IACnE,MAAM,EAAE,kBAAkB;IAC1B,WAAW,EAAE,eAAe,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,kBAAkB,MAAM,eAAe,CAAC;CAC5F,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC,gBAAgB,CAAA;AAC5D,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC,UAAU,CAAA;AAChD,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAAA;AAC9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC,SAAS,CAAA"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/vfs/aliyun/config.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,uEAAuE;AAGvE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExF,MAAM,CAAC,MAAM,YAAY,GAAG,kBAAkB,CAAC;IAC7C,MAAM,EAAE,kBAAkB,CAAC,EAAE,CAAC;IAC9B,WAAW,EAAE,eAAe,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,kBAAkB,MAAM,eAAe,CAAC;CAC5F,CAAC,CAAA"}
@@ -1,8 +1,7 @@
1
- import { S3AliasVFS, type S3AliasVFSState } from '../s3_alias.ts';
2
- import { type BackblazeConfig, type BackblazeConfigRedacted } from './config.ts';
3
- export type BackblazeVFSState = S3AliasVFSState<BackblazeConfigRedacted>;
4
- export declare class BackblazeVFS extends S3AliasVFS<BackblazeConfig, BackblazeConfigRedacted> {
5
- readonly prompt: string;
1
+ import type { RedactedSchema } from '@struktoai/mirage-core/vfs/secrets';
2
+ import { S3AliasVFS } from '../s3_alias.ts';
3
+ import { BackblazeConfig } from './config.ts';
4
+ export declare class BackblazeVFS extends S3AliasVFS<BackblazeConfig, RedactedSchema<typeof BackblazeConfig>> {
6
5
  constructor(config: BackblazeConfig);
7
6
  }
8
7
  //# sourceMappingURL=backblaze.d.ts.map