@imgly/codesign-mcp 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/README.md +5 -10
  2. package/assets/docs/api/index.d.ts +9 -3
  3. package/assets/docs/guide/SKILL.md +2 -2
  4. package/assets/docs/guide/api/node/classes/creativeengine.md +13 -13
  5. package/assets/docs/guide/edit-image/transform/scale.md +1 -3
  6. package/assets/docs/guide/filters-and-effects/duotone.md +1 -1
  7. package/assets/docs/guide/get-started/bun.md +0 -2
  8. package/assets/docs/guide/get-started/deno.md +0 -1
  9. package/assets/docs/guide/get-started/vanilla.md +0 -2
  10. package/assets/docs/guide/import-media/default-assets.md +20 -24
  11. package/assets/docs/guide/plugins/print-ready-pdf.md +0 -2
  12. package/assets/docs/guide/serve-assets.md +80 -23
  13. package/assets/docs/handbook/SKILL.md +6 -7
  14. package/dist/assets/inline.generated.js +12 -12
  15. package/dist/assets/inline.generated.js.map +1 -1
  16. package/dist/cli/http.d.ts.map +1 -1
  17. package/dist/cli/http.js +29 -5
  18. package/dist/cli/http.js.map +1 -1
  19. package/dist/cli/stdio.d.ts.map +1 -1
  20. package/dist/cli/stdio.js +145 -48
  21. package/dist/cli/stdio.js.map +1 -1
  22. package/dist/cli/trial-license.generated.d.ts +1 -1
  23. package/dist/cli/trial-license.generated.js +1 -1
  24. package/dist/cli/trial-license.generated.js.map +1 -1
  25. package/dist/config.d.ts +17 -2
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +20 -1
  28. package/dist/config.js.map +1 -1
  29. package/dist/diagnostics/bundle.d.ts +3 -0
  30. package/dist/diagnostics/bundle.d.ts.map +1 -1
  31. package/dist/diagnostics/bundle.js +25 -22
  32. package/dist/diagnostics/bundle.js.map +1 -1
  33. package/dist/diagnostics/events.d.ts +6 -0
  34. package/dist/diagnostics/events.d.ts.map +1 -1
  35. package/dist/diagnostics/events.js.map +1 -1
  36. package/dist/diagnostics/prompt.d.ts +3 -0
  37. package/dist/diagnostics/prompt.d.ts.map +1 -0
  38. package/dist/diagnostics/prompt.js +21 -0
  39. package/dist/diagnostics/prompt.js.map +1 -0
  40. package/dist/diagnostics/router.d.ts +12 -0
  41. package/dist/diagnostics/router.d.ts.map +1 -0
  42. package/dist/diagnostics/router.js +64 -0
  43. package/dist/diagnostics/router.js.map +1 -0
  44. package/dist/diagnostics/spa-assets.generated.d.ts.map +1 -0
  45. package/dist/diagnostics/spa-assets.generated.js +1231 -0
  46. package/dist/diagnostics/spa-assets.generated.js.map +1 -0
  47. package/dist/diagnostics/status.d.ts +38 -0
  48. package/dist/diagnostics/status.d.ts.map +1 -0
  49. package/dist/diagnostics/status.js +53 -0
  50. package/dist/diagnostics/status.js.map +1 -0
  51. package/dist/diagnostics/summary.d.ts +48 -0
  52. package/dist/diagnostics/summary.d.ts.map +1 -0
  53. package/dist/diagnostics/summary.js +116 -0
  54. package/dist/diagnostics/summary.js.map +1 -0
  55. package/dist/diagnostics/tool.d.ts +16 -0
  56. package/dist/diagnostics/tool.d.ts.map +1 -0
  57. package/dist/diagnostics/tool.js +90 -0
  58. package/dist/diagnostics/tool.js.map +1 -0
  59. package/dist/engine/asset-sources.d.ts +8 -0
  60. package/dist/engine/asset-sources.d.ts.map +1 -1
  61. package/dist/engine/asset-sources.js +9 -2
  62. package/dist/engine/asset-sources.js.map +1 -1
  63. package/dist/engine/cesdk-adapter.d.ts +5 -1
  64. package/dist/engine/cesdk-adapter.d.ts.map +1 -1
  65. package/dist/engine/cesdk-adapter.js +8 -1
  66. package/dist/engine/cesdk-adapter.js.map +1 -1
  67. package/dist/engine/engine-capacity.d.ts +16 -0
  68. package/dist/engine/engine-capacity.d.ts.map +1 -0
  69. package/dist/engine/engine-capacity.js +48 -0
  70. package/dist/engine/engine-capacity.js.map +1 -0
  71. package/dist/engine/engine-slots.d.ts +48 -0
  72. package/dist/engine/engine-slots.d.ts.map +1 -0
  73. package/dist/engine/engine-slots.js +182 -0
  74. package/dist/engine/engine-slots.js.map +1 -0
  75. package/dist/engine/uri-resolver.js.map +1 -1
  76. package/dist/server.d.ts +25 -0
  77. package/dist/server.d.ts.map +1 -1
  78. package/dist/server.js +24 -4
  79. package/dist/server.js.map +1 -1
  80. package/dist/tools/engine.d.ts +92 -14
  81. package/dist/tools/engine.d.ts.map +1 -1
  82. package/dist/tools/engine.js +147 -20
  83. package/dist/tools/engine.js.map +1 -1
  84. package/dist/tools/export.d.ts.map +1 -1
  85. package/dist/tools/export.js +34 -4
  86. package/dist/tools/export.js.map +1 -1
  87. package/dist/tools/index.js +2 -2
  88. package/dist/tools/index.js.map +1 -1
  89. package/dist/tools/load.d.ts.map +1 -1
  90. package/dist/tools/load.js +26 -19
  91. package/dist/tools/load.js.map +1 -1
  92. package/dist/tools/preview.d.ts.map +1 -1
  93. package/dist/tools/preview.js +60 -40
  94. package/dist/tools/preview.js.map +1 -1
  95. package/dist/tools/{open-editor.d.ts → view.d.ts} +3 -3
  96. package/dist/tools/view.d.ts.map +1 -0
  97. package/dist/tools/{open-editor.js → view.js} +20 -18
  98. package/dist/tools/view.js.map +1 -0
  99. package/dist/viewer/listener.d.ts +2 -0
  100. package/dist/viewer/listener.d.ts.map +1 -1
  101. package/dist/viewer/listener.js +2 -0
  102. package/dist/viewer/listener.js.map +1 -1
  103. package/dist/viewer/presigned-r2-url-builder.d.ts +1 -1
  104. package/dist/viewer/presigned-r2-url-builder.js +1 -1
  105. package/dist/viewer/presigned-r2-url-builder.js.map +1 -1
  106. package/dist/viewer/router.d.ts.map +1 -1
  107. package/dist/viewer/router.js +8 -17
  108. package/dist/viewer/router.js.map +1 -1
  109. package/dist/viewer/session-mount.js.map +1 -1
  110. package/dist/viewer/spa-assets.generated.d.ts.map +1 -1
  111. package/dist/viewer/spa-assets.generated.js +750 -869
  112. package/dist/viewer/spa-assets.generated.js.map +1 -1
  113. package/dist/viewer/url-builder.d.ts +4 -3
  114. package/dist/viewer/url-builder.d.ts.map +1 -1
  115. package/dist/viewer/url-builder.js +4 -4
  116. package/dist/viewer/url-builder.js.map +1 -1
  117. package/package.json +7 -6
  118. package/dist/dashboard/router.d.ts +0 -3
  119. package/dist/dashboard/router.d.ts.map +0 -1
  120. package/dist/dashboard/router.js +0 -19
  121. package/dist/dashboard/router.js.map +0 -1
  122. package/dist/dashboard/spa-assets.generated.d.ts.map +0 -1
  123. package/dist/dashboard/spa-assets.generated.js +0 -220
  124. package/dist/dashboard/spa-assets.generated.js.map +0 -1
  125. package/dist/metrics/mount.d.ts +0 -11
  126. package/dist/metrics/mount.d.ts.map +0 -1
  127. package/dist/metrics/mount.js +0 -13
  128. package/dist/metrics/mount.js.map +0 -1
  129. package/dist/metrics/recorder.d.ts +0 -55
  130. package/dist/metrics/recorder.d.ts.map +0 -1
  131. package/dist/metrics/recorder.js +0 -97
  132. package/dist/metrics/recorder.js.map +0 -1
  133. package/dist/test/scripts/changelog-add.d.ts +0 -8
  134. package/dist/test/scripts/changelog-add.d.ts.map +0 -1
  135. package/dist/test/scripts/changelog-add.js +0 -50
  136. package/dist/test/scripts/changelog-add.js.map +0 -1
  137. package/dist/test/scripts/changelog-collate.d.ts +0 -38
  138. package/dist/test/scripts/changelog-collate.d.ts.map +0 -1
  139. package/dist/test/scripts/changelog-collate.js +0 -171
  140. package/dist/test/scripts/changelog-collate.js.map +0 -1
  141. package/dist/test/test/changelog.test.d.ts +0 -2
  142. package/dist/test/test/changelog.test.d.ts.map +0 -1
  143. package/dist/test/test/changelog.test.js +0 -293
  144. package/dist/test/test/changelog.test.js.map +0 -1
  145. package/dist/test/test/cli/dispatcher.test.d.ts +0 -2
  146. package/dist/test/test/cli/dispatcher.test.d.ts.map +0 -1
  147. package/dist/test/test/cli/dispatcher.test.js +0 -54
  148. package/dist/test/test/cli/dispatcher.test.js.map +0 -1
  149. package/dist/test/test/cli/redirect-console.test.d.ts +0 -2
  150. package/dist/test/test/cli/redirect-console.test.d.ts.map +0 -1
  151. package/dist/test/test/cli/redirect-console.test.js +0 -78
  152. package/dist/test/test/cli/redirect-console.test.js.map +0 -1
  153. package/dist/test/test/cli/resolve-license.test.d.ts +0 -2
  154. package/dist/test/test/cli/resolve-license.test.d.ts.map +0 -1
  155. package/dist/test/test/cli/resolve-license.test.js +0 -29
  156. package/dist/test/test/cli/resolve-license.test.js.map +0 -1
  157. package/dist/test/test/cli/stdio-diagnostics.test.d.ts +0 -2
  158. package/dist/test/test/cli/stdio-diagnostics.test.d.ts.map +0 -1
  159. package/dist/test/test/cli/stdio-diagnostics.test.js +0 -31
  160. package/dist/test/test/cli/stdio-diagnostics.test.js.map +0 -1
  161. package/dist/test/test/cli/stdio-license.test.d.ts +0 -2
  162. package/dist/test/test/cli/stdio-license.test.d.ts.map +0 -1
  163. package/dist/test/test/cli/stdio-license.test.js +0 -19
  164. package/dist/test/test/cli/stdio-license.test.js.map +0 -1
  165. package/dist/test/test/config.test.d.ts +0 -2
  166. package/dist/test/test/config.test.d.ts.map +0 -1
  167. package/dist/test/test/config.test.js +0 -95
  168. package/dist/test/test/config.test.js.map +0 -1
  169. package/dist/test/test/cross-ref.test.d.ts +0 -2
  170. package/dist/test/test/cross-ref.test.d.ts.map +0 -1
  171. package/dist/test/test/cross-ref.test.js +0 -39
  172. package/dist/test/test/cross-ref.test.js.map +0 -1
  173. package/dist/test/test/diagnostics/bundle.test.d.ts +0 -2
  174. package/dist/test/test/diagnostics/bundle.test.d.ts.map +0 -1
  175. package/dist/test/test/diagnostics/bundle.test.js +0 -53
  176. package/dist/test/test/diagnostics/bundle.test.js.map +0 -1
  177. package/dist/test/test/diagnostics/compose.test.d.ts +0 -2
  178. package/dist/test/test/diagnostics/compose.test.d.ts.map +0 -1
  179. package/dist/test/test/diagnostics/compose.test.js +0 -31
  180. package/dist/test/test/diagnostics/compose.test.js.map +0 -1
  181. package/dist/test/test/diagnostics/file-sink.test.d.ts +0 -2
  182. package/dist/test/test/diagnostics/file-sink.test.d.ts.map +0 -1
  183. package/dist/test/test/diagnostics/file-sink.test.js +0 -113
  184. package/dist/test/test/diagnostics/file-sink.test.js.map +0 -1
  185. package/dist/test/test/diagnostics/redact.test.d.ts +0 -2
  186. package/dist/test/test/diagnostics/redact.test.d.ts.map +0 -1
  187. package/dist/test/test/diagnostics/redact.test.js +0 -59
  188. package/dist/test/test/diagnostics/redact.test.js.map +0 -1
  189. package/dist/test/test/diagnostics/tool-call-adapter.test.d.ts +0 -2
  190. package/dist/test/test/diagnostics/tool-call-adapter.test.d.ts.map +0 -1
  191. package/dist/test/test/diagnostics/tool-call-adapter.test.js +0 -34
  192. package/dist/test/test/diagnostics/tool-call-adapter.test.js.map +0 -1
  193. package/dist/test/test/engine/asset-sources.test.d.ts +0 -2
  194. package/dist/test/test/engine/asset-sources.test.d.ts.map +0 -1
  195. package/dist/test/test/engine/asset-sources.test.js +0 -100
  196. package/dist/test/test/engine/asset-sources.test.js.map +0 -1
  197. package/dist/test/test/engine/cesdk-adapter.test.d.ts +0 -2
  198. package/dist/test/test/engine/cesdk-adapter.test.d.ts.map +0 -1
  199. package/dist/test/test/engine/cesdk-adapter.test.js +0 -32
  200. package/dist/test/test/engine/cesdk-adapter.test.js.map +0 -1
  201. package/dist/test/test/engine/mutex.test.d.ts +0 -2
  202. package/dist/test/test/engine/mutex.test.d.ts.map +0 -1
  203. package/dist/test/test/engine/mutex.test.js +0 -63
  204. package/dist/test/test/engine/mutex.test.js.map +0 -1
  205. package/dist/test/test/engine/session.test.d.ts +0 -2
  206. package/dist/test/test/engine/session.test.d.ts.map +0 -1
  207. package/dist/test/test/engine/session.test.js +0 -159
  208. package/dist/test/test/engine/session.test.js.map +0 -1
  209. package/dist/test/test/engine/unsplash-source.test.d.ts +0 -2
  210. package/dist/test/test/engine/unsplash-source.test.d.ts.map +0 -1
  211. package/dist/test/test/engine/unsplash-source.test.js +0 -129
  212. package/dist/test/test/engine/unsplash-source.test.js.map +0 -1
  213. package/dist/test/test/engine/uri-resolver.test.d.ts +0 -2
  214. package/dist/test/test/engine/uri-resolver.test.d.ts.map +0 -1
  215. package/dist/test/test/engine/uri-resolver.test.js +0 -38
  216. package/dist/test/test/engine/uri-resolver.test.js.map +0 -1
  217. package/dist/test/test/gateway/hosted-stub.test.d.ts +0 -2
  218. package/dist/test/test/gateway/hosted-stub.test.d.ts.map +0 -1
  219. package/dist/test/test/gateway/hosted-stub.test.js +0 -11
  220. package/dist/test/test/gateway/hosted-stub.test.js.map +0 -1
  221. package/dist/test/test/gateway/local.test.d.ts +0 -2
  222. package/dist/test/test/gateway/local.test.d.ts.map +0 -1
  223. package/dist/test/test/gateway/local.test.js +0 -29
  224. package/dist/test/test/gateway/local.test.js.map +0 -1
  225. package/dist/test/test/handbook-contract.test.d.ts +0 -2
  226. package/dist/test/test/handbook-contract.test.d.ts.map +0 -1
  227. package/dist/test/test/handbook-contract.test.js +0 -79
  228. package/dist/test/test/handbook-contract.test.js.map +0 -1
  229. package/dist/test/test/http/server.test.d.ts +0 -2
  230. package/dist/test/test/http/server.test.d.ts.map +0 -1
  231. package/dist/test/test/http/server.test.js +0 -338
  232. package/dist/test/test/http/server.test.js.map +0 -1
  233. package/dist/test/test/http/session-id-header.test.d.ts +0 -2
  234. package/dist/test/test/http/session-id-header.test.d.ts.map +0 -1
  235. package/dist/test/test/http/session-id-header.test.js +0 -76
  236. package/dist/test/test/http/session-id-header.test.js.map +0 -1
  237. package/dist/test/test/http/session-manager.test.d.ts +0 -2
  238. package/dist/test/test/http/session-manager.test.d.ts.map +0 -1
  239. package/dist/test/test/http/session-manager.test.js +0 -97
  240. package/dist/test/test/http/session-manager.test.js.map +0 -1
  241. package/dist/test/test/http/workspace-auth.test.d.ts +0 -2
  242. package/dist/test/test/http/workspace-auth.test.d.ts.map +0 -1
  243. package/dist/test/test/http/workspace-auth.test.js +0 -40
  244. package/dist/test/test/http/workspace-auth.test.js.map +0 -1
  245. package/dist/test/test/metrics/mount.test.d.ts +0 -2
  246. package/dist/test/test/metrics/mount.test.d.ts.map +0 -1
  247. package/dist/test/test/metrics/mount.test.js +0 -59
  248. package/dist/test/test/metrics/mount.test.js.map +0 -1
  249. package/dist/test/test/metrics/recorder.test.d.ts +0 -2
  250. package/dist/test/test/metrics/recorder.test.d.ts.map +0 -1
  251. package/dist/test/test/metrics/recorder.test.js +0 -118
  252. package/dist/test/test/metrics/recorder.test.js.map +0 -1
  253. package/dist/test/test/revisions/hash.test.d.ts +0 -2
  254. package/dist/test/test/revisions/hash.test.d.ts.map +0 -1
  255. package/dist/test/test/revisions/hash.test.js +0 -33
  256. package/dist/test/test/revisions/hash.test.js.map +0 -1
  257. package/dist/test/test/revisions/store.test.d.ts +0 -2
  258. package/dist/test/test/revisions/store.test.d.ts.map +0 -1
  259. package/dist/test/test/revisions/store.test.js +0 -315
  260. package/dist/test/test/revisions/store.test.js.map +0 -1
  261. package/dist/test/test/server.metrics.test.d.ts +0 -2
  262. package/dist/test/test/server.metrics.test.d.ts.map +0 -1
  263. package/dist/test/test/server.metrics.test.js +0 -87
  264. package/dist/test/test/server.metrics.test.js.map +0 -1
  265. package/dist/test/test/server.test.d.ts +0 -2
  266. package/dist/test/test/server.test.d.ts.map +0 -1
  267. package/dist/test/test/server.test.js +0 -146
  268. package/dist/test/test/server.test.js.map +0 -1
  269. package/dist/test/test/skill-tools.test.d.ts +0 -2
  270. package/dist/test/test/skill-tools.test.d.ts.map +0 -1
  271. package/dist/test/test/skill-tools.test.js +0 -84
  272. package/dist/test/test/skill-tools.test.js.map +0 -1
  273. package/dist/test/test/smoke.test.d.ts +0 -2
  274. package/dist/test/test/smoke.test.d.ts.map +0 -1
  275. package/dist/test/test/smoke.test.js +0 -8
  276. package/dist/test/test/smoke.test.js.map +0 -1
  277. package/dist/test/test/tools/asset-generate.test.d.ts +0 -2
  278. package/dist/test/test/tools/asset-generate.test.d.ts.map +0 -1
  279. package/dist/test/test/tools/asset-generate.test.js +0 -66
  280. package/dist/test/test/tools/asset-generate.test.js.map +0 -1
  281. package/dist/test/test/tools/asset-search.test.d.ts +0 -2
  282. package/dist/test/test/tools/asset-search.test.d.ts.map +0 -1
  283. package/dist/test/test/tools/asset-search.test.js +0 -121
  284. package/dist/test/test/tools/asset-search.test.js.map +0 -1
  285. package/dist/test/test/tools/edit-harness.d.ts +0 -14
  286. package/dist/test/test/tools/edit-harness.d.ts.map +0 -1
  287. package/dist/test/test/tools/edit-harness.js +0 -30
  288. package/dist/test/test/tools/edit-harness.js.map +0 -1
  289. package/dist/test/test/tools/edit.telemetry.test.d.ts +0 -2
  290. package/dist/test/test/tools/edit.telemetry.test.d.ts.map +0 -1
  291. package/dist/test/test/tools/edit.telemetry.test.js +0 -46
  292. package/dist/test/test/tools/edit.telemetry.test.js.map +0 -1
  293. package/dist/test/test/tools/edit.test.d.ts +0 -2
  294. package/dist/test/test/tools/edit.test.d.ts.map +0 -1
  295. package/dist/test/test/tools/edit.test.js +0 -267
  296. package/dist/test/test/tools/edit.test.js.map +0 -1
  297. package/dist/test/test/tools/export-harness.d.ts +0 -13
  298. package/dist/test/test/tools/export-harness.d.ts.map +0 -1
  299. package/dist/test/test/tools/export-harness.js +0 -27
  300. package/dist/test/test/tools/export-harness.js.map +0 -1
  301. package/dist/test/test/tools/export.telemetry.test.d.ts +0 -2
  302. package/dist/test/test/tools/export.telemetry.test.d.ts.map +0 -1
  303. package/dist/test/test/tools/export.telemetry.test.js +0 -65
  304. package/dist/test/test/tools/export.telemetry.test.js.map +0 -1
  305. package/dist/test/test/tools/export.test.d.ts +0 -2
  306. package/dist/test/test/tools/export.test.d.ts.map +0 -1
  307. package/dist/test/test/tools/export.test.js +0 -174
  308. package/dist/test/test/tools/export.test.js.map +0 -1
  309. package/dist/test/test/tools/history.test.d.ts +0 -2
  310. package/dist/test/test/tools/history.test.d.ts.map +0 -1
  311. package/dist/test/test/tools/history.test.js +0 -29
  312. package/dist/test/test/tools/history.test.js.map +0 -1
  313. package/dist/test/test/tools/import.test.d.ts +0 -2
  314. package/dist/test/test/tools/import.test.d.ts.map +0 -1
  315. package/dist/test/test/tools/import.test.js +0 -122
  316. package/dist/test/test/tools/import.test.js.map +0 -1
  317. package/dist/test/test/tools/index.test.d.ts +0 -2
  318. package/dist/test/test/tools/index.test.d.ts.map +0 -1
  319. package/dist/test/test/tools/index.test.js +0 -117
  320. package/dist/test/test/tools/index.test.js.map +0 -1
  321. package/dist/test/test/tools/inspect.test.d.ts +0 -2
  322. package/dist/test/test/tools/inspect.test.d.ts.map +0 -1
  323. package/dist/test/test/tools/inspect.test.js +0 -62
  324. package/dist/test/test/tools/inspect.test.js.map +0 -1
  325. package/dist/test/test/tools/list.test.d.ts +0 -2
  326. package/dist/test/test/tools/list.test.d.ts.map +0 -1
  327. package/dist/test/test/tools/list.test.js +0 -23
  328. package/dist/test/test/tools/list.test.js.map +0 -1
  329. package/dist/test/test/tools/load.integration.test.d.ts +0 -2
  330. package/dist/test/test/tools/load.integration.test.d.ts.map +0 -1
  331. package/dist/test/test/tools/load.integration.test.js +0 -165
  332. package/dist/test/test/tools/load.integration.test.js.map +0 -1
  333. package/dist/test/test/tools/load.test.d.ts +0 -2
  334. package/dist/test/test/tools/load.test.d.ts.map +0 -1
  335. package/dist/test/test/tools/load.test.js +0 -387
  336. package/dist/test/test/tools/load.test.js.map +0 -1
  337. package/dist/test/test/tools/metrics.test.d.ts +0 -2
  338. package/dist/test/test/tools/metrics.test.d.ts.map +0 -1
  339. package/dist/test/test/tools/metrics.test.js +0 -29
  340. package/dist/test/test/tools/metrics.test.js.map +0 -1
  341. package/dist/test/test/tools/open-editor.test.d.ts +0 -2
  342. package/dist/test/test/tools/open-editor.test.d.ts.map +0 -1
  343. package/dist/test/test/tools/open-editor.test.js +0 -53
  344. package/dist/test/test/tools/open-editor.test.js.map +0 -1
  345. package/dist/test/test/tools/preview-harness.d.ts +0 -9
  346. package/dist/test/test/tools/preview-harness.d.ts.map +0 -1
  347. package/dist/test/test/tools/preview-harness.js +0 -23
  348. package/dist/test/test/tools/preview-harness.js.map +0 -1
  349. package/dist/test/test/tools/preview.telemetry.test.d.ts +0 -2
  350. package/dist/test/test/tools/preview.telemetry.test.d.ts.map +0 -1
  351. package/dist/test/test/tools/preview.telemetry.test.js +0 -36
  352. package/dist/test/test/tools/preview.telemetry.test.js.map +0 -1
  353. package/dist/test/test/tools/preview.test.d.ts +0 -2
  354. package/dist/test/test/tools/preview.test.d.ts.map +0 -1
  355. package/dist/test/test/tools/preview.test.js +0 -75
  356. package/dist/test/test/tools/preview.test.js.map +0 -1
  357. package/dist/test/test/tools/rename.test.d.ts +0 -2
  358. package/dist/test/test/tools/rename.test.d.ts.map +0 -1
  359. package/dist/test/test/tools/rename.test.js +0 -16
  360. package/dist/test/test/tools/rename.test.js.map +0 -1
  361. package/dist/test/test/tools/save.test.d.ts +0 -2
  362. package/dist/test/test/tools/save.test.d.ts.map +0 -1
  363. package/dist/test/test/tools/save.test.js +0 -137
  364. package/dist/test/test/tools/save.test.js.map +0 -1
  365. package/dist/test/test/tools/schema-best-practices.d.ts +0 -13
  366. package/dist/test/test/tools/schema-best-practices.d.ts.map +0 -1
  367. package/dist/test/test/tools/schema-best-practices.js +0 -169
  368. package/dist/test/test/tools/schema-best-practices.js.map +0 -1
  369. package/dist/test/test/tools/schema-best-practices.test.d.ts +0 -3
  370. package/dist/test/test/tools/schema-best-practices.test.d.ts.map +0 -1
  371. package/dist/test/test/tools/schema-best-practices.test.js +0 -194
  372. package/dist/test/test/tools/schema-best-practices.test.js.map +0 -1
  373. package/dist/test/test/tools/spans.test.d.ts +0 -2
  374. package/dist/test/test/tools/spans.test.d.ts.map +0 -1
  375. package/dist/test/test/tools/spans.test.js +0 -84
  376. package/dist/test/test/tools/spans.test.js.map +0 -1
  377. package/dist/test/test/viewer/broadcaster.test.d.ts +0 -2
  378. package/dist/test/test/viewer/broadcaster.test.d.ts.map +0 -1
  379. package/dist/test/test/viewer/broadcaster.test.js +0 -53
  380. package/dist/test/test/viewer/broadcaster.test.js.map +0 -1
  381. package/dist/test/test/viewer/cesdk-cdn.test.d.ts +0 -2
  382. package/dist/test/test/viewer/cesdk-cdn.test.d.ts.map +0 -1
  383. package/dist/test/test/viewer/cesdk-cdn.test.js +0 -19
  384. package/dist/test/test/viewer/cesdk-cdn.test.js.map +0 -1
  385. package/dist/test/test/viewer/config-route.test.d.ts +0 -2
  386. package/dist/test/test/viewer/config-route.test.d.ts.map +0 -1
  387. package/dist/test/test/viewer/config-route.test.js +0 -28
  388. package/dist/test/test/viewer/config-route.test.js.map +0 -1
  389. package/dist/test/test/viewer/resource-route.test.d.ts +0 -2
  390. package/dist/test/test/viewer/resource-route.test.d.ts.map +0 -1
  391. package/dist/test/test/viewer/resource-route.test.js +0 -70
  392. package/dist/test/test/viewer/resource-route.test.js.map +0 -1
  393. package/dist/test/test/viewer/router.test.d.ts +0 -2
  394. package/dist/test/test/viewer/router.test.d.ts.map +0 -1
  395. package/dist/test/test/viewer/router.test.js +0 -227
  396. package/dist/test/test/viewer/router.test.js.map +0 -1
  397. package/dist/test/test/viewer/session-mount.test.d.ts +0 -2
  398. package/dist/test/test/viewer/session-mount.test.d.ts.map +0 -1
  399. package/dist/test/test/viewer/session-mount.test.js +0 -52
  400. package/dist/test/test/viewer/session-mount.test.js.map +0 -1
  401. package/dist/test/test/viewer/spa-version.test.d.ts +0 -2
  402. package/dist/test/test/viewer/spa-version.test.d.ts.map +0 -1
  403. package/dist/test/test/viewer/spa-version.test.js +0 -14
  404. package/dist/test/test/viewer/spa-version.test.js.map +0 -1
  405. package/dist/test/test/viewer/url-builder.test.d.ts +0 -2
  406. package/dist/test/test/viewer/url-builder.test.d.ts.map +0 -1
  407. package/dist/test/test/viewer/url-builder.test.js +0 -98
  408. package/dist/test/test/viewer/url-builder.test.js.map +0 -1
  409. package/dist/test/test/workspace/content-hash.test.d.ts +0 -2
  410. package/dist/test/test/workspace/content-hash.test.d.ts.map +0 -1
  411. package/dist/test/test/workspace/content-hash.test.js +0 -17
  412. package/dist/test/test/workspace/content-hash.test.js.map +0 -1
  413. package/dist/test/test/workspace/hosted-stub.test.d.ts +0 -2
  414. package/dist/test/test/workspace/hosted-stub.test.d.ts.map +0 -1
  415. package/dist/test/test/workspace/hosted-stub.test.js +0 -30
  416. package/dist/test/test/workspace/hosted-stub.test.js.map +0 -1
  417. package/dist/test/test/workspace/in-memory.test.d.ts +0 -2
  418. package/dist/test/test/workspace/in-memory.test.d.ts.map +0 -1
  419. package/dist/test/test/workspace/in-memory.test.js +0 -4
  420. package/dist/test/test/workspace/in-memory.test.js.map +0 -1
  421. package/dist/test/test/workspace/node-fs.test.d.ts +0 -2
  422. package/dist/test/test/workspace/node-fs.test.d.ts.map +0 -1
  423. package/dist/test/test/workspace/node-fs.test.js +0 -20
  424. package/dist/test/test/workspace/node-fs.test.js.map +0 -1
  425. package/dist/test/test/workspace/s3.test.d.ts +0 -2
  426. package/dist/test/test/workspace/s3.test.d.ts.map +0 -1
  427. package/dist/test/test/workspace/s3.test.js +0 -153
  428. package/dist/test/test/workspace/s3.test.js.map +0 -1
  429. package/dist/test/test/workspace/scoped.test.d.ts +0 -2
  430. package/dist/test/test/workspace/scoped.test.d.ts.map +0 -1
  431. package/dist/test/test/workspace/scoped.test.js +0 -59
  432. package/dist/test/test/workspace/scoped.test.js.map +0 -1
  433. package/dist/test/test/workspace/shared-contract.d.ts +0 -3
  434. package/dist/test/test/workspace/shared-contract.d.ts.map +0 -1
  435. package/dist/test/test/workspace/shared-contract.js +0 -92
  436. package/dist/test/test/workspace/shared-contract.js.map +0 -1
  437. package/dist/test/tsconfig.test.tsbuildinfo +0 -1
  438. package/dist/test/vitest.config.d.ts +0 -3
  439. package/dist/test/vitest.config.d.ts.map +0 -1
  440. package/dist/test/vitest.config.js +0 -8
  441. package/dist/test/vitest.config.js.map +0 -1
  442. package/dist/tools/metrics.d.ts +0 -11
  443. package/dist/tools/metrics.d.ts.map +0 -1
  444. package/dist/tools/metrics.js +0 -28
  445. package/dist/tools/metrics.js.map +0 -1
  446. package/dist/tools/open-editor.d.ts.map +0 -1
  447. package/dist/tools/open-editor.js.map +0 -1
  448. /package/dist/{dashboard → diagnostics}/spa-assets.generated.d.ts +0 -0
