@faicad/faijs 0.29.3 → 0.30.9

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 (614) hide show
  1. package/NOTICE +6 -5
  2. package/dist/api/api-namespace.d.ts +1 -1
  3. package/dist/api/api-namespace.d.ts.map +1 -1
  4. package/dist/api/api-namespace.js +53 -1
  5. package/dist/api/api-namespace.js.map +1 -1
  6. package/dist/api/appearance.d.ts +136 -0
  7. package/dist/api/appearance.d.ts.map +1 -0
  8. package/dist/api/appearance.js +228 -0
  9. package/dist/api/appearance.js.map +1 -0
  10. package/dist/api/assembly/entities.d.ts +1 -1
  11. package/dist/api/assembly/entities.js +1 -1
  12. package/dist/api/assembly/entities.js.map +1 -1
  13. package/dist/api/assembly/index.d.ts +1 -1
  14. package/dist/api/assembly/index.js +1 -1
  15. package/dist/api/assembly/index.js.map +1 -1
  16. package/dist/api/assembly/joints.d.ts +33 -15
  17. package/dist/api/assembly/joints.d.ts.map +1 -1
  18. package/dist/api/assembly/joints.js +31 -13
  19. package/dist/api/assembly/joints.js.map +1 -1
  20. package/dist/api/assembly/preview.d.ts +1 -1
  21. package/dist/api/assembly/preview.js +1 -1
  22. package/dist/api/assembly/preview.js.map +1 -1
  23. package/dist/api/assembly/solve.d.ts +1 -1
  24. package/dist/api/assembly/solve.js +1 -1
  25. package/dist/api/assembly/solve.js.map +1 -1
  26. package/dist/api/assembly/solvers/assembly-tree.d.ts +1 -1
  27. package/dist/api/assembly/solvers/assembly-tree.js +1 -1
  28. package/dist/api/assembly/solvers/assembly-tree.js.map +1 -1
  29. package/dist/api/assembly/solvers/chain-solver.d.ts +2 -2
  30. package/dist/api/assembly/solvers/chain-solver.js.map +1 -1
  31. package/dist/api/assembly/solvers/global-solver.d.ts +1 -2
  32. package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
  33. package/dist/api/assembly/solvers/global-solver.js +3 -4
  34. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  35. package/dist/api/assembly/solvers/joints-kinematics.js +1 -1
  36. package/dist/api/assembly/solvers/joints-kinematics.js.map +1 -1
  37. package/dist/api/assembly/solvers/linalg.d.ts +2 -2
  38. package/dist/api/assembly/solvers/linalg.js +2 -2
  39. package/dist/api/assembly/solvers/linalg.js.map +1 -1
  40. package/dist/api/assembly/solvers/types.d.ts +2 -5
  41. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  42. package/dist/api/assembly/solvers/types.js +1 -4
  43. package/dist/api/assembly/solvers/types.js.map +1 -1
  44. package/dist/api/boolean.d.ts.map +1 -1
  45. package/dist/api/boolean.js +7 -6
  46. package/dist/api/boolean.js.map +1 -1
  47. package/dist/api/brep-mirror/booleanFns.d.ts +3 -3
  48. package/dist/api/brep-mirror/booleanFns.js +5 -5
  49. package/dist/api/brep-mirror/booleanFns.js.map +1 -1
  50. package/dist/api/brep-mirror/compoundFns.d.ts +1 -1
  51. package/dist/api/brep-mirror/compoundFns.js +4 -4
  52. package/dist/api/brep-mirror/compoundFns.js.map +1 -1
  53. package/dist/api/brep-mirror/healingFns.d.ts +4 -4
  54. package/dist/api/brep-mirror/healingFns.js +4 -4
  55. package/dist/api/brep-mirror/healingFns.js.map +1 -1
  56. package/dist/api/brep-mirror/hullFns.d.ts +2 -2
  57. package/dist/api/brep-mirror/hullFns.js +2 -2
  58. package/dist/api/brep-mirror/hullFns.js.map +1 -1
  59. package/dist/api/brep-mirror/patternFns.d.ts +5 -5
  60. package/dist/api/brep-mirror/patternFns.js +10 -10
  61. package/dist/api/brep-mirror/patternFns.js.map +1 -1
  62. package/dist/api/brep-mirror/primitiveFns.d.ts +4 -4
  63. package/dist/api/brep-mirror/primitiveFns.js +4 -4
  64. package/dist/api/brep-mirror/primitiveFns.js.map +1 -1
  65. package/dist/api/brep-mirror/roofFns.d.ts +3 -3
  66. package/dist/api/brep-mirror/roofFns.js +7 -7
  67. package/dist/api/brep-mirror/roofFns.js.map +1 -1
  68. package/dist/api/brep-mirror/sweepFns.d.ts +7 -7
  69. package/dist/api/brep-mirror/sweepFns.js +14 -14
  70. package/dist/api/brep-mirror/sweepFns.js.map +1 -1
  71. package/dist/api/brep-mirror/threadFns.d.ts +1 -1
  72. package/dist/api/brep-mirror/threadFns.js +1 -1
  73. package/dist/api/brep-mirror/threadFns.js.map +1 -1
  74. package/dist/api/brep-mirror/topologyFns.d.ts +5 -5
  75. package/dist/api/brep-mirror/topologyFns.js +8 -8
  76. package/dist/api/brep-mirror/topologyFns.js.map +1 -1
  77. package/dist/api/brep-operations/booleanFns.d.ts +40 -0
  78. package/dist/api/brep-operations/booleanFns.d.ts.map +1 -0
  79. package/dist/api/brep-operations/booleanFns.js +104 -0
  80. package/dist/api/brep-operations/booleanFns.js.map +1 -0
  81. package/dist/api/brep-operations/brepHelpers.d.ts +55 -0
  82. package/dist/api/brep-operations/brepHelpers.d.ts.map +1 -0
  83. package/dist/api/brep-operations/brepHelpers.js +131 -0
  84. package/dist/api/brep-operations/brepHelpers.js.map +1 -0
  85. package/dist/api/brep-operations/compoundFns.d.ts +46 -0
  86. package/dist/api/brep-operations/compoundFns.d.ts.map +1 -0
  87. package/dist/api/brep-operations/compoundFns.js +299 -0
  88. package/dist/api/brep-operations/compoundFns.js.map +1 -0
  89. package/dist/api/brep-operations/healingFns.d.ts +78 -0
  90. package/dist/api/brep-operations/healingFns.d.ts.map +1 -0
  91. package/dist/api/brep-operations/healingFns.js +294 -0
  92. package/dist/api/brep-operations/healingFns.js.map +1 -0
  93. package/dist/api/brep-operations/hullFns.d.ts +20 -0
  94. package/dist/api/brep-operations/hullFns.d.ts.map +1 -0
  95. package/dist/api/brep-operations/hullFns.js +46 -0
  96. package/dist/api/brep-operations/hullFns.js.map +1 -0
  97. package/dist/api/brep-operations/joinery-brep.d.ts +172 -0
  98. package/dist/api/brep-operations/joinery-brep.d.ts.map +1 -0
  99. package/dist/api/brep-operations/joinery-brep.js +463 -0
  100. package/dist/api/brep-operations/joinery-brep.js.map +1 -0
  101. package/dist/api/brep-operations/patternFns.d.ts +43 -0
  102. package/dist/api/brep-operations/patternFns.d.ts.map +1 -0
  103. package/dist/api/brep-operations/patternFns.js +178 -0
  104. package/dist/api/brep-operations/patternFns.js.map +1 -0
  105. package/dist/api/brep-operations/primitiveFns.d.ts +42 -0
  106. package/dist/api/brep-operations/primitiveFns.d.ts.map +1 -0
  107. package/dist/api/brep-operations/primitiveFns.js +104 -0
  108. package/dist/api/brep-operations/primitiveFns.js.map +1 -0
  109. package/dist/api/brep-operations/roofFns.d.ts +24 -0
  110. package/dist/api/brep-operations/roofFns.d.ts.map +1 -0
  111. package/dist/api/brep-operations/roofFns.js +229 -0
  112. package/dist/api/brep-operations/roofFns.js.map +1 -0
  113. package/dist/api/brep-operations/straightSkeleton.d.ts +36 -0
  114. package/dist/api/brep-operations/straightSkeleton.d.ts.map +1 -0
  115. package/dist/api/brep-operations/straightSkeleton.js +431 -0
  116. package/dist/api/brep-operations/straightSkeleton.js.map +1 -0
  117. package/dist/api/brep-operations/sweepFns.d.ts +60 -0
  118. package/dist/api/brep-operations/sweepFns.d.ts.map +1 -0
  119. package/dist/api/brep-operations/sweepFns.js +323 -0
  120. package/dist/api/brep-operations/sweepFns.js.map +1 -0
  121. package/dist/api/brep-operations/threadFns.d.ts +83 -0
  122. package/dist/api/brep-operations/threadFns.d.ts.map +1 -0
  123. package/dist/api/brep-operations/threadFns.js +138 -0
  124. package/dist/api/brep-operations/threadFns.js.map +1 -0
  125. package/dist/api/brep-operations/topologyFns.d.ts +90 -0
  126. package/dist/api/brep-operations/topologyFns.d.ts.map +1 -0
  127. package/dist/api/brep-operations/topologyFns.js +276 -0
  128. package/dist/api/brep-operations/topologyFns.js.map +1 -0
  129. package/dist/api/brep-topology.d.ts +1 -1
  130. package/dist/api/brep-topology.d.ts.map +1 -1
  131. package/dist/api/brep-topology.js +1 -1
  132. package/dist/api/brep-topology.js.map +1 -1
  133. package/dist/api/brepjs-compat/index.d.ts +1 -1
  134. package/dist/api/brepjs-compat/index.js +3 -3
  135. package/dist/api/brepjs-compat/index.js.map +1 -1
  136. package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -1
  137. package/dist/api/cadquery-selectors/borrow-bridge.js +3 -4
  138. package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -1
  139. package/dist/api/curve-sketch/index.d.ts +235 -0
  140. package/dist/api/curve-sketch/index.d.ts.map +1 -0
  141. package/dist/api/curve-sketch/index.js +487 -0
  142. package/dist/api/curve-sketch/index.js.map +1 -0
  143. package/dist/api/engrave.d.ts.map +1 -1
  144. package/dist/api/engrave.js +3 -2
  145. package/dist/api/engrave.js.map +1 -1
  146. package/dist/api/export-brep.d.ts +41 -0
  147. package/dist/api/export-brep.d.ts.map +1 -0
  148. package/dist/api/export-brep.js +58 -0
  149. package/dist/api/export-brep.js.map +1 -0
  150. package/dist/api/export-stl.d.ts +50 -0
  151. package/dist/api/export-stl.d.ts.map +1 -0
  152. package/dist/api/export-stl.js +99 -0
  153. package/dist/api/export-stl.js.map +1 -0
  154. package/dist/api/extrude.d.ts +8 -11
  155. package/dist/api/extrude.d.ts.map +1 -1
  156. package/dist/api/extrude.js +11 -14
  157. package/dist/api/extrude.js.map +1 -1
  158. package/dist/api/fillet-variable.d.ts +2 -2
  159. package/dist/api/fillet-variable.js +2 -2
  160. package/dist/api/fillet-variable.js.map +1 -1
  161. package/dist/api/fillet.d.ts +2 -4
  162. package/dist/api/fillet.d.ts.map +1 -1
  163. package/dist/api/fillet.js +2 -4
  164. package/dist/api/fillet.js.map +1 -1
  165. package/dist/api/generated/2d.d.ts +4 -0
  166. package/dist/api/generated/2d.d.ts.map +1 -1
  167. package/dist/api/generated/2d.js +4 -0
  168. package/dist/api/generated/2d.js.map +1 -1
  169. package/dist/api/generated/core.d.ts +4 -0
  170. package/dist/api/generated/core.d.ts.map +1 -1
  171. package/dist/api/generated/core.js +4 -0
  172. package/dist/api/generated/core.js.map +1 -1
  173. package/dist/api/generated/gear.d.ts +4 -0
  174. package/dist/api/generated/gear.d.ts.map +1 -1
  175. package/dist/api/generated/gear.js +4 -0
  176. package/dist/api/generated/gear.js.map +1 -1
  177. package/dist/api/generated/io.d.ts +4 -0
  178. package/dist/api/generated/io.d.ts.map +1 -1
  179. package/dist/api/generated/io.js +4 -0
  180. package/dist/api/generated/io.js.map +1 -1
  181. package/dist/api/generated/kernel.d.ts +4 -0
  182. package/dist/api/generated/kernel.d.ts.map +1 -1
  183. package/dist/api/generated/kernel.js +4 -0
  184. package/dist/api/generated/kernel.js.map +1 -1
  185. package/dist/api/generated/measurement.d.ts +21 -21
  186. package/dist/api/generated/measurement.d.ts.map +1 -1
  187. package/dist/api/generated/measurement.js +25 -21
  188. package/dist/api/generated/measurement.js.map +1 -1
  189. package/dist/api/generated/ns.d.ts +4 -0
  190. package/dist/api/generated/ns.d.ts.map +1 -1
  191. package/dist/api/generated/ns.js +4 -0
  192. package/dist/api/generated/ns.js.map +1 -1
  193. package/dist/api/generated/operations.d.ts +32 -32
  194. package/dist/api/generated/operations.d.ts.map +1 -1
  195. package/dist/api/generated/operations.js +52 -48
  196. package/dist/api/generated/operations.js.map +1 -1
  197. package/dist/api/generated/projection.d.ts +4 -0
  198. package/dist/api/generated/projection.d.ts.map +1 -1
  199. package/dist/api/generated/projection.js +4 -0
  200. package/dist/api/generated/projection.js.map +1 -1
  201. package/dist/api/generated/query.d.ts +4 -0
  202. package/dist/api/generated/query.d.ts.map +1 -1
  203. package/dist/api/generated/query.js +4 -0
  204. package/dist/api/generated/query.js.map +1 -1
  205. package/dist/api/generated/sketching.d.ts +2 -2
  206. package/dist/api/generated/sketching.d.ts.map +1 -1
  207. package/dist/api/generated/sketching.js +7 -3
  208. package/dist/api/generated/sketching.js.map +1 -1
  209. package/dist/api/generated/text.d.ts +4 -0
  210. package/dist/api/generated/text.d.ts.map +1 -1
  211. package/dist/api/generated/text.js +4 -0
  212. package/dist/api/generated/text.js.map +1 -1
  213. package/dist/api/generated/topology.d.ts +45 -45
  214. package/dist/api/generated/topology.d.ts.map +1 -1
  215. package/dist/api/generated/topology.js +67 -63
  216. package/dist/api/generated/topology.js.map +1 -1
  217. package/dist/api/generated/view.d.ts +4 -0
  218. package/dist/api/generated/view.d.ts.map +1 -1
  219. package/dist/api/generated/view.js +4 -0
  220. package/dist/api/generated/view.js.map +1 -1
  221. package/dist/api/geom-types/constants.d.ts +11 -0
  222. package/dist/api/geom-types/constants.d.ts.map +1 -0
  223. package/dist/api/geom-types/constants.js +11 -0
  224. package/dist/api/geom-types/constants.js.map +1 -0
  225. package/dist/api/geom-types/index.d.ts +21 -0
  226. package/dist/api/geom-types/index.d.ts.map +1 -0
  227. package/dist/api/geom-types/index.js +22 -0
  228. package/dist/api/geom-types/index.js.map +1 -0
  229. package/dist/api/geom-types/planeOps.d.ts +98 -0
  230. package/dist/api/geom-types/planeOps.d.ts.map +1 -0
  231. package/dist/api/geom-types/planeOps.js +170 -0
  232. package/dist/api/geom-types/planeOps.js.map +1 -0
  233. package/dist/api/geom-types/planeTypes.d.ts +24 -0
  234. package/dist/api/geom-types/planeTypes.d.ts.map +1 -0
  235. package/dist/api/geom-types/planeTypes.js +8 -0
  236. package/dist/api/geom-types/planeTypes.js.map +1 -0
  237. package/dist/api/geom-types/types.d.ts +64 -0
  238. package/dist/api/geom-types/types.d.ts.map +1 -0
  239. package/dist/api/geom-types/types.js +48 -0
  240. package/dist/api/geom-types/types.js.map +1 -0
  241. package/dist/api/geom-types/vecOps.d.ts +124 -0
  242. package/dist/api/geom-types/vecOps.d.ts.map +1 -0
  243. package/dist/api/geom-types/vecOps.js +202 -0
  244. package/dist/api/geom-types/vecOps.js.map +1 -0
  245. package/dist/api/geom.d.ts.map +1 -1
  246. package/dist/api/geom.js +6 -5
  247. package/dist/api/geom.js.map +1 -1
  248. package/dist/api/half-space.d.ts +56 -0
  249. package/dist/api/half-space.d.ts.map +1 -0
  250. package/dist/api/half-space.js +82 -0
  251. package/dist/api/half-space.js.map +1 -0
  252. package/dist/api/helix.d.ts +10 -1
  253. package/dist/api/helix.d.ts.map +1 -1
  254. package/dist/api/helix.js +19 -3
  255. package/dist/api/helix.js.map +1 -1
  256. package/dist/api/import-step.d.ts.map +1 -1
  257. package/dist/api/import-step.js +28 -0
  258. package/dist/api/import-step.js.map +1 -1
  259. package/dist/api/index.d.ts +19 -6
  260. package/dist/api/index.d.ts.map +1 -1
  261. package/dist/api/index.js +31 -8
  262. package/dist/api/index.js.map +1 -1
  263. package/dist/api/internal/compat-op.d.ts +4 -30
  264. package/dist/api/internal/compat-op.d.ts.map +1 -1
  265. package/dist/api/internal/compat-op.js +10 -42
  266. package/dist/api/internal/compat-op.js.map +1 -1
  267. package/dist/api/internal/compat-projection.d.ts +5 -5
  268. package/dist/api/internal/compat-projection.js +5 -5
  269. package/dist/api/internal/compat-projection.js.map +1 -1
  270. package/dist/api/internal/dual-form-args.d.ts +0 -2
  271. package/dist/api/internal/dual-form-args.d.ts.map +1 -1
  272. package/dist/api/internal/dual-form-args.js +1 -3
  273. package/dist/api/internal/dual-form-args.js.map +1 -1
  274. package/dist/api/internal/l3-bridge.d.ts +5 -37
  275. package/dist/api/internal/l3-bridge.d.ts.map +1 -1
  276. package/dist/api/internal/l3-bridge.js +7 -76
  277. package/dist/api/internal/l3-bridge.js.map +1 -1
  278. package/dist/api/internal/profile-wire.d.ts +1 -1
  279. package/dist/api/internal/profile-wire.js +1 -1
  280. package/dist/api/internal/profile-wire.js.map +1 -1
  281. package/dist/api/internal/result-unwrap.d.ts +4 -6
  282. package/dist/api/internal/result-unwrap.d.ts.map +1 -1
  283. package/dist/api/internal/result-unwrap.js +4 -6
  284. package/dist/api/internal/result-unwrap.js.map +1 -1
  285. package/dist/api/knurl.d.ts.map +1 -1
  286. package/dist/api/knurl.js +5 -3
  287. package/dist/api/knurl.js.map +1 -1
  288. package/dist/api/loft.d.ts +2 -2
  289. package/dist/api/loft.d.ts.map +1 -1
  290. package/dist/api/loft.js +2 -2
  291. package/dist/api/loft.js.map +1 -1
  292. package/dist/api/measurement/index.d.ts +3 -3
  293. package/dist/api/measurement/index.js +3 -3
  294. package/dist/api/measurement/index.js.map +1 -1
  295. package/dist/api/meta.d.ts +91 -0
  296. package/dist/api/meta.d.ts.map +1 -0
  297. package/dist/api/meta.js +97 -0
  298. package/dist/api/meta.js.map +1 -0
  299. package/dist/api/offset2d.d.ts +49 -0
  300. package/dist/api/offset2d.d.ts.map +1 -0
  301. package/dist/api/offset2d.js +86 -0
  302. package/dist/api/offset2d.js.map +1 -0
  303. package/dist/api/pattern.js +3 -3
  304. package/dist/api/pattern.js.map +1 -1
  305. package/dist/api/primitives.d.ts.map +1 -1
  306. package/dist/api/primitives.js +124 -8
  307. package/dist/api/primitives.js.map +1 -1
  308. package/dist/api/replicate.d.ts +2 -2
  309. package/dist/api/replicate.d.ts.map +1 -1
  310. package/dist/api/replicate.js +12 -12
  311. package/dist/api/replicate.js.map +1 -1
  312. package/dist/api/result.d.ts +1 -1
  313. package/dist/api/result.js +1 -1
  314. package/dist/api/result.js.map +1 -1
  315. package/dist/api/revolve.d.ts +2 -2
  316. package/dist/api/revolve.js +3 -3
  317. package/dist/api/revolve.js.map +1 -1
  318. package/dist/api/screw.d.ts +1 -1
  319. package/dist/api/screw.d.ts.map +1 -1
  320. package/dist/api/screw.js +5 -4
  321. package/dist/api/screw.js.map +1 -1
  322. package/dist/api/sdf.d.ts.map +1 -1
  323. package/dist/api/sdf.js +3 -2
  324. package/dist/api/sdf.js.map +1 -1
  325. package/dist/api/shape-type/index.d.ts +141 -0
  326. package/dist/api/shape-type/index.d.ts.map +1 -0
  327. package/dist/api/shape-type/index.js +182 -0
  328. package/dist/api/shape-type/index.js.map +1 -0
  329. package/dist/api/shell.d.ts +2 -2
  330. package/dist/api/shell.js +2 -2
  331. package/dist/api/shell.js.map +1 -1
  332. package/dist/api/solid-from-faces.d.ts +45 -0
  333. package/dist/api/solid-from-faces.d.ts.map +1 -0
  334. package/dist/api/solid-from-faces.js +72 -0
  335. package/dist/api/solid-from-faces.js.map +1 -0
  336. package/dist/api/solid-offset/index.d.ts +67 -0
  337. package/dist/api/solid-offset/index.d.ts.map +1 -0
  338. package/dist/api/solid-offset/index.js +132 -0
  339. package/dist/api/solid-offset/index.js.map +1 -0
  340. package/dist/api/surface/arg-spec.d.ts +35 -33
  341. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  342. package/dist/api/surface/arg-spec.js +222 -224
  343. package/dist/api/surface/arg-spec.js.map +1 -1
  344. package/dist/api/surface-face/index.d.ts +104 -0
  345. package/dist/api/surface-face/index.d.ts.map +1 -0
  346. package/dist/api/surface-face/index.js +217 -0
  347. package/dist/api/surface-face/index.js.map +1 -0
  348. package/dist/api/surface.d.ts +44 -0
  349. package/dist/api/surface.d.ts.map +1 -0
  350. package/dist/api/surface.js +66 -0
  351. package/dist/api/surface.js.map +1 -0
  352. package/dist/api/sweep.d.ts +59 -9
  353. package/dist/api/sweep.d.ts.map +1 -1
  354. package/dist/api/sweep.js +11 -6
  355. package/dist/api/sweep.js.map +1 -1
  356. package/dist/api/thicken.d.ts +1 -1
  357. package/dist/api/thicken.js +1 -1
  358. package/dist/api/thicken.js.map +1 -1
  359. package/dist/api/transform.d.ts +5 -5
  360. package/dist/api/transform.d.ts.map +1 -1
  361. package/dist/api/transform.js +11 -10
  362. package/dist/api/transform.js.map +1 -1
  363. package/dist/api/view/cameraFns.d.ts +1 -1
  364. package/dist/api/view/cameraFns.d.ts.map +1 -1
  365. package/dist/api/view/cameraFns.js +1 -1
  366. package/dist/api/view/cameraFns.js.map +1 -1
  367. package/dist/api/view/index.d.ts +0 -2
  368. package/dist/api/view/index.d.ts.map +1 -1
  369. package/dist/api/view/index.js +0 -2
  370. package/dist/api/view/index.js.map +1 -1
  371. package/dist/api/view/projectionPlanes.d.ts +1 -1
  372. package/dist/api/view/projectionPlanes.d.ts.map +1 -1
  373. package/dist/api/view/projectionPlanes.js.map +1 -1
  374. package/dist/api/view/view-camera.d.ts +7 -9
  375. package/dist/api/view/view-camera.d.ts.map +1 -1
  376. package/dist/api/view/view-camera.js +4 -6
  377. package/dist/api/view/view-camera.js.map +1 -1
  378. package/dist/api/view/view-projection.d.ts +0 -2
  379. package/dist/api/view/view-projection.d.ts.map +1 -1
  380. package/dist/api/view/view-projection.js +0 -2
  381. package/dist/api/view/view-projection.js.map +1 -1
  382. package/dist/api/view/view-sheet.d.ts +0 -2
  383. package/dist/api/view/view-sheet.d.ts.map +1 -1
  384. package/dist/api/view/view-sheet.js +0 -2
  385. package/dist/api/view/view-sheet.js.map +1 -1
  386. package/dist/api/view-export/index.d.ts +97 -0
  387. package/dist/api/view-export/index.d.ts.map +1 -0
  388. package/dist/api/view-export/index.js +118 -0
  389. package/dist/api/view-export/index.js.map +1 -0
  390. package/dist/brep/brep-ops.d.ts +89 -1
  391. package/dist/brep/brep-ops.d.ts.map +1 -1
  392. package/dist/brep/brep-ops.js +204 -13
  393. package/dist/brep/brep-ops.js.map +1 -1
  394. package/dist/brep/brep-topology.d.ts +20 -0
  395. package/dist/brep/brep-topology.d.ts.map +1 -1
  396. package/dist/brep/brep-topology.js +46 -0
  397. package/dist/brep/brep-topology.js.map +1 -1
  398. package/dist/brep/engine/adapters/occt.d.ts +1 -1
  399. package/dist/brep/engine/adapters/occt.js +8 -8
  400. package/dist/brep/engine/adapters/occt.js.map +1 -1
  401. package/dist/brep/engine/primitives.d.ts +2 -3
  402. package/dist/brep/engine/primitives.d.ts.map +1 -1
  403. package/dist/brep/engine/primitives.js +1 -2
  404. package/dist/brep/engine/primitives.js.map +1 -1
  405. package/dist/brep/engine/registry.d.ts +1 -1
  406. package/dist/brep/engine/registry.js +1 -1
  407. package/dist/brep/engine/registry.js.map +1 -1
  408. package/dist/brep/engine/types.d.ts +2 -2
  409. package/dist/brep/engine/types.js.map +1 -1
  410. package/dist/brep/export/export-model.d.ts +40 -0
  411. package/dist/brep/export/export-model.d.ts.map +1 -1
  412. package/dist/brep/export/export-model.js +268 -25
  413. package/dist/brep/export/export-model.js.map +1 -1
  414. package/dist/brep/export/step-meta-header.d.ts +102 -0
  415. package/dist/brep/export/step-meta-header.d.ts.map +1 -0
  416. package/dist/brep/export/step-meta-header.js +225 -0
  417. package/dist/brep/export/step-meta-header.js.map +1 -0
  418. package/dist/brep/export/step.d.ts +5 -1
  419. package/dist/brep/export/step.d.ts.map +1 -1
  420. package/dist/brep/export/step.js +11 -2
  421. package/dist/brep/export/step.js.map +1 -1
  422. package/dist/brep/handle-bridge.d.ts +2 -2
  423. package/dist/brep/handle-bridge.js +2 -2
  424. package/dist/brep/handle-bridge.js.map +1 -1
  425. package/dist/brep/index.d.ts +6 -3
  426. package/dist/brep/index.d.ts.map +1 -1
  427. package/dist/brep/index.js +6 -3
  428. package/dist/brep/index.js.map +1 -1
  429. package/dist/brepkit-kernel/brepkitKernel.d.ts +1 -1
  430. package/dist/brepkit-kernel/brepkitKernel.js +2 -2
  431. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  432. package/dist/browser.d.ts +2 -2
  433. package/dist/browser.d.ts.map +1 -1
  434. package/dist/browser.js +5 -4
  435. package/dist/browser.js.map +1 -1
  436. package/dist/cad-runtime/admit-compat-lib.d.ts +3 -10
  437. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  438. package/dist/cad-runtime/admit-compat-lib.js +3 -9
  439. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  440. package/dist/cad-runtime/backend-dispatch.js +12 -3
  441. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  442. package/dist/cad-runtime/direct-executor.d.ts +6 -3
  443. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  444. package/dist/cad-runtime/direct-executor.js +31 -9
  445. package/dist/cad-runtime/direct-executor.js.map +1 -1
  446. package/dist/cad-runtime/interp/env.d.ts +1 -1
  447. package/dist/cad-runtime/interp/env.js.map +1 -1
  448. package/dist/cad-runtime/lib-id.d.ts +0 -2
  449. package/dist/cad-runtime/lib-id.d.ts.map +1 -1
  450. package/dist/cad-runtime/lib-id.js +0 -2
  451. package/dist/cad-runtime/lib-id.js.map +1 -1
  452. package/dist/cad-runtime/live-shapes.d.ts +3 -5
  453. package/dist/cad-runtime/live-shapes.d.ts.map +1 -1
  454. package/dist/cad-runtime/live-shapes.js +8 -10
  455. package/dist/cad-runtime/live-shapes.js.map +1 -1
  456. package/dist/cad-runtime/ports.d.ts +3 -3
  457. package/dist/cad-runtime/ports.js.map +1 -1
  458. package/dist/cad-runtime/runtime.d.ts +21 -7
  459. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  460. package/dist/cad-runtime/runtime.js +45 -6
  461. package/dist/cad-runtime/runtime.js.map +1 -1
  462. package/dist/define-op.d.ts +4 -3
  463. package/dist/define-op.d.ts.map +1 -1
  464. package/dist/define-op.js +65 -3
  465. package/dist/define-op.js.map +1 -1
  466. package/dist/geometry2d/bridge/plane.d.ts +1 -1
  467. package/dist/geometry2d/bridge/plane.js +1 -1
  468. package/dist/geometry2d/bridge/plane.js.map +1 -1
  469. package/dist/geometry2d/curve2d.d.ts +1 -1
  470. package/dist/geometry2d/curve2d.js +1 -1
  471. package/dist/geometry2d/curve2d.js.map +1 -1
  472. package/dist/index.d.ts +1 -1
  473. package/dist/index.d.ts.map +1 -1
  474. package/dist/index.js +10 -4
  475. package/dist/index.js.map +1 -1
  476. package/dist/io/fai-zip/container-read.d.ts +16 -0
  477. package/dist/io/fai-zip/container-read.d.ts.map +1 -1
  478. package/dist/io/fai-zip/container-read.js +22 -0
  479. package/dist/io/fai-zip/container-read.js.map +1 -1
  480. package/dist/io/fai-zip/index.d.ts +1 -1
  481. package/dist/io/fai-zip/index.d.ts.map +1 -1
  482. package/dist/io/fai-zip/index.js +1 -1
  483. package/dist/io/fai-zip/index.js.map +1 -1
  484. package/dist/lang/code-to-args.d.ts.map +1 -1
  485. package/dist/lang/code-to-args.js +10 -1
  486. package/dist/lang/code-to-args.js.map +1 -1
  487. package/dist/lang/determinism-scanner.d.ts.map +1 -1
  488. package/dist/lang/determinism-scanner.js +22 -9
  489. package/dist/lang/determinism-scanner.js.map +1 -1
  490. package/dist/lang/metadata-extractor.d.ts +27 -6
  491. package/dist/lang/metadata-extractor.d.ts.map +1 -1
  492. package/dist/lang/metadata-extractor.js +90 -29
  493. package/dist/lang/metadata-extractor.js.map +1 -1
  494. package/dist/lang/parse-error.d.ts +4 -0
  495. package/dist/lang/parse-error.d.ts.map +1 -1
  496. package/dist/lang/parse-error.js.map +1 -1
  497. package/dist/lang/security-scanner.d.ts +27 -2
  498. package/dist/lang/security-scanner.d.ts.map +1 -1
  499. package/dist/lang/security-scanner.js +29 -2
  500. package/dist/lang/security-scanner.js.map +1 -1
  501. package/dist/lang/source-edit.d.ts +2 -2
  502. package/dist/lang/source-edit.js.map +1 -1
  503. package/dist/lang/symbol-table.generated.d.ts +36 -0
  504. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  505. package/dist/lang/symbol-table.generated.js +36 -0
  506. package/dist/lang/symbol-table.generated.js.map +1 -1
  507. package/dist/lang/types.d.ts +5 -6
  508. package/dist/lang/types.d.ts.map +1 -1
  509. package/dist/lang/types.js.map +1 -1
  510. package/dist/mesh/import-model.d.ts +94 -0
  511. package/dist/mesh/import-model.d.ts.map +1 -0
  512. package/dist/mesh/import-model.js +15 -0
  513. package/dist/mesh/import-model.js.map +1 -0
  514. package/dist/mesh/index.d.ts +19 -58
  515. package/dist/mesh/index.d.ts.map +1 -1
  516. package/dist/mesh/index.js +19 -70
  517. package/dist/mesh/index.js.map +1 -1
  518. package/dist/mesh/io.d.ts +39 -16
  519. package/dist/mesh/io.d.ts.map +1 -1
  520. package/dist/mesh/io.js +151 -22
  521. package/dist/mesh/io.js.map +1 -1
  522. package/dist/mesh/primitives.d.ts.map +1 -1
  523. package/dist/mesh/primitives.js +42 -7
  524. package/dist/mesh/primitives.js.map +1 -1
  525. package/dist/mesh/threemf-bambu.d.ts +12 -1
  526. package/dist/mesh/threemf-bambu.d.ts.map +1 -1
  527. package/dist/mesh/threemf-bambu.js +68 -16
  528. package/dist/mesh/threemf-bambu.js.map +1 -1
  529. package/dist/mesh/threemf-loader.d.ts +37 -1
  530. package/dist/mesh/threemf-loader.d.ts.map +1 -1
  531. package/dist/mesh/threemf-loader.js +205 -14
  532. package/dist/mesh/threemf-loader.js.map +1 -1
  533. package/dist/mesh/transform.d.ts +1 -1
  534. package/dist/mesh/transform.js +1 -1
  535. package/dist/mesh/transform.js.map +1 -1
  536. package/dist/mesh/types.d.ts +43 -5
  537. package/dist/mesh/types.d.ts.map +1 -1
  538. package/dist/mesh/types.js.map +1 -1
  539. package/dist/node-host/cli.d.ts +49 -1
  540. package/dist/node-host/cli.d.ts.map +1 -1
  541. package/dist/node-host/cli.js +125 -19
  542. package/dist/node-host/cli.js.map +1 -1
  543. package/dist/node-host/execute-script.d.ts +55 -0
  544. package/dist/node-host/execute-script.d.ts.map +1 -0
  545. package/dist/node-host/execute-script.js +46 -0
  546. package/dist/node-host/execute-script.js.map +1 -0
  547. package/dist/node.d.ts +2 -0
  548. package/dist/node.d.ts.map +1 -1
  549. package/dist/node.js +3 -0
  550. package/dist/node.js.map +1 -1
  551. package/dist/occt-kernel/generated/occtPlatform.generated.d.ts +260 -0
  552. package/dist/occt-kernel/generated/occtPlatform.generated.d.ts.map +1 -0
  553. package/dist/occt-kernel/generated/occtPlatform.generated.js +875 -0
  554. package/dist/occt-kernel/generated/occtPlatform.generated.js.map +1 -0
  555. package/dist/occt-kernel/highLevelApi.d.ts +4 -1
  556. package/dist/occt-kernel/highLevelApi.d.ts.map +1 -1
  557. package/dist/occt-kernel/highLevelApi.js +4 -2
  558. package/dist/occt-kernel/highLevelApi.js.map +1 -1
  559. package/dist/occt-kernel/hullGeometry.d.ts +2 -2
  560. package/dist/occt-kernel/hullGeometry.js +2 -3
  561. package/dist/occt-kernel/hullGeometry.js.map +1 -1
  562. package/dist/occt-kernel/hullOps.d.ts +3 -3
  563. package/dist/occt-kernel/hullOps.js +4 -4
  564. package/dist/occt-kernel/hullOps.js.map +1 -1
  565. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  566. package/dist/occt-kernel/occt-primitives.js +32 -5
  567. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  568. package/dist/occt-kernel/occtKernel.d.ts +1 -1
  569. package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
  570. package/dist/occt-kernel/occtKernel.js +19 -1
  571. package/dist/occt-kernel/occtKernel.js.map +1 -1
  572. package/dist/occt-kernel/stepMetaParser.d.ts +44 -0
  573. package/dist/occt-kernel/stepMetaParser.d.ts.map +1 -0
  574. package/dist/occt-kernel/stepMetaParser.js +166 -0
  575. package/dist/occt-kernel/stepMetaParser.js.map +1 -0
  576. package/dist/occt-scan/recognize.d.ts +58 -0
  577. package/dist/occt-scan/recognize.d.ts.map +1 -0
  578. package/dist/occt-scan/recognize.js +216 -0
  579. package/dist/occt-scan/recognize.js.map +1 -0
  580. package/dist/primitives/brep-primitives.js +7 -7
  581. package/dist/primitives/brep-primitives.js.map +1 -1
  582. package/dist/result/bug.d.ts +1 -1
  583. package/dist/result/bug.js +1 -1
  584. package/dist/result/bug.js.map +1 -1
  585. package/dist/result/errors.d.ts +2 -2
  586. package/dist/result/errors.d.ts.map +1 -1
  587. package/dist/result/errors.js +1 -1
  588. package/dist/result/errors.js.map +1 -1
  589. package/dist/result/vec3.d.ts +1 -1
  590. package/dist/result/vec3.js +1 -1
  591. package/dist/result/vec3.js.map +1 -1
  592. package/dist/runtime-state.d.ts +16 -0
  593. package/dist/runtime-state.d.ts.map +1 -1
  594. package/dist/runtime-state.js +27 -0
  595. package/dist/runtime-state.js.map +1 -1
  596. package/dist/script-globals.d.ts +24 -0
  597. package/dist/script-globals.d.ts.map +1 -0
  598. package/dist/script-globals.js +24 -0
  599. package/dist/script-globals.js.map +1 -0
  600. package/dist/shape.d.ts +35 -3
  601. package/dist/shape.d.ts.map +1 -1
  602. package/dist/shape.js +44 -2
  603. package/dist/shape.js.map +1 -1
  604. package/dist/step/stepMetaParser.d.ts +55 -0
  605. package/dist/step/stepMetaParser.d.ts.map +1 -0
  606. package/dist/step/stepMetaParser.js +177 -0
  607. package/dist/step/stepMetaParser.js.map +1 -0
  608. package/dist/topology/naming/lineage.d.ts +3 -2
  609. package/dist/topology/naming/lineage.d.ts.map +1 -1
  610. package/dist/topology/naming/lineage.js.map +1 -1
  611. package/dist/weapp.d.ts +1 -1
  612. package/dist/weapp.js +1 -1
  613. package/dist/weapp.js.map +1 -1
  614. package/package.json +9 -11
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @faicad/faijs �?Faicad CAD execution engine\n *\n * 公开 API 统一入口。所有导出按层组织:\n * - L0 文本层:parser / codegen / symbol-table / types\n * - L1 几何执行层:BREP ops / Shape / 导出\n * - L1 Mesh 执行层:cad API\n * - L1 Boolean/CSG 辅助:cross-section / deriveNormals / extrude-helpers / joinery-shapes\n * - L1 Primitives:geometry / screw / svg-extrude / text / types\n * - L1 SDF:sdf-runner / templates / types\n * - L1 Knurl:KnurlGenerator / subdivision / textureLoader\n * - L1 Topology:build-face-ids / build-selector-runtime / types\n * - L2 编排层:CadRuntime / HostPorts\n * - L3 Node Host:createNodePorts / CLI\n * - OCCT Kernel:initOcctWasm / getKernel / setOcctWasmInitFn / ...\n * - CSG Backend:setCsgBackend / geoToManifoldMesh / ...\n */\n\n// ── 共享面(env-agnostic:identity + runtime-state + lang/*)──\n// 手写清单已收敛:三处 umbrella(index/browser/weapp)统一 re-export,防漂移。\nexport * from './env-agnostic'\n\n// ── L1 几何执行 ──\nexport type { Shape } from './mesh/types'\nexport type { BrepChainState } from './brep/brep-chain'\nexport {\n createBrepChainState, initBrepChainState, releaseBrepChainState,\n isCadFormat,\n} from './brep/brep-chain'\nexport {\n solidToShape, getSolidBoundingBox,\n translateBrep, rotateBrep, scaleBrep,\n fuseBrep, cutBrep, commonBrep,\n drillBrep, splitBrep, extrudeBrep,\n loadBrep, matrixToArray,\n} from './brep'\nexport type { DrillBrepParams, SplitBrepParams, SplitBrepResult, ExtrudeBrepParams } from './brep'\nexport { buildStlBufferFromMesh } from './brep/export/stl'\nexport { exportStepFromSolid, exportStepFromSolids } from './brep/export/step'\nexport type { StepExportEntry } from './brep/export/step'\n\n// ── L1 Mesh ──\nexport { cad } from './mesh'\n// 宿主注入的 mesh 装饰几何(cad.engrave 的文字/SVG 几何链在 @faicad/faijs-extra)\nexport { setEngraveDecorationProvider, getEngraveDecorationProvider } from './mesh/decoration-provider'\nexport type { EngraveDecorationProvider, EngraveDecorationParams } from './mesh/decoration-provider'\nexport { setManifoldWasmUrl, getManifoldWasmUrl, getManifoldModule } from './mesh/manifold-loader'\nexport type {\n BoundingBox, FaceDescriptor,\n BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams,\n TextParams, SvgExtrudeParams, SdfParams,\n DrillParams, ExtrudeParams, EngraveParams, KnurlParams,\n SplitPlane, SplitResult,\n} from './mesh/types'\nexport { NRAD_DEFAULT, NRAD_MIN, NRAD_MAX, clampNRad } from './mesh/types'\nexport { faceAt } from './mesh/query'\n\n// ── L1 Boolean/CSG 辅助 ──\nexport { computeSection, buildExtrudedProfile } from './boolean/cross-section'\nexport { manifoldToMeshData, weldPositionsWorker, dovetailBooleanSplit, dowelOrTenonBooleanSplit } from './boolean/csg-core'\nexport { deriveNormals } from './boolean/deriveNormals'\nexport { buildExtrudeParts, makeWorldPlane } from './boolean/extrude-helpers'\nexport type { ExtrudeParts, ExtrudeOffsetMode } from './boolean/extrude-helpers'\nexport {\n buildWedgeGeometry, buildDowelGeometry, buildStraightTenonGeometry,\n} from './boolean/joinery-shapes'\nexport type { JoineryMeshData } from './boolean/joinery-shapes'\n\n// ── CSG Backend ──\nexport { setCsgBackend } from './boolean/csg-backend'\nexport { geoToManifoldMesh, manifoldMeshToGeo } from './boolean/geo-convert'\nexport type {\n ManifoldMeshData, BooleanOperation,\n DovetailGrooveParams, DowelSplitParams, StraightTenonSplitParams,\n} from './boolean/geo-convert'\n\n// ── L1 Primitives ──\nexport { mergeBufferGeometries, makePrimitiveGeo, DEFAULT_SIZE, applyPrimitiveOffset } from './primitives/mesh-primitives'\nexport { makeScrew } from './primitives/screw/screw'\nexport { getScrewSpec, getScrewSpecs, threadToPitchMm, SCREW_HEAD_DIMS } from './primitives/screw/screw-db'\nexport type { ScrewParams, ScrewSpec, ScrewSystem } from './primitives/screw/screw-db'\nexport { parseSvgNaturalSize } from './primitives/parse-svg-size'\nexport {\n extractMeshData, primitiveToBrepSolid, geometryToBrepSolid,\n brepSolidToStep, primitiveToBrepStep,\n} from './primitives/brep-primitives'\nexport type { PrimitiveToBrepResult, PrimitiveParams } from './primitives/brep-primitives'\n// B 组(svg 挤出 / 3D 文字几何链)已随 @faicad/faijs-extra 迁出;\n// 留 core 的是零 three 的 CJK 字符判定与系统字体装载。\nexport { loadSystemCjkFont, containsCjk, isCjkChar } from './primitives/text/cjk-font'\nexport type { CjkFontResult } from './primitives/text/cjk-font'\nexport type {\n PrimitiveType, PrimitiveParamsRecord, PrimitiveArgsRecord, PrimitiveMeta,\n} from './primitives/types'\nexport { nextPrimitiveColor } from './primitives/types'\n\n// ── L1 SDF ──\nexport { runSdf } from './sdf/sdf-runner'\nexport type { SdfMeshData } from './sdf/sdf-runner'\nexport { runSdfInline } from './sdf/sdf-core'\nexport { SDF_TEMPLATES, DEFAULT_SDF_TEMPLATE } from './sdf/templates'\nexport type {\n SdfMeta, SdfBox, SdfParamDef, SdfTemplateCategory,\n SdfWorkerInput, SdfWorkerMessage,\n} from './sdf/types'\nexport { boxToTuple, parseParamDefs, defaultParamValues } from './sdf/types'\n\n// ── L1 Knurl ──\nexport { applyKnurlDisplacement, KNURL_DEFAULTS } from './mesh/knurl/KnurlGenerator'\nexport type { KnurlBounds } from './mesh/knurl/KnurlGenerator'\nexport { subdivide } from './mesh/knurl/subdivision'\nexport { loadKnurlingTexture, setKnurlTextureLoader } from './mesh/knurl/textureLoader'\nexport type { TextureData } from './mesh/knurl/textureLoader'\nexport { QuantizedPointMap, weldVertices } from './mesh/knurl/meshIndex'\nexport { computeUV, MODE_TRIPLANAR, getCubicBlendWeights, type MappingSettings } from './mesh/knurl/mapping'\nexport { applyDisplacement, type DisplacementSettings } from './mesh/knurl/displacement'\n\n// ── L1 Topology ──\nexport { TOPOLOGY_FACE_ID_NONE, buildFaceIdsForPart } from './topology/build-face-ids'\nexport {\n buildSelectorRuntime, buildSelectorRuntimeData, buildSelectorRuntimeMaps,\n} from './topology/build-selector-runtime'\nexport type { SelectorRuntimeData } from './topology/build-selector-runtime'\nexport type {\n SelectorRuntime, SelectorBundle, SelectorManifest, SelectorBuffers,\n FaceRow, EdgeRow, Reference,\n BufferViewDescriptor, SelectorProxy,\n} from './topology/types'\n\nexport * from './topology/naming'\n\n// ── L2 编排�?──\n// D1(2026-09-19):createRuntime 自注册 cad 默认命名空间(引擎 + 标准库定位)。\n// 需要纯引擎(不带 cad)的宿主可直接 import { createRuntime } from './cad-runtime/runtime'。\nexport { CadRuntime, createRuntime, computeContentKey, AppendPrefixError } from './cad-runtime/createRuntimeWithCad'\nexport { createPreviewExec } from './cad-runtime/preview-exec'\nexport type { PreviewExec } from './cad-runtime/preview-exec'\nexport type { ExecutionResult, ExecuteOptions, CheckResult, CheckError, CadRuntimeOptions } from './cad-runtime/runtime'\nexport type {\n HostPorts, CsgBackend, SdfBackend, FontProvider, TextureSampler,\n AssetResolver, EventSink, ExecutionMode,\n MeshData, PlaneParams, SplitResult as CsgSplitResult,\n DovetailGrooveParams as PortDovetailGrooveParams,\n DowelSplitParams as PortDowelSplitParams,\n StraightTenonSplitParams as PortStraightTenonSplitParams,\n LibLoader, ProjectLoader,\n} from './cad-runtime/ports'\n\n// ── OCCT Kernel ──\nexport {\n initOcctWasm, getKernel, disposeOcctWasm, setOcctWasmInitFn,\n computeEffectiveDeflection, importStepToMesh, importBrepToMesh,\n meshesToStep, releaseShape,\n importAssemblyFromStep, releaseAssemblyTree, collectLeafParts,\n} from './occt-kernel/occtKernel'\nexport type {\n WasmTessellatedMesh, WasmImportResult, AssemblyPartNode,\n MeshDeflectionOptions, ShapeHandle, OcctKernel,\n Mesh, EdgeData, SurfaceKind, CurveKind,\n} from './occt-kernel/occtKernel'\n\n// ── OCCT Mesh Reconstruct ──\nexport { reconstructSolidFromMesh, meshToAsciiStl, cadShapeIsValid, meshToStepBrep } from './occt-kernel/meshReconstruct'\n\n// ── OCCT 高层导出(多实体、零 fuse) ──\nexport { exportStepFromSolidsHighLevel } from './occt-kernel/highLevelApi'\n\n// ── OCCT Topology Extension ──\nexport { buildSelectorManifest, buildAssemblySelectorManifest, buildTopologyAdjacency } from './occt-kernel/topologyExt'\nexport type { SelectorManifestInput, PartTopologyInput, AssemblyTopologyResult, TopologyAdjacency } from './occt-kernel/topologyExt'\n\n// ── BREP 引擎注册(宿主装配;引擎可切换——occt 只是默认实现) ──\nexport { registerOcctBrepEngine, OCCT_BREP_ENGINE_ID } from './brep/engine/adapters/occt'\nexport { registerBrepMockEngine, BREP_MOCK_ENGINE_ID, createBrepMockApi } from './brep/engine/adapters/brep-mock'\n// brepkit 端侧 BREP 引擎(微信小程序等无 OCCT 环境):由宿主注入 wasm init 并抢先注册,\n// 使 ensureBrepChain 不回退 OCCT。setBrepkitWasmInitFn 注入自定义初始化(如 WXWebAssembly 实例化)。\nexport { registerBrepkitBrepEngine, BREPKIT_BREP_ENGINE_ID, ensureBrepkitDefaultEngine } from './brep/engine/adapters/brepkit'\n// brepkit 网格实体后端(网格语义路径;与 BREP 槽独立注册)。装了它,`cad.load`\n// 的 STL/3MF 路径才产出「网格实体 + 近似拓扑」;不装则维持裸网格的历史行为。\nexport { registerBrepkitMeshEngine, BREPKIT_MESH_ENGINE_ID, ensureBrepkitMeshBackend } from './brep/engine/adapters/brepkit'\nexport { setBrepkitWasmInitFn, initBrepkitWasm, isBrepkitInitialized } from './brepkit-kernel/brepkitWasm'\nexport {\n registerBrepEngine, getBrepEngine, hasBrepEngine, getActiveBrepEngineId,\n registerMeshEngine, getMeshEngine, getActiveMeshEngineId, freezeEngineRegistries,\n isMeshEngineRegistered, getMeshSolidBackend,\n} from './brep/engine/registry'\nexport type { BrepEngine, BrepEngineProvider, MeshEngine } from './brep/engine/registry'\n// 网格实体(近似拓扑的载体):端口 + 注册表 + 驱动。\nexport { MeshSolidRegistry, normalizeMeshSolid, describeMeshSolid, buildMeshSolidTopology, weldToleranceFor } from './brep/mesh-solid'\nexport type {\n MeshSolidBackend, MeshSolidResult, MeshSolidKernelOps, MeshSolidInput, MeshSolidNormalizeOptions,\n} from './brep/mesh-solid'\n// 槽位互斥不变量(分派前置校验;缺陷即报错)\nexport { assertShapeSlotExclusive } from './cad-runtime/backend-dispatch'\nexport type { BrepEngineApi } from './brep/engine/primitives'\nexport type {\n BrepHandle, BrepMeshResult, BrepBoundingBox, BrepVec3, BrepCapabilities,\n BrepEvolutionData, BrepXcafDocument,\n} from './brep/engine/types'\n\n// ── BREP Topology ──\nexport { buildSolidTopologyRuntime } from './brep/brep-topology'\nexport type { SolidTopologyResult } from './brep/brep-topology'\n\n// ── Font Registry (for browser host injection) ──\nexport { setFontLoader, getFontLoader, loadFont, ensureDefaultFont, ensureFont, getFont, clearFonts } from './brep/text/fontRegistry'\nexport type { FontLoader } from './brep/text/fontRegistry'\n\n// ── L3 Node Host ──\n// node-host 模块已移�?@faicad/faijs/node 入口,避免浏览器环境静�?import\n// node-host 模块(含 Node.js 专用代码�?fs/path)导致生产构�?404�?\n// �?Node.js 环境中:import { createNodePorts } from '@faicad/faijs/node'\n\n// ── L3 Browser Host ──\nexport { createBrowserPorts } from './browser-host'\nexport type { CreateBrowserPortsOptions } from './browser-host'\n// D3-Browser(§9.4):CDN 通用 libLoader 工厂(a/b 混合)。**不**被 createBrowserPorts\n// 默认装配——demo 的源码 alias HMR 路径必须零网络;CDN 装载由主机显式注入。\nexport { createBrowserLibLoader, DEFAULT_CDN_BASE } from './cad-runtime/browser-lib-loader'\nexport type {\n BrowserLibLoader, BrowserLibMeta, CreateBrowserLibLoaderOptions,\n} from './cad-runtime/browser-lib-loader'\nexport { BrowserEventSink } from './browser-host/browser-event-sink'\nexport { BrowserFontProvider } from './browser-host/browser-font-provider'\nexport type { BrowserFontProviderOptions } from './browser-host/browser-font-provider'\nexport { FetchAssetResolver } from './browser-host/fetch-asset-resolver'\nexport type { FetchAssetResolverOptions } from './browser-host/fetch-asset-resolver'\n\n// ── L3 API 面(api/ 层)──\n// P23 主导出切换(§4.2 / Q1):`export * from './api'` 现在同时带来\n// ① faijs 特有 dual op(mesh+brep 双路径,D11 双形态归一);\n// ② 生成脚本面 op(`api/generated/script-face.ts`,compatOp(projectBrepOp(…)) 包装的\n// brep-only 语句级 op——`cad.*` 脚本面与此同源,B1 三源一致);\n// ③ 2026-09-25 core-decouple:brepjsCompat 命名空间与 op 投影随 vendored 树删除\n// (裁决 9);`api/brepjs-compat` 仅保留 core 内联的 Result / 向量 / 平面 / 错误 /\n// 常量组合器(§5.2),顶层平铺不变。\nexport * from './api'\nexport { createApiNamespace } from './api/api-namespace'\n// Vec3 双源消歧:env-agnostic(lang/types)与 api(mesh/types)均有 Vec3,\n// 显式 re-export 定为 lang 版(与收敛前 index.ts 的具名导出一致)。\nexport type { Vec3 } from './lang/types'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @faicad/faijs �?Faicad CAD execution engine\n *\n * 公开 API 统一入口。所有导出按层组织:\n * - L0 文本层:parser / codegen / symbol-table / types\n * - L1 几何执行层:BREP ops / Shape / 导出\n * - L1 Mesh 执行层:cad API\n * - L1 Boolean/CSG 辅助:cross-section / deriveNormals / extrude-helpers / joinery-shapes\n * - L1 Primitives:geometry / screw / svg-extrude / text / types\n * - L1 SDF:sdf-runner / templates / types\n * - L1 Knurl:KnurlGenerator / subdivision / textureLoader\n * - L1 Topology:build-face-ids / build-selector-runtime / types\n * - L2 编排层:CadRuntime / HostPorts\n * - L3 Node Host:createNodePorts / CLI\n * - OCCT Kernel:initOcctWasm / getKernel / setOcctWasmInitFn / ...\n * - CSG Backend:setCsgBackend / geoToManifoldMesh / ...\n */\n\n// ── 共享面(env-agnostic:identity + runtime-state + lang/*)──\n// 手写清单已收敛:三处 umbrella(index/browser/weapp)统一 re-export,防漂移。\nexport * from './env-agnostic'\n\n// ── L1 几何执行 ──\nexport type { Shape } from './mesh/types'\nexport type { BrepChainState } from './brep/brep-chain'\nexport {\n createBrepChainState, initBrepChainState, releaseBrepChainState,\n isCadFormat,\n} from './brep/brep-chain'\nexport {\n solidToShape, getSolidBoundingBox,\n translateBrep, rotateBrep, scaleBrep,\n fuseBrep, cutBrep, commonBrep,\n drillBrep, splitBrep, extrudeBrep,\n loadBrep, matrixToArray,\n} from './brep'\nexport type { DrillBrepParams, SplitBrepParams, SplitBrepResult, ExtrudeBrepParams } from './brep'\nexport { buildStlBufferFromMesh } from './brep/export/stl'\nexport { exportStepFromSolid, exportStepFromSolids } from './brep/export/step'\nexport type { StepExportEntry } from './brep/export/step'\n\n// ── L1 Mesh ──\n// B3 correction (2026-10-06): no `cad` / `meshCad` aggregate is exported from the library\n// face. `cad` belongs to the script face (host-injected ops); TS consumers import\n// per-module from `@faicad/faijs/mesh/*`.\n// 宿主注入的 mesh 装饰几何(cad.engrave 的文字/SVG 几何链在 @faicad/faijs-extra)\nexport { setEngraveDecorationProvider, getEngraveDecorationProvider } from './mesh/decoration-provider'\nexport type { EngraveDecorationProvider, EngraveDecorationParams } from './mesh/decoration-provider'\nexport { setManifoldWasmUrl, getManifoldWasmUrl, getManifoldModule } from './mesh/manifold-loader'\nexport type {\n BoundingBox, FaceDescriptor,\n BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams,\n TextParams, SvgExtrudeParams, SdfParams,\n DrillParams, ExtrudeParams, EngraveParams, KnurlParams,\n SplitPlane, SplitResult,\n} from './mesh/types'\nexport { NRAD_DEFAULT, NRAD_MIN, NRAD_MAX, clampNRad } from './mesh/types'\nexport { faceAt } from './mesh/query'\n\n// ── L1 Boolean/CSG 辅助 ──\nexport { computeSection, buildExtrudedProfile } from './boolean/cross-section'\nexport { manifoldToMeshData, weldPositionsWorker, dovetailBooleanSplit, dowelOrTenonBooleanSplit } from './boolean/csg-core'\nexport { deriveNormals } from './boolean/deriveNormals'\nexport { buildExtrudeParts, makeWorldPlane } from './boolean/extrude-helpers'\nexport type { ExtrudeParts, ExtrudeOffsetMode } from './boolean/extrude-helpers'\nexport {\n buildWedgeGeometry, buildDowelGeometry, buildStraightTenonGeometry,\n} from './boolean/joinery-shapes'\nexport type { JoineryMeshData } from './boolean/joinery-shapes'\n\n// ── CSG Backend ──\nexport { setCsgBackend } from './boolean/csg-backend'\nexport { geoToManifoldMesh, manifoldMeshToGeo } from './boolean/geo-convert'\nexport type {\n ManifoldMeshData, BooleanOperation,\n DovetailGrooveParams, DowelSplitParams, StraightTenonSplitParams,\n} from './boolean/geo-convert'\n\n// ── L1 Primitives ──\nexport { mergeBufferGeometries, makePrimitiveGeo, DEFAULT_SIZE, applyPrimitiveOffset } from './primitives/mesh-primitives'\nexport { makeScrew } from './primitives/screw/screw'\nexport { getScrewSpec, getScrewSpecs, threadToPitchMm, SCREW_HEAD_DIMS } from './primitives/screw/screw-db'\nexport type { ScrewParams, ScrewSpec, ScrewSystem } from './primitives/screw/screw-db'\nexport { parseSvgNaturalSize } from './primitives/parse-svg-size'\nexport {\n extractMeshData, primitiveToBrepSolid, geometryToBrepSolid,\n brepSolidToStep, primitiveToBrepStep,\n} from './primitives/brep-primitives'\nexport type { PrimitiveToBrepResult, PrimitiveParams } from './primitives/brep-primitives'\n// B 组(svg 挤出 / 3D 文字几何链)已随 @faicad/faijs-extra 迁出;\n// 留 core 的是零 three 的 CJK 字符判定与系统字体装载。\nexport { loadSystemCjkFont, containsCjk, isCjkChar } from './primitives/text/cjk-font'\nexport type { CjkFontResult } from './primitives/text/cjk-font'\nexport type {\n PrimitiveType, PrimitiveParamsRecord, PrimitiveArgsRecord, PrimitiveMeta,\n} from './primitives/types'\nexport { nextPrimitiveColor } from './primitives/types'\n\n// ── L1 SDF ──\nexport { runSdf } from './sdf/sdf-runner'\nexport type { SdfMeshData } from './sdf/sdf-runner'\nexport { runSdfInline } from './sdf/sdf-core'\nexport { SDF_TEMPLATES, DEFAULT_SDF_TEMPLATE } from './sdf/templates'\nexport type {\n SdfMeta, SdfBox, SdfParamDef, SdfTemplateCategory,\n SdfWorkerInput, SdfWorkerMessage,\n} from './sdf/types'\nexport { boxToTuple, parseParamDefs, defaultParamValues } from './sdf/types'\n\n// ── L1 Knurl ──\nexport { applyKnurlDisplacement, KNURL_DEFAULTS } from './mesh/knurl/KnurlGenerator'\nexport type { KnurlBounds } from './mesh/knurl/KnurlGenerator'\nexport { subdivide } from './mesh/knurl/subdivision'\nexport { loadKnurlingTexture, setKnurlTextureLoader } from './mesh/knurl/textureLoader'\nexport type { TextureData } from './mesh/knurl/textureLoader'\nexport { QuantizedPointMap, weldVertices } from './mesh/knurl/meshIndex'\nexport { computeUV, MODE_TRIPLANAR, getCubicBlendWeights, type MappingSettings } from './mesh/knurl/mapping'\nexport { applyDisplacement, type DisplacementSettings } from './mesh/knurl/displacement'\n\n// ── L1 Topology ──\nexport { TOPOLOGY_FACE_ID_NONE, buildFaceIdsForPart } from './topology/build-face-ids'\nexport {\n buildSelectorRuntime, buildSelectorRuntimeData, buildSelectorRuntimeMaps,\n} from './topology/build-selector-runtime'\nexport type { SelectorRuntimeData } from './topology/build-selector-runtime'\nexport type {\n SelectorRuntime, SelectorBundle, SelectorManifest, SelectorBuffers,\n FaceRow, EdgeRow, Reference,\n BufferViewDescriptor, SelectorProxy,\n} from './topology/types'\n\nexport * from './topology/naming'\n\n// ── L2 编排�?──\n// D1(2026-09-19):createRuntime 自注册 cad 默认命名空间(引擎 + 标准库定位)。\n// 需要纯引擎(不带 cad)的宿主可直接 import { createRuntime } from './cad-runtime/runtime'。\nexport { CadRuntime, createRuntime, computeContentKey, AppendPrefixError } from './cad-runtime/createRuntimeWithCad'\nexport { createPreviewExec } from './cad-runtime/preview-exec'\nexport type { PreviewExec } from './cad-runtime/preview-exec'\nexport type { ExecutionResult, ExecuteOptions, CheckResult, CheckError, CadRuntimeOptions } from './cad-runtime/runtime'\nexport type {\n HostPorts, CsgBackend, SdfBackend, FontProvider, TextureSampler,\n AssetResolver, EventSink, ExecutionMode,\n MeshData, PlaneParams, SplitResult as CsgSplitResult,\n DovetailGrooveParams as PortDovetailGrooveParams,\n DowelSplitParams as PortDowelSplitParams,\n StraightTenonSplitParams as PortStraightTenonSplitParams,\n LibLoader, ProjectLoader,\n} from './cad-runtime/ports'\n\n// ── OCCT Kernel ──\nexport {\n initOcctWasm, getKernel, disposeOcctWasm, setOcctWasmInitFn,\n computeEffectiveDeflection, importStepToMesh, importBrepToMesh,\n meshesToStep, releaseShape,\n importAssemblyFromStep, releaseAssemblyTree, collectLeafParts,\n} from './occt-kernel/occtKernel'\nexport type {\n WasmTessellatedMesh, WasmImportResult, AssemblyPartNode,\n MeshDeflectionOptions, ShapeHandle, OcctKernel,\n Mesh, EdgeData, SurfaceKind, CurveKind,\n} from './occt-kernel/occtKernel'\n\n// ── OCCT Mesh Reconstruct ──\nexport { reconstructSolidFromMesh, meshToAsciiStl, cadShapeIsValid, meshToStepBrep } from './occt-kernel/meshReconstruct'\n\n// ── OCCT 高层导出(多实体、零 fuse) ──\nexport { exportStepFromSolidsHighLevel } from './occt-kernel/highLevelApi'\n\n// ── OCCT Topology Extension ──\nexport { buildSelectorManifest, buildAssemblySelectorManifest, buildTopologyAdjacency } from './occt-kernel/topologyExt'\nexport type { SelectorManifestInput, PartTopologyInput, AssemblyTopologyResult, TopologyAdjacency } from './occt-kernel/topologyExt'\n\n// ── BREP 引擎注册(宿主装配;引擎可切换——occt 只是默认实现) ──\nexport { registerOcctBrepEngine, OCCT_BREP_ENGINE_ID } from './brep/engine/adapters/occt'\nexport { registerBrepMockEngine, BREP_MOCK_ENGINE_ID, createBrepMockApi } from './brep/engine/adapters/brep-mock'\n// brepkit 端侧 BREP 引擎(微信小程序等无 OCCT 环境):由宿主注入 wasm init 并抢先注册,\n// 使 ensureBrepChain 不回退 OCCT。setBrepkitWasmInitFn 注入自定义初始化(如 WXWebAssembly 实例化)。\nexport { registerBrepkitBrepEngine, BREPKIT_BREP_ENGINE_ID, ensureBrepkitDefaultEngine } from './brep/engine/adapters/brepkit'\n// brepkit 网格实体后端(网格语义路径;与 BREP 槽独立注册)。装了它,`cad.load`\n// 的 STL/3MF 路径才产出「网格实体 + 近似拓扑」;不装则维持裸网格的历史行为。\nexport { registerBrepkitMeshEngine, BREPKIT_MESH_ENGINE_ID, ensureBrepkitMeshBackend } from './brep/engine/adapters/brepkit'\nexport { setBrepkitWasmInitFn, initBrepkitWasm, isBrepkitInitialized } from './brepkit-kernel/brepkitWasm'\nexport {\n registerBrepEngine, getBrepEngine, hasBrepEngine, getActiveBrepEngineId,\n registerMeshEngine, getMeshEngine, getActiveMeshEngineId, freezeEngineRegistries,\n isMeshEngineRegistered, getMeshSolidBackend,\n} from './brep/engine/registry'\nexport type { BrepEngine, BrepEngineProvider, MeshEngine } from './brep/engine/registry'\n// 网格实体(近似拓扑的载体):端口 + 注册表 + 驱动。\nexport { MeshSolidRegistry, normalizeMeshSolid, describeMeshSolid, buildMeshSolidTopology, weldToleranceFor } from './brep/mesh-solid'\nexport type {\n MeshSolidBackend, MeshSolidResult, MeshSolidKernelOps, MeshSolidInput, MeshSolidNormalizeOptions,\n} from './brep/mesh-solid'\n// 槽位互斥不变量(分派前置校验;缺陷即报错)\nexport { assertShapeSlotExclusive } from './cad-runtime/backend-dispatch'\nexport type { BrepEngineApi } from './brep/engine/primitives'\nexport type {\n BrepHandle, BrepMeshResult, BrepBoundingBox, BrepVec3, BrepCapabilities,\n BrepEvolutionData, BrepXcafDocument,\n} from './brep/engine/types'\n\n// ── BREP Topology ──\nexport { buildSolidTopologyRuntime } from './brep/brep-topology'\nexport type { SolidTopologyResult } from './brep/brep-topology'\n\n// ── Font Registry (for browser host injection) ──\nexport { setFontLoader, getFontLoader, loadFont, ensureDefaultFont, ensureFont, getFont, clearFonts } from './brep/text/fontRegistry'\nexport type { FontLoader } from './brep/text/fontRegistry'\n\n// ── L3 Node Host ──\n// node-host 模块已移�?@faicad/faijs/node 入口,避免浏览器环境静�?import\n// node-host 模块(含 Node.js 专用代码�?fs/path)导致生产构�?404�?\n// �?Node.js 环境中:import { createNodePorts } from '@faicad/faijs/node'\n\n// ── L3 Browser Host ──\nexport { createBrowserPorts } from './browser-host'\nexport type { CreateBrowserPortsOptions } from './browser-host'\n// D3-Browser(§9.4):CDN 通用 libLoader 工厂(a/b 混合)。**不**被 createBrowserPorts\n// 默认装配——demo 的源码 alias HMR 路径必须零网络;CDN 装载由主机显式注入。\nexport { createBrowserLibLoader, DEFAULT_CDN_BASE } from './cad-runtime/browser-lib-loader'\nexport type {\n BrowserLibLoader, BrowserLibMeta, CreateBrowserLibLoaderOptions,\n} from './cad-runtime/browser-lib-loader'\nexport { BrowserEventSink } from './browser-host/browser-event-sink'\nexport { BrowserFontProvider } from './browser-host/browser-font-provider'\nexport type { BrowserFontProviderOptions } from './browser-host/browser-font-provider'\nexport { FetchAssetResolver } from './browser-host/fetch-asset-resolver'\nexport type { FetchAssetResolverOptions } from './browser-host/fetch-asset-resolver'\n\n// ── L3 API 面(api/ 层)──\n// P23 主导出切换(§4.2 / Q1):`export * from './api'` 现在同时带来\n// ① faijs 特有 dual op(mesh+brep 双路径,D11 双形态归一);\n// ② 生成脚本面 op(`api/generated/script-face.ts`,defineOp({ brep: __own_* }) 直连的\n// brep-only 语句级 op——`cad.*` 脚本面与此同源,B1 三源一致);\n// ③ 2026-09-25 core-decouple:brepjsCompat 命名空间与 op 投影随旧子包删除\n// (裁决 9);`api/geom-types`(原名 api/brepjs-compat,2026-10-07 改名)仅保留 core 内联的 Result / 向量 / 平面 / 错误 /\n// 常量组合器(§5.2),顶层平铺不变。\nexport * from './api'\nexport { createApiNamespace } from './api/api-namespace'\n// B5 (2026-10-06): unit constants re-exported from the main entry. In the script\n// face they are import-free globals (S4_SAFE_GLOBALS subset); TS consumers now\n// get the same names here instead of hunting for the /units subpath.\nexport {\n MM, CM, M, MICRON, INCH, FOOT, YARD,\n DEGREE, RADIAN,\n SCRIPT_UNIT_NAMES,\n} from './units'\n// Vec3 双源消歧:env-agnostic(lang/types)与 api(mesh/types)均有 Vec3,\n// 显式 re-export 定为 lang 版(与收敛前 index.ts 的具名导出一致)。\nexport type { Vec3 } from './lang/types'\n"]}
@@ -78,6 +78,22 @@ export declare function readModule(bytes: Uint8Array, key: string): string;
78
78
  * member, or content that does not parse as JSON
