@jxsuite/studio 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-799jpvhm.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-799jpvhm.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-8jxwts2p.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-gs6kqdt1.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-gs6kqdt1.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-esrewxap.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-v7jkjqng.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-jm0z592w.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +21080 -32585
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +7 -0
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +221 -245
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -53
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +30 -1
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +7 -1
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qr3drkkw.js +0 -531
  363. package/dist/chunks/extension-sections-qr3drkkw.js.map +0 -12
  364. package/dist/chunks/files-j8a1t06k.js +0 -50
  365. package/dist/chunks/files-j8a1t06k.js.map +0 -9
  366. package/dist/chunks/git-panel-xtq5z81x.js +0 -28
  367. package/dist/chunks/git-panel-xtq5z81x.js.map +0 -9
  368. package/dist/chunks/layers-panel-ancn2wpq.js +0 -26
  369. package/dist/chunks/layers-panel-ancn2wpq.js.map +0 -9
  370. package/dist/chunks/settings-modal-17ttr96g.js +0 -29
  371. package/dist/chunks/settings-modal-17ttr96g.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-0xgs7xrs.js +0 -429
  381. package/dist/chunks/studio-0xgs7xrs.js.map +0 -13
  382. package/dist/chunks/studio-4d8hzcz5.js +0 -3427
  383. package/dist/chunks/studio-4d8hzcz5.js.map +0 -26
  384. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  385. package/dist/chunks/studio-9smfzqhc.js +0 -19
  386. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  387. package/dist/chunks/studio-jm0z592w.js.map +0 -115
  388. package/dist/chunks/studio-m2t4mdg5.js +0 -1854
  389. package/dist/chunks/studio-m2t4mdg5.js.map +0 -18
  390. package/dist/chunks/studio-n4p11dfy.js +0 -853
  391. package/dist/chunks/studio-n4p11dfy.js.map +0 -12
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-sjh1wt1a.js +0 -3744
  394. package/dist/chunks/studio-sjh1wt1a.js.map +0 -22
  395. package/dist/chunks/studio-v7jkjqng.js.map +0 -46
  396. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  397. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  398. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  399. package/dist/chunks/studio-yfcstdzy.js +0 -399
  400. package/dist/chunks/studio-yfcstdzy.js.map +0 -12
  401. package/dist/chunks/studio-zp7jncs8.js +0 -469
  402. package/dist/chunks/studio-zp7jncs8.js.map +0 -14
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-8jxwts2p.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-esrewxap.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
@@ -0,0 +1,1000 @@
1
+ import {
2
+ cellToText,
3
+ coerceCellInput,
4
+ collectionDirs,
5
+ columnsFromSchema,
6
+ createCollectionSource,
7
+ createGridController,
8
+ createPagesSource,
9
+ inferColumnsFromRows,
10
+ isRecentLocal,
11
+ makeGridTabId,
12
+ markLocalMutation
13
+ } from "./studio-k2sxjph5.js";
14
+ import {
15
+ MEDIA_EXTENSIONS,
16
+ extensionOf
17
+ } from "./studio-f12h6177.js";
18
+ import {
19
+ activateTab,
20
+ argsSchema,
21
+ errorMessage,
22
+ findContentTypeSchema,
23
+ openModal,
24
+ openTab,
25
+ optionalStringArg,
26
+ resolveI18n,
27
+ servedLocaleOfPath,
28
+ stringArg,
29
+ stringProperty,
30
+ workspace
31
+ } from "./studio-41exgzhq.js";
32
+ import {
33
+ html
34
+ } from "./studio-5x5774ak.js";
35
+ import {
36
+ projectState
37
+ } from "./studio-cjm7fdjf.js";
38
+ import {
39
+ formatForPath,
40
+ loadFormats
41
+ } from "./studio-adn0z1k3.js";
42
+ import {
43
+ getPlatform
44
+ } from "./studio-sas7mt3k.js";
45
+
46
+ // src/services/data-service.ts
47
+ function platformOrNull() {
48
+ try {
49
+ return getPlatform();
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+ function dataSurfaceAvailable() {
55
+ return typeof platformOrNull()?.dataRows === "function";
56
+ }
57
+ async function fetchConnections() {
58
+ const platform = platformOrNull();
59
+ if (typeof platform?.dataConnections !== "function") {
60
+ return null;
61
+ }
62
+ return platform.dataConnections();
63
+ }
64
+ async function testConnection(connection) {
65
+ const platform = platformOrNull();
66
+ if (typeof platform?.dataConnectionTest !== "function") {
67
+ return { error: "Connection tests are not supported by this backend", ok: false };
68
+ }
69
+ try {
70
+ return await platform.dataConnectionTest(connection);
71
+ } catch (error) {
72
+ return { error: error instanceof Error ? error.message : String(error), ok: false };
73
+ }
74
+ }
75
+ async function pushSchema(opts) {
76
+ const platform = platformOrNull();
77
+ if (typeof platform?.dataPush !== "function") {
78
+ return { applied: false, errors: ["Schema push is not supported by this backend"], plan: [] };
79
+ }
80
+ try {
81
+ return await platform.dataPush(opts);
82
+ } catch (error) {
83
+ return {
84
+ applied: false,
85
+ errors: [error instanceof Error ? error.message : String(error)],
86
+ plan: []
87
+ };
88
+ }
89
+ }
90
+ function requireMember(name) {
91
+ const platform = platformOrNull();
92
+ const member = platform?.[name];
93
+ if (member === undefined || member === null) {
94
+ throw new Error(`The ${String(name)} surface is not supported by this backend`);
95
+ }
96
+ return member;
97
+ }
98
+ function fetchRows(query) {
99
+ return requireMember("dataRows")(query);
100
+ }
101
+ function insertRow(req) {
102
+ return requireMember("dataInsertRow")(req);
103
+ }
104
+ function updateRow(req) {
105
+ return requireMember("dataUpdateRow")(req);
106
+ }
107
+ function deleteRow(req) {
108
+ return requireMember("dataDeleteRow")(req);
109
+ }
110
+ function deriveSecretEnvName(sectionKey, entryKey, fieldKey) {
111
+ const constant = (raw) => raw.replaceAll(/([a-z0-9])([A-Z])/g, "$1_$2").replaceAll(/[^A-Za-z0-9]+/g, "_").replaceAll(/^_+|_+$/g, "").toUpperCase();
112
+ const parts = [entryKey ?? sectionKey, fieldKey.replace(/Env$/, "")].map((part) => constant(part)).filter(Boolean);
113
+ const name = parts.join("_") || "SECRET";
114
+ return /^\d/.test(name) ? `JX_${name}` : name;
115
+ }
116
+
117
+ // src/grid/csv-codec.ts
118
+ function splitRecords(text) {
119
+ const records = [];
120
+ let fields = [];
121
+ let field = "";
122
+ let inQuotes = false;
123
+ let fieldStarted = false;
124
+ const endField = () => {
125
+ fields.push(field);
126
+ field = "";
127
+ fieldStarted = false;
128
+ };
129
+ const endRecord = () => {
130
+ endField();
131
+ if (fields.length === 1 && fields[0] === "") {
132
+ fields = [];
133
+ return;
134
+ }
135
+ records.push(fields);
136
+ fields = [];
137
+ };
138
+ for (let i = 0;i < text.length; i++) {
139
+ const ch = text[i];
140
+ if (inQuotes) {
141
+ if (ch === '"') {
142
+ if (text[i + 1] === '"') {
143
+ field += '"';
144
+ i += 1;
145
+ } else {
146
+ inQuotes = false;
147
+ }
148
+ } else {
149
+ field += ch;
150
+ }
151
+ continue;
152
+ }
153
+ if (ch === '"' && !fieldStarted) {
154
+ inQuotes = true;
155
+ fieldStarted = true;
156
+ } else if (ch === '"') {
157
+ field += ch;
158
+ } else if (ch === ",") {
159
+ endField();
160
+ } else if (ch === `
161
+ `) {
162
+ endRecord();
163
+ } else if (ch === "\r") {
164
+ if (text[i + 1] === `
165
+ `) {
166
+ i += 1;
167
+ }
168
+ endRecord();
169
+ } else {
170
+ field += ch;
171
+ fieldStarted = true;
172
+ }
173
+ }
174
+ if (field !== "" || fields.length > 0) {
175
+ endRecord();
176
+ }
177
+ return records;
178
+ }
179
+ function parseCsv(text) {
180
+ const crlf = (text.match(/\r\n/g) ?? []).length;
181
+ const bareLf = (text.match(/(?<!\r)\n/g) ?? []).length;
182
+ const eol = crlf > bareLf ? `\r
183
+ ` : `
184
+ `;
185
+ const trailingNewline = text.endsWith(`
186
+ `);
187
+ const records = splitRecords(text);
188
+ const headers = records[0] ?? [];
189
+ const rows = records.slice(1);
190
+ const width = Math.max(headers.length, ...rows.map((r) => r.length), 0);
191
+ while (headers.length < width) {
192
+ headers.push("");
193
+ }
194
+ for (const row of rows) {
195
+ while (row.length < width) {
196
+ row.push("");
197
+ }
198
+ }
199
+ return { eol, headers, rows, trailingNewline };
200
+ }
201
+ function encodeField(value) {
202
+ if (/[",\n\r]/.test(value)) {
203
+ return `"${value.replaceAll('"', '""')}"`;
204
+ }
205
+ return value;
206
+ }
207
+ function serializeCsv(doc) {
208
+ const lines = [doc.headers, ...doc.rows].map((fields) => fields.map((field) => encodeField(field)).join(","));
209
+ return lines.join(doc.eol) + (doc.trailingNewline ? doc.eol : "");
210
+ }
211
+
212
+ // src/grid/sources/csv-file-source.ts
213
+ var ID_FIELDS = ["id", "sku", "slug", "Slug"];
214
+ function fieldNamesForHeaders(headers) {
215
+ const used = new Set;
216
+ return headers.map((header, i) => {
217
+ let name = header.trim() === "" ? `column${i + 1}` : header;
218
+ if (used.has(name)) {
219
+ name = `${name}__${i + 1}`;
220
+ }
221
+ used.add(name);
222
+ return name;
223
+ });
224
+ }
225
+ function pickIdField(fields, doc) {
226
+ for (const candidate of ID_FIELDS) {
227
+ const idx = fields.indexOf(candidate);
228
+ if (idx === -1) {
229
+ continue;
230
+ }
231
+ const values = doc.rows.map((row) => row[idx] ?? "");
232
+ if (values.every((v) => v !== "") && new Set(values).size === values.length) {
233
+ return candidate;
234
+ }
235
+ }
236
+ return null;
237
+ }
238
+ function buildModel(text, path) {
239
+ const doc = parseCsv(text);
240
+ const fields = fieldNamesForHeaders(doc.headers);
241
+ const idField = pickIdField(fields, doc);
242
+ const idIndex = idField ? fields.indexOf(idField) : -1;
243
+ const keys = doc.rows.map((row, i) => idIndex === -1 ? String(i) : row[idIndex]);
244
+ const keyToIndex = new Map(keys.map((key, i) => [key, i]));
245
+ const contentType = findContentTypeSchema(path, projectState?.projectConfig);
246
+ const schemaProps = contentType?.schema?.properties ?? {};
247
+ const sampleRows = doc.rows.slice(0, 50).map((row) => {
248
+ const cells = {};
249
+ for (const [i, field] of fields.entries()) {
250
+ cells[field] = row[i] ?? "";
251
+ }
252
+ return cells;
253
+ });
254
+ const inferred = new Map(inferColumnsFromRows(sampleRows).map((c) => [c.field, c]));
255
+ const typed = new Map(columnsFromSchema(contentType?.schema, { idField: idField ?? undefined }).map((c) => [
256
+ c.field,
257
+ c
258
+ ]));
259
+ const columns = fields.map((field, i) => {
260
+ const fromSchema = field in schemaProps ? typed.get(field) : undefined;
261
+ const column = fromSchema ?? inferred.get(field) ?? {
262
+ editable: true,
263
+ field,
264
+ kind: "string",
265
+ title: doc.headers[i] || field
266
+ };
267
+ return { ...column, pk: field === idField, title: doc.headers[i]?.trim() || column.title };
268
+ });
269
+ return { columns, doc, fields, keys, keyToIndex, loadText: text };
270
+ }
271
+ function rowCells(model, rowIndex) {
272
+ const cells = {};
273
+ const row = model.doc.rows[rowIndex] ?? [];
274
+ for (const [i, field] of model.fields.entries()) {
275
+ const column = model.columns[i];
276
+ const raw = row[i] ?? "";
277
+ cells[field] = column.kind === "string" || column.kind === "text" || column.kind === "readonly" ? raw : coerceCellInput(raw, column);
278
+ }
279
+ return cells;
280
+ }
281
+ function applyBatch(model, batch) {
282
+ const rows = model.doc.rows.map((row) => [...row]);
283
+ const colFor = (field) => model.fields.indexOf(field);
284
+ for (const cell of batch.cells) {
285
+ const rowIndex = model.keyToIndex.get(cell.rowKey);
286
+ const colIndex = colFor(cell.field);
287
+ if (rowIndex === undefined || colIndex === -1) {
288
+ continue;
289
+ }
290
+ rows[rowIndex][colIndex] = cellToText(cell.value);
291
+ }
292
+ for (const insert of batch.inserts) {
293
+ const row = model.fields.map((field) => cellToText(insert.cells[field] ?? null));
294
+ rows.push(row);
295
+ }
296
+ const dropIndexes = batch.deletes.map((del) => model.keyToIndex.get(del.rowKey)).filter((i) => i !== undefined).toSorted((a, b) => b - a);
297
+ for (const index of dropIndexes) {
298
+ rows.splice(index, 1);
299
+ }
300
+ return { ...model.doc, rows };
301
+ }
302
+ function uniformResult(batch, outcome) {
303
+ return {
304
+ cells: batch.cells.map((c) => ({ field: c.field, rowKey: c.rowKey, ...outcome })),
305
+ deletes: batch.deletes.map((d) => ({ rowKey: d.rowKey, ...outcome })),
306
+ inserts: batch.inserts.map((i) => ({
307
+ error: outcome.error,
308
+ ok: outcome.ok,
309
+ tempKey: i.tempKey
310
+ }))
311
+ };
312
+ }
313
+ function createCsvFileSource(path) {
314
+ let loadPromise = null;
315
+ const load = (force = false) => {
316
+ if (!force && loadPromise) {
317
+ return loadPromise;
318
+ }
319
+ loadPromise = getPlatform().readFile(path).then((text) => buildModel(text, path));
320
+ return loadPromise;
321
+ };
322
+ return {
323
+ backingPaths: () => new Map([[path, "*"]]),
324
+ capabilities: { delete: true, insert: true, remotePaging: false, remoteSort: false },
325
+ async columns() {
326
+ const current = await load();
327
+ return current.columns;
328
+ },
329
+ async commit(batch) {
330
+ const current = await load();
331
+ const platform = getPlatform();
332
+ let onDisk = null;
333
+ try {
334
+ onDisk = await platform.readFile(path);
335
+ } catch {
336
+ onDisk = null;
337
+ }
338
+ if (onDisk !== current.loadText && !isRecentLocal(path)) {
339
+ return uniformResult(batch, {
340
+ error: "File changed on disk — refresh to reload",
341
+ ok: false,
342
+ stale: true
343
+ });
344
+ }
345
+ const nextDoc = applyBatch(current, batch);
346
+ const text = serializeCsv(nextDoc);
347
+ markLocalMutation(path);
348
+ await platform.writeFile(path, text);
349
+ loadPromise = Promise.resolve(buildModel(text, path));
350
+ return uniformResult(batch, { ok: true });
351
+ },
352
+ id: path,
353
+ label: path.split("/").pop() ?? path,
354
+ async refresh() {
355
+ await load(true);
356
+ },
357
+ async rows() {
358
+ const current = await load();
359
+ const rows = current.doc.rows.map((_, i) => ({
360
+ cells: rowCells(current, i),
361
+ key: current.keys[i]
362
+ }));
363
+ return { rows, total: rows.length };
364
+ },
365
+ async serializeForSource(batch) {
366
+ const current = await load();
367
+ return serializeCsv(applyBatch(current, batch));
368
+ }
369
+ };
370
+ }
371
+
372
+ // src/grid/sources/connector-source.ts
373
+ var DATA_PAGE_SIZE = 50;
374
+ function kindForSqlType(type) {
375
+ const t = type.toLowerCase();
376
+ if (/(int|real|floa|doub|num|dec)/.test(t)) {
377
+ return "number";
378
+ }
379
+ if (t.includes("bool")) {
380
+ return "boolean";
381
+ }
382
+ if (/(timestamp|datetime|date)/.test(t)) {
383
+ return "date";
384
+ }
385
+ return "string";
386
+ }
387
+ function editableColumn(column) {
388
+ return !column.pk && column.name !== "created_at" && column.name !== "updated_at";
389
+ }
390
+ function toCellValue(value) {
391
+ if (value === null || value === undefined) {
392
+ return null;
393
+ }
394
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
395
+ return value;
396
+ }
397
+ return JSON.stringify(value);
398
+ }
399
+ function createConnectorSource(connection, table) {
400
+ let columnsMeta = [];
401
+ let pkName = "id";
402
+ const pkValues = new Map;
403
+ const applyMeta = (columns) => {
404
+ if (columns.length > 0) {
405
+ columnsMeta = columns;
406
+ pkName = columns.find((c) => c.pk)?.name ?? "id";
407
+ }
408
+ };
409
+ const toQuery = (query) => ({
410
+ table,
411
+ ...connection ? { connection } : {},
412
+ limit: query?.limit ?? DATA_PAGE_SIZE,
413
+ offset: query?.offset ?? 0,
414
+ ...query?.orderBy ? { dir: query.dir ?? "asc", orderBy: query.orderBy } : {}
415
+ });
416
+ const rowKeyOf = (row, index) => {
417
+ const pk = row[pkName];
418
+ if (typeof pk === "string" || typeof pk === "number") {
419
+ pkValues.set(String(pk), pk);
420
+ return String(pk);
421
+ }
422
+ return `row-${index}`;
423
+ };
424
+ return {
425
+ capabilities: { delete: true, insert: true, remotePaging: true, remoteSort: true },
426
+ async columns() {
427
+ if (columnsMeta.length === 0) {
428
+ const result = await fetchRows(toQuery({ limit: 1, offset: 0 }));
429
+ applyMeta(result.columns);
430
+ }
431
+ return columnsMeta.map((meta) => {
432
+ const kind = editableColumn(meta) ? kindForSqlType(meta.type) : "readonly";
433
+ return {
434
+ editable: kind !== "readonly",
435
+ field: meta.name,
436
+ kind,
437
+ pk: meta.pk === true,
438
+ title: meta.name,
439
+ widthHint: meta.pk ? 80 : undefined
440
+ };
441
+ });
442
+ },
443
+ async commit(batch) {
444
+ const result = { cells: [], deletes: [], inserts: [] };
445
+ const byRow = new Map;
446
+ for (const cell of batch.cells) {
447
+ const list = byRow.get(cell.rowKey) ?? [];
448
+ list.push({ field: cell.field, value: cell.value });
449
+ byRow.set(cell.rowKey, list);
450
+ }
451
+ for (const [rowKey, patches] of byRow) {
452
+ const pk = pkValues.get(rowKey);
453
+ const outcome = (ok, error) => {
454
+ for (const patch of patches) {
455
+ result.cells.push({ error, field: patch.field, ok, rowKey });
456
+ }
457
+ };
458
+ if (pk === undefined) {
459
+ outcome(false, "Row has no primary key — refresh the grid");
460
+ continue;
461
+ }
462
+ try {
463
+ const set = {};
464
+ for (const patch of patches) {
465
+ set[patch.field] = patch.value;
466
+ }
467
+ await updateRow({ pk, set, table, ...connection ? { connection } : {} });
468
+ outcome(true);
469
+ } catch (error) {
470
+ outcome(false, error instanceof Error ? error.message : String(error));
471
+ }
472
+ }
473
+ for (const insert of batch.inserts) {
474
+ try {
475
+ const values = {};
476
+ for (const [field, value] of Object.entries(insert.cells)) {
477
+ if (value !== null) {
478
+ values[field] = value;
479
+ }
480
+ }
481
+ const { row } = await insertRow({ table, values, ...connection ? { connection } : {} });
482
+ const pk = row[pkName];
483
+ const newKey = typeof pk === "string" || typeof pk === "number" ? String(pk) : undefined;
484
+ if (newKey !== undefined && (typeof pk === "string" || typeof pk === "number")) {
485
+ pkValues.set(newKey, pk);
486
+ }
487
+ result.inserts.push({ newKey, ok: true, tempKey: insert.tempKey });
488
+ } catch (error) {
489
+ result.inserts.push({
490
+ error: error instanceof Error ? error.message : String(error),
491
+ ok: false,
492
+ tempKey: insert.tempKey
493
+ });
494
+ }
495
+ }
496
+ for (const del of batch.deletes) {
497
+ const pk = pkValues.get(del.rowKey);
498
+ if (pk === undefined) {
499
+ result.deletes.push({
500
+ error: "Row has no primary key — refresh the grid",
501
+ ok: false,
502
+ rowKey: del.rowKey
503
+ });
504
+ continue;
505
+ }
506
+ try {
507
+ await deleteRow({ pk, table, ...connection ? { connection } : {} });
508
+ result.deletes.push({ ok: true, rowKey: del.rowKey });
509
+ } catch (error) {
510
+ result.deletes.push({
511
+ error: error instanceof Error ? error.message : String(error),
512
+ ok: false,
513
+ rowKey: del.rowKey
514
+ });
515
+ }
516
+ }
517
+ return result;
518
+ },
519
+ id: makeGridTabId({ connection: connection ?? "default", kind: "data", table }),
520
+ label: table,
521
+ async refresh() {
522
+ columnsMeta = [];
523
+ pkValues.clear();
524
+ },
525
+ async rows(query) {
526
+ const result = await fetchRows(toQuery(query));
527
+ applyMeta(result.columns);
528
+ const rows = result.rows.map((row, index) => {
529
+ const key = rowKeyOf(row, index);
530
+ const cells = {};
531
+ for (const meta of columnsMeta) {
532
+ cells[meta.name] = toCellValue(row[meta.name]);
533
+ }
534
+ return { cells, key };
535
+ });
536
+ return { rows, total: result.total };
537
+ }
538
+ };
539
+ }
540
+
541
+ // src/browse/library-model.ts
542
+ var LIBRARY_CATEGORIES = [
543
+ { key: "all", label: "All" },
544
+ { dir: "pages", key: "pages", label: "Pages" },
545
+ { dir: "layouts", key: "layouts", label: "Layouts" },
546
+ { dir: "components", key: "components", label: "Components" },
547
+ { dir: "content", key: "content", label: "Content" },
548
+ { dir: "public", key: "media", label: "Media" }
549
+ ];
550
+ var LIBRARY_CATEGORY_KEYS = LIBRARY_CATEGORIES.map((c) => c.key);
551
+ function libraryCategory(key) {
552
+ return LIBRARY_CATEGORIES.find((c) => c.key === key);
553
+ }
554
+ function uploadDirForCategory(key) {
555
+ return libraryCategory(key)?.dir;
556
+ }
557
+ function categoryFor(dir, ext) {
558
+ if (ext && MEDIA_EXTENSIONS.has(ext)) {
559
+ return "Media";
560
+ }
561
+ if (dir.startsWith("pages")) {
562
+ return "Pages";
563
+ }
564
+ if (dir.startsWith("layouts")) {
565
+ return "Layouts";
566
+ }
567
+ if (dir.startsWith("components")) {
568
+ return "Components";
569
+ }
570
+ if (dir.startsWith("content")) {
571
+ return "Content";
572
+ }
573
+ if (dir.startsWith("public")) {
574
+ return "Media";
575
+ }
576
+ if (dir.startsWith("data")) {
577
+ return "Content";
578
+ }
579
+ if (dir.startsWith("styles")) {
580
+ return "Components";
581
+ }
582
+ return "Other";
583
+ }
584
+ function contentTypeFor(filePath) {
585
+ const content = projectState?.projectConfig?.content ?? {};
586
+ for (const [name, entry] of Object.entries(content)) {
587
+ if (!entry.source) {
588
+ continue;
589
+ }
590
+ const prefix = entry.source.replace(/^\.\//, "").replace(/\/$/, "");
591
+ if (filePath.startsWith(`${prefix}/`) || filePath === prefix) {
592
+ return name.charAt(0).toUpperCase() + name.slice(1);
593
+ }
594
+ }
595
+ return null;
596
+ }
597
+ var SKIP_DIRS = new Set(["node_modules", ".git", ".jx", "dist", "build", ".cache"]);
598
+ async function walk(dir, platform, out, failures, i18n) {
599
+ let entries;
600
+ try {
601
+ entries = await platform.listDirectory(dir);
602
+ } catch (error) {
603
+ failures.push({ dir, error: errorMessage(error) });
604
+ return;
605
+ }
606
+ const subdirectories = [];
607
+ for (const entry of entries) {
608
+ if (entry.type === "directory") {
609
+ if (!SKIP_DIRS.has(entry.name)) {
610
+ subdirectories.push(entry.path);
611
+ }
612
+ continue;
613
+ }
614
+ const ext = extensionOf(entry.name);
615
+ const category = categoryFor(entry.path, ext);
616
+ out.push({
617
+ category,
618
+ ext,
619
+ locale: servedLocaleOfPath(entry.path, i18n) ?? undefined,
620
+ modified: entry.modified,
621
+ name: entry.name,
622
+ path: entry.path,
623
+ size: entry.size,
624
+ type: category === "Content" ? contentTypeFor(entry.path) ?? ext ?? "file" : ext || "file"
625
+ });
626
+ }
627
+ await Promise.all(subdirectories.map((sub) => walk(sub, platform, out, failures, i18n)));
628
+ }
629
+ async function scanLibrary(dirs, platform) {
630
+ const files = [];
631
+ const failures = [];
632
+ const { i18n } = resolveI18n(projectState?.projectConfig ?? {});
633
+ await Promise.all(dirs.map((dir) => walk(dir, platform, files, failures, i18n)));
634
+ files.sort((a, b) => a.path.localeCompare(b.path));
635
+ return { failures, files };
636
+ }
637
+ function filterLibrary(files, filter) {
638
+ let result = files;
639
+ const category = libraryCategory(filter.category);
640
+ if (category && category.key !== "all") {
641
+ result = result.filter((f) => f.category === category.label);
642
+ }
643
+ const query = filter.query.trim().toLowerCase();
644
+ if (query) {
645
+ result = result.filter((f) => f.name.toLowerCase().includes(query) || f.path.toLowerCase().includes(query));
646
+ }
647
+ const locale = filter.locale?.trim();
648
+ if (locale) {
649
+ result = result.filter((f) => f.locale === locale);
650
+ }
651
+ return result;
652
+ }
653
+ var LIBRARY_LAYOUTS = ["table", "cards", "media", "calendar", "board"];
654
+ var LIBRARY_LAYOUT_LABELS = {
655
+ board: "Board",
656
+ calendar: "Calendar",
657
+ cards: "Cards",
658
+ media: "Media",
659
+ table: "Table"
660
+ };
661
+ var PREVIEW_LAYOUTS = new Set([
662
+ "cards",
663
+ "media"
664
+ ]);
665
+ var DATE_PREFIX = /^(\d{4}-\d{2}-\d{2})/;
666
+ function libraryDate(file) {
667
+ const prefix = DATE_PREFIX.exec(file.name);
668
+ if (prefix) {
669
+ return prefix[1];
670
+ }
671
+ if (file.modified) {
672
+ const parsed = new Date(file.modified);
673
+ if (!Number.isNaN(parsed.getTime())) {
674
+ return parsed.toISOString().slice(0, 10);
675
+ }
676
+ }
677
+ return null;
678
+ }
679
+ function projectLocales() {
680
+ return resolveI18n(projectState?.projectConfig ?? {}).i18n?.locales ?? [];
681
+ }
682
+ function libraryLocales(files) {
683
+ const present = new Set;
684
+ for (const file of files) {
685
+ if (file.locale) {
686
+ present.add(file.locale);
687
+ }
688
+ }
689
+ return projectLocales().filter((tag) => present.has(tag));
690
+ }
691
+ function groupByDate(files) {
692
+ const byDay = new Map;
693
+ const undated = [];
694
+ for (const file of files) {
695
+ const date = libraryDate(file);
696
+ if (date === null) {
697
+ undated.push(file);
698
+ continue;
699
+ }
700
+ const bucket = byDay.get(date);
701
+ if (bucket) {
702
+ bucket.push(file);
703
+ } else {
704
+ byDay.set(date, [file]);
705
+ }
706
+ }
707
+ const days = [...byDay.entries()].map(([date, dayFiles]) => ({ date, files: dayFiles })).toSorted((a, b) => b.date.localeCompare(a.date));
708
+ return { days, undated };
709
+ }
710
+ function groupByCategory(files) {
711
+ const byGroup = new Map;
712
+ for (const file of files) {
713
+ const bucket = byGroup.get(file.category);
714
+ if (bucket) {
715
+ bucket.push(file);
716
+ } else {
717
+ byGroup.set(file.category, [file]);
718
+ }
719
+ }
720
+ const order = LIBRARY_CATEGORIES.map((c) => c.label);
721
+ return [...byGroup.entries()].map(([group, groupFiles]) => ({ files: groupFiles, group })).toSorted((a, b) => {
722
+ const ai = order.indexOf(a.group);
723
+ const bi = order.indexOf(b.group);
724
+ if (ai === bi) {
725
+ return a.group.localeCompare(b.group);
726
+ }
727
+ return (ai === -1 ? order.length : ai) - (bi === -1 ? order.length : bi);
728
+ });
729
+ }
730
+
731
+ // src/browse/library-source.ts
732
+ var LIBRARY_READ_ONLY = "The Library lists files; it does not edit them. Rename, duplicate or delete from the file's " + "context menu, or open the file to edit it.";
733
+ function libraryColumns() {
734
+ return [
735
+ { editable: false, field: "name", kind: "string", pk: true, title: "Name", widthHint: 260 },
736
+ { editable: false, field: "category", kind: "string", title: "Category", widthHint: 120 },
737
+ { editable: false, field: "locale", kind: "string", title: "Locale", widthHint: 90 },
738
+ { editable: false, field: "type", kind: "string", title: "Type", widthHint: 120 },
739
+ { editable: false, field: "size", kind: "number", title: "Size", widthHint: 90 },
740
+ { editable: false, field: "modified", kind: "date", title: "Modified", widthHint: 160 },
741
+ { editable: false, field: "path", kind: "readonly", title: "Path", widthHint: 320 }
742
+ ];
743
+ }
744
+ function libraryRow(file) {
745
+ return {
746
+ cells: {
747
+ category: file.category,
748
+ locale: file.locale ?? null,
749
+ modified: file.modified ?? null,
750
+ name: file.name,
751
+ path: file.path,
752
+ size: file.size ?? null,
753
+ type: file.type
754
+ },
755
+ key: file.path
756
+ };
757
+ }
758
+ function libraryTabId() {
759
+ return makeGridTabId({ kind: "library" });
760
+ }
761
+ function createLibrarySource(dirs) {
762
+ let scan = null;
763
+ let inFlight = null;
764
+ const projectDirs = dirs ?? (() => projectState?.projectDirs ?? []);
765
+ async function ensureScan() {
766
+ if (scan) {
767
+ return scan;
768
+ }
769
+ inFlight ??= scanLibrary(projectDirs(), getPlatform()).then((result) => {
770
+ scan = result;
771
+ inFlight = null;
772
+ return result;
773
+ });
774
+ return inFlight;
775
+ }
776
+ return {
777
+ capabilities: { delete: false, insert: false, remotePaging: false, remoteSort: false },
778
+ columns: () => Promise.resolve(libraryColumns()),
779
+ commit(batch) {
780
+ return Promise.resolve({
781
+ cells: batch.cells.map((cell) => ({
782
+ error: LIBRARY_READ_ONLY,
783
+ field: cell.field,
784
+ ok: false,
785
+ rowKey: cell.rowKey
786
+ })),
787
+ deletes: batch.deletes.map((row) => ({
788
+ error: LIBRARY_READ_ONLY,
789
+ ok: false,
790
+ rowKey: row.rowKey
791
+ })),
792
+ inserts: batch.inserts.map((row) => ({
793
+ error: LIBRARY_READ_ONLY,
794
+ ok: false,
795
+ tempKey: row.tempKey
796
+ }))
797
+ });
798
+ },
799
+ failures: () => scan?.failures ?? [],
800
+ files: () => scan?.files ?? [],
801
+ id: libraryTabId(),
802
+ label: "Library",
803
+ async refresh() {
804
+ scan = null;
805
+ inFlight = null;
806
+ await ensureScan();
807
+ },
808
+ async rows() {
809
+ const result = await ensureScan();
810
+ return { rows: result.files.map((file) => libraryRow(file)), total: result.files.length };
811
+ },
812
+ scanned: () => scan !== null
813
+ };
814
+ }
815
+
816
+ // src/grid/grid-open.ts
817
+ var GRID_STUB_DOCUMENT = { children: [], tagName: "div" };
818
+ async function openCsvGridTab(path) {
819
+ const existing = workspace.tabs.get(path);
820
+ if (existing) {
821
+ activateTab(path);
822
+ return existing;
823
+ }
824
+ try {
825
+ await loadFormats();
826
+ } catch {}
827
+ const source = createCsvFileSource(path);
828
+ const tab = openTab({
829
+ capabilities: { modes: ["grid", "source"] },
830
+ document: structuredClone(GRID_STUB_DOCUMENT),
831
+ documentPath: path,
832
+ id: path,
833
+ sourceFormat: formatForPath(path)?.name ?? null
834
+ });
835
+ const controller = createGridController(tab, source);
836
+ controller.load();
837
+ return tab;
838
+ }
839
+ function openVirtualGridTab(source) {
840
+ const tab = openTab({
841
+ capabilities: { modes: ["grid"] },
842
+ document: structuredClone(GRID_STUB_DOCUMENT),
843
+ documentPath: null,
844
+ id: source.id
845
+ });
846
+ const controller = createGridController(tab, source);
847
+ controller.load();
848
+ return tab;
849
+ }
850
+ function openCollectionGrid(typeName) {
851
+ const id = makeGridTabId({ kind: "collection", name: typeName });
852
+ const existing = workspace.tabs.get(id);
853
+ if (existing) {
854
+ activateTab(id);
855
+ return existing;
856
+ }
857
+ return openVirtualGridTab(createCollectionSource(typeName));
858
+ }
859
+ function openLibraryTab() {
860
+ const id = libraryTabId();
861
+ const existing = workspace.tabs.get(id);
862
+ if (existing) {
863
+ activateTab(id);
864
+ return existing;
865
+ }
866
+ return openTab({
867
+ capabilities: { modes: ["manage"] },
868
+ document: structuredClone(GRID_STUB_DOCUMENT),
869
+ documentPath: null,
870
+ id
871
+ });
872
+ }
873
+ function openPagesGrid() {
874
+ const id = makeGridTabId({ kind: "pages" });
875
+ const existing = workspace.tabs.get(id);
876
+ if (existing) {
877
+ activateTab(id);
878
+ return existing;
879
+ }
880
+ return openVirtualGridTab(createPagesSource());
881
+ }
882
+ function openConnectorGrid(connection, table) {
883
+ const id = makeGridTabId({ connection: connection ?? "default", kind: "data", table });
884
+ const existing = workspace.tabs.get(id);
885
+ if (existing) {
886
+ activateTab(id);
887
+ return existing;
888
+ }
889
+ return openVirtualGridTab(createConnectorSource(connection, table));
890
+ }
891
+ async function openGridSourcePicker() {
892
+ const collections = collectionDirs();
893
+ let connections = [];
894
+ if (dataSurfaceAvailable()) {
895
+ const response = await fetchConnections().catch(() => null);
896
+ connections = response?.connections ?? [];
897
+ }
898
+ const handle = openModal(html`<sp-dialog-wrapper
899
+ open
900
+ dismissable
901
+ underlay
902
+ headline="Open Grid"
903
+ @close=${() => handle.close()}
904
+ >
905
+ <sp-menu class="jx-grid-picker">
906
+ <sp-menu-group>
907
+ <span slot="header">Project</span>
908
+ <sp-menu-item
909
+ @click=${() => {
910
+ handle.close();
911
+ openPagesGrid();
912
+ }}
913
+ >Pages</sp-menu-item
914
+ >
915
+ ${collections.map(({ name }) => html`<sp-menu-item
916
+ @click=${() => {
917
+ handle.close();
918
+ openCollectionGrid(name);
919
+ }}
920
+ >Collection: ${name}</sp-menu-item
921
+ >`)}
922
+ </sp-menu-group>
923
+ ${connections.map((conn) => html`<sp-menu-group>
924
+ <span slot="header">Data · ${conn.name}</span>
925
+ ${conn.tables.length === 0 ? html`<sp-menu-item disabled>No tables — push a schema first</sp-menu-item>` : conn.tables.map((table) => html`<sp-menu-item
926
+ @click=${() => {
927
+ handle.close();
928
+ openConnectorGrid(conn.name, table);
929
+ }}
930
+ >${table}</sp-menu-item
931
+ >`)}
932
+ </sp-menu-group>`)}
933
+ </sp-menu>
934
+ </sp-dialog-wrapper>`, { label: "Open Grid" });
935
+ }
936
+ function gridCommands() {
937
+ return [
938
+ {
939
+ args: argsSchema({
940
+ name: stringProperty("The content collection's name, as project.json declares it.")
941
+ }),
942
+ category: "Project",
943
+ id: "collection.editInGrid",
944
+ level: "project",
945
+ menus: ["context/file", "palette"],
946
+ group: "5_data",
947
+ requires: "a project that declares content collections",
948
+ when: (ctx) => ctx.project.open,
949
+ aiTool: {
950
+ description: "Open a content collection's entries as an editable grid in a new tab.",
951
+ name: "open_collection_grid"
952
+ },
953
+ run: (_commandCtx, args) => {
954
+ const name = stringArg("collection.editInGrid", args, "name");
955
+ const declared = collectionDirs().map((c) => c.name);
956
+ if (!declared.includes(name)) {
957
+ throw new RangeError(`command "collection.editInGrid" argument "name": "${name}" is not a content ` + `collection this project declares — it declares: ` + `${declared.length > 0 ? declared.join(", ") : "none"}`);
958
+ }
959
+ openCollectionGrid(name);
960
+ },
961
+ title: "Edit Collection in Grid"
962
+ },
963
+ {
964
+ args: {
965
+ additionalProperties: false,
966
+ properties: {
967
+ connection: stringProperty('The connection name from project.json. Defaults to "default".'),
968
+ table: stringProperty("The table to open.")
969
+ },
970
+ required: ["table"],
971
+ type: "object"
972
+ },
973
+ category: "Project",
974
+ id: "data.openGrid",
975
+ level: "project",
976
+ menus: ["palette"],
977
+ group: "5_data",
978
+ requires: "a platform that serves the data routes",
979
+ when: (ctx) => ctx.project.open,
980
+ enablement: (ctx) => ctx.capability.dataRows,
981
+ aiTool: {
982
+ description: "Open a connector table as an editable grid in a new tab.",
983
+ name: "open_data_grid"
984
+ },
985
+ run: (_commandCtx, args) => {
986
+ const table = stringArg("data.openGrid", args, "table");
987
+ openConnectorGrid(optionalStringArg("data.openGrid", args, "connection"), table);
988
+ },
989
+ title: "Open Data Grid"
990
+ }
991
+ ];
992
+ }
993
+ function registerGridCommands(registry) {
994
+ registry.registerAll(gridCommands());
995
+ }
996
+
997
+ export { dataSurfaceAvailable, testConnection, pushSchema, deriveSecretEnvName, parseCsv, createCsvFileSource, LIBRARY_CATEGORIES, LIBRARY_CATEGORY_KEYS, libraryCategory, uploadDirForCategory, scanLibrary, filterLibrary, LIBRARY_LAYOUTS, LIBRARY_LAYOUT_LABELS, PREVIEW_LAYOUTS, projectLocales, libraryLocales, groupByDate, groupByCategory, libraryColumns, createLibrarySource, openCsvGridTab, openLibraryTab, openPagesGrid, openGridSourcePicker, registerGridCommands };
998
+
999
+ //# debugId=B5A73986FCDCB07464756E2164756E21
1000
+ //# sourceMappingURL=studio-9je6w5sq.js.map