@@ -1,227 +0,0 @@
1
- import express from 'express';
2
- import request from 'supertest';
3
- import { describe, expect, it } from 'vitest';
4
- import { RevisionStore } from '../../src/revisions/store.js';
5
- import { SseBroadcaster } from '../../src/viewer/broadcaster.js';
6
- import { createViewerRouter } from '../../src/viewer/router.js';
7
- import { InMemoryWorkspaceFS } from '../../src/workspace/in-memory.js';
8
- async function makeApp() {
9
- const fs = new InMemoryWorkspaceFS();
10
- const store = new RevisionStore(fs);
11
- const broadcaster = new SseBroadcaster();
12
- const app = express();
13
- app.use(createViewerRouter({ store, broadcaster, fs }));
14
- return { app, fs, store, broadcaster };
15
- }
16
- // The HTTP transport mounts the router under "/viewer"; the stdio listener
17
- // mounts it at root. The SPA must address its assets/API relative to the live
18
- // mount path, injected at serve time. This mounts under a prefix to lock that
19
- // in.
20
- async function makeMountedApp(mount) {
21
- const fs = new InMemoryWorkspaceFS();
22
- const store = new RevisionStore(fs);
23
- const broadcaster = new SseBroadcaster();
24
- const app = express();
25
- app.use(mount, createViewerRouter({ store, broadcaster, fs }));
26
- return { app, fs, store, broadcaster };
27
- }
28
- describe('viewer router', () => {
29
- it('GET / serves the studio HTML shell', async () => {
30
- const { app } = await makeApp();
31
- const res = await request(app).get('/');
32
- expect(res.status).toBe(200);
33
- expect(res.headers['content-type']).toMatch(/html/);
34
- expect(res.text).toContain('IMG.LY CODESIGN MCP Workspace');
35
- });
36
- it('GET /d/<root> serves the viewer HTML shell', async () => {
37
- const { app, store } = await makeApp();
38
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
39
- const res = await request(app).get(`/d/${r.id}`);
40
- expect(res.status).toBe(200);
41
- expect(res.headers['content-type']).toMatch(/html/);
42
- expect(res.text).toContain('codesign viewer');
43
- });
44
- it('GET /d/<root>/<rev> serves the viewer HTML shell', async () => {
45
- const { app, store } = await makeApp();
46
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
47
- const res = await request(app).get(`/d/${r.id}/${r.id}`);
48
- expect(res.status).toBe(200);
49
- expect(res.headers['content-type']).toMatch(/html/);
50
- expect(res.text).toContain('codesign viewer');
51
- });
52
- it('GET /s/<rev> is removed — returns 404', async () => {
53
- const { app, store } = await makeApp();
54
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
55
- const res = await request(app).get(`/s/${r.id}`);
56
- expect(res.status).toBe(404);
57
- });
58
- it('GET /static/viewer.js serves the SPA JS', async () => {
59
- const { app } = await makeApp();
60
- const res = await request(app).get('/static/viewer.js');
61
- expect(res.status).toBe(200);
62
- expect(res.headers['content-type']).toMatch(/javascript/);
63
- expect(res.text).toContain('CreativeEditorSDK');
64
- expect(res.text).toContain('setURIResolver');
65
- });
66
- it('GET /static/revision-panel.js serves the panel module', async () => {
67
- const { app } = await makeApp();
68
- const res = await request(app).get('/static/revision-panel.js');
69
- expect(res.status).toBe(200);
70
- expect(res.headers['content-type']).toMatch(/javascript/);
71
- expect(res.text).toContain('createRevisionPanel');
72
- });
73
- it('GET /snapshot/<rev> returns scene + meta + rootRevision', async () => {
74
- const { app, store } = await makeApp();
75
- const r = await store.write({
76
- scene: 'SCENE_BYTES',
77
- parent: null,
78
- title: 'T'
79
- });
80
- const res = await request(app).get(`/snapshot/${r.id}`);
81
- expect(res.status).toBe(200);
82
- expect(res.body).toMatchObject({
83
- scene: 'SCENE_BYTES',
84
- rootRevision: r.id,
85
- title: 'T'
86
- });
87
- });
88
- it('GET /snapshot/<rev> reflects a renamed title (live, not creation-time)', async () => {
89
- const { app, store } = await makeApp();
90
- const r = await store.write({ scene: 'S', parent: null, title: 'Before' });
91
- await store.renameRoot(r.id, 'After');
92
- const res = await request(app).get(`/snapshot/${r.id}`);
93
- expect(res.status).toBe(200);
94
- expect(res.body.title).toBe('After');
95
- });
96
- it('GET /snapshot/<rev>/thumbnail returns the per-revision webp if present', async () => {
97
- const { app, store, fs } = await makeApp();
98
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
99
- const shard = r.id.slice(0, 2);
100
- const rest = r.id.slice(2);
101
- const bytes = new Uint8Array([1, 2, 3, 4]);
102
- await fs.writeFile(`exports/${shard}/${rest}/preview.webp`, bytes);
103
- const res = await request(app).get(`/snapshot/${r.id}/thumbnail`);
104
- expect(res.status).toBe(200);
105
- expect(res.headers['content-type']).toBe('image/webp');
106
- });
107
- it('GET /api/designs returns the root list', async () => {
108
- const { app, store } = await makeApp();
109
- const r = await store.write({ scene: 'S', parent: null, title: 'T1' });
110
- const res = await request(app).get('/api/designs');
111
- expect(res.status).toBe(200);
112
- expect(res.body).toEqual(expect.arrayContaining([
113
- expect.objectContaining({ rootRevision: r.id, title: 'T1' })
114
- ]));
115
- });
116
- it("GET /api/design/<root> returns that design's record", async () => {
117
- const { app, store } = await makeApp();
118
- const r = await store.write({ scene: 'S', parent: null, title: 'T1' });
119
- const res = await request(app).get(`/api/design/${r.id}`);
120
- expect(res.status).toBe(200);
121
- expect(res.body).toMatchObject({
122
- rootRevision: r.id,
123
- title: 'T1',
124
- latestLeaf: r.id
125
- });
126
- });
127
- it('GET /api/design/<unknown> returns 404', async () => {
128
- const { app } = await makeApp();
129
- const res = await request(app).get('/api/design/deadbeefdead');
130
- expect(res.status).toBe(404);
131
- expect(res.body).toEqual({ error: 'unknown design' });
132
- });
133
- it("GET /api/design/<root>/revisions returns the design's revision tree", async () => {
134
- const { app, store } = await makeApp();
135
- const r1 = await store.write({ scene: 'a', parent: null, title: 'T' });
136
- const r2 = await store.write({ scene: 'b', parent: r1.id, note: 'second' });
137
- const fork = await store.write({
138
- scene: 'b2',
139
- parent: r1.id,
140
- note: 'fork'
141
- });
142
- const res = await request(app).get(`/api/design/${r1.id}/revisions`);
143
- expect(res.status).toBe(200);
144
- expect(res.body.map((n) => n.id).sort()).toEqual([r1.id, r2.id, fork.id].sort());
145
- expect(res.body).toEqual(expect.arrayContaining([
146
- expect.objectContaining({ id: r2.id, parent: r1.id, note: 'second' })
147
- ]));
148
- });
149
- it('GET /api/design/<unknown>/revisions returns 404', async () => {
150
- const { app } = await makeApp();
151
- const res = await request(app).get('/api/design/deadbeefdead/revisions');
152
- expect(res.status).toBe(404);
153
- expect(res.body).toEqual({ error: 'unknown design' });
154
- });
155
- it('a /api/design/<root>/revisions error is sanitised to a generic 500', async () => {
156
- const { app, store, fs } = await makeApp();
157
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
158
- await fs.writeFile(`objects/${r.id.slice(0, 2)}/${r.id.slice(2)}.json`, 'not json');
159
- const res = await request(app).get(`/api/design/${r.id}/revisions`);
160
- expect(res.status).toBe(500);
161
- expect(res.text).toBe('internal error');
162
- });
163
- it('GET /snapshot/<unknown> returns 404', async () => {
164
- const { app } = await makeApp();
165
- const res = await request(app).get('/snapshot/deadbeefdead');
166
- expect(res.status).toBe(404);
167
- });
168
- it('GET /api/config includes the /r/ resourceBase', async () => {
169
- const { app } = await makeApp();
170
- const res = await request(app).get('/api/config');
171
- expect(res.status).toBe(200);
172
- expect(res.body.resourceBase).toBe('/r/');
173
- });
174
- it('serves a root-relative SPA base when mounted at root', async () => {
175
- const { app, store } = await makeApp();
176
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
177
- const res = await request(app).get(`/d/${r.id}`);
178
- expect(res.text).toContain("window.__VIEWER_BASE__ = '';");
179
- expect(res.text).toContain('src="/static/viewer.js"');
180
- });
181
- it('injects the mount prefix into the SPA base when mounted at /viewer', async () => {
182
- const { app, store } = await makeMountedApp('/viewer');
183
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
184
- const res = await request(app).get(`/viewer/d/${r.id}`);
185
- expect(res.status).toBe(200);
186
- expect(res.text).toContain("window.__VIEWER_BASE__ = '/viewer';");
187
- expect(res.text).toContain('src="/viewer/static/viewer.js"');
188
- // No leftover unprefixed asset path that would 404 under the mount.
189
- expect(res.text).not.toContain('src="/static/viewer.js"');
190
- });
191
- it('studio shell carries the mount prefix too when mounted at /viewer', async () => {
192
- const { app } = await makeMountedApp('/viewer');
193
- const res = await request(app).get('/viewer/');
194
- expect(res.status).toBe(200);
195
- expect(res.text).toContain("window.__VIEWER_BASE__ = '/viewer';");
196
- expect(res.text).toContain('src="/viewer/static/studio.js"');
197
- });
198
- it('resourceBase is mount-relative when mounted at /viewer', async () => {
199
- const { app } = await makeMountedApp('/viewer');
200
- const res = await request(app).get('/viewer/api/config');
201
- expect(res.status).toBe(200);
202
- expect(res.body.resourceBase).toBe('/viewer/r/');
203
- });
204
- it('serves the SPA JS under the mount prefix', async () => {
205
- const { app } = await makeMountedApp('/viewer');
206
- const res = await request(app).get('/viewer/static/viewer.js');
207
- expect(res.status).toBe(200);
208
- expect(res.headers['content-type']).toMatch(/javascript/);
209
- });
210
- it('GET /r/<asset> is reachable through the viewer router', async () => {
211
- const { app, fs } = await makeApp();
212
- await fs.writeFile('assets/abc.png', new Uint8Array([1, 2, 3]));
213
- const res = await request(app).get('/r/assets/abc.png');
214
- expect(res.status).toBe(200);
215
- });
216
- it('a route error is sanitised to a generic 500 (no leak)', async () => {
217
- const { app, store, fs } = await makeApp();
218
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
219
- // Corrupt the revision meta so store.read throws a non-ENOENT parse error.
220
- await fs.writeFile(`objects/${r.id.slice(0, 2)}/${r.id.slice(2)}.json`, 'not json');
221
- const res = await request(app).get(`/snapshot/${r.id}`);
222
- expect(res.status).toBe(500);
223
- expect(res.text).toBe('internal error');
224
- expect(res.text).not.toContain('not json');
225
- });
226
- });
227
- //# sourceMappingURL=router.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"router.test.js","sourceRoot":"","sources":["../../../../test/viewer/router.test.ts"],"names":[],"mappings":"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","sourcesContent":["import express from 'express';\nimport request from 'supertest';\nimport { describe, expect, it } from 'vitest';\nimport { RevisionStore } from '../../src/revisions/store.js';\nimport { SseBroadcaster } from '../../src/viewer/broadcaster.js';\nimport { createViewerRouter } from '../../src/viewer/router.js';\nimport { InMemoryWorkspaceFS } from '../../src/workspace/in-memory.js';\n\nasync function makeApp() {\n const fs = new InMemoryWorkspaceFS();\n const store = new RevisionStore(fs);\n const broadcaster = new SseBroadcaster();\n const app = express();\n app.use(createViewerRouter({ store, broadcaster, fs }));\n return { app, fs, store, broadcaster };\n}\n\n// The HTTP transport mounts the router under \"/viewer\"; the stdio listener\n// mounts it at root. The SPA must address its assets/API relative to the live\n// mount path, injected at serve time. This mounts under a prefix to lock that\n// in.\nasync function makeMountedApp(mount: string) {\n const fs = new InMemoryWorkspaceFS();\n const store = new RevisionStore(fs);\n const broadcaster = new SseBroadcaster();\n const app = express();\n app.use(mount, createViewerRouter({ store, broadcaster, fs }));\n return { app, fs, store, broadcaster };\n}\n\ndescribe('viewer router', () => {\n it('GET / serves the studio HTML shell', async () => {\n const { app } = await makeApp();\n const res = await request(app).get('/');\n expect(res.status).toBe(200);\n expect(res.headers['content-type']).toMatch(/html/);\n expect(res.text).toContain('IMG.LY CODESIGN MCP Workspace');\n });\n\n it('GET /d/<root> serves the viewer HTML shell', async () => {\n const { app, store } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n const res = await request(app).get(`/d/${r.id}`);\n expect(res.status).toBe(200);\n expect(res.headers['content-type']).toMatch(/html/);\n expect(res.text).toContain('codesign viewer');\n });\n\n it('GET /d/<root>/<rev> serves the viewer HTML shell', async () => {\n const { app, store } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n const res = await request(app).get(`/d/${r.id}/${r.id}`);\n expect(res.status).toBe(200);\n expect(res.headers['content-type']).toMatch(/html/);\n expect(res.text).toContain('codesign viewer');\n });\n\n it('GET /s/<rev> is removed — returns 404', async () => {\n const { app, store } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n const res = await request(app).get(`/s/${r.id}`);\n expect(res.status).toBe(404);\n });\n\n it('GET /static/viewer.js serves the SPA JS', async () => {\n const { app } = await makeApp();\n const res = await request(app).get('/static/viewer.js');\n expect(res.status).toBe(200);\n expect(res.headers['content-type']).toMatch(/javascript/);\n expect(res.text).toContain('CreativeEditorSDK');\n expect(res.text).toContain('setURIResolver');\n });\n\n it('GET /static/revision-panel.js serves the panel module', async () => {\n const { app } = await makeApp();\n const res = await request(app).get('/static/revision-panel.js');\n expect(res.status).toBe(200);\n expect(res.headers['content-type']).toMatch(/javascript/);\n expect(res.text).toContain('createRevisionPanel');\n });\n\n it('GET /snapshot/<rev> returns scene + meta + rootRevision', async () => {\n const { app, store } = await makeApp();\n const r = await store.write({\n scene: 'SCENE_BYTES',\n parent: null,\n title: 'T'\n });\n const res = await request(app).get(`/snapshot/${r.id}`);\n expect(res.status).toBe(200);\n expect(res.body).toMatchObject({\n scene: 'SCENE_BYTES',\n rootRevision: r.id,\n title: 'T'\n });\n });\n\n it('GET /snapshot/<rev> reflects a renamed title (live, not creation-time)', async () => {\n const { app, store } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'Before' });\n await store.renameRoot(r.id, 'After');\n const res = await request(app).get(`/snapshot/${r.id}`);\n expect(res.status).toBe(200);\n expect(res.body.title).toBe('After');\n });\n\n it('GET /snapshot/<rev>/thumbnail returns the per-revision webp if present', async () => {\n const { app, store, fs } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n const shard = r.id.slice(0, 2);\n const rest = r.id.slice(2);\n const bytes = new Uint8Array([1, 2, 3, 4]);\n await fs.writeFile(`exports/${shard}/${rest}/preview.webp`, bytes);\n const res = await request(app).get(`/snapshot/${r.id}/thumbnail`);\n expect(res.status).toBe(200);\n expect(res.headers['content-type']).toBe('image/webp');\n });\n\n it('GET /api/designs returns the root list', async () => {\n const { app, store } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T1' });\n const res = await request(app).get('/api/designs');\n expect(res.status).toBe(200);\n expect(res.body).toEqual(\n expect.arrayContaining([\n expect.objectContaining({ rootRevision: r.id, title: 'T1' })\n ])\n );\n });\n\n it(\"GET /api/design/<root> returns that design's record\", async () => {\n const { app, store } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T1' });\n const res = await request(app).get(`/api/design/${r.id}`);\n expect(res.status).toBe(200);\n expect(res.body).toMatchObject({\n rootRevision: r.id,\n title: 'T1',\n latestLeaf: r.id\n });\n });\n\n it('GET /api/design/<unknown> returns 404', async () => {\n const { app } = await makeApp();\n const res = await request(app).get('/api/design/deadbeefdead');\n expect(res.status).toBe(404);\n expect(res.body).toEqual({ error: 'unknown design' });\n });\n\n it(\"GET /api/design/<root>/revisions returns the design's revision tree\", async () => {\n const { app, store } = await makeApp();\n const r1 = await store.write({ scene: 'a', parent: null, title: 'T' });\n const r2 = await store.write({ scene: 'b', parent: r1.id, note: 'second' });\n const fork = await store.write({\n scene: 'b2',\n parent: r1.id,\n note: 'fork'\n });\n const res = await request(app).get(`/api/design/${r1.id}/revisions`);\n expect(res.status).toBe(200);\n expect(res.body.map((n: { id: string }) => n.id).sort()).toEqual(\n [r1.id, r2.id, fork.id].sort()\n );\n expect(res.body).toEqual(\n expect.arrayContaining([\n expect.objectContaining({ id: r2.id, parent: r1.id, note: 'second' })\n ])\n );\n });\n\n it('GET /api/design/<unknown>/revisions returns 404', async () => {\n const { app } = await makeApp();\n const res = await request(app).get('/api/design/deadbeefdead/revisions');\n expect(res.status).toBe(404);\n expect(res.body).toEqual({ error: 'unknown design' });\n });\n\n it('a /api/design/<root>/revisions error is sanitised to a generic 500', async () => {\n const { app, store, fs } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n await fs.writeFile(\n `objects/${r.id.slice(0, 2)}/${r.id.slice(2)}.json`,\n 'not json'\n );\n const res = await request(app).get(`/api/design/${r.id}/revisions`);\n expect(res.status).toBe(500);\n expect(res.text).toBe('internal error');\n });\n\n it('GET /snapshot/<unknown> returns 404', async () => {\n const { app } = await makeApp();\n const res = await request(app).get('/snapshot/deadbeefdead');\n expect(res.status).toBe(404);\n });\n\n it('GET /api/config includes the /r/ resourceBase', async () => {\n const { app } = await makeApp();\n const res = await request(app).get('/api/config');\n expect(res.status).toBe(200);\n expect(res.body.resourceBase).toBe('/r/');\n });\n\n it('serves a root-relative SPA base when mounted at root', async () => {\n const { app, store } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n const res = await request(app).get(`/d/${r.id}`);\n expect(res.text).toContain(\"window.__VIEWER_BASE__ = '';\");\n expect(res.text).toContain('src=\"/static/viewer.js\"');\n });\n\n it('injects the mount prefix into the SPA base when mounted at /viewer', async () => {\n const { app, store } = await makeMountedApp('/viewer');\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n const res = await request(app).get(`/viewer/d/${r.id}`);\n expect(res.status).toBe(200);\n expect(res.text).toContain(\"window.__VIEWER_BASE__ = '/viewer';\");\n expect(res.text).toContain('src=\"/viewer/static/viewer.js\"');\n // No leftover unprefixed asset path that would 404 under the mount.\n expect(res.text).not.toContain('src=\"/static/viewer.js\"');\n });\n\n it('studio shell carries the mount prefix too when mounted at /viewer', async () => {\n const { app } = await makeMountedApp('/viewer');\n const res = await request(app).get('/viewer/');\n expect(res.status).toBe(200);\n expect(res.text).toContain(\"window.__VIEWER_BASE__ = '/viewer';\");\n expect(res.text).toContain('src=\"/viewer/static/studio.js\"');\n });\n\n it('resourceBase is mount-relative when mounted at /viewer', async () => {\n const { app } = await makeMountedApp('/viewer');\n const res = await request(app).get('/viewer/api/config');\n expect(res.status).toBe(200);\n expect(res.body.resourceBase).toBe('/viewer/r/');\n });\n\n it('serves the SPA JS under the mount prefix', async () => {\n const { app } = await makeMountedApp('/viewer');\n const res = await request(app).get('/viewer/static/viewer.js');\n expect(res.status).toBe(200);\n expect(res.headers['content-type']).toMatch(/javascript/);\n });\n\n it('GET /r/<asset> is reachable through the viewer router', async () => {\n const { app, fs } = await makeApp();\n await fs.writeFile('assets/abc.png', new Uint8Array([1, 2, 3]));\n const res = await request(app).get('/r/assets/abc.png');\n expect(res.status).toBe(200);\n });\n\n it('a route error is sanitised to a generic 500 (no leak)', async () => {\n const { app, store, fs } = await makeApp();\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n // Corrupt the revision meta so store.read throws a non-ENOENT parse error.\n await fs.writeFile(\n `objects/${r.id.slice(0, 2)}/${r.id.slice(2)}.json`,\n 'not json'\n );\n const res = await request(app).get(`/snapshot/${r.id}`);\n expect(res.status).toBe(500);\n expect(res.text).toBe('internal error');\n expect(res.text).not.toContain('not json');\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=session-mount.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-mount.test.d.ts","sourceRoot":"","sources":["../../../../test/viewer/session-mount.test.ts"],"names":[],"mappings":""}
@@ -1,52 +0,0 @@
1
- import express from 'express';
2
- import request from 'supertest';
3
- import { describe, expect, it } from 'vitest';
4
- import { RevisionStore } from '../../src/revisions/store.js';
5
- import { SseBroadcaster } from '../../src/viewer/broadcaster.js';
6
- import { mountSessionViewer } from '../../src/viewer/session-mount.js';
7
- import { InMemoryWorkspaceFS } from '../../src/workspace/in-memory.js';
8
- import { ScopedWorkspaceFS } from '../../src/workspace/scoped.js';
9
- function makeApp() {
10
- const rawFs = new InMemoryWorkspaceFS();
11
- const app = express();
12
- mountSessionViewer(app, {
13
- rawFs,
14
- broadcaster: new SseBroadcaster(),
15
- cesdkLicense: 'lic-123'
16
- });
17
- return { app, rawFs };
18
- }
19
- describe('session viewer mount (/v/:sid)', () => {
20
- it('serves the studio shell with the per-session base injected', async () => {
21
- const { app } = makeApp();
22
- const res = await request(app).get('/v/sid-1/');
23
- expect(res.status).toBe(200);
24
- expect(res.headers['content-type']).toMatch(/html/);
25
- expect(res.text).toContain('/v/sid-1');
26
- });
27
- it('scopes data to the sid: a design in s/<sid> is visible only there', async () => {
28
- const { app, rawFs } = makeApp();
29
- const store = new RevisionStore(new ScopedWorkspaceFS(rawFs, 's/sid-1'));
30
- const r = await store.write({ scene: 'S', parent: null, title: 'T' });
31
- const mine = await request(app).get('/v/sid-1/api/designs');
32
- expect(mine.status).toBe(200);
33
- expect(mine.body.map((d) => d.rootRevision)).toContain(r.id);
34
- const theirs = await request(app).get('/v/sid-2/api/designs');
35
- expect(theirs.status).toBe(200);
36
- expect(theirs.body).toEqual([]);
37
- });
38
- it('serves the license via /api/config', async () => {
39
- const { app } = makeApp();
40
- const res = await request(app).get('/v/sid-1/api/config');
41
- expect(res.status).toBe(200);
42
- expect(res.body.license).toBe('lic-123');
43
- expect(res.body.resourceBase).toBe('/v/sid-1/r/');
44
- });
45
- it('rejects a traversal sid with 404', async () => {
46
- const { app } = makeApp();
47
- // %2E%2E decodes to ".." — sanitizeWorkspaceId must reject it.
48
- const res = await request(app).get('/v/%2E%2E/api/designs');
49
- expect(res.status).toBe(404);
50
- });
51
- });
52
- //# sourceMappingURL=session-mount.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-mount.test.js","sourceRoot":"","sources":["../../../../test/viewer/session-mount.test.ts"],"names":[],"mappings":"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","sourcesContent":["import express from 'express';\nimport request from 'supertest';\nimport { describe, expect, it } from 'vitest';\nimport { RevisionStore } from '../../src/revisions/store.js';\nimport { SseBroadcaster } from '../../src/viewer/broadcaster.js';\nimport { mountSessionViewer } from '../../src/viewer/session-mount.js';\nimport { InMemoryWorkspaceFS } from '../../src/workspace/in-memory.js';\nimport { ScopedWorkspaceFS } from '../../src/workspace/scoped.js';\n\nfunction makeApp() {\n const rawFs = new InMemoryWorkspaceFS();\n const app = express();\n mountSessionViewer(app, {\n rawFs,\n broadcaster: new SseBroadcaster(),\n cesdkLicense: 'lic-123'\n });\n return { app, rawFs };\n}\n\ndescribe('session viewer mount (/v/:sid)', () => {\n it('serves the studio shell with the per-session base injected', async () => {\n const { app } = makeApp();\n const res = await request(app).get('/v/sid-1/');\n expect(res.status).toBe(200);\n expect(res.headers['content-type']).toMatch(/html/);\n expect(res.text).toContain('/v/sid-1');\n });\n\n it('scopes data to the sid: a design in s/<sid> is visible only there', async () => {\n const { app, rawFs } = makeApp();\n const store = new RevisionStore(new ScopedWorkspaceFS(rawFs, 's/sid-1'));\n const r = await store.write({ scene: 'S', parent: null, title: 'T' });\n\n const mine = await request(app).get('/v/sid-1/api/designs');\n expect(mine.status).toBe(200);\n expect(\n mine.body.map((d: { rootRevision: string }) => d.rootRevision)\n ).toContain(r.id);\n\n const theirs = await request(app).get('/v/sid-2/api/designs');\n expect(theirs.status).toBe(200);\n expect(theirs.body).toEqual([]);\n });\n\n it('serves the license via /api/config', async () => {\n const { app } = makeApp();\n const res = await request(app).get('/v/sid-1/api/config');\n expect(res.status).toBe(200);\n expect(res.body.license).toBe('lic-123');\n expect(res.body.resourceBase).toBe('/v/sid-1/r/');\n });\n\n it('rejects a traversal sid with 404', async () => {\n const { app } = makeApp();\n // %2E%2E decodes to \"..\" — sanitizeWorkspaceId must reject it.\n const res = await request(app).get('/v/%2E%2E/api/designs');\n expect(res.status).toBe(404);\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=spa-version.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spa-version.test.d.ts","sourceRoot":"","sources":["../../../../test/viewer/spa-version.test.ts"],"names":[],"mappings":""}
@@ -1,14 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { fileURLToPath } from 'node:url';
3
- import { describe, expect, it } from 'vitest';
4
- const viewerSrc = readFileSync(fileURLToPath(new URL('../../src/viewer/spa/viewer.js', import.meta.url)), 'utf8');
5
- describe('viewer SPA CE.SDK loading', () => {
6
- it('does not hardcode a cesdk-js version', () => {
7
- expect(viewerSrc).not.toMatch(/cesdk-js\/\d+\.\d+\.\d+/);
8
- });
9
- it('imports the server-supplied cesdkEngineUrl', () => {
10
- expect(viewerSrc).toMatch(/cesdkEngineUrl/);
11
- expect(viewerSrc).toMatch(/await import\(\s*cesdkEngineUrl\s*\)/);
12
- });
13
- });
14
- //# sourceMappingURL=spa-version.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spa-version.test.js","sourceRoot":"","sources":["../../../../test/viewer/spa-version.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,MAAM,SAAS,GAAG,YAAY,CAC5B,aAAa,CAAC,IAAI,GAAG,CAAC,gCAAgC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACzE,MAAM,CACP,CAAC;AAEF,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { describe, expect, it } from 'vitest';\n\nconst viewerSrc = readFileSync(\n fileURLToPath(new URL('../../src/viewer/spa/viewer.js', import.meta.url)),\n 'utf8'\n);\n\ndescribe('viewer SPA CE.SDK loading', () => {\n it('does not hardcode a cesdk-js version', () => {\n expect(viewerSrc).not.toMatch(/cesdk-js\\/\\d+\\.\\d+\\.\\d+/);\n });\n it('imports the server-supplied cesdkEngineUrl', () => {\n expect(viewerSrc).toMatch(/cesdkEngineUrl/);\n expect(viewerSrc).toMatch(/await import\\(\\s*cesdkEngineUrl\\s*\\)/);\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=url-builder.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"url-builder.test.d.ts","sourceRoot":"","sources":["../../../../test/viewer/url-builder.test.ts"],"names":[],"mappings":""}
@@ -1,98 +0,0 @@
1
- import { S3Client } from '@aws-sdk/client-s3';
2
- import { describe, expect, it } from 'vitest';
3
- import { LocalViewerUrlBuilder, viewerBaseFor } from '../../src/viewer/url-builder.js';
4
- import { PresignedR2UrlBuilder } from '../../src/viewer/presigned-r2-url-builder.js';
5
- describe('LocalViewerUrlBuilder', () => {
6
- it('builds /d/<root> design URLs against the listener base', () => {
7
- const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });
8
- expect(b.forDesign('abc123def456')).toBe('http://127.0.0.1:8745/d/abc123def456');
9
- });
10
- it('builds /d/<root>/<rev> pinned-revision URLs', () => {
11
- const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });
12
- expect(b.forPinnedRevision('abc123def456', '0011deadbeef')).toBe('http://127.0.0.1:8745/d/abc123def456/0011deadbeef');
13
- });
14
- it('builds the studio landing URL', () => {
15
- const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });
16
- expect(b.forStudio()).toBe('http://127.0.0.1:8745/');
17
- });
18
- it('builds /r/<relpath> resource URLs against the listener base', () => {
19
- const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });
20
- expect(b.forResource('assets/9f2a1c.png')).toBe('http://127.0.0.1:8745/r/assets/9f2a1c.png');
21
- });
22
- it('forDownload resolves to the same URL as forResource', async () => {
23
- const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });
24
- const relpath = 'exports/ab/cd1234/image.png';
25
- await expect(b.forDownload(relpath)).resolves.toBe(b.forResource(relpath));
26
- });
27
- });
28
- describe('viewerBaseFor', () => {
29
- it('session mode + public base → /v/<sid> on the public origin', () => {
30
- expect(viewerBaseFor({
31
- publicBaseUrl: 'https://codesign.example.com',
32
- port: 8080,
33
- mode: 'session',
34
- sessionId: 'abc-123'
35
- })).toBe('https://codesign.example.com/v/abc-123');
36
- });
37
- it('session mode without public base → loopback /v/<sid>', () => {
38
- expect(viewerBaseFor({
39
- publicBaseUrl: undefined,
40
- port: 8745,
41
- mode: 'session',
42
- sessionId: 'abc-123'
43
- })).toBe('http://127.0.0.1:8745/v/abc-123');
44
- });
45
- it('single mode → /viewer (the fixed-workspace mount)', () => {
46
- expect(viewerBaseFor({
47
- publicBaseUrl: undefined,
48
- port: 8745,
49
- mode: 'single',
50
- sessionId: 'abc-123'
51
- })).toBe('http://127.0.0.1:8745/viewer');
52
- });
53
- });
54
- describe('PresignedR2UrlBuilder', () => {
55
- // getSignedUrl from @aws-sdk/s3-request-presigner signs locally — no network
56
- // call is made. We use dummy credentials and a fake R2 endpoint.
57
- const client = new S3Client({
58
- region: 'auto',
59
- endpoint: 'https://accountid.r2.cloudflarestorage.com',
60
- forcePathStyle: true,
61
- credentials: { accessKeyId: 'test', secretAccessKey: 'test' }
62
- });
63
- const workspaceId = 'ws-test-001';
64
- const builder = new PresignedR2UrlBuilder({
65
- base: 'http://127.0.0.1:8745',
66
- client,
67
- bucket: 'codesign-bucket',
68
- workspaceId,
69
- expiresIn: 300
70
- });
71
- it('forDownload returns a presigned URL containing the workspace-scoped R2 key', async () => {
72
- const relpath = 'exports/ab/cd1234ef/scene.scene';
73
- const url = await builder.forDownload(relpath);
74
- // The full key must appear as one ordered, contiguous path segment —
75
- // workspaces/<workspaceId>/<relpath> — not just the fragments in any order.
76
- // R2 keys aren't percent-encoded for these chars, so assert the exact path.
77
- expect(url).toContain(`workspaces/${workspaceId}/${relpath}`);
78
- });
79
- it('forDownload URL contains X-Amz-Signature (proves it is presigned)', async () => {
80
- const url = await builder.forDownload('exports/ab/cd/image.png');
81
- expect(url).toContain('X-Amz-Signature');
82
- });
83
- it('inherits sync forResource from LocalViewerUrlBuilder unchanged', () => {
84
- expect(builder.forResource('assets/9f2a1c.png')).toBe('http://127.0.0.1:8745/r/assets/9f2a1c.png');
85
- });
86
- it('forDownload with default expiresIn (3600) also signs', async () => {
87
- const b = new PresignedR2UrlBuilder({
88
- base: 'http://127.0.0.1:8745',
89
- client,
90
- bucket: 'codesign-bucket',
91
- workspaceId: 'ws-default'
92
- });
93
- const url = await b.forDownload('exports/11/22/design.scene');
94
- expect(url).toContain('X-Amz-Signature');
95
- expect(url).toContain('ws-default');
96
- });
97
- });
98
- //# sourceMappingURL=url-builder.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"url-builder.test.js","sourceRoot":"","sources":["../../../../test/viewer/url-builder.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { S3Client } from '@aws-sdk/client-s3';\nimport { describe, expect, it } from 'vitest';\nimport {\n LocalViewerUrlBuilder,\n viewerBaseFor\n} from '../../src/viewer/url-builder.js';\nimport { PresignedR2UrlBuilder } from '../../src/viewer/presigned-r2-url-builder.js';\n\ndescribe('LocalViewerUrlBuilder', () => {\n it('builds /d/<root> design URLs against the listener base', () => {\n const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });\n expect(b.forDesign('abc123def456')).toBe(\n 'http://127.0.0.1:8745/d/abc123def456'\n );\n });\n\n it('builds /d/<root>/<rev> pinned-revision URLs', () => {\n const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });\n expect(b.forPinnedRevision('abc123def456', '0011deadbeef')).toBe(\n 'http://127.0.0.1:8745/d/abc123def456/0011deadbeef'\n );\n });\n\n it('builds the studio landing URL', () => {\n const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });\n expect(b.forStudio()).toBe('http://127.0.0.1:8745/');\n });\n\n it('builds /r/<relpath> resource URLs against the listener base', () => {\n const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });\n expect(b.forResource('assets/9f2a1c.png')).toBe(\n 'http://127.0.0.1:8745/r/assets/9f2a1c.png'\n );\n });\n\n it('forDownload resolves to the same URL as forResource', async () => {\n const b = new LocalViewerUrlBuilder({ base: 'http://127.0.0.1:8745' });\n const relpath = 'exports/ab/cd1234/image.png';\n await expect(b.forDownload(relpath)).resolves.toBe(b.forResource(relpath));\n });\n});\n\ndescribe('viewerBaseFor', () => {\n it('session mode + public base → /v/<sid> on the public origin', () => {\n expect(\n viewerBaseFor({\n publicBaseUrl: 'https://codesign.example.com',\n port: 8080,\n mode: 'session',\n sessionId: 'abc-123'\n })\n ).toBe('https://codesign.example.com/v/abc-123');\n });\n\n it('session mode without public base → loopback /v/<sid>', () => {\n expect(\n viewerBaseFor({\n publicBaseUrl: undefined,\n port: 8745,\n mode: 'session',\n sessionId: 'abc-123'\n })\n ).toBe('http://127.0.0.1:8745/v/abc-123');\n });\n\n it('single mode → /viewer (the fixed-workspace mount)', () => {\n expect(\n viewerBaseFor({\n publicBaseUrl: undefined,\n port: 8745,\n mode: 'single',\n sessionId: 'abc-123'\n })\n ).toBe('http://127.0.0.1:8745/viewer');\n });\n});\n\ndescribe('PresignedR2UrlBuilder', () => {\n // getSignedUrl from @aws-sdk/s3-request-presigner signs locally — no network\n // call is made. We use dummy credentials and a fake R2 endpoint.\n const client = new S3Client({\n region: 'auto',\n endpoint: 'https://accountid.r2.cloudflarestorage.com',\n forcePathStyle: true,\n credentials: { accessKeyId: 'test', secretAccessKey: 'test' }\n });\n const workspaceId = 'ws-test-001';\n const builder = new PresignedR2UrlBuilder({\n base: 'http://127.0.0.1:8745',\n client,\n bucket: 'codesign-bucket',\n workspaceId,\n expiresIn: 300\n });\n\n it('forDownload returns a presigned URL containing the workspace-scoped R2 key', async () => {\n const relpath = 'exports/ab/cd1234ef/scene.scene';\n const url = await builder.forDownload(relpath);\n // The full key must appear as one ordered, contiguous path segment —\n // workspaces/<workspaceId>/<relpath> — not just the fragments in any order.\n // R2 keys aren't percent-encoded for these chars, so assert the exact path.\n expect(url).toContain(`workspaces/${workspaceId}/${relpath}`);\n });\n\n it('forDownload URL contains X-Amz-Signature (proves it is presigned)', async () => {\n const url = await builder.forDownload('exports/ab/cd/image.png');\n expect(url).toContain('X-Amz-Signature');\n });\n\n it('inherits sync forResource from LocalViewerUrlBuilder unchanged', () => {\n expect(builder.forResource('assets/9f2a1c.png')).toBe(\n 'http://127.0.0.1:8745/r/assets/9f2a1c.png'\n );\n });\n\n it('forDownload with default expiresIn (3600) also signs', async () => {\n const b = new PresignedR2UrlBuilder({\n base: 'http://127.0.0.1:8745',\n client,\n bucket: 'codesign-bucket',\n workspaceId: 'ws-default'\n });\n const url = await b.forDownload('exports/11/22/design.scene');\n expect(url).toContain('X-Amz-Signature');\n expect(url).toContain('ws-default');\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=content-hash.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"content-hash.test.d.ts","sourceRoot":"","sources":["../../../../test/workspace/content-hash.test.ts"],"names":[],"mappings":""}
@@ -1,17 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { shortHash } from '../../src/workspace/content-hash.js';
3
- describe('shortHash', () => {
4
- it('returns the first 6 bytes of SHA-256 as 12 hex chars', async () => {
5
- // SHA-256("") = e3b0c44298fc1c14…
6
- expect(await shortHash(new Uint8Array())).toBe('e3b0c44298fc');
7
- });
8
- it('is deterministic and content-sensitive', async () => {
9
- const a = await shortHash(new Uint8Array([1, 2, 3]));
10
- const b = await shortHash(new Uint8Array([1, 2, 3]));
11
- const c = await shortHash(new Uint8Array([1, 2, 4]));
12
- expect(a).toBe(b);
13
- expect(a).not.toBe(c);
14
- expect(a).toMatch(/^[0-9a-f]{12}$/);
15
- });
16
- });
17
- //# sourceMappingURL=content-hash.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"content-hash.test.js","sourceRoot":"","sources":["../../../../test/workspace/content-hash.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAEhE,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,kCAAkC;QAClC,MAAM,CAAC,MAAM,SAAS,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { shortHash } from '../../src/workspace/content-hash.js';\n\ndescribe('shortHash', () => {\n it('returns the first 6 bytes of SHA-256 as 12 hex chars', async () => {\n // SHA-256(\"\") = e3b0c44298fc1c14…\n expect(await shortHash(new Uint8Array())).toBe('e3b0c44298fc');\n });\n\n it('is deterministic and content-sensitive', async () => {\n const a = await shortHash(new Uint8Array([1, 2, 3]));\n const b = await shortHash(new Uint8Array([1, 2, 3]));\n const c = await shortHash(new Uint8Array([1, 2, 4]));\n expect(a).toBe(b);\n expect(a).not.toBe(c);\n expect(a).toMatch(/^[0-9a-f]{12}$/);\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=hosted-stub.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hosted-stub.test.d.ts","sourceRoot":"","sources":["../../../../test/workspace/hosted-stub.test.ts"],"names":[],"mappings":""}
@@ -1,30 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { HostedStubWorkspaceFS } from '../../src/workspace/hosted-stub.js';
3
- describe('HostedStubWorkspaceFS', () => {
4
- it("every method throws ENOSYS with a 'Phase 2' message", async () => {
5
- const fs = new HostedStubWorkspaceFS({ account: 'acct_123' });
6
- for (const op of [
7
- () => fs.readFile('x'),
8
- () => fs.writeFile('x', 'y'),
9
- () => fs.stat('x'),
10
- () => fs.readdir('x'),
11
- () => fs.mkdir('x'),
12
- () => fs.rm('x'),
13
- () => fs.rename('x', 'y')
14
- ]) {
15
- await expect(op()).rejects.toMatchObject({
16
- code: 'ENOSYS',
17
- message: expect.stringContaining('Phase 2')
18
- });
19
- }
20
- });
21
- it('exists returns false (so flow can branch without throwing)', async () => {
22
- const fs = new HostedStubWorkspaceFS({ account: 'acct_123' });
23
- expect(await fs.exists('anything')).toBe(false);
24
- });
25
- it('carries the account id for routing', () => {
26
- const fs = new HostedStubWorkspaceFS({ account: 'acct_xyz' });
27
- expect(fs.account).toBe('acct_xyz');
28
- });
29
- });
30
- //# sourceMappingURL=hosted-stub.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hosted-stub.test.js","sourceRoot":"","sources":["../../../../test/workspace/hosted-stub.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAE3E,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,EAAE,GAAG,IAAI,qBAAqB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAC9D,KAAK,MAAM,EAAE,IAAI;YACf,GAAG,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;YACtB,GAAG,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;YAC5B,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;YAClB,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;YACrB,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC;YACnB,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC;YAChB,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC;SAC1B,EAAE,CAAC;YACF,MAAM,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBACvC,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC;aAC5C,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,EAAE,GAAG,IAAI,qBAAqB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,EAAE,GAAG,IAAI,qBAAqB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { HostedStubWorkspaceFS } from '../../src/workspace/hosted-stub.js';\n\ndescribe('HostedStubWorkspaceFS', () => {\n it(\"every method throws ENOSYS with a 'Phase 2' message\", async () => {\n const fs = new HostedStubWorkspaceFS({ account: 'acct_123' });\n for (const op of [\n () => fs.readFile('x'),\n () => fs.writeFile('x', 'y'),\n () => fs.stat('x'),\n () => fs.readdir('x'),\n () => fs.mkdir('x'),\n () => fs.rm('x'),\n () => fs.rename('x', 'y')\n ]) {\n await expect(op()).rejects.toMatchObject({\n code: 'ENOSYS',\n message: expect.stringContaining('Phase 2')\n });\n }\n });\n\n it('exists returns false (so flow can branch without throwing)', async () => {\n const fs = new HostedStubWorkspaceFS({ account: 'acct_123' });\n expect(await fs.exists('anything')).toBe(false);\n });\n\n it('carries the account id for routing', () => {\n const fs = new HostedStubWorkspaceFS({ account: 'acct_xyz' });\n expect(fs.account).toBe('acct_xyz');\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=in-memory.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"in-memory.test.d.ts","sourceRoot":"","sources":["../../../../test/workspace/in-memory.test.ts"],"names":[],"mappings":""}
@@ -1,4 +0,0 @@
1
- import { InMemoryWorkspaceFS } from '../../src/workspace/in-memory.js';
2
- import { runWorkspaceContract } from './shared-contract.js';
3
- runWorkspaceContract('InMemoryWorkspaceFS', () => new InMemoryWorkspaceFS());
4
- //# sourceMappingURL=in-memory.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"in-memory.test.js","sourceRoot":"","sources":["../../../../test/workspace/in-memory.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,oBAAoB,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,IAAI,mBAAmB,EAAE,CAAC,CAAC","sourcesContent":["import { InMemoryWorkspaceFS } from '../../src/workspace/in-memory.js';\nimport { runWorkspaceContract } from './shared-contract.js';\n\nrunWorkspaceContract('InMemoryWorkspaceFS', () => new InMemoryWorkspaceFS());\n"]}