79
79
  */
80
80
  export declare function readDataMember(bytes: Uint8Array, memberPath: string): string;
81
+ /**
82
+ * Read one producer-defined member (spec §3) by its container path.
83
+ *
84
+ * Members outside the table — `mapping.json`, `freecad/**`, `ui/**`, or any
85
+ * other producer-defined path — are optional and opaque to the reader. Unlike
86
+ * `readDataMember` (which is constrained to `data/` and is JSON by contract),
87
+ * this function returns the raw bytes of any safe relative member path and
88
+ * reports absence with `undefined` rather than an error: a missing optional
89
+ * member is the normal shape of a conforming container (§8), never a defect.
90
+ *
91
+ * @param bytes the .fai.zip archive bytes
92
+ * @param memberPath the safe relative member path to read (e.g. `ui/state.json`)
93
+ * @returns the member bytes, or `undefined` when the member does not exist
94
+ * @throws for an empty/unsafe path (assertSafeMemberPath)
95
+ */
96
+ export declare function readContainerMember(bytes: Uint8Array, memberPath: string): Uint8Array | undefined;
81
97
  /**
82
98
  * Collect the payload bytes of a container.
83
99
  * Keys are unique across `files/**` and `assets/**` together (spec §7.1);
@@ -1 +1 @@
1
- {"version":3,"file":"container-read.d.ts","sourceRoot":"","sources":["../../../src/io/fai-zip/container-read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAML,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAA;AAEpB,6BAA6B;AAC7B,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sEAAsE;IACtE,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB;AAED,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,WAAW,EAAE,cAAc,CAAA;IAC3B,gFAAgF;IAChF,MAAM,EAAE,aAAa,CAAA;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CACnC;AAsJD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,iBAAiB,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,cAAc,EAAE,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,CAEvD;AAaD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAajE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAgB5E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,qBAAqB,CAEzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,oBAAyB,GAAG,mBAAmB,CA+BrG"}
1
+ {"version":3,"file":"container-read.d.ts","sourceRoot":"","sources":["../../../src/io/fai-zip/container-read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAML,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAA;AAEpB,6BAA6B;AAC7B,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sEAAsE;IACtE,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB;AAED,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,WAAW,EAAE,cAAc,CAAA;IAC3B,gFAAgF;IAChF,MAAM,EAAE,aAAa,CAAA;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CACnC;AAsJD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,iBAAiB,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,cAAc,EAAE,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,CAEvD;AAaD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAajE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAgB5E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAMjG;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,qBAAqB,CAEzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,oBAAyB,GAAG,mBAAmB,CA+BrG"}
@@ -252,6 +252,28 @@ export function readDataMember(bytes, memberPath) {
252
252
  }
253
253
  return text;
254
254
  }
255
+ /**
256
+ * Read one producer-defined member (spec §3) by its container path.
257
+ *
258
+ * Members outside the table — `mapping.json`, `freecad/**`, `ui/**`, or any
259
+ * other producer-defined path — are optional and opaque to the reader. Unlike
260
+ * `readDataMember` (which is constrained to `data/` and is JSON by contract),
261
+ * this function returns the raw bytes of any safe relative member path and
262
+ * reports absence with `undefined` rather than an error: a missing optional
263
+ * member is the normal shape of a conforming container (§8), never a defect.
264
+ *
265
+ * @param bytes the .fai.zip archive bytes
266
+ * @param memberPath the safe relative member path to read (e.g. `ui/state.json`)
267
+ * @returns the member bytes, or `undefined` when the member does not exist
268
+ * @throws for an empty/unsafe path (assertSafeMemberPath)
269
+ */
270
+ export function readContainerMember(bytes, memberPath) {
271
+ if (typeof memberPath !== 'string' || memberPath === '') {
272
+ throw new Error('[fai-zip] readContainerMember: memberPath must be a non-empty string');
273
+ }
274
+ assertSafeMemberPath(memberPath, 'readContainerMember path');
275
+ return unzipMembers(bytes).get(memberPath);
276
+ }
255
277
  /**
256
278
  * Collect the payload bytes of a container.
257
279
  * Keys are unique across `files/**` and `assets/**` together (spec §7.1);
@@ -1 +1 @@
1
- {"version":3,"file":"container-read.js","sourceRoot":"","sources":["../../../src/io/fai-zip/container-read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,cAAc,EAAuB,MAAM,QAAQ,CAAA;AAE5D,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,GAIjB,MAAM,aAAa,CAAA;AAuBpB,gDAAgD;AAChD,MAAM,YAAY,GAAG,QAAQ,CAAA;AAC7B,iDAAiD;AACjD,MAAM,YAAY,GAAG,QAAQ,CAAA;AAC7B,mDAAmD;AACnD,MAAM,aAAa,GAAG,SAAS,CAAA;AAE/B;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAiB,EAAE,IAAqB;IAC5D,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IACpC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAA;QAC5F,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,2CAA2C,KAAK,EAAE,CAAC,CACxE;QAAC,GAAmC,CAAC,KAAK,GAAG,CAAC,CAAA;QAC/C,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,SAAS,aAAa,CAAC,MAAc,EAAE,KAAe;IACpD,MAAM,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAA;IAChF,OAAO,IAAI,KAAK,CAAC,+BAA+B,MAAM,GAAG,KAAK,EAAE,CAAC,CAAA;AACnE,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,OAAkB;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IACxC,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAA;IACtH,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IAC7I,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,aAAa,CAAC,qCAAqC,CAAC,CAAA;IAC5D,CAAC;IACD,MAAM,QAAQ,GAAG,MAAiC,CAAA;IAElD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,aAAa,CAAC,+EAA+E,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACvH,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,aAAa,CAAC,oBAAoB,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC3D,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpE,MAAM,aAAa,CAAC,kCAAkC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC1E,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAmB,CAAA;IAC3C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;IACrC,MAAM,UAAU,GAAqB,EAAE,CAAA;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QACnB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5D,MAAM,aAAa,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAA;QAC1D,CAAC;QACD,MAAM,GAAG,GAAG,CAA4B,CAAA;QACxC,MAAM,EAAE,GAAG,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACnD,IAAI,EAAE,KAAK,EAAE;YAAE,MAAM,aAAa,CAAC,UAAU,CAAC,iCAAiC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QACxF,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,MAAM,aAAa,CAAC,UAAU,CAAC,mCAAmC,EAAE,EAAE,CAAC,CAAA;QAClH,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,MAAM,aAAa,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAA;QAC1E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAEf,MAAM,KAAK,GAAG,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5D,IAAI,KAAK,KAAK,EAAE;YAAE,MAAM,aAAa,CAAC,UAAU,CAAC,oCAAoC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;QACjG,qBAAqB,CAAC,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;QAClD,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,MAAM,aAAa,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;QACvF,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACtB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,aAAa,CAAC,UAAU,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAA;QAClF,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;QAChE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;YAC/C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,aAAa,CAAC,UAAU,CAAC,2CAA2C,EAAE,IAAI,CAAC,CAAA;YACnF,CAAC;QACH,CAAC;QAED,UAAU,CAAC,IAAI,CAAC;YACd,EAAE;YACF,KAAK;YACL,GAAG,CAAC,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,MAA0B,CAAA;IAC9B,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACzE,MAAM,aAAa,CAAC,oCAAoC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;QAC5E,CAAC;QACD,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAA;IAC1B,CAAC;IAED,OAAO;QACL,MAAM,EAAE,CAAC;QACT,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,UAAU;QAClB,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,OAAO,QAAQ,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,GAAG,CAAC,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,GAAG,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,GAAG,CAAC,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAqC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvI,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,OAAkB;IAC9C,MAAM,KAAK,GAA+B,EAAE,CAAA;IAC5C,MAAM,MAAM,GAA+B,EAAE,CAAA;IAC7C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;YAC1C,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;gBAC9B,CAAC,CAAC,aAAa;gBACf,CAAC,CAAC,SAAS,CAAA;QACf,IAAI,MAAM,KAAK,SAAS;YAAE,SAAQ;QAClC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACpC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,GAAG,GAAG,CAAC,CAAA;QACtG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAChB,IAAI,MAAM,KAAK,YAAY;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;;YACzC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACzB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAC1B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,KAAiB;IAC5C,OAAO,gBAAgB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,MAAM,CAAA;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,OAAO,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;AAC7C,CAAC;AAED,8EAA8E;AAC9E,SAAS,eAAe,CAAC,OAAkB;IACzC,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;YACnG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;AACpB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,GAAW;IACvD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAA;IACzE,CAAC;IACD,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;IAC3C,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,mFAAmF,GAAG,GAAG,CAAC,CAAA;IAC5G,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,CAAA;IAC1D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,+BAA+B,CAAC,CAAA;IACtF,CAAC;IACD,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAA;AACjC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,KAAiB,EAAE,UAAkB;IAClE,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;IACpF,CAAC;IACD,oBAAoB,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAA;IACvD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAClD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,qCAAqC,UAAU,mCAAmC,CAAC,CAAA;IACrG,CAAC;IACD,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IACrC,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,wBAAwB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IAC7I,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,OAAO,oBAAoB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;AAClD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,KAAiB,EAAE,OAA6B,EAAE;IAC9E,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAE1C,MAAM,WAAW,GAAmB,CAAC,GAAG,EAAE;QACxC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAA;YACtE,OAAO,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACvC,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,CAAA;QAClE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAA;QACxF,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC,CAAC,EAAE,CAAA;IAEJ,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;IAErC,MAAM,MAAM,GAAkB;QAC5B,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;QAC5B,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;YAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC,CAAA;YACpD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,6BAA6B,SAAS,+BAA+B,CAAC,CAAA;YACxF,CAAC;YACD,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAA;QACjC,CAAC;KACF,CAAA;IAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;IACvD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AACzD,CAAC","sourcesContent":["/**\n * Unified `.fai.zip` read API (docs/fai-zip-format.md §4–§9).\n *\n * Environment-independent by constraint: reading goes through `io/zip.ts`\n * (`readZipEntries`) plus JSON parsing — no `node:*`, no DOM, no fs, and no\n * direct ZIP library. Web workers, the weapp worker and node share this code.\n *\n * Contract highlights (spec §9 Reader obligations):\n * - a missing/malformed manifest, `format !== 3`, a malformed `models` array,\n * a missing entry, a missing named data member and a duplicate asset key are\n * all errors carrying the offending value;\n * - entry selection is `active` or `models[0]` — never a file-name heuristic;\n * - members outside the table (§3), unknown manifest fields and unknown\n * data-member keys are ignored, never errors, never decision inputs.\n */\nimport { readZipEntries, type ZipReadOptions } from '../zip'\nimport type { ProjectLoader } from '../../cad-runtime/ports'\nimport {\n assetKeyOf,\n assertDataMemberPath,\n assertModelMemberPath,\n assertSafeMemberPath,\n decodeMemberText,\n type ContainerAssetEntries,\n type ContainerManifest,\n type ContainerModel,\n} from './container'\n\n/** openContainer options. */\nexport interface OpenContainerOptions {\n /** override `manifest.active`; default = `manifest.active`, else `models[0]` */\n modelId?: string\n /** override the `io/zip.ts` read caps (maxEntries / maxTotalBytes) */\n caps?: ZipReadOptions\n}\n\n/** openContainer result: manifest, active model, loader and payloads. */\nexport interface OpenContainerResult {\n manifest: ContainerManifest\n activeModel: ContainerModel\n /** project loader over the container's module graph (listModules/readSource) */\n loader: ProjectLoader\n files: Record<string, Uint8Array>\n assets: Record<string, Uint8Array>\n}\n\n/** Unzipped members, keyed by container path. */\ntype MemberMap = Map<string, Uint8Array>\n\n/** Path prefix of every model script member. */\nconst MODEL_PREFIX = 'model/'\n/** Path prefix of the imported-file payloads. */\nconst FILES_PREFIX = 'files/'\n/** Path prefix of the script-consumed payloads. */\nconst ASSETS_PREFIX = 'assets/'\n\n/**\n * Unpack the archive; a non-ZIP input is a hard error carrying the original\n * failure as `cause`. Caps violations keep `io/zip.ts`'s wording.\n */\nfunction unzipMembers(bytes: Uint8Array, caps?: ZipReadOptions): MemberMap {\n try {\n return readZipEntries(bytes, caps)\n } catch (e) {\n const inner = (e instanceof Error ? e.message : String(e)).replace(/^zip read failed: /, '')\n const err = new Error(`[fai-zip] cannot open container as ZIP: ${inner}`)\n ;(err as Error & { cause?: unknown }).cause = e\n throw err\n }\n}\n\n/** Normalize a manifest field error into one message naming the offending value. */\nfunction manifestError(reason: string, value?: unknown): Error {\n const shown = value === undefined ? '' : ` (observed: ${JSON.stringify(value)})`\n return new Error(`[fai-zip] invalid manifest: ${reason}${shown}`)\n}\n\n/**\n * Read and validate the container manifest from already-unpacked members.\n * @param members the unpacked container members\n * @returns the validated manifest\n */\nfunction readManifestFrom(members: MemberMap): ContainerManifest {\n const raw = members.get('manifest.json')\n if (raw === undefined) throw new Error('[fai-zip] invalid manifest: missing manifest.json — not a .fai.zip container')\n let parsed: unknown\n try {\n parsed = JSON.parse(decodeMemberText(raw))\n } catch (e) {\n throw new Error(`[fai-zip] invalid manifest: manifest.json is not valid JSON: ${e instanceof Error ? e.message : String(e)}`, { cause: e })\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw manifestError('manifest.json must be a JSON object')\n }\n const manifest = parsed as Record<string, unknown>\n\n if (manifest.format !== 3) {\n throw manifestError('format must be the integer 3 (this revision); no other value is interpretable', manifest.format)\n }\n if (manifest.units !== 'mm') {\n throw manifestError('units must be \"mm\"', manifest.units)\n }\n if (!Array.isArray(manifest.models) || manifest.models.length === 0) {\n throw manifestError('models must be a non-empty array', manifest.models)\n }\n\n const models = manifest.models as unknown[]\n const seenIds = new Set<string>()\n const seenEntries = new Set<string>()\n const normalized: ContainerModel[] = []\n for (let i = 0; i < models.length; i++) {\n const m = models[i]\n if (typeof m !== 'object' || m === null || Array.isArray(m)) {\n throw manifestError(`models[${i}] must be an object`, m)\n }\n const rec = m as Record<string, unknown>\n const id = typeof rec.id === 'string' ? rec.id : ''\n if (id === '') throw manifestError(`models[${i}].id must be a non-empty string`, rec.id)\n if (id.includes('/') || id.includes('\\\\')) throw manifestError(`models[${i}].id must not contain \"/\" or \"\\\\\"`, id)\n if (seenIds.has(id)) throw manifestError('models[].id must be unique', id)\n seenIds.add(id)\n\n const entry = typeof rec.entry === 'string' ? rec.entry : ''\n if (entry === '') throw manifestError(`models[${i}].entry must be a non-empty string`, rec.entry)\n assertModelMemberPath(entry, `models[${i}].entry`)\n if (seenEntries.has(entry)) throw manifestError('models[].entry must be unique', entry)\n seenEntries.add(entry)\n if (!members.has(entry)) {\n throw manifestError(`models[${i}].entry does not exist in the container`, entry)\n }\n\n const data = typeof rec.data === 'string' ? rec.data : undefined\n if (data !== undefined) {\n assertSafeMemberPath(data, `models[${i}].data`)\n if (!members.has(data)) {\n throw manifestError(`models[${i}].data names a member that does not exist`, data)\n }\n }\n\n normalized.push({\n id,\n entry,\n ...(typeof rec.label === 'string' ? { label: rec.label } : {}),\n ...(data !== undefined ? { data } : {}),\n })\n }\n\n let active: string | undefined\n if (manifest.active !== undefined) {\n if (typeof manifest.active !== 'string' || !seenIds.has(manifest.active)) {\n throw manifestError('active must equal some models[].id', manifest.active)\n }\n active = manifest.active\n }\n\n return {\n format: 3,\n units: 'mm',\n models: normalized,\n ...(active !== undefined ? { active } : {}),\n ...(typeof manifest.createdAt === 'string' ? { createdAt: manifest.createdAt } : {}),\n ...(typeof manifest.appVersion === 'string' ? { appVersion: manifest.appVersion } : {}),\n ...(typeof manifest.label === 'string' ? { label: manifest.label } : {}),\n ...(typeof manifest.source === 'object' && manifest.source !== null ? { source: manifest.source as ContainerManifest['source'] } : {}),\n }\n}\n\n/**\n * Collect the payload bytes of already-unpacked members.\n * Keys are unique across `files/**` and `assets/**` together (spec §7.1);\n * a duplicate key is an error rather than a pick.\n * @param members the unpacked container members\n * @returns the payload entries keyed by asset key\n */\nfunction readAssetEntriesFrom(members: MemberMap): ContainerAssetEntries {\n const files: Record<string, Uint8Array> = {}\n const assets: Record<string, Uint8Array> = {}\n const claimed = new Set<string>()\n for (const [path, body] of members) {\n const prefix = path.startsWith(FILES_PREFIX)\n ? FILES_PREFIX\n : path.startsWith(ASSETS_PREFIX)\n ? ASSETS_PREFIX\n : undefined\n if (prefix === undefined) continue\n const key = assetKeyOf(path, prefix)\n if (claimed.has(key)) throw new Error(`[fai-zip] duplicate asset key across files//assets/: \"${key}\"`)\n claimed.add(key)\n if (prefix === FILES_PREFIX) files[key] = body\n else assets[key] = body\n }\n return { files, assets }\n}\n\n/**\n * Read and validate the container manifest (spec §4).\n * @param bytes the .fai.zip archive bytes\n * @returns the validated manifest\n * @throws when the archive is not a ZIP, the manifest is missing/malformed,\n * `format !== 3`, `units !== \"mm\"`, `models` is empty/malformed, ids/entries\n * are duplicated, an entry is not under `model/` or does not exist, `active`\n * is not in `models[].id`, or a named `data` member does not exist.\n */\nexport function readManifest(bytes: Uint8Array): ContainerManifest {\n return readManifestFrom(unzipMembers(bytes))\n}\n\n/**\n * List the container models (validated). Same validation as readManifest.\n * @param bytes the .fai.zip archive bytes\n * @returns the validated model list\n */\nexport function listModels(bytes: Uint8Array): ContainerModel[] {\n return readManifest(bytes).models\n}\n\n/**\n * List every module under `model/` (keys relative to `model/`, sorted).\n * Members outside the table are ignored (§3), never an error.\n * @param bytes the .fai.zip archive bytes\n * @returns module keys relative to `model/`, sorted\n */\nexport function listModules(bytes: Uint8Array): string[] {\n return listModulesFrom(unzipMembers(bytes))\n}\n\n/** Module keys (relative to `model/`, sorted) of already-unpacked members. */\nfunction listModulesFrom(members: MemberMap): string[] {\n const keys: string[] = []\n for (const path of members.keys()) {\n if (path.startsWith(MODEL_PREFIX) && path.endsWith('.fai.js') && path.length > MODEL_PREFIX.length) {\n keys.push(path.slice(MODEL_PREFIX.length))\n }\n }\n return keys.sort()\n}\n\n/**\n * Read one module's source text by module key (relative to `model/`).\n * @param bytes the .fai.zip archive bytes\n * @param key the module key relative to `model/` (e.g. `main.fai.js`)\n * @returns the module source text\n * @throws for a key outside `model/` or that does not exist\n */\nexport function readModule(bytes: Uint8Array, key: string): string {\n if (typeof key !== 'string' || key === '') {\n throw new Error('[fai-zip] readModule: key must be a non-empty string')\n }\n assertSafeMemberPath(key, 'readModule key')\n if (!key.endsWith('.fai.js')) {\n throw new Error(`[fai-zip] readModule: key must name a module under model/ (ends with .fai.js): \"${key}\"`)\n }\n const member = unzipMembers(bytes).get(MODEL_PREFIX + key)\n if (member === undefined) {\n throw new Error(`[fai-zip] readModule: module \"${key}\" does not exist under model/`)\n }\n return decodeMemberText(member)\n}\n\n/**\n * Read one model data member's JSON text by member path (e.g. `data/main.json`).\n *\n * The path must be exactly what `models[].data` declares (spec §4): a safe,\n * relative member under `data/` ending with `.json`. Content is validated to\n * parse as JSON — the editor keeps data members pure JSON (§6.1), so a\n * non-JSON member is a format violation and an error, never a silent skip.\n *\n * @param bytes the .fai.zip archive bytes\n * @param memberPath the member path named by `models[].data`\n * @returns the raw JSON text\n * @throws for a non-string/unsafe path, a path outside `data/`, a missing\n * member, or content that does not parse as JSON\n */\nexport function readDataMember(bytes: Uint8Array, memberPath: string): string {\n if (typeof memberPath !== 'string' || memberPath === '') {\n throw new Error('[fai-zip] readDataMember: memberPath must be a non-empty string')\n }\n assertDataMemberPath(memberPath, 'readDataMember path')\n const member = unzipMembers(bytes).get(memberPath)\n if (member === undefined) {\n throw new Error(`[fai-zip] readDataMember: member \"${memberPath}\" does not exist in the container`)\n }\n const text = decodeMemberText(member)\n try {\n JSON.parse(text)\n } catch (e) {\n throw new Error(`[fai-zip] readDataMember: \"${memberPath}\" is not valid JSON: ${e instanceof Error ? e.message : String(e)}`, { cause: e })\n }\n return text\n}\n\n/**\n * Collect the payload bytes of a container.\n * Keys are unique across `files/**` and `assets/**` together (spec §7.1);\n * a duplicate key is an error rather than a pick.\n * @param bytes the .fai.zip archive bytes\n * @returns the payload entries keyed by asset key\n */\nexport function readAssetEntries(bytes: Uint8Array): ContainerAssetEntries {\n return readAssetEntriesFrom(unzipMembers(bytes))\n}\n\n/**\n * Host entry point: open a container and return the manifest, the active\n * model and a ProjectLoader over its module graph, plus the payloads.\n *\n * The archive is unpacked exactly once for the whole call.\n *\n * @param bytes the .fai.zip archive bytes\n * @param opts optional active-model override and `io/zip.ts` read caps\n * @returns manifest, active model, project loader and payload entries\n * @throws when the container is invalid, the requested model id is unknown, or\n * the read caps are exceeded\n */\nexport function openContainer(bytes: Uint8Array, opts: OpenContainerOptions = {}): OpenContainerResult {\n const members = unzipMembers(bytes, opts.caps)\n const manifest = readManifestFrom(members)\n\n const activeModel: ContainerModel = (() => {\n if (opts.modelId === undefined) {\n const byActive = manifest.models.find((m) => m.id === manifest.active)\n return byActive ?? manifest.models[0]\n }\n const byParam = manifest.models.find((m) => m.id === opts.modelId)\n if (byParam === undefined) {\n throw new Error(`[fai-zip] openContainer: model \"${opts.modelId}\" is not in models[]`)\n }\n return byParam\n })()\n\n const keys = listModulesFrom(members)\n\n const loader: ProjectLoader = {\n listModules: () => [...keys],\n readSource: async (moduleKey) => {\n const member = members.get(MODEL_PREFIX + moduleKey)\n if (member === undefined) {\n throw new Error(`[fai-zip] loader: module \"${moduleKey}\" does not exist under model/`)\n }\n return decodeMemberText(member)\n },\n }\n\n const { files, assets } = readAssetEntriesFrom(members)\n return { manifest, activeModel, loader, files, assets }\n}\n"]}
1
+ {"version":3,"file":"container-read.js","sourceRoot":"","sources":["../../../src/io/fai-zip/container-read.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unified `.fai.zip` read API (docs/fai-zip-format.md §4–§9).\n *\n * Environment-independent by constraint: reading goes through `io/zip.ts`\n * (`readZipEntries`) plus JSON parsing — no `node:*`, no DOM, no fs, and no\n * direct ZIP library. Web workers, the weapp worker and node share this code.\n *\n * Contract highlights (spec §9 Reader obligations):\n * - a missing/malformed manifest, `format !== 3`, a malformed `models` array,\n * a missing entry, a missing named data member and a duplicate asset key are\n * all errors carrying the offending value;\n * - entry selection is `active` or `models[0]` — never a file-name heuristic;\n * - members outside the table (§3), unknown manifest fields and unknown\n * data-member keys are ignored, never errors, never decision inputs.\n */\nimport { readZipEntries, type ZipReadOptions } from '../zip'\nimport type { ProjectLoader } from '../../cad-runtime/ports'\nimport {\n assetKeyOf,\n assertDataMemberPath,\n assertModelMemberPath,\n assertSafeMemberPath,\n decodeMemberText,\n type ContainerAssetEntries,\n type ContainerManifest,\n type ContainerModel,\n} from './container'\n\n/** openContainer options. */\nexport interface OpenContainerOptions {\n /** override `manifest.active`; default = `manifest.active`, else `models[0]` */\n modelId?: string\n /** override the `io/zip.ts` read caps (maxEntries / maxTotalBytes) */\n caps?: ZipReadOptions\n}\n\n/** openContainer result: manifest, active model, loader and payloads. */\nexport interface OpenContainerResult {\n manifest: ContainerManifest\n activeModel: ContainerModel\n /** project loader over the container's module graph (listModules/readSource) */\n loader: ProjectLoader\n files: Record<string, Uint8Array>\n assets: Record<string, Uint8Array>\n}\n\n/** Unzipped members, keyed by container path. */\ntype MemberMap = Map<string, Uint8Array>\n\n/** Path prefix of every model script member. */\nconst MODEL_PREFIX = 'model/'\n/** Path prefix of the imported-file payloads. */\nconst FILES_PREFIX = 'files/'\n/** Path prefix of the script-consumed payloads. */\nconst ASSETS_PREFIX = 'assets/'\n\n/**\n * Unpack the archive; a non-ZIP input is a hard error carrying the original\n * failure as `cause`. Caps violations keep `io/zip.ts`'s wording.\n */\nfunction unzipMembers(bytes: Uint8Array, caps?: ZipReadOptions): MemberMap {\n try {\n return readZipEntries(bytes, caps)\n } catch (e) {\n const inner = (e instanceof Error ? e.message : String(e)).replace(/^zip read failed: /, '')\n const err = new Error(`[fai-zip] cannot open container as ZIP: ${inner}`)\n ;(err as Error & { cause?: unknown }).cause = e\n throw err\n }\n}\n\n/** Normalize a manifest field error into one message naming the offending value. */\nfunction manifestError(reason: string, value?: unknown): Error {\n const shown = value === undefined ? '' : ` (observed: ${JSON.stringify(value)})`\n return new Error(`[fai-zip] invalid manifest: ${reason}${shown}`)\n}\n\n/**\n * Read and validate the container manifest from already-unpacked members.\n * @param members the unpacked container members\n * @returns the validated manifest\n */\nfunction readManifestFrom(members: MemberMap): ContainerManifest {\n const raw = members.get('manifest.json')\n if (raw === undefined) throw new Error('[fai-zip] invalid manifest: missing manifest.json — not a .fai.zip container')\n let parsed: unknown\n try {\n parsed = JSON.parse(decodeMemberText(raw))\n } catch (e) {\n throw new Error(`[fai-zip] invalid manifest: manifest.json is not valid JSON: ${e instanceof Error ? e.message : String(e)}`, { cause: e })\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw manifestError('manifest.json must be a JSON object')\n }\n const manifest = parsed as Record<string, unknown>\n\n if (manifest.format !== 3) {\n throw manifestError('format must be the integer 3 (this revision); no other value is interpretable', manifest.format)\n }\n if (manifest.units !== 'mm') {\n throw manifestError('units must be \"mm\"', manifest.units)\n }\n if (!Array.isArray(manifest.models) || manifest.models.length === 0) {\n throw manifestError('models must be a non-empty array', manifest.models)\n }\n\n const models = manifest.models as unknown[]\n const seenIds = new Set<string>()\n const seenEntries = new Set<string>()\n const normalized: ContainerModel[] = []\n for (let i = 0; i < models.length; i++) {\n const m = models[i]\n if (typeof m !== 'object' || m === null || Array.isArray(m)) {\n throw manifestError(`models[${i}] must be an object`, m)\n }\n const rec = m as Record<string, unknown>\n const id = typeof rec.id === 'string' ? rec.id : ''\n if (id === '') throw manifestError(`models[${i}].id must be a non-empty string`, rec.id)\n if (id.includes('/') || id.includes('\\\\')) throw manifestError(`models[${i}].id must not contain \"/\" or \"\\\\\"`, id)\n if (seenIds.has(id)) throw manifestError('models[].id must be unique', id)\n seenIds.add(id)\n\n const entry = typeof rec.entry === 'string' ? rec.entry : ''\n if (entry === '') throw manifestError(`models[${i}].entry must be a non-empty string`, rec.entry)\n assertModelMemberPath(entry, `models[${i}].entry`)\n if (seenEntries.has(entry)) throw manifestError('models[].entry must be unique', entry)\n seenEntries.add(entry)\n if (!members.has(entry)) {\n throw manifestError(`models[${i}].entry does not exist in the container`, entry)\n }\n\n const data = typeof rec.data === 'string' ? rec.data : undefined\n if (data !== undefined) {\n assertSafeMemberPath(data, `models[${i}].data`)\n if (!members.has(data)) {\n throw manifestError(`models[${i}].data names a member that does not exist`, data)\n }\n }\n\n normalized.push({\n id,\n entry,\n ...(typeof rec.label === 'string' ? { label: rec.label } : {}),\n ...(data !== undefined ? { data } : {}),\n })\n }\n\n let active: string | undefined\n if (manifest.active !== undefined) {\n if (typeof manifest.active !== 'string' || !seenIds.has(manifest.active)) {\n throw manifestError('active must equal some models[].id', manifest.active)\n }\n active = manifest.active\n }\n\n return {\n format: 3,\n units: 'mm',\n models: normalized,\n ...(active !== undefined ? { active } : {}),\n ...(typeof manifest.createdAt === 'string' ? { createdAt: manifest.createdAt } : {}),\n ...(typeof manifest.appVersion === 'string' ? { appVersion: manifest.appVersion } : {}),\n ...(typeof manifest.label === 'string' ? { label: manifest.label } : {}),\n ...(typeof manifest.source === 'object' && manifest.source !== null ? { source: manifest.source as ContainerManifest['source'] } : {}),\n }\n}\n\n/**\n * Collect the payload bytes of already-unpacked members.\n * Keys are unique across `files/**` and `assets/**` together (spec §7.1);\n * a duplicate key is an error rather than a pick.\n * @param members the unpacked container members\n * @returns the payload entries keyed by asset key\n */\nfunction readAssetEntriesFrom(members: MemberMap): ContainerAssetEntries {\n const files: Record<string, Uint8Array> = {}\n const assets: Record<string, Uint8Array> = {}\n const claimed = new Set<string>()\n for (const [path, body] of members) {\n const prefix = path.startsWith(FILES_PREFIX)\n ? FILES_PREFIX\n : path.startsWith(ASSETS_PREFIX)\n ? ASSETS_PREFIX\n : undefined\n if (prefix === undefined) continue\n const key = assetKeyOf(path, prefix)\n if (claimed.has(key)) throw new Error(`[fai-zip] duplicate asset key across files//assets/: \"${key}\"`)\n claimed.add(key)\n if (prefix === FILES_PREFIX) files[key] = body\n else assets[key] = body\n }\n return { files, assets }\n}\n\n/**\n * Read and validate the container manifest (spec §4).\n * @param bytes the .fai.zip archive bytes\n * @returns the validated manifest\n * @throws when the archive is not a ZIP, the manifest is missing/malformed,\n * `format !== 3`, `units !== \"mm\"`, `models` is empty/malformed, ids/entries\n * are duplicated, an entry is not under `model/` or does not exist, `active`\n * is not in `models[].id`, or a named `data` member does not exist.\n */\nexport function readManifest(bytes: Uint8Array): ContainerManifest {\n return readManifestFrom(unzipMembers(bytes))\n}\n\n/**\n * List the container models (validated). Same validation as readManifest.\n * @param bytes the .fai.zip archive bytes\n * @returns the validated model list\n */\nexport function listModels(bytes: Uint8Array): ContainerModel[] {\n return readManifest(bytes).models\n}\n\n/**\n * List every module under `model/` (keys relative to `model/`, sorted).\n * Members outside the table are ignored (§3), never an error.\n * @param bytes the .fai.zip archive bytes\n * @returns module keys relative to `model/`, sorted\n */\nexport function listModules(bytes: Uint8Array): string[] {\n return listModulesFrom(unzipMembers(bytes))\n}\n\n/** Module keys (relative to `model/`, sorted) of already-unpacked members. */\nfunction listModulesFrom(members: MemberMap): string[] {\n const keys: string[] = []\n for (const path of members.keys()) {\n if (path.startsWith(MODEL_PREFIX) && path.endsWith('.fai.js') && path.length > MODEL_PREFIX.length) {\n keys.push(path.slice(MODEL_PREFIX.length))\n }\n }\n return keys.sort()\n}\n\n/**\n * Read one module's source text by module key (relative to `model/`).\n * @param bytes the .fai.zip archive bytes\n * @param key the module key relative to `model/` (e.g. `main.fai.js`)\n * @returns the module source text\n * @throws for a key outside `model/` or that does not exist\n */\nexport function readModule(bytes: Uint8Array, key: string): string {\n if (typeof key !== 'string' || key === '') {\n throw new Error('[fai-zip] readModule: key must be a non-empty string')\n }\n assertSafeMemberPath(key, 'readModule key')\n if (!key.endsWith('.fai.js')) {\n throw new Error(`[fai-zip] readModule: key must name a module under model/ (ends with .fai.js): \"${key}\"`)\n }\n const member = unzipMembers(bytes).get(MODEL_PREFIX + key)\n if (member === undefined) {\n throw new Error(`[fai-zip] readModule: module \"${key}\" does not exist under model/`)\n }\n return decodeMemberText(member)\n}\n\n/**\n * Read one model data member's JSON text by member path (e.g. `data/main.json`).\n *\n * The path must be exactly what `models[].data` declares (spec §4): a safe,\n * relative member under `data/` ending with `.json`. Content is validated to\n * parse as JSON — the editor keeps data members pure JSON (§6.1), so a\n * non-JSON member is a format violation and an error, never a silent skip.\n *\n * @param bytes the .fai.zip archive bytes\n * @param memberPath the member path named by `models[].data`\n * @returns the raw JSON text\n * @throws for a non-string/unsafe path, a path outside `data/`, a missing\n * member, or content that does not parse as JSON\n */\nexport function readDataMember(bytes: Uint8Array, memberPath: string): string {\n if (typeof memberPath !== 'string' || memberPath === '') {\n throw new Error('[fai-zip] readDataMember: memberPath must be a non-empty string')\n }\n assertDataMemberPath(memberPath, 'readDataMember path')\n const member = unzipMembers(bytes).get(memberPath)\n if (member === undefined) {\n throw new Error(`[fai-zip] readDataMember: member \"${memberPath}\" does not exist in the container`)\n }\n const text = decodeMemberText(member)\n try {\n JSON.parse(text)\n } catch (e) {\n throw new Error(`[fai-zip] readDataMember: \"${memberPath}\" is not valid JSON: ${e instanceof Error ? e.message : String(e)}`, { cause: e })\n }\n return text\n}\n\n/**\n * Read one producer-defined member (spec §3) by its container path.\n *\n * Members outside the table — `mapping.json`, `freecad/**`, `ui/**`, or any\n * other producer-defined path — are optional and opaque to the reader. Unlike\n * `readDataMember` (which is constrained to `data/` and is JSON by contract),\n * this function returns the raw bytes of any safe relative member path and\n * reports absence with `undefined` rather than an error: a missing optional\n * member is the normal shape of a conforming container (§8), never a defect.\n *\n * @param bytes the .fai.zip archive bytes\n * @param memberPath the safe relative member path to read (e.g. `ui/state.json`)\n * @returns the member bytes, or `undefined` when the member does not exist\n * @throws for an empty/unsafe path (assertSafeMemberPath)\n */\nexport function readContainerMember(bytes: Uint8Array, memberPath: string): Uint8Array | undefined {\n if (typeof memberPath !== 'string' || memberPath === '') {\n throw new Error('[fai-zip] readContainerMember: memberPath must be a non-empty string')\n }\n assertSafeMemberPath(memberPath, 'readContainerMember path')\n return unzipMembers(bytes).get(memberPath)\n}\n\n/**\n * Collect the payload bytes of a container.\n * Keys are unique across `files/**` and `assets/**` together (spec §7.1);\n * a duplicate key is an error rather than a pick.\n * @param bytes the .fai.zip archive bytes\n * @returns the payload entries keyed by asset key\n */\nexport function readAssetEntries(bytes: Uint8Array): ContainerAssetEntries {\n return readAssetEntriesFrom(unzipMembers(bytes))\n}\n\n/**\n * Host entry point: open a container and return the manifest, the active\n * model and a ProjectLoader over its module graph, plus the payloads.\n *\n * The archive is unpacked exactly once for the whole call.\n *\n * @param bytes the .fai.zip archive bytes\n * @param opts optional active-model override and `io/zip.ts` read caps\n * @returns manifest, active model, project loader and payload entries\n * @throws when the container is invalid, the requested model id is unknown, or\n * the read caps are exceeded\n */\nexport function openContainer(bytes: Uint8Array, opts: OpenContainerOptions = {}): OpenContainerResult {\n const members = unzipMembers(bytes, opts.caps)\n const manifest = readManifestFrom(members)\n\n const activeModel: ContainerModel = (() => {\n if (opts.modelId === undefined) {\n const byActive = manifest.models.find((m) => m.id === manifest.active)\n return byActive ?? manifest.models[0]\n }\n const byParam = manifest.models.find((m) => m.id === opts.modelId)\n if (byParam === undefined) {\n throw new Error(`[fai-zip] openContainer: model \"${opts.modelId}\" is not in models[]`)\n }\n return byParam\n })()\n\n const keys = listModulesFrom(members)\n\n const loader: ProjectLoader = {\n listModules: () => [...keys],\n readSource: async (moduleKey) => {\n const member = members.get(MODEL_PREFIX + moduleKey)\n if (member === undefined) {\n throw new Error(`[fai-zip] loader: module \"${moduleKey}\" does not exist under model/`)\n }\n return decodeMemberText(member)\n },\n }\n\n const { files, assets } = readAssetEntriesFrom(members)\n return { manifest, activeModel, loader, files, assets }\n}\n"]}
@@ -13,6 +13,6 @@
13
13
  */
14
14
  export type { ContainerAssetEntries, ContainerManifest, ContainerModel } from './container.js';
15
15
  export { decodeMemberText, encodeMemberText } from './container.js';
16
- export { listModels, listModules, openContainer, readAssetEntries, readDataMember, readManifest, readModule, type OpenContainerOptions, type OpenContainerResult, } from './container-read.js';
16
+ export { listModels, listModules, openContainer, readAssetEntries, readContainerMember, readDataMember, readManifest, readModule, type OpenContainerOptions, type OpenContainerResult, } from './container-read.js';
17
17
  export { createManifest, writeContainer, type ContainerAssembly, type WriteContainerResult, } from './container-write.js';
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/io/fai-zip/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC3F,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/io/fai-zip/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,YAAY,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC3F,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAA"}
@@ -1,4 +1,4 @@
1
1
  export { decodeMemberText, encodeMemberText } from './container.js';
2
- export { listModels, listModules, openContainer, readAssetEntries, readDataMember, readManifest, readModule, } from './container-read.js';
2
+ export { listModels, listModules, openContainer, readAssetEntries, readContainerMember, readDataMember, readManifest, readModule, } from './container-read.js';
3
3
  export { createManifest, writeContainer, } from './container-write.js';
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/io/fai-zip/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,UAAU,GAGX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,cAAc,EACd,cAAc,GAGf,MAAM,mBAAmB,CAAA","sourcesContent":["/**\n * `@faicad/faijs/io/fai-zip` — the `.fai.zip` container layer.\n *\n * `.fai.zip` is faijs' own container format (docs/fai-zip-format.md). Reading,\n * writing and the manifest schema live here, in core, because every host that\n * loads or saves a faijs project needs them and none of them needs a\n * producer-specific converter to get at them.\n *\n * The layer is a peer of `@faicad/faijs/io`, not a child of it: `io` owns ZIP\n * bytes, this owns the container format built on top. `io/index.ts` therefore\n * does not re-export anything from here — a base layer never depends on a\n * format layer.\n */\nexport type { ContainerAssetEntries, ContainerManifest, ContainerModel } from './container'\nexport { decodeMemberText, encodeMemberText } from './container'\nexport {\n listModels,\n listModules,\n openContainer,\n readAssetEntries,\n readDataMember,\n readManifest,\n readModule,\n type OpenContainerOptions,\n type OpenContainerResult,\n} from './container-read'\nexport {\n createManifest,\n writeContainer,\n type ContainerAssembly,\n type WriteContainerResult,\n} from './container-write'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/io/fai-zip/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,UAAU,GAGX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,cAAc,EACd,cAAc,GAGf,MAAM,mBAAmB,CAAA","sourcesContent":["/**\n * `@faicad/faijs/io/fai-zip` — the `.fai.zip` container layer.\n *\n * `.fai.zip` is faijs' own container format (docs/fai-zip-format.md). Reading,\n * writing and the manifest schema live here, in core, because every host that\n * loads or saves a faijs project needs them and none of them needs a\n * producer-specific converter to get at them.\n *\n * The layer is a peer of `@faicad/faijs/io`, not a child of it: `io` owns ZIP\n * bytes, this owns the container format built on top. `io/index.ts` therefore\n * does not re-export anything from here — a base layer never depends on a\n * format layer.\n */\nexport type { ContainerAssetEntries, ContainerManifest, ContainerModel } from './container'\nexport { decodeMemberText, encodeMemberText } from './container'\nexport {\n listModels,\n listModules,\n openContainer,\n readAssetEntries,\n readContainerMember,\n readDataMember,\n readManifest,\n readModule,\n type OpenContainerOptions,\n type OpenContainerResult,\n} from './container-read'\nexport {\n createManifest,\n writeContainer,\n type ContainerAssembly,\n type WriteContainerResult,\n} from './container-write'\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"code-to-args.d.ts","sourceRoot":"","sources":["../../src/lang/code-to-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAGrE,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAsDjD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,OAAO,EAAE,CAAA;IACrB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,QAAQ,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CA+BvF;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAAG,IAAI,CAWxG"}
1
+ {"version":3,"file":"code-to-args.d.ts","sourceRoot":"","sources":["../../src/lang/code-to-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAIrE,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAiEjD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,OAAO,EAAE,CAAA;IACrB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,QAAQ,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CA+BvF;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAAG,IAAI,CAWxG"}
@@ -20,6 +20,7 @@
20
20
  */
21
21
  import { extractMetadata } from './metadata-extractor.js';
22
22
  import { isHostRef } from './host-arg.js';
23
+ import { isSafeGlobalIdent } from './security-scanner.js';
23
24
  import { SCRIPT_UNIT_NAMES, UNIT_SCALE, UNIT_DIM, SCRIPT_UNIT_TO_NAME } from '../units.js';
24
25
  /**
25
26
  * 单行提取的前置声明规则(确定性静态规则,非 try/catch 兜底):
@@ -46,8 +47,16 @@ function extractIdentifiers(line, namespaces) {
46
47
  // P7/D10.4: unit constants (MM, INCH, DEGREE, …) must NOT be pre-declared
47
48
  // as sentinel parameters (`let INCH = 0`), because that would shadow the
48
49
  // real global value and cause `10 * INCH` to fold to 0.
49
- if (NON_DECL.has(id) || declared.has(id) || namespaces?.has(id) || SCRIPT_UNIT_NAMES.has(id))
50
+ // 2026-10-06:其余免 import 安全全局(Math / JSON / Number / console / …)同理。
51
+ // 它们不是脚本参数,前置 `let Math = 0` 会让提取结果带上幻影参数引用
52
+ // (`cad.box(Math.PI, …)` → expr-ref params:['Math']),宿主会据此误判依赖。
53
+ if (NON_DECL.has(id) ||
54
+ declared.has(id) ||
55
+ namespaces?.has(id) ||
56
+ SCRIPT_UNIT_NAMES.has(id) ||
57
+ isSafeGlobalIdent(id)) {
50
58
  continue;
59
+ }
51
60
  ids.add(id);
52
61
  }
53
62
  return [...ids];
@@ -1 +1 @@
1
- {"version":3,"file":"code-to-args.js","sourceRoot":"","sources":["../../src/lang/code-to-args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * code-to-args — 单语句行 args 提取(编辑回填配套)\n *\n * See docs/language-design.md §3 (statement model ↔ StatementSummary mapping) and §6.4 (check).\n *\n * 宿主编辑回填(FeatureEditor.backfill / editStatement)需要从代码行\n * 反提参数对象。此能力由 faijs 标配提供(与 parse 语义一致),\n * 宿主不得用 acorn 自行解析(B3 修正)。\n *\n * 无 IR 双通道方案(2026-09-06)后实现换 MetadataExtractor 行级提取:\n * 单行文本经哨兵参数前置声明(与 MetadataExtractor looseLocalCalls 同构)\n * 交给 extractMetadata,取末条 op 行摘要的 positional/args。函数名、签名与\n * 返回契约(CodeToArgsResult)不变;HostArg 引用形态保真(A-5)。\n *\n * F1(表达式折叠):args 含计算表达式(binary/template/conditional/spread)时,\n * 与 parser 折叠语义一致地**求值后返回字面值**,不抛错。\n * 单行提取缺失参数真实值 → 前置声明用哨兵字面量 `let <id> = 0`(参数形态),\n * 使表达式可静态折叠;宿主用 StatementSummary.hasComputedArgs 判定只读降级,\n * 不得把折叠值写回源码(会丢失原表达式)。\n */\n\nimport type { HostArg } from './host-arg'\nimport { extractMetadata, type OpDimMap } from './metadata-extractor'\nimport { isHostRef } from './host-arg'\nimport { SCRIPT_UNIT_NAMES, UNIT_SCALE, UNIT_DIM, SCRIPT_UNIT_TO_NAME } from '../units'\nimport type { DimName, UnitName } from '../units'\n\n/**\n * 单行提取的前置声明规则(确定性静态规则,非 try/catch 兜底):\n * parser 的作用域检查(inputs / 重赋值 LHS / 成员方法 receiver / args 中的\n * 裸标识符参数引用)要求变量已声明,而单行提取天然缺失声明上下文。\n * 规则:提取行内全部标识符(剥掉字符串字面量后),为每个非 `cad`/关键字\n * 标识符前置一行 `let <id> = 0`(哨兵参数)。parser 对该形态只做语法\n * 检查、不查符号表;多余声明对 varToId 仅是\"可查到\",不影响目标行的\n * args 解析结果。F1 起用哨兵参数(而非 `cad.assembly({})` 语句)——\n * 参数值已知 → 表达式可静态折叠,满足\"参数为表达式时返回折叠字面值\"。\n */\nconst IDENT_RE = /[A-Za-z_$][\\w$]*/g\nconst STRING_RE = /'(?:[^'\\\\]|\\\\.)*'|\"(?:[^\"\\\\]|\\\\.)*\"/g\nconst NON_DECL = new Set([\n 'cad', 'const', 'let', 'true', 'false', 'null', 'undefined',\n 'await', 'return', 'new', 'typeof', 'var', 'function',\n])\n\nfunction extractIdentifiers(line: string, namespaces?: Set<string>): string[] {\n const withoutStrings = line.replace(STRING_RE, \"''\")\n const declared = declaredByLine(withoutStrings)\n const ids = new Set<string>()\n for (const m of withoutStrings.matchAll(IDENT_RE)) {\n const id = m[0]\n // P7/D10.4: unit constants (MM, INCH, DEGREE, …) must NOT be pre-declared\n // as sentinel parameters (`let INCH = 0`), because that would shadow the\n // real global value and cause `10 * INCH` to fold to 0.\n if (NON_DECL.has(id) || declared.has(id) || namespaces?.has(id) || SCRIPT_UNIT_NAMES.has(id)) continue\n ids.add(id)\n }\n return [...ids]\n}\n\n/**\n * 行内自身声明的标识符(前置声明必须跳过,否则 acorn 重声明报错):\n * - `const/let x = ...` 的 x\n * - `const { k1: v1, k2 } = ...` 的绑定名 v1/k2(键名 k1 不是声明,仍需前置声明——无害)\n */\nfunction declaredByLine(line: string): Set<string> {\n const ids = new Set<string>()\n let m = /^\\s*(?:const|let)\\s+([A-Za-z_$][\\w$]*)\\s*=/.exec(line)\n if (m) ids.add(m[1])\n m = /^\\s*const\\s*\\{([^}]*)\\}\\s*=/.exec(line)\n if (m) {\n for (const prop of m[1].split(',')) {\n const bound = (prop.split(':')[1] ?? prop).trim()\n const id = /^([A-Za-z_$][\\w$]*)/.exec(bound)\n if (id) ids.add(id[1])\n }\n }\n return ids\n}\n\n/**\n * `codeToArgs` 的返回契约:位置实参槽 + 尾随选项对象(HostArg 形态,纯数据无 IR)。\n */\nexport interface CodeToArgsResult {\n positional: HostArg[]\n args: Record<string, HostArg>\n}\n\n/**\n * codeToArgs 选项。`opDims` 为 P4/P6 (unit-system D8) 透传:callee → 量纲声明,\n * 供单行回填路径的 dimension pass 消费(P6 落地前声明面透传即可,不影响解析结果)。\n */\nexport interface CodeToArgsOptions {\n /** 该脚本顶层 import 的绑定名(F2)。 */\n namespaces?: string[]\n /** callee → 量纲声明(unit-system D8,P6 消费)。 */\n opDims?: OpDimMap\n}\n\n/**\n * 解析单条语句行,提取其位置实参槽与选项对象(序列化形态,无 IR 变体语义)。\n *\n * true-JS-subset §4.6.3 新契约:返回 `{ positional, args }`——\n * - `positional`: HostArg[],按调用顺序的位置实参(字面量原样;var-ref/\n * param-ref/call-ref/expr-ref 以 `{kind,...}` 标记对象呈现,宿主据此降级为\n * 只读编辑);宿主不接触内部类型(纯数据面)。\n * - `args`: 尾随选项对象(键值 HostArg 形态;无选项对象时为 `{}`)。\n * 旧契约(只返回对象槽)在位置形态下会静默丢弃非对象实参——本契约显式保留全部信息。\n *\n * 支持的行形态(与 parser 接受的语句一致):\n * - `const part0 = cad.box(10, 20, 30)`\n * - `part0 = cad.fai_drill(part0, { diameter: 5 })`(裸重赋值)\n * - `const { front: a, back: b } = cad.fai_split(part0, { normal: [0,0,1] })`(解构)\n * - `asm0.add_constraint({ ... })`(成员方法调用)\n * - 位置实参为字面量/变量引用/表达式(`cad.box(10, 20, 30)`、`cad.hem(p0.solid, {...})`)\n * - args 中的裸标识符参数引用(`cad.box(10, 20, height)`)\n * - args 中的计算表达式(`cad.box(10, 20, base + 20)`)→ 折叠为字面值返回\n *\n * @param codeLine 单条语句源码行\n * @param opts.namespaces 该脚本顶层 import 的绑定名(F2:`mech.makeHeadstock(...)`\n * 中 `mech` 不得被前置声明为变量)。L0 不感知注册表,由宿主从脚本 imports 提供。\n * @returns the extracted positional slot and trailing options object (both in\n * serialized JSON form).\n * @throws ParseError — 行文本不是合法语句时抛出(含行号)\n */\nexport function codeToArgs(codeLine: string, opts?: CodeToArgsOptions): CodeToArgsResult {\n const namespaces = new Set(opts?.namespaces ?? [])\n const decls = extractIdentifiers(codeLine, namespaces)\n .map((id) => `let ${id} = 0`)\n .join('\\n')\n const code = decls ? `${decls}\\n${codeLine}` : codeLine\n // 单行提取语义:前置哨兵参数(let id = 0)在 extractMetadata 中按参数行处理;\n // 末条 op 行摘要 = 目标行。裸本机函数 callee(makeArray 等)放行(looseLocalCalls,\n // 与现状 codeToArgs 的 MetadataExtractor looseLocalCalls 同语义;ABI 校验延后到完整脚本上下文)。\n // opDims 透传给 dimension pass(P6 消费,P4 仅透传声明面)。\n const meta = extractMetadata(code, {\n namespaces: opts?.namespaces ?? [],\n looseLocalCalls: true,\n ...(opts?.opDims ? { opDims: opts.opDims } : {}),\n })\n const last = meta.lines[meta.lines.length - 1]\n if (!last) return { positional: [], args: {} }\n // 尾随纯对象(选项槽)从 positional 切出到 args(与现状 splitTrailingOptions\n // 同构:末位纯数据对象是选项槽;引用形态/字面量留在 positional)。\n const positional = [...last.positional]\n const lastArg = positional[positional.length - 1]\n if (\n lastArg !== null &&\n typeof lastArg === 'object' &&\n !Array.isArray(lastArg) &&\n !isHostRef(lastArg as HostArg)\n ) {\n positional.pop()\n return { positional, args: { ...(lastArg as Record<string, HostArg>) } }\n }\n return { positional, args: { ...last.args } }\n}\n\n// ── P7/D10: unit literal parsing ────────────────────────────────────────────\n\n/**\n * Reverse mapping: script-side constant name (UPPERCASE) → internal UnitName.\n */\nconst CONST_TO_UNIT: Readonly<Record<string, UnitName>> = Object.freeze(\n Object.fromEntries(\n (Object.keys(SCRIPT_UNIT_TO_NAME) as string[]).map(\n (k) => [k, SCRIPT_UNIT_TO_NAME[k]] as [string, UnitName],\n ),\n ),\n)\n\n/**\n * Parse a unit literal text expression (`n * UNIT`) into its base-unit value.\n *\n * P7/D10.3: This is the reverse of `formatUnitLiteral`. Given text like\n * `10 * INCH`, returns `{ base: 254, dim: 'length', unitName: 'inch' }`.\n * Non-unit-literal expressions return `null` (host decides whether to\n * downgrade to read-only).\n *\n * @param text - the expression text (e.g. `10 * INCH` or `0.5 * DEGREE`).\n * @returns the parsed unit literal info, or `null` if not a unit literal.\n */\nexport function parseUnitLiteral(text: string): { base: number; dim: DimName; unitName: UnitName } | null {\n const match = /^\\s*(-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)\\s*\\*\\s*([A-Z]+)\\s*$/.exec(text)\n if (!match) return null\n const n = Number(match[1])\n const constName = match[2]\n const unitName = CONST_TO_UNIT[constName]\n if (!unitName) return null\n const dim = UNIT_DIM[unitName]\n // toBase: n * UNIT_SCALE[unitName]\n const base = n * UNIT_SCALE[unitName]\n return { base, dim, unitName }\n}\n"]}
1
+ {"version":3,"file":"code-to-args.js","sourceRoot":"","sources":["../../src/lang/code-to-args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * code-to-args — 单语句行 args 提取(编辑回填配套)\n *\n * See docs/language-design.md §3 (statement model ↔ StatementSummary mapping) and §6.4 (check).\n *\n * 宿主编辑回填(FeatureEditor.backfill / editStatement)需要从代码行\n * 反提参数对象。此能力由 faijs 标配提供(与 parse 语义一致),\n * 宿主不得用 acorn 自行解析(B3 修正)。\n *\n * 无 IR 双通道方案(2026-09-06)后实现换 MetadataExtractor 行级提取:\n * 单行文本经哨兵参数前置声明(与 MetadataExtractor looseLocalCalls 同构)\n * 交给 extractMetadata,取末条 op 行摘要的 positional/args。函数名、签名与\n * 返回契约(CodeToArgsResult)不变;HostArg 引用形态保真(A-5)。\n *\n * F1(表达式折叠):args 含计算表达式(binary/template/conditional/spread)时,\n * 与 parser 折叠语义一致地**求值后返回字面值**,不抛错。\n * 单行提取缺失参数真实值 → 前置声明用哨兵字面量 `let <id> = 0`(参数形态),\n * 使表达式可静态折叠;宿主用 StatementSummary.hasComputedArgs 判定只读降级,\n * 不得把折叠值写回源码(会丢失原表达式)。\n */\n\nimport type { HostArg } from './host-arg'\nimport { extractMetadata, type OpDimMap } from './metadata-extractor'\nimport { isHostRef } from './host-arg'\nimport { isSafeGlobalIdent } from './security-scanner'\nimport { SCRIPT_UNIT_NAMES, UNIT_SCALE, UNIT_DIM, SCRIPT_UNIT_TO_NAME } from '../units'\nimport type { DimName, UnitName } from '../units'\n\n/**\n * 单行提取的前置声明规则(确定性静态规则,非 try/catch 兜底):\n * parser 的作用域检查(inputs / 重赋值 LHS / 成员方法 receiver / args 中的\n * 裸标识符参数引用)要求变量已声明,而单行提取天然缺失声明上下文。\n * 规则:提取行内全部标识符(剥掉字符串字面量后),为每个非 `cad`/关键字\n * 标识符前置一行 `let <id> = 0`(哨兵参数)。parser 对该形态只做语法\n * 检查、不查符号表;多余声明对 varToId 仅是\"可查到\",不影响目标行的\n * args 解析结果。F1 起用哨兵参数(而非 `cad.assembly({})` 语句)——\n * 参数值已知 → 表达式可静态折叠,满足\"参数为表达式时返回折叠字面值\"。\n */\nconst IDENT_RE = /[A-Za-z_$][\\w$]*/g\nconst STRING_RE = /'(?:[^'\\\\]|\\\\.)*'|\"(?:[^\"\\\\]|\\\\.)*\"/g\nconst NON_DECL = new Set([\n 'cad', 'const', 'let', 'true', 'false', 'null', 'undefined',\n 'await', 'return', 'new', 'typeof', 'var', 'function',\n])\n\nfunction extractIdentifiers(line: string, namespaces?: Set<string>): string[] {\n const withoutStrings = line.replace(STRING_RE, \"''\")\n const declared = declaredByLine(withoutStrings)\n const ids = new Set<string>()\n for (const m of withoutStrings.matchAll(IDENT_RE)) {\n const id = m[0]\n // P7/D10.4: unit constants (MM, INCH, DEGREE, …) must NOT be pre-declared\n // as sentinel parameters (`let INCH = 0`), because that would shadow the\n // real global value and cause `10 * INCH` to fold to 0.\n // 2026-10-06:其余免 import 安全全局(Math / JSON / Number / console / …)同理。\n // 它们不是脚本参数,前置 `let Math = 0` 会让提取结果带上幻影参数引用\n // (`cad.box(Math.PI, …)` → expr-ref params:['Math']),宿主会据此误判依赖。\n if (\n NON_DECL.has(id) ||\n declared.has(id) ||\n namespaces?.has(id) ||\n SCRIPT_UNIT_NAMES.has(id) ||\n isSafeGlobalIdent(id)\n ) {\n continue\n }\n ids.add(id)\n }\n return [...ids]\n}\n\n/**\n * 行内自身声明的标识符(前置声明必须跳过,否则 acorn 重声明报错):\n * - `const/let x = ...` 的 x\n * - `const { k1: v1, k2 } = ...` 的绑定名 v1/k2(键名 k1 不是声明,仍需前置声明——无害)\n */\nfunction declaredByLine(line: string): Set<string> {\n const ids = new Set<string>()\n let m = /^\\s*(?:const|let)\\s+([A-Za-z_$][\\w$]*)\\s*=/.exec(line)\n if (m) ids.add(m[1])\n m = /^\\s*const\\s*\\{([^}]*)\\}\\s*=/.exec(line)\n if (m) {\n for (const prop of m[1].split(',')) {\n const bound = (prop.split(':')[1] ?? prop).trim()\n const id = /^([A-Za-z_$][\\w$]*)/.exec(bound)\n if (id) ids.add(id[1])\n }\n }\n return ids\n}\n\n/**\n * `codeToArgs` 的返回契约:位置实参槽 + 尾随选项对象(HostArg 形态,纯数据无 IR)。\n */\nexport interface CodeToArgsResult {\n positional: HostArg[]\n args: Record<string, HostArg>\n}\n\n/**\n * codeToArgs 选项。`opDims` 为 P4/P6 (unit-system D8) 透传:callee → 量纲声明,\n * 供单行回填路径的 dimension pass 消费(P6 落地前声明面透传即可,不影响解析结果)。\n */\nexport interface CodeToArgsOptions {\n /** 该脚本顶层 import 的绑定名(F2)。 */\n namespaces?: string[]\n /** callee → 量纲声明(unit-system D8,P6 消费)。 */\n opDims?: OpDimMap\n}\n\n/**\n * 解析单条语句行,提取其位置实参槽与选项对象(序列化形态,无 IR 变体语义)。\n *\n * true-JS-subset §4.6.3 新契约:返回 `{ positional, args }`——\n * - `positional`: HostArg[],按调用顺序的位置实参(字面量原样;var-ref/\n * param-ref/call-ref/expr-ref 以 `{kind,...}` 标记对象呈现,宿主据此降级为\n * 只读编辑);宿主不接触内部类型(纯数据面)。\n * - `args`: 尾随选项对象(键值 HostArg 形态;无选项对象时为 `{}`)。\n * 旧契约(只返回对象槽)在位置形态下会静默丢弃非对象实参——本契约显式保留全部信息。\n *\n * 支持的行形态(与 parser 接受的语句一致):\n * - `const part0 = cad.box(10, 20, 30)`\n * - `part0 = cad.fai_drill(part0, { diameter: 5 })`(裸重赋值)\n * - `const { front: a, back: b } = cad.fai_split(part0, { normal: [0,0,1] })`(解构)\n * - `asm0.add_constraint({ ... })`(成员方法调用)\n * - 位置实参为字面量/变量引用/表达式(`cad.box(10, 20, 30)`、`cad.hem(p0.solid, {...})`)\n * - args 中的裸标识符参数引用(`cad.box(10, 20, height)`)\n * - args 中的计算表达式(`cad.box(10, 20, base + 20)`)→ 折叠为字面值返回\n *\n * @param codeLine 单条语句源码行\n * @param opts.namespaces 该脚本顶层 import 的绑定名(F2:`mech.makeHeadstock(...)`\n * 中 `mech` 不得被前置声明为变量)。L0 不感知注册表,由宿主从脚本 imports 提供。\n * @returns the extracted positional slot and trailing options object (both in\n * serialized JSON form).\n * @throws ParseError — 行文本不是合法语句时抛出(含行号)\n */\nexport function codeToArgs(codeLine: string, opts?: CodeToArgsOptions): CodeToArgsResult {\n const namespaces = new Set(opts?.namespaces ?? [])\n const decls = extractIdentifiers(codeLine, namespaces)\n .map((id) => `let ${id} = 0`)\n .join('\\n')\n const code = decls ? `${decls}\\n${codeLine}` : codeLine\n // 单行提取语义:前置哨兵参数(let id = 0)在 extractMetadata 中按参数行处理;\n // 末条 op 行摘要 = 目标行。裸本机函数 callee(makeArray 等)放行(looseLocalCalls,\n // 与现状 codeToArgs 的 MetadataExtractor looseLocalCalls 同语义;ABI 校验延后到完整脚本上下文)。\n // opDims 透传给 dimension pass(P6 消费,P4 仅透传声明面)。\n const meta = extractMetadata(code, {\n namespaces: opts?.namespaces ?? [],\n looseLocalCalls: true,\n ...(opts?.opDims ? { opDims: opts.opDims } : {}),\n })\n const last = meta.lines[meta.lines.length - 1]\n if (!last) return { positional: [], args: {} }\n // 尾随纯对象(选项槽)从 positional 切出到 args(与现状 splitTrailingOptions\n // 同构:末位纯数据对象是选项槽;引用形态/字面量留在 positional)。\n const positional = [...last.positional]\n const lastArg = positional[positional.length - 1]\n if (\n lastArg !== null &&\n typeof lastArg === 'object' &&\n !Array.isArray(lastArg) &&\n !isHostRef(lastArg as HostArg)\n ) {\n positional.pop()\n return { positional, args: { ...(lastArg as Record<string, HostArg>) } }\n }\n return { positional, args: { ...last.args } }\n}\n\n// ── P7/D10: unit literal parsing ────────────────────────────────────────────\n\n/**\n * Reverse mapping: script-side constant name (UPPERCASE) → internal UnitName.\n */\nconst CONST_TO_UNIT: Readonly<Record<string, UnitName>> = Object.freeze(\n Object.fromEntries(\n (Object.keys(SCRIPT_UNIT_TO_NAME) as string[]).map(\n (k) => [k, SCRIPT_UNIT_TO_NAME[k]] as [string, UnitName],\n ),\n ),\n)\n\n/**\n * Parse a unit literal text expression (`n * UNIT`) into its base-unit value.\n *\n * P7/D10.3: This is the reverse of `formatUnitLiteral`. Given text like\n * `10 * INCH`, returns `{ base: 254, dim: 'length', unitName: 'inch' }`.\n * Non-unit-literal expressions return `null` (host decides whether to\n * downgrade to read-only).\n *\n * @param text - the expression text (e.g. `10 * INCH` or `0.5 * DEGREE`).\n * @returns the parsed unit literal info, or `null` if not a unit literal.\n */\nexport function parseUnitLiteral(text: string): { base: number; dim: DimName; unitName: UnitName } | null {\n const match = /^\\s*(-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)\\s*\\*\\s*([A-Z]+)\\s*$/.exec(text)\n if (!match) return null\n const n = Number(match[1])\n const constName = match[2]\n const unitName = CONST_TO_UNIT[constName]\n if (!unitName) return null\n const dim = UNIT_DIM[unitName]\n // toBase: n * UNIT_SCALE[unitName]\n const base = n * UNIT_SCALE[unitName]\n return { base, dim, unitName }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"determinism-scanner.d.ts","sourceRoot":"","sources":["../../src/lang/determinism-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,2DAA2D;AAC3D,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;AAExD,mDAAmD;AACnD,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,MAAM,GACN,QAAQ,GACR,iBAAiB,GACjB,iBAAiB,CAAA;AAErB,iDAAiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,MAAM,EAAE,iBAAiB,CAAA;IACzB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,oBAAoB;AACpB,MAAM,WAAW,sBAAsB;IACrC,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,mBAAmB;AACnB,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,EAAE,EAAE,OAAO,CAAA;IACX,UAAU,EAAE,oBAAoB,EAAE,CAAA;CACnC;AAwED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B,GAAG,qBAAqB,CAmjBtG"}
1
+ {"version":3,"file":"determinism-scanner.d.ts","sourceRoot":"","sources":["../../src/lang/determinism-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,2DAA2D;AAC3D,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;AAExD,mDAAmD;AACnD,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,MAAM,GACN,QAAQ,GACR,iBAAiB,GACjB,iBAAiB,CAAA;AAErB,iDAAiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,MAAM,EAAE,iBAAiB,CAAA;IACzB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,oBAAoB;AACpB,MAAM,WAAW,sBAAsB;IACrC,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,mBAAmB;AACnB,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,EAAE,EAAE,OAAO,CAAA;IACX,UAAU,EAAE,oBAAoB,EAAE,CAAA;CACnC;AAwFD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B,GAAG,qBAAqB,CAmjBtG"}
@@ -19,6 +19,9 @@
19
19
  * cross-kernel parity tests (docs/reproducibility-contract.md §5).
20
20
  */
21
21
  import { parse as acornParse } from 'acorn';
22
+ // A4 (2026-10-06): SAFE_CONTAINERS / SAFE_FUNCTIONS are derived from the S4
23
+ // admission list — single source of truth for script-face globals.
24
+ import { S4_SAFE_GLOBALS } from './security-scanner.js';
22
25
  // ── rule tables ──
23
26
  /** Containers (identifier → member) whose member access is a non-deterministic source. */
24
27
  const SOURCE_MEMBERS = {
@@ -35,16 +38,26 @@ const SOURCE_IDENTS = new Set(['Date', 'crypto', 'getRandomValues', 'performance
35
38
  /**
36
39
  * Safe containers: member calls on these neither violate nor introduce taint;
37
40
  * taint only propagates through their arguments (pure/observable-only globals).
41
+ *
42
+ * A4 (2026-10-06, user decision): DERIVED from `S4_SAFE_GLOBALS`
43
+ * (security-scanner.ts) instead of hand-maintained. The script face can only
44
+ * name identifiers admitted by the S4 gate, so any container not in S4 is
45
+ * unreachable dead weight — the former hand-copied entries `Intl` / `Reflect`
46
+ * (and the encodeURI family in SAFE_FUNCTIONS) were exactly that, and are gone.
47
+ * Excluded here: bare non-deterministic sources (Date / crypto / performance —
48
+ * they are handled by SOURCE_MEMBERS / SOURCE_IDENTS above). Unit constants
49
+ * (MM, INCH, …) are inert numeric values; keeping them is harmless.
50
+ */
51
+ const SAFE_CONTAINERS = new Set([...S4_SAFE_GLOBALS].filter((name) => !SOURCE_IDENTS.has(name)));
52
+ /**
53
+ * Safe top-level functions (pure/known, not geometry). Also derived from
54
+ * `S4_SAFE_GLOBALS`: every name here must be S4-admitted (guard test
55
+ * `test/lang/determinism-scanner.test.ts` enforces both derivations).
56
+ * The former `encodeURI` / `encodeURIComponent` / `decodeURI` /
57
+ * `decodeURIComponent` entries were unreachable in scripts (not in S4) —
58
+ * URL construction is host/IO territory, not geometry-script territory.
38
59
  */
39
- const SAFE_CONTAINERS = new Set([
40
- 'console', 'Math', 'JSON', 'Number', 'String', 'Boolean', 'Object', 'Array',
41
- 'Map', 'Set', 'Symbol', 'RegExp', 'Promise', 'Error', 'Intl', 'Reflect',
42
- ]);
43
- /** Safe top-level functions (pure/known, not geometry). */
44
- const SAFE_FUNCTIONS = new Set([
45
- 'parseInt', 'parseFloat', 'isNaN', 'isFinite', 'String', 'Number', 'Boolean',
46
- 'encodeURI', 'encodeURIComponent', 'decodeURI', 'decodeURIComponent',
47
- ]);
60
+ const SAFE_FUNCTIONS = new Set(['parseInt', 'parseFloat', 'isNaN', 'isFinite', 'String', 'Number', 'Boolean'].filter((name) => S4_SAFE_GLOBALS.has(name)));
48
61
  function childScope(parent) {
49
62
  return { parent, tainted: new Map() };
50
63
  }