@jxsuite/studio 6.1.1 → 6.1.2
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.
- package/dist/chunks/{2020-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-4912g339.js +4 -0
- package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
- package/dist/chunks/cf-settings-br6105tr.js +4 -0
- package/dist/chunks/color-28ksk2qm.js +4 -0
- package/dist/chunks/color-area-0fj8a4ga.js +4 -0
- package/dist/chunks/color-field-xch8kx2g.js +4 -0
- package/dist/chunks/color-slider-jxd8v350.js +4 -0
- package/dist/chunks/combobox-p0efwjke.js +4 -0
- package/dist/chunks/components-db68vsn7.js +4 -0
- package/dist/chunks/content-source-1449qesq.js +4 -0
- package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-x9jn86a7.js +4 -0
- package/dist/chunks/entry-commands-may24cpt.js +4 -0
- package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
- package/dist/chunks/file-ops-x9v54pcj.js +4 -0
- package/dist/chunks/files-j3knqf0s.js +4 -0
- package/dist/chunks/format-host-tyre2trb.js +4 -0
- package/dist/chunks/fs-events-64ma9htc.js +4 -0
- package/dist/chunks/git-panel-84ps5dex.js +4 -0
- package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
- package/dist/chunks/icons-pnfz478q.js +4 -0
- package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
- package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
- package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
- package/dist/chunks/iframe-entry-zap785cw.js +5 -0
- package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
- package/dist/chunks/index-b8xw3vy9.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
- package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
- package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
- package/dist/chunks/layers-h4xp1pss.js +4 -0
- package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
- package/dist/chunks/listbox-e74qjyq6.js +4 -0
- package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
- package/dist/chunks/media-picker-2cweexc5.js +4 -0
- package/dist/chunks/menu-n6yzswmy.js +4 -0
- package/dist/chunks/menu-ynw13y0s.js +4 -0
- package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
- package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
- package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
- package/dist/chunks/notify-cj5zbrs2.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-b7ddhr8m.js +4 -0
- package/dist/chunks/platform-3dfws9js.js +4 -0
- package/dist/chunks/popover-jt2gxmzs.js +4 -0
- package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
- package/dist/chunks/quick-search-0dajrwqg.js +4 -0
- package/dist/chunks/references-49qgt404.js +4 -0
- package/dist/chunks/right-panel-jm1bwe53.js +4 -0
- package/dist/chunks/section-registry-6kwc4fky.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/split-n2gfpm5m.js +4 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-0q988f9w.js} +3 -3
- package/dist/chunks/studio-0rt52vpq.js +5 -0
- package/dist/chunks/studio-18vgbhs5.js +5 -0
- package/dist/chunks/{studio-h46vtzk8.js → studio-1fxkaaea.js} +4 -4
- package/dist/chunks/studio-24mccdrj.js +5 -0
- package/dist/chunks/studio-2eh507zk.js +9 -0
- package/dist/chunks/studio-2hcbccfv.js +5 -0
- package/dist/chunks/studio-2j1cb95x.js +5 -0
- package/dist/chunks/studio-2jbs3rxv.js +5 -0
- package/dist/chunks/{studio-rv11kfwa.js → studio-485046te.js} +7 -7
- package/dist/chunks/studio-4h8k4dw9.js +5 -0
- package/dist/chunks/studio-5f6n18kx.js +5 -0
- package/dist/chunks/studio-5gthpky6.js +5 -0
- package/dist/chunks/studio-5ve6bbep.js +5 -0
- package/dist/chunks/studio-6ep3js6b.js +9 -0
- package/dist/chunks/studio-6wkmf3wz.js +9 -0
- package/dist/chunks/studio-841rf3cg.js +5 -0
- package/dist/chunks/studio-8gmwgheg.js +5 -0
- package/dist/chunks/studio-8qm0ep50.js +5 -0
- package/dist/chunks/{studio-8grwxtqk.js → studio-90pq9km1.js} +4 -4
- package/dist/chunks/studio-924p1tm1.js +6 -0
- package/dist/chunks/{studio-pre0skq6.js → studio-a3g98wjr.js} +4 -4
- package/dist/chunks/studio-a3shpz9y.js +5 -0
- package/dist/chunks/studio-amsbaaar.js +6 -0
- package/dist/chunks/studio-at5spjbc.js +7 -0
- package/dist/chunks/studio-b2xv945e.js +5 -0
- package/dist/chunks/studio-bn5nkafw.js +5 -0
- package/dist/chunks/studio-bw6q5xjf.js +9 -0
- package/dist/chunks/studio-c7q0t9x1.js +5 -0
- package/dist/chunks/studio-camnhc96.js +6 -0
- package/dist/chunks/studio-cffqvnzd.js +5 -0
- package/dist/chunks/studio-d81xfh1g.js +5 -0
- package/dist/chunks/studio-dgz8d0c1.js +5 -0
- package/dist/chunks/studio-efvfrsf8.js +5 -0
- package/dist/chunks/studio-er30bpcx.js +5 -0
- package/dist/chunks/studio-ezscgr64.js +5 -0
- package/dist/chunks/studio-ffrrncvz.js +5 -0
- package/dist/chunks/studio-fpphgn8y.js +10 -0
- package/dist/chunks/studio-j1kvhdjk.js +4 -0
- package/dist/chunks/{studio-vrmcjf9g.js → studio-j430n16g.js} +5 -5
- package/dist/chunks/studio-jjkg84nj.js +5 -0
- package/dist/chunks/studio-m0q32ars.js +4 -0
- package/dist/chunks/studio-m6bdst11.js +5 -0
- package/dist/chunks/studio-nv2cptd4.js +64 -0
- package/dist/chunks/studio-nwfrc98n.js +5 -0
- package/dist/chunks/studio-p1wgvp7r.js +5 -0
- package/dist/chunks/studio-pag2wncm.js +5 -0
- package/dist/chunks/studio-qvanvzfd.js +5 -0
- package/dist/chunks/studio-qwa64kt7.js +5 -0
- package/dist/chunks/studio-rk1zc4x3.js +928 -0
- package/dist/chunks/studio-se2r3ptc.js +5 -0
- package/dist/chunks/studio-sg2a0dh0.js +5 -0
- package/dist/chunks/studio-tjzjhe68.js +5 -0
- package/dist/chunks/{studio-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
- package/dist/chunks/{studio-kggey1jt.js → studio-v0jzqdjm.js} +4 -4
- package/dist/chunks/studio-v2w7q8r1.js +7 -0
- package/dist/chunks/studio-v5vjq1h0.js +4 -0
- package/dist/chunks/studio-v8aga3vp.js +14 -0
- package/dist/chunks/studio-vfcdrfmv.js +5 -0
- package/dist/chunks/studio-vmfkgdjf.js +5 -0
- package/dist/chunks/studio-wt1816jj.js +5 -0
- package/dist/chunks/studio-wz73q5kq.js +4 -0
- package/dist/chunks/studio-y04qtxvp.js +7 -0
- package/dist/chunks/studio-y21g8zzg.js +5 -0
- package/dist/chunks/{studio-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
- package/dist/chunks/studio-ynn90f58.js +16 -0
- package/dist/chunks/studio-yxz682sx.js +5 -0
- package/dist/chunks/studio-zp7snvkq.js +5 -0
- package/dist/chunks/studio-zq4z6tm6.js +5 -0
- package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
- package/dist/chunks/tabs-f5cw3tgp.js +4 -0
- package/dist/chunks/textfield-wewc8rq2.js +4 -0
- package/dist/chunks/toast-c9fn075p.js +4 -0
- package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
- package/dist/chunks/tree-mdq3v5cw.js +4 -0
- package/dist/chunks/{tsMode-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
- package/dist/chunks/workspace-jtfahpee.js +4 -0
- package/dist/chunks/ws-client-nze0k6mv.js +4 -0
- package/dist/iframe-entry.js +16 -16
- package/dist/manifest.json +63 -63
- package/dist/studio.js +97 -97
- package/package.json +6 -6
- package/src/about/about-modal.ts +4 -3
- package/src/account/action-flow.ts +45 -38
- package/src/account-status.ts +7 -2
- package/src/browse/library-layouts.ts +8 -5
- package/src/browse/library-model.ts +18 -6
- package/src/browse/library-pane.ts +37 -21
- package/src/browse/library-preview.ts +14 -9
- package/src/browse/library-source.ts +1 -1
- package/src/canvas/asset-refs.ts +24 -9
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +44 -53
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +62 -41
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +90 -49
- package/src/canvas/dialog-path.ts +9 -4
- package/src/canvas/dialog-state.ts +1 -2
- package/src/canvas/diff-marks.ts +9 -16
- package/src/canvas/diff-toolbar.ts +8 -7
- package/src/canvas/edit-width-drag.ts +4 -1
- package/src/canvas/edit-width.ts +1 -3
- package/src/canvas/iframe-channel.ts +27 -13
- package/src/canvas/iframe-drop.ts +13 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +80 -63
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +135 -96
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +18 -15
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +12 -16
- package/src/canvas/iframe-render.ts +36 -34
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +6 -2
- package/src/canvas/path-mapping.ts +19 -12
- package/src/canvas/popover-path.ts +7 -3
- package/src/canvas/popover-state.ts +1 -2
- package/src/canvas/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +2 -1
- package/src/canvas/surface-registry.ts +21 -3
- package/src/collab/collab-commands.ts +7 -2
- package/src/collab/collab-session.ts +84 -45
- package/src/collab/collab-state.ts +4 -3
- package/src/collab/monaco-binding.ts +16 -13
- package/src/collab/monaco-cursors.ts +5 -2
- package/src/commands/budget.ts +3 -3
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +22 -20
- package/src/commands/keymap.ts +47 -43
- package/src/commands/levels.ts +3 -3
- package/src/commands/live-context.ts +7 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +12 -10
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +5 -4
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +3 -2
- package/src/content/entry-editor.ts +29 -17
- package/src/content/entry-fields.ts +12 -7
- package/src/content/entry-model.ts +21 -12
- package/src/editor/canvas-context-menu.ts +1 -2
- package/src/editor/canvas-slash-bridge.ts +3 -6
- package/src/editor/content-slice.ts +16 -14
- package/src/editor/context-menu.ts +35 -22
- package/src/editor/convert-targets.ts +30 -35
- package/src/editor/convert-to-component.ts +11 -5
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +21 -22
- package/src/editor/inline-edit-apply.ts +35 -17
- package/src/editor/inline-edit.ts +66 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +32 -20
- package/src/editor/slash-menu.ts +1 -6
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +15 -10
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +77 -36
- package/src/files/files.ts +90 -95
- package/src/files/media-meta.ts +2 -1
- package/src/files/media-paths.ts +3 -0
- package/src/files/serialize-document.ts +2 -2
- package/src/format/constraints.ts +1 -1
- package/src/format/convert-file.ts +27 -13
- package/src/format/format-choices.ts +2 -1
- package/src/format/format-host.ts +76 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +19 -9
- package/src/github/github-publish.ts +24 -20
- package/src/grid/cell-editors.ts +46 -31
- package/src/grid/cell-popovers.ts +5 -3
- package/src/grid/edit-buffer.ts +10 -9
- package/src/grid/grid-controller.ts +20 -22
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -6
- package/src/grid/grid-panel.ts +11 -4
- package/src/grid/grid-source.ts +8 -8
- package/src/grid/grid-view.ts +14 -17
- package/src/grid/redirects-grid.ts +14 -5
- package/src/grid/redirects.ts +16 -14
- package/src/grid/schema-columns.ts +25 -19
- package/src/grid/sources/connector-source.ts +47 -20
- package/src/grid/sources/content-source.ts +25 -24
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +55 -34
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +1 -2
- package/src/media/media-pane.ts +4 -1
- package/src/new-project/add-repo-modal.ts +20 -19
- package/src/new-project/import-tab.ts +10 -14
- package/src/new-project/location-fields.ts +2 -1
- package/src/new-project/new-project-modal.ts +12 -9
- package/src/packages/jxsuite-update.ts +4 -3
- package/src/packages/pull-package-sync.ts +26 -25
- package/src/page-params.ts +97 -68
- package/src/panels/activity-panel.ts +17 -9
- package/src/panels/ai-chat/attached-context.ts +13 -7
- package/src/panels/ai-chat/chat-view.ts +80 -73
- package/src/panels/ai-chat/composer.ts +30 -33
- package/src/panels/ai-chat/sessions-view.ts +1 -2
- package/src/panels/ai-panel.ts +23 -20
- package/src/panels/block-action-bar.ts +46 -35
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +31 -24
- package/src/panels/data-explorer.ts +62 -25
- package/src/panels/data-grid.ts +14 -11
- package/src/panels/dnd.ts +108 -118
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +10 -3
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +76 -51
- package/src/panels/frontmatter-fields.ts +24 -19
- package/src/panels/frontmatter-panel.ts +44 -34
- package/src/panels/git-diff-open.ts +4 -4
- package/src/panels/git-panel.ts +49 -61
- package/src/panels/head-panel.ts +131 -111
- package/src/panels/i18n-panel.ts +10 -3
- package/src/panels/imports-panel.ts +23 -47
- package/src/panels/jump-bar.ts +48 -29
- package/src/panels/layers-panel.ts +97 -74
- package/src/panels/left-panel.ts +3 -3
- package/src/panels/pane-context.ts +31 -22
- package/src/panels/pane-grid.ts +49 -20
- package/src/panels/panel-registry.ts +22 -37
- package/src/panels/properties-panel.ts +175 -121
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +3 -3
- package/src/panels/seo-modal.ts +13 -17
- package/src/panels/settings-menu.ts +15 -15
- package/src/panels/signals-panel.ts +153 -131
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +218 -205
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +57 -54
- package/src/panels/stylebook-layers-panel.ts +9 -9
- package/src/panels/stylebook-panel.ts +13 -17
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +36 -26
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +58 -30
- package/src/platforms/cloud.ts +345 -175
- package/src/platforms/default-platform.ts +10 -4
- package/src/platforms/devserver.ts +129 -117
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +8 -2
- package/src/publish/pages-service.ts +28 -13
- package/src/publish/publish-commands.ts +5 -4
- package/src/publish/publish-panel.ts +10 -6
- package/src/recent-projects.ts +15 -8
- package/src/resize-edges.ts +26 -36
- package/src/services/a11y-report.ts +26 -19
- package/src/services/agent-seed.ts +23 -11
- package/src/services/ai-ask.ts +9 -12
- package/src/services/ai-command-tools.ts +68 -62
- package/src/services/ai-import-tools.ts +80 -67
- package/src/services/ai-models.ts +17 -13
- package/src/services/ai-project-tools.ts +68 -32
- package/src/services/ai-session-store.ts +19 -10
- package/src/services/ai-system-prompt.ts +46 -20
- package/src/services/ai-tools.ts +71 -27
- package/src/services/ai-write-report.ts +20 -12
- package/src/services/ai-writes.ts +4 -4
- package/src/services/automation.ts +58 -31
- package/src/services/cem-export.ts +149 -58
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- package/src/services/context-manager.ts +14 -10
- package/src/services/context-resolver.ts +20 -8
- package/src/services/data-service.ts +19 -15
- package/src/services/directory-picker.ts +18 -12
- package/src/services/document-assistant.ts +39 -19
- package/src/services/gated-registry.ts +10 -6
- package/src/services/harness/chat-reducer.ts +23 -1
- package/src/services/import-client.ts +91 -38
- package/src/services/import-seed.ts +8 -2
- package/src/services/jx-validate.ts +28 -31
- package/src/services/live-preview.ts +0 -0
- package/src/services/live-surfaces.ts +6 -3
- package/src/services/model-uri.ts +10 -2
- package/src/services/module-preloads.ts +12 -8
- package/src/services/monaco-buffer.ts +43 -24
- package/src/services/monaco-lazy.ts +7 -8
- package/src/services/monaco-setup.ts +23 -16
- package/src/services/notify.ts +44 -17
- package/src/services/popover-report.ts +25 -10
- package/src/services/preview-eval.ts +20 -8
- package/src/services/profile.ts +13 -6
- package/src/services/project-path.ts +13 -10
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +8 -7
- package/src/services/settings/kernel.ts +13 -4
- package/src/services/settings/write-queue.ts +9 -9
- package/src/services/token-lint.ts +12 -10
- package/src/services/tool-executor.ts +17 -5
- package/src/services/tool-outcomes.ts +44 -24
- package/src/services/trusted-types.ts +24 -7
- package/src/settings/contexts-section.ts +11 -8
- package/src/settings/contributed-section.ts +79 -60
- package/src/settings/css-vars-editor.ts +37 -16
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +23 -13
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +11 -8
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +9 -6
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +1 -1
- package/src/settings/schema-field-ui.ts +9 -0
- package/src/settings/settings-document.ts +5 -5
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +104 -81
- package/src/site-context.ts +37 -22
- package/src/state.ts +41 -49
- package/src/store.ts +54 -34
- package/src/studio.ts +25 -75
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +6 -7
- package/src/style/token-ref.ts +5 -4
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +31 -36
- package/src/surfaces/ai-credentials-form.ts +6 -16
- package/src/surfaces/ai-managed-connect.ts +3 -4
- package/src/surfaces/ai-model-picker.ts +3 -5
- package/src/surfaces/block-action-bar.ts +22 -11
- package/src/surfaces/boot-failure.ts +4 -5
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.ts +12 -11
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/commandbar.ts +14 -9
- package/src/surfaces/convert-repeater.ts +17 -19
- package/src/surfaces/data-actions.ts +9 -7
- package/src/surfaces/dialog.ts +26 -28
- package/src/surfaces/diff-toolbar.ts +9 -7
- package/src/surfaces/doc-header.ts +10 -19
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.ts +14 -11
- package/src/surfaces/expression-editor.ts +11 -25
- package/src/surfaces/files-panel.ts +27 -14
- package/src/surfaces/formula-palette.ts +4 -5
- package/src/surfaces/git-panel.ts +7 -15
- package/src/surfaces/github-auth.ts +16 -20
- package/src/surfaces/github-publish.ts +17 -22
- package/src/surfaces/grid-cell.ts +30 -31
- package/src/surfaces/grid-open.ts +10 -14
- package/src/surfaces/grid-panel.ts +13 -9
- package/src/surfaces/grid-replace.ts +13 -13
- package/src/surfaces/grid-views.ts +15 -18
- package/src/surfaces/inspector-dock.ts +13 -12
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.ts +19 -20
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.ts +11 -10
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/menu.ts +29 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.ts +20 -25
- package/src/surfaces/pane-grid.ts +15 -10
- package/src/surfaces/panel-activity.ts +5 -6
- package/src/surfaces/panel-data.ts +3 -4
- package/src/surfaces/panel-deploy-checklist.ts +5 -6
- package/src/surfaces/panel-elements.ts +5 -7
- package/src/surfaces/panel-i18n.ts +5 -7
- package/src/surfaces/panel-imports.ts +6 -13
- package/src/surfaces/panel-outline.ts +25 -19
- package/src/surfaces/panel-page.ts +11 -18
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.ts +20 -34
- package/src/surfaces/panel-stylebook-layers.ts +5 -8
- package/src/surfaces/preferences.ts +21 -11
- package/src/surfaces/progress-modal.ts +15 -9
- package/src/surfaces/properties-panel.json +1 -1
- package/src/surfaces/properties-panel.ts +20 -42
- package/src/surfaces/publish.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.ts +13 -13
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.ts +15 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.ts +14 -10
- package/src/surfaces/settings-css-vars.ts +5 -12
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.ts +8 -15
- package/src/surfaces/settings-extensions.ts +5 -6
- package/src/surfaces/settings-head.ts +33 -39
- package/src/surfaces/settings-locales.ts +8 -20
- package/src/surfaces/settings-overview.ts +5 -6
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.ts +9 -18
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/slash-menu.ts +19 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +17 -14
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +5 -7
- package/src/tabs/patch-ops.ts +4 -3
- package/src/tabs/project-config.ts +32 -21
- package/src/tabs/selection.ts +36 -8
- package/src/tabs/tab.ts +52 -41
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +32 -17
- package/src/ui/ai-credentials-form.ts +10 -13
- package/src/ui/ai-model-picker.ts +3 -3
- package/src/ui/cf-account-picker.ts +7 -9
- package/src/ui/color-selector.ts +9 -5
- package/src/ui/dynamic-slot.ts +7 -8
- package/src/ui/expression-editor.ts +112 -105
- package/src/ui/form-controls.ts +57 -48
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +44 -31
- package/src/ui/media-picker.ts +18 -9
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +113 -70
- package/src/ui/surface.ts +71 -8
- package/src/ui/timing.ts +9 -0
- package/src/ui/value-source.ts +44 -31
- package/src/ui/virtual-window.ts +3 -2
- package/src/utils/base64.ts +3 -1
- package/src/utils/edit-display.ts +73 -73
- package/src/utils/element-selectors.ts +3 -2
- package/src/utils/google-fonts.ts +15 -14
- package/src/utils/inherited-style.ts +18 -20
- package/src/utils/link-target.ts +1 -1
- package/src/utils/preview-format.ts +25 -3
- package/src/utils/strip-events.ts +49 -22
- package/src/utils/studio-utils.ts +29 -14
- package/src/view.ts +2 -3
- package/src/workspace/pane-derive.ts +10 -12
- package/src/workspace/session.ts +53 -43
- package/src/workspace/workspace.ts +40 -36
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-t6b6qe31.js +0 -5
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
|
@@ -38,6 +38,11 @@ export interface CloudSignal {
|
|
|
38
38
|
project: CloudProject | null;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
declare global {
|
|
42
|
+
/** Published by the cloud shell's boot module before the studio bundle evaluates. */
|
|
43
|
+
var __jxCloud: CloudSignal | undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
/**
|
|
42
47
|
* Why Studio will not fall back to the dev-server adapter, most specific evidence first.
|
|
43
48
|
*
|
|
@@ -86,13 +91,14 @@ const BACKENDLESS_SCHEMES: ReadonlySet<string> = new Set(["views:", "file:"]);
|
|
|
86
91
|
|
|
87
92
|
/** Read the boot environment from the live globals and document. */
|
|
88
93
|
export function bootEnvironment(): BootEnvironment {
|
|
89
|
-
|
|
94
|
+
// A DOM-less host (a test runner, a worker) has no document or location to read.
|
|
95
|
+
const doc = typeof document === "undefined" ? undefined : document;
|
|
90
96
|
const meta = `meta[name="${BOOT_META.name}"][content="${BOOT_META.content}"]`;
|
|
91
97
|
return {
|
|
92
|
-
cloud:
|
|
98
|
+
cloud: globalThis.__jxCloud != null,
|
|
93
99
|
declared: doc?.querySelector(meta) != null,
|
|
94
100
|
launcher: launcherSignal(),
|
|
95
|
-
protocol:
|
|
101
|
+
protocol: typeof location === "undefined" ? "" : location.protocol,
|
|
96
102
|
};
|
|
97
103
|
}
|
|
98
104
|
|
|
@@ -159,6 +165,6 @@ export function resolveDefaultPlatform(): StudioPlatform {
|
|
|
159
165
|
if (refusal) {
|
|
160
166
|
throw new PlatformUnavailableError(refusal);
|
|
161
167
|
}
|
|
162
|
-
const cloud =
|
|
168
|
+
const cloud = globalThis.__jxCloud;
|
|
163
169
|
return cloud ? createCloudPlatform(cloud.project) : createDevServerPlatform();
|
|
164
170
|
}
|
|
@@ -13,9 +13,9 @@ import { canPickDirectory, pickDirectoryPath } from "../services/directory-picke
|
|
|
13
13
|
import { negotiateCollab } from "@jxsuite/collab/negotiate";
|
|
14
14
|
import type { CollabNegotiation } from "@jxsuite/collab/negotiate";
|
|
15
15
|
import type { WsCollabConnection } from "@jxsuite/collab/client";
|
|
16
|
-
import
|
|
16
|
+
import { isFunction } from "@jxsuite/schema/guards";
|
|
17
|
+
import type { JsonObject, JsonValue, JxMutableNode, ProjectConfig } from "@jxsuite/schema/types";
|
|
17
18
|
import type {
|
|
18
|
-
CreateProjectDestination,
|
|
19
19
|
DataConnectionsResponse,
|
|
20
20
|
DataConnectionTestResult,
|
|
21
21
|
DataPushResult,
|
|
@@ -35,20 +35,22 @@ import type {
|
|
|
35
35
|
ProjectSchemasResponse,
|
|
36
36
|
ReferencesResult,
|
|
37
37
|
RenameResult,
|
|
38
|
-
|
|
38
|
+
KeyValuePatch,
|
|
39
39
|
SecretsSetResponse,
|
|
40
40
|
SiteBuildResult,
|
|
41
41
|
SitePreviewResult,
|
|
42
42
|
StarterInfo,
|
|
43
|
+
StudioPlatform,
|
|
43
44
|
} from "../types";
|
|
44
45
|
import { problemDetail, problemMessage } from "@jxsuite/protocol";
|
|
46
|
+
import type { CfProxyEnvelope } from "./cloud";
|
|
45
47
|
import type { UploadResult } from "@jxsuite/protocol";
|
|
46
48
|
|
|
47
|
-
/** A directory entry from the server, tolerating extra wire fields. */
|
|
48
|
-
type WireDirEntry = DirEntry & Record<string, unknown>;
|
|
49
|
-
|
|
50
49
|
/** Parse a fetch Response body as JSON, asserting the expected shape at the boundary. */
|
|
51
50
|
async function readJson<T>(res: Response): Promise<T> {
|
|
51
|
+
/* SAFETY: every route read here is a `/__studio/*` route of @jxsuite/server (specs/server.md §4),
|
|
52
|
+
whose replies have the shapes ../types and the wire interfaces in this file describe, and each
|
|
53
|
+
caller names the type of the route it called. */
|
|
52
54
|
return (await res.json()) as T;
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -56,11 +58,46 @@ interface ErrorBody {
|
|
|
56
58
|
error?: string;
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
/** One entry of the `/__studio/sites` glob: a site's folder and its parsed project.json. */
|
|
59
62
|
interface SiteEntry {
|
|
60
|
-
config:
|
|
63
|
+
config: ProjectConfig | null;
|
|
61
64
|
path: string;
|
|
62
65
|
}
|
|
63
66
|
|
|
67
|
+
/**
|
|
68
|
+
* `GET /__studio/project-info`: what the server knows about a folder. The route sends more than
|
|
69
|
+
* Studio reads (`projectRoot` among them), and those members ride along untouched.
|
|
70
|
+
*/
|
|
71
|
+
interface ProjectInfoReply {
|
|
72
|
+
isSiteProject: boolean;
|
|
73
|
+
projectConfig?: ProjectConfig | null;
|
|
74
|
+
directories?: string[];
|
|
75
|
+
[member: string]: JsonValue | ProjectConfig | undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The body of an `fs` event on the `/__reload` stream (the server's watcher batches them). */
|
|
79
|
+
interface FsEventBatch {
|
|
80
|
+
events?: FsEvent[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** `showDirectoryPicker()` (WICG File System Access), which only Chromium-based browsers expose. */
|
|
84
|
+
type ShowDirectoryPicker = (options: { mode: string }) => Promise<FileSystemDirectoryHandle>;
|
|
85
|
+
|
|
86
|
+
/** True when the window implements the File System Access directory picker. */
|
|
87
|
+
function hasDirectoryPicker(
|
|
88
|
+
host: Window,
|
|
89
|
+
): host is Window & { showDirectoryPicker: ShowDirectoryPicker } {
|
|
90
|
+
return "showDirectoryPicker" in host && isFunction(host.showDirectoryPicker);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** The options object {@link StudioPlatform.createProject} takes. */
|
|
94
|
+
type CreateProjectOptions = Parameters<StudioPlatform["createProject"]>[0];
|
|
95
|
+
|
|
96
|
+
/** What a row insert or update answers: the row as stored. */
|
|
97
|
+
interface DataRowWrite {
|
|
98
|
+
row: JsonObject;
|
|
99
|
+
}
|
|
100
|
+
|
|
64
101
|
/**
|
|
65
102
|
* Create a DevServerPlatform instance.
|
|
66
103
|
*
|
|
@@ -117,7 +154,7 @@ export function createDevServerPlatform() {
|
|
|
117
154
|
method: "POST",
|
|
118
155
|
});
|
|
119
156
|
if (!res.ok) {
|
|
120
|
-
const body =
|
|
157
|
+
const body = await readJson<ErrorBody>(res).catch((): ErrorBody => ({}));
|
|
121
158
|
throw new Error(
|
|
122
159
|
`Could not open ${root}: ${problemDetail(body) ?? `activation failed (${res.status})`}`,
|
|
123
160
|
);
|
|
@@ -134,7 +171,7 @@ export function createDevServerPlatform() {
|
|
|
134
171
|
if (!_projectRoot) {
|
|
135
172
|
return;
|
|
136
173
|
}
|
|
137
|
-
_activation = postActivate(_projectRoot).catch((error
|
|
174
|
+
_activation = postActivate(_projectRoot).catch((error) => {
|
|
138
175
|
console.error("Project re-activation failed:", error);
|
|
139
176
|
});
|
|
140
177
|
}
|
|
@@ -171,6 +208,36 @@ export function createDevServerPlatform() {
|
|
|
171
208
|
return p.startsWith(`${_projectRoot}/`) ? p.slice(_projectRoot.length + 1) : p;
|
|
172
209
|
}
|
|
173
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Native folder chooser for the New Project modal's Browse… button. Present only when the browser
|
|
213
|
+
* implements `showDirectoryPicker` (Chromium-based); elsewhere the member stays undefined and the
|
|
214
|
+
* modal falls back to a typed Location field.
|
|
215
|
+
*
|
|
216
|
+
* The picked handle carries no filesystem path, so it is resolved by the id the picker tags the
|
|
217
|
+
* folder with (see `@jxsuite/studio/directory-picker`). Resolves `null` only when the user
|
|
218
|
+
* dismisses the chooser; every other failure rejects with a sentence the modal shows under
|
|
219
|
+
* Location. So `locate` keeps the helper's contract: `null` is "no folder holds this id" (the
|
|
220
|
+
* route's 200 `{ path: null }`), and a non-ok answer throws the problem the server sent rather
|
|
221
|
+
* than posing as a miss. A network failure (`TypeError: Failed to fetch`, e.g. a page that is not
|
|
222
|
+
* being served by the dev server at all) propagates as is, and the picker names it.
|
|
223
|
+
*/
|
|
224
|
+
const directoryPicking: Pick<StudioPlatform, "pickDirectory"> = {};
|
|
225
|
+
if (canPickDirectory()) {
|
|
226
|
+
directoryPicking.pickDirectory = async (): Promise<string | null> =>
|
|
227
|
+
pickDirectoryPath(async ({ id, name }) => {
|
|
228
|
+
const res = await fetch(
|
|
229
|
+
`/__studio/locate-directory?name=${encodeURIComponent(name)}&id=${encodeURIComponent(id)}`,
|
|
230
|
+
);
|
|
231
|
+
if (!res.ok) {
|
|
232
|
+
// A proxy, or a `views://` host with no dev server behind it, may answer in HTML.
|
|
233
|
+
const body = await readJson<JsonValue>(res).catch(() => null);
|
|
234
|
+
throw new Error(problemMessage(body, res.status));
|
|
235
|
+
}
|
|
236
|
+
const found = await readJson<{ path?: string | null }>(res);
|
|
237
|
+
return found.path ?? null;
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
174
241
|
return {
|
|
175
242
|
id: "devserver",
|
|
176
243
|
|
|
@@ -189,7 +256,7 @@ export function createDevServerPlatform() {
|
|
|
189
256
|
// Fire-and-forget: callers that need the binding in place before reading await activate()
|
|
190
257
|
// Themselves. The rejection is reported rather than dropped — an unactivated root leaves
|
|
191
258
|
// Every rootless endpoint (git especially) operating on the server's OWN root.
|
|
192
|
-
_activation = this.activate(_projectRoot).catch((error
|
|
259
|
+
_activation = this.activate(_projectRoot).catch((error) => {
|
|
193
260
|
console.error("Project activation failed:", error);
|
|
194
261
|
});
|
|
195
262
|
}
|
|
@@ -213,17 +280,14 @@ export function createDevServerPlatform() {
|
|
|
213
280
|
|
|
214
281
|
async openProject() {
|
|
215
282
|
// Use Chrome's showDirectoryPicker API
|
|
216
|
-
|
|
283
|
+
const host = window;
|
|
284
|
+
if (!hasDirectoryPicker(host)) {
|
|
217
285
|
throw new Error("showDirectoryPicker not available — use a Chromium-based browser");
|
|
218
286
|
}
|
|
219
287
|
|
|
220
288
|
let dirHandle;
|
|
221
289
|
try {
|
|
222
|
-
dirHandle = await (
|
|
223
|
-
window as unknown as {
|
|
224
|
-
showDirectoryPicker: (opts: { mode: string }) => Promise<FileSystemDirectoryHandle>;
|
|
225
|
-
}
|
|
226
|
-
).showDirectoryPicker({ mode: "readwrite" });
|
|
290
|
+
dirHandle = await host.showDirectoryPicker({ mode: "readwrite" });
|
|
227
291
|
} catch (error) {
|
|
228
292
|
// User cancelled the picker
|
|
229
293
|
if (error instanceof Error && error.name === "AbortError") {
|
|
@@ -241,6 +305,9 @@ export function createDevServerPlatform() {
|
|
|
241
305
|
}
|
|
242
306
|
|
|
243
307
|
const file = await siteHandle.getFile();
|
|
308
|
+
/* SAFETY: the user picked this folder as a project, and project.json is that project's own
|
|
309
|
+
config file; it is matched below against the server's parse of the same file, and every
|
|
310
|
+
adapter hands project.json to Studio as the ProjectConfig the session edits. */
|
|
244
311
|
const config = JSON.parse(await file.text()) as ProjectConfig;
|
|
245
312
|
|
|
246
313
|
// Resolve server-relative path by matching against known sites
|
|
@@ -297,12 +364,7 @@ export function createDevServerPlatform() {
|
|
|
297
364
|
? await readJson<{ name: string; root: string }>(projectRes)
|
|
298
365
|
: { name: "project", root: "." };
|
|
299
366
|
const info = infoRes.ok
|
|
300
|
-
? await readJson<
|
|
301
|
-
isSiteProject: boolean;
|
|
302
|
-
projectConfig?: ProjectConfig | null;
|
|
303
|
-
directories?: string[];
|
|
304
|
-
[key: string]: unknown;
|
|
305
|
-
}>(infoRes)
|
|
367
|
+
? await readJson<ProjectInfoReply>(infoRes)
|
|
306
368
|
: { isSiteProject: false };
|
|
307
369
|
return { info, meta };
|
|
308
370
|
} catch {
|
|
@@ -315,27 +377,8 @@ export function createDevServerPlatform() {
|
|
|
315
377
|
/**
|
|
316
378
|
* Scaffold a project at `destination.parent/directory`. The dev server refuses the request
|
|
317
379
|
* outright when no destination is supplied — it will not fall back to its own root.
|
|
318
|
-
*
|
|
319
|
-
* @param {{
|
|
320
|
-
* name: string;
|
|
321
|
-
* description?: string;
|
|
322
|
-
* url?: string;
|
|
323
|
-
* adapter?: string;
|
|
324
|
-
* directory: string;
|
|
325
|
-
* destination: CreateProjectDestination;
|
|
326
|
-
* }} opts
|
|
327
380
|
*/
|
|
328
|
-
async createProject(opts: {
|
|
329
|
-
name: string;
|
|
330
|
-
description?: string;
|
|
331
|
-
url?: string;
|
|
332
|
-
adapter?: string;
|
|
333
|
-
directory: string;
|
|
334
|
-
destination: CreateProjectDestination;
|
|
335
|
-
starter?: string;
|
|
336
|
-
template?: string;
|
|
337
|
-
design?: Record<string, unknown>;
|
|
338
|
-
}) {
|
|
381
|
+
async createProject(opts: CreateProjectOptions) {
|
|
339
382
|
const res = await fetch("/__studio/create-project", {
|
|
340
383
|
body: JSON.stringify(opts),
|
|
341
384
|
headers: { "Content-Type": "application/json" },
|
|
@@ -348,37 +391,7 @@ export function createDevServerPlatform() {
|
|
|
348
391
|
return await res.json();
|
|
349
392
|
},
|
|
350
393
|
|
|
351
|
-
|
|
352
|
-
* Native folder chooser for the New Project modal's Browse… button. Present only when the
|
|
353
|
-
* browser implements `showDirectoryPicker` (Chromium-based); elsewhere the member stays
|
|
354
|
-
* undefined and the modal falls back to a typed Location field.
|
|
355
|
-
*
|
|
356
|
-
* The picked handle carries no filesystem path, so it is resolved by the id the picker tags the
|
|
357
|
-
* folder with (see `@jxsuite/studio/directory-picker`). Resolves `null` only when the user
|
|
358
|
-
* dismisses the chooser; every other failure rejects with a sentence the modal shows under
|
|
359
|
-
* Location. So `locate` keeps the helper's contract: `null` is "no folder holds this id" (the
|
|
360
|
-
* route's 200 `{ path: null }`), and a non-ok answer throws the problem the server sent rather
|
|
361
|
-
* than posing as a miss. A network failure (`TypeError: Failed to fetch`, e.g. a page that is
|
|
362
|
-
* not being served by the dev server at all) propagates as is, and the picker names it.
|
|
363
|
-
*/
|
|
364
|
-
...(canPickDirectory()
|
|
365
|
-
? {
|
|
366
|
-
async pickDirectory(): Promise<string | null> {
|
|
367
|
-
return pickDirectoryPath(async ({ id, name }) => {
|
|
368
|
-
const res = await fetch(
|
|
369
|
-
`/__studio/locate-directory?name=${encodeURIComponent(name)}&id=${encodeURIComponent(id)}`,
|
|
370
|
-
);
|
|
371
|
-
if (!res.ok) {
|
|
372
|
-
// A proxy, or a `views://` host with no dev server behind it, may answer in HTML.
|
|
373
|
-
const body: unknown = await res.json().catch(() => null);
|
|
374
|
-
throw new Error(problemMessage(body, res.status));
|
|
375
|
-
}
|
|
376
|
-
const found = await readJson<{ path?: string | null }>(res);
|
|
377
|
-
return found.path ?? null;
|
|
378
|
-
});
|
|
379
|
-
},
|
|
380
|
-
}
|
|
381
|
-
: {}),
|
|
394
|
+
...directoryPicking,
|
|
382
395
|
|
|
383
396
|
/** List starter templates from the dev server. */
|
|
384
397
|
async listStarters(): Promise<StarterInfo[]> {
|
|
@@ -407,7 +420,7 @@ export function createDevServerPlatform() {
|
|
|
407
420
|
if (!res.ok) {
|
|
408
421
|
throw new Error(`Failed to list directory: ${dir}`);
|
|
409
422
|
}
|
|
410
|
-
const entries = await readJson<
|
|
423
|
+
const entries = await readJson<DirEntry[]>(res);
|
|
411
424
|
for (const e of entries) {
|
|
412
425
|
e.path = stripRoot(e.path);
|
|
413
426
|
}
|
|
@@ -465,10 +478,14 @@ export function createDevServerPlatform() {
|
|
|
465
478
|
if (!res.ok) {
|
|
466
479
|
throw new Error(`Upload failed: ${path}`);
|
|
467
480
|
}
|
|
468
|
-
const body =
|
|
481
|
+
const body = await readJson<Partial<UploadResult>>(res);
|
|
469
482
|
// The dev server echoes the path today; falling back to the request keeps a backend that says
|
|
470
483
|
// Nothing working rather than writing `undefined` into a document.
|
|
471
|
-
|
|
484
|
+
const uploaded: UploadResult = { path: body.path ?? path };
|
|
485
|
+
if (body.size !== undefined) {
|
|
486
|
+
uploaded.size = body.size;
|
|
487
|
+
}
|
|
488
|
+
return uploaded;
|
|
472
489
|
},
|
|
473
490
|
|
|
474
491
|
/** @param {string} path */
|
|
@@ -552,10 +569,12 @@ export function createDevServerPlatform() {
|
|
|
552
569
|
options?.onResync?.("reconnect");
|
|
553
570
|
}
|
|
554
571
|
});
|
|
555
|
-
es.addEventListener("fs", (ev: MessageEvent) => {
|
|
556
|
-
let payload:
|
|
572
|
+
es.addEventListener("fs", (ev: MessageEvent<string>) => {
|
|
573
|
+
let payload: FsEventBatch;
|
|
557
574
|
try {
|
|
558
|
-
|
|
575
|
+
/* SAFETY: `fs` events on /__reload are sent only by @jxsuite/server's watcher, as
|
|
576
|
+
broadcastEvent("fs", { events }) over its batched FsEvent buffer (server watch.ts). */
|
|
577
|
+
payload = JSON.parse(ev.data) as FsEventBatch;
|
|
559
578
|
} catch {
|
|
560
579
|
return;
|
|
561
580
|
}
|
|
@@ -597,7 +616,7 @@ export function createDevServerPlatform() {
|
|
|
597
616
|
}
|
|
598
617
|
if (_collabProbe === null) {
|
|
599
618
|
_collabProbe = fetch("/__studio/collab")
|
|
600
|
-
.then(async (res) => (res.ok ? negotiateCollab(await res
|
|
619
|
+
.then(async (res) => (res.ok ? negotiateCollab(await readJson<JsonValue>(res)) : null))
|
|
601
620
|
.catch(() => null);
|
|
602
621
|
}
|
|
603
622
|
const negotiation = await _collabProbe;
|
|
@@ -694,7 +713,7 @@ export function createDevServerPlatform() {
|
|
|
694
713
|
if (!res.ok) {
|
|
695
714
|
return false;
|
|
696
715
|
}
|
|
697
|
-
const data =
|
|
716
|
+
const data = await readJson<{ needsInstall?: boolean }>(res);
|
|
698
717
|
return Boolean(data.needsInstall);
|
|
699
718
|
},
|
|
700
719
|
|
|
@@ -721,11 +740,8 @@ export function createDevServerPlatform() {
|
|
|
721
740
|
|
|
722
741
|
// ─── Code services (optional) ─────────────────────────────────────────
|
|
723
742
|
|
|
724
|
-
/**
|
|
725
|
-
|
|
726
|
-
* @param {unknown} payload
|
|
727
|
-
*/
|
|
728
|
-
async codeService(action: string, payload: unknown) {
|
|
743
|
+
/** Run one code-service action on the server; null when the route fails or is absent. */
|
|
744
|
+
async codeService(action: string, payload: Parameters<StudioPlatform["codeService"]>[1]) {
|
|
729
745
|
try {
|
|
730
746
|
const res = await fetch(`/__studio/code/${action}`, {
|
|
731
747
|
body: JSON.stringify(payload),
|
|
@@ -788,7 +804,7 @@ export function createDevServerPlatform() {
|
|
|
788
804
|
if (!res.ok) {
|
|
789
805
|
return [];
|
|
790
806
|
}
|
|
791
|
-
const entries = await readJson<
|
|
807
|
+
const entries = await readJson<DirEntry[]>(res);
|
|
792
808
|
for (const e of entries) {
|
|
793
809
|
e.path = stripRoot(e.path);
|
|
794
810
|
}
|
|
@@ -911,26 +927,26 @@ export function createDevServerPlatform() {
|
|
|
911
927
|
return data;
|
|
912
928
|
},
|
|
913
929
|
|
|
914
|
-
async dataInsertRow(req: DataRowInsert): Promise<
|
|
930
|
+
async dataInsertRow(req: DataRowInsert): Promise<DataRowWrite> {
|
|
915
931
|
const res = await fetch(`/__studio/data/rows?dir=${encodeURIComponent(serverPath("."))}`, {
|
|
916
932
|
body: JSON.stringify(req),
|
|
917
933
|
headers: { "Content-Type": "application/json" },
|
|
918
934
|
method: "POST",
|
|
919
935
|
});
|
|
920
|
-
const data = await readJson<
|
|
936
|
+
const data = await readJson<DataRowWrite & ErrorBody>(res);
|
|
921
937
|
if (!res.ok) {
|
|
922
938
|
throw new Error(problemDetail(data) ?? "Insert failed");
|
|
923
939
|
}
|
|
924
940
|
return data;
|
|
925
941
|
},
|
|
926
942
|
|
|
927
|
-
async dataUpdateRow(req: DataRowUpdate): Promise<
|
|
943
|
+
async dataUpdateRow(req: DataRowUpdate): Promise<DataRowWrite> {
|
|
928
944
|
const res = await fetch(`/__studio/data/rows?dir=${encodeURIComponent(serverPath("."))}`, {
|
|
929
945
|
body: JSON.stringify(req),
|
|
930
946
|
headers: { "Content-Type": "application/json" },
|
|
931
947
|
method: "PUT",
|
|
932
948
|
});
|
|
933
|
-
const data = await readJson<
|
|
949
|
+
const data = await readJson<DataRowWrite & ErrorBody>(res);
|
|
934
950
|
if (!res.ok) {
|
|
935
951
|
throw new Error(problemDetail(data) ?? "Update failed");
|
|
936
952
|
}
|
|
@@ -966,7 +982,7 @@ export function createDevServerPlatform() {
|
|
|
966
982
|
},
|
|
967
983
|
|
|
968
984
|
/** Write/remove secrets in the dev server's .dev.vars; names-only response. */
|
|
969
|
-
async setSecrets(req:
|
|
985
|
+
async setSecrets(req: KeyValuePatch): Promise<SecretsSetResponse> {
|
|
970
986
|
const res = await fetch(`/__studio/secrets?dir=${encodeURIComponent(serverPath("."))}`, {
|
|
971
987
|
body: JSON.stringify(req),
|
|
972
988
|
headers: { "Content-Type": "application/json" },
|
|
@@ -982,15 +998,17 @@ export function createDevServerPlatform() {
|
|
|
982
998
|
/**
|
|
983
999
|
* Invoke a format capability (parse/serialize) server-side.
|
|
984
1000
|
*
|
|
985
|
-
* @param
|
|
1001
|
+
* @param payload — { format, action, source?, doc?, options? }
|
|
986
1002
|
*/
|
|
987
|
-
async formatAction(payload:
|
|
1003
|
+
async formatAction(payload: Parameters<NonNullable<StudioPlatform["formatAction"]>>[0]) {
|
|
988
1004
|
const res = await fetch("/__studio/format", {
|
|
989
1005
|
body: JSON.stringify({ ...payload, dir: serverPath(".") }),
|
|
990
1006
|
headers: { "Content-Type": "application/json" },
|
|
991
1007
|
method: "POST",
|
|
992
1008
|
});
|
|
993
|
-
|
|
1009
|
+
/* The format route answers `{ result }` on success (the document a format class's `parse`
|
|
1010
|
+
built, or the text its `serialize` wrote) and a problem document otherwise. */
|
|
1011
|
+
const data = await readJson<JsonObject & { result: JxMutableNode | string }>(res);
|
|
994
1012
|
if (!res.ok) {
|
|
995
1013
|
throw new Error(problemDetail(data) ?? "Format action failed");
|
|
996
1014
|
}
|
|
@@ -1016,14 +1034,13 @@ export function createDevServerPlatform() {
|
|
|
1016
1034
|
if (!res.ok) {
|
|
1017
1035
|
return null;
|
|
1018
1036
|
}
|
|
1019
|
-
const { schema } = await readJson<{ schema:
|
|
1037
|
+
const { schema } = await readJson<{ schema: JsonValue }>(res);
|
|
1020
1038
|
return schema;
|
|
1021
1039
|
},
|
|
1022
1040
|
|
|
1023
1041
|
// ─── Class resolution (dev-proxy) ─────────────────────────────────────
|
|
1024
1042
|
|
|
1025
|
-
|
|
1026
|
-
async resolveClass(body: Record<string, unknown>) {
|
|
1043
|
+
async resolveClass(body: Parameters<NonNullable<StudioPlatform["resolveClass"]>>[0]) {
|
|
1027
1044
|
const res = await fetch("/__jx_resolve__", {
|
|
1028
1045
|
body: JSON.stringify(body),
|
|
1029
1046
|
headers: { "content-type": "application/json" },
|
|
@@ -1032,7 +1049,7 @@ export function createDevServerPlatform() {
|
|
|
1032
1049
|
if (!res.ok) {
|
|
1033
1050
|
throw new Error(`Class resolution failed: ${res.status}`);
|
|
1034
1051
|
}
|
|
1035
|
-
return await readJson<
|
|
1052
|
+
return await readJson<JsonValue>(res);
|
|
1036
1053
|
},
|
|
1037
1054
|
|
|
1038
1055
|
// ─── Git operations ──────────────────────────────────────────────────
|
|
@@ -1229,7 +1246,7 @@ export function createDevServerPlatform() {
|
|
|
1229
1246
|
const body = await readJson<ErrorBody>(res);
|
|
1230
1247
|
throw new Error(problemDetail(body) ?? "The site could not be built.");
|
|
1231
1248
|
}
|
|
1232
|
-
return
|
|
1249
|
+
return await readJson<SiteBuildResult>(res);
|
|
1233
1250
|
},
|
|
1234
1251
|
|
|
1235
1252
|
/**
|
|
@@ -1248,7 +1265,7 @@ export function createDevServerPlatform() {
|
|
|
1248
1265
|
const body = await readJson<ErrorBody>(res);
|
|
1249
1266
|
throw new Error(problemDetail(body) ?? "The site could not be previewed.");
|
|
1250
1267
|
}
|
|
1251
|
-
return
|
|
1268
|
+
return await readJson<SitePreviewResult>(res);
|
|
1252
1269
|
},
|
|
1253
1270
|
|
|
1254
1271
|
async setPreviewOverlay(path: string, contents: string) {
|
|
@@ -1300,12 +1317,7 @@ export function createDevServerPlatform() {
|
|
|
1300
1317
|
headers: { "Content-Type": "application/json", "X-CF-Token": token },
|
|
1301
1318
|
body: JSON.stringify({ path: apiPath, method: init?.method ?? "GET", body: init?.body }),
|
|
1302
1319
|
});
|
|
1303
|
-
const envelope =
|
|
1304
|
-
success?: boolean;
|
|
1305
|
-
result?: unknown;
|
|
1306
|
-
errors?: { message: string }[];
|
|
1307
|
-
error?: string;
|
|
1308
|
-
};
|
|
1320
|
+
const envelope = await readJson<CfProxyEnvelope>(res);
|
|
1309
1321
|
if (!res.ok || envelope.success === false) {
|
|
1310
1322
|
const message =
|
|
1311
1323
|
envelope.errors?.map((e) => e.message).join("; ") ?? envelope.error ?? res.statusText;
|
|
@@ -1322,10 +1334,13 @@ export function createDevServerPlatform() {
|
|
|
1322
1334
|
return null;
|
|
1323
1335
|
}
|
|
1324
1336
|
try {
|
|
1325
|
-
const
|
|
1326
|
-
if (!
|
|
1337
|
+
const result = await this.cfApi("/accounts");
|
|
1338
|
+
if (!Array.isArray(result) || result.length === 0) {
|
|
1327
1339
|
return { connected: false };
|
|
1328
1340
|
}
|
|
1341
|
+
/* SAFETY: cfApi resolved the v4 envelope's `result`, and Cloudflare documents GET /accounts
|
|
1342
|
+
as answering an array of account objects, each with a string `id` and `name`. */
|
|
1343
|
+
const accounts = result as { id: string; name: string }[];
|
|
1329
1344
|
const chosen = accounts.find((a) => a.id === getCfAccountId()) ?? accounts[0]!;
|
|
1330
1345
|
setCfAccountId(chosen.id);
|
|
1331
1346
|
return { connected: true, accountId: chosen.id, accountName: chosen.name };
|
|
@@ -1343,14 +1358,11 @@ export function createDevServerPlatform() {
|
|
|
1343
1358
|
return [];
|
|
1344
1359
|
}
|
|
1345
1360
|
const sites = await readJson<SiteEntry[]>(res);
|
|
1346
|
-
return sites.map((site) => {
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
description: site.path,
|
|
1352
|
-
};
|
|
1353
|
-
});
|
|
1361
|
+
return sites.map((site) => ({
|
|
1362
|
+
name: site.config?.name || site.path.split("/").at(-1) || site.path,
|
|
1363
|
+
root: site.path,
|
|
1364
|
+
description: site.path,
|
|
1365
|
+
}));
|
|
1354
1366
|
},
|
|
1355
1367
|
|
|
1356
1368
|
// ─── AI Assistant (Stack B: OpenAI-compatible SSE proxy) ───────────────────
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
import { READ_FILES_MAX_PATHS } from "@jxsuite/protocol";
|
|
23
23
|
import type { ReadFilesResult } from "@jxsuite/protocol";
|
|
24
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* What one batch request came back as.
|
|
@@ -57,14 +58,20 @@ export interface ReadBatcher {
|
|
|
57
58
|
|
|
58
59
|
interface Waiter {
|
|
59
60
|
resolve: (content: string) => void;
|
|
60
|
-
|
|
61
|
+
/** Rejects with whatever the transport or `fetchOne` rejected with, unchanged. */
|
|
62
|
+
reject: (cause: unknown) => void;
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
/** Path → every caller waiting on it. Same-path reads in one window share ONE request and result. */
|
|
64
66
|
type Pending = Map<string, Waiter[]>;
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
/**
|
|
69
|
+
* A row's outcome as the batcher reads it. Every protocol outcome fits it, but the rows come off
|
|
70
|
+
* the wire unchecked, so `content` may be any value and either member may be missing.
|
|
71
|
+
*/
|
|
72
|
+
interface WireOutcome {
|
|
73
|
+
content?: unknown;
|
|
74
|
+
error?: { message?: string } | undefined;
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
/**
|
|
@@ -108,7 +115,7 @@ export function createReadBatcher(options: ReadBatcherOptions): ReadBatcher {
|
|
|
108
115
|
waiter.resolve(content);
|
|
109
116
|
}
|
|
110
117
|
},
|
|
111
|
-
(error
|
|
118
|
+
(error) => {
|
|
112
119
|
for (const waiter of waiters) {
|
|
113
120
|
waiter.reject(error);
|
|
114
121
|
}
|
|
@@ -182,7 +189,7 @@ export function createReadBatcher(options: ReadBatcherOptions): ReadBatcher {
|
|
|
182
189
|
}
|
|
183
190
|
/* Anything that is not an object cannot be a ReadFilesResult (a `null` body, a bare string).
|
|
184
191
|
The route did not answer this chunk, so it is served singly — the same as a failed call. */
|
|
185
|
-
if (answer === "retry-singly" || answer === "unsupported" || !
|
|
192
|
+
if (answer === "retry-singly" || answer === "unsupported" || !isNonNullObject(answer)) {
|
|
186
193
|
if (answer === "unsupported") {
|
|
187
194
|
batching = false;
|
|
188
195
|
}
|
|
@@ -213,14 +220,15 @@ export function createReadBatcher(options: ReadBatcherOptions): ReadBatcher {
|
|
|
213
220
|
}
|
|
214
221
|
chunk.delete(path);
|
|
215
222
|
answered += 1;
|
|
216
|
-
|
|
217
|
-
|
|
223
|
+
const wire: WireOutcome | undefined = outcome;
|
|
224
|
+
const content = wire?.content;
|
|
225
|
+
if (isString(content)) {
|
|
218
226
|
for (const waiter of waiters) {
|
|
219
227
|
waiter.resolve(content);
|
|
220
228
|
}
|
|
221
229
|
} else {
|
|
222
230
|
// Per path: one missing file (404), one binary file (415) fails ITS readers and no others.
|
|
223
|
-
const message =
|
|
231
|
+
const message = wire?.error?.message;
|
|
224
232
|
const error = new Error(message || `Failed to read file: ${path}`);
|
|
225
233
|
for (const waiter of waiters) {
|
|
226
234
|
waiter.reject(error);
|
package/src/project-list.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* member (dev server sites, cloud platforms). Hydrated once at boot (studio.ts) like the
|
|
4
4
|
* recent-projects cache; the welcome screen reads it synchronously.
|
|
5
5
|
*/
|
|
6
|
+
import { isFunction } from "@jxsuite/schema/guards";
|
|
6
7
|
import { getPlatform, hasPlatform } from "./platform";
|
|
7
8
|
import type { ProjectListEntry } from "./types";
|
|
8
9
|
|
|
@@ -10,7 +11,7 @@ let cache: ProjectListEntry[] = [];
|
|
|
10
11
|
|
|
11
12
|
/** True when the active platform exposes a project catalogue. */
|
|
12
13
|
export function platformListsProjects(): boolean {
|
|
13
|
-
return hasPlatform() &&
|
|
14
|
+
return hasPlatform() && isFunction(getPlatform().listProjects);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
/** Refresh the cache from the platform; resolves to [] when unsupported or failing. */
|
|
@@ -75,7 +75,7 @@ export interface DeployStep {
|
|
|
75
75
|
|
|
76
76
|
/** The active project's configuration, or null when no project is open. */
|
|
77
77
|
function currentConfig(): ProjectConfig | null {
|
|
78
|
-
return
|
|
78
|
+
return projectState?.projectConfig ?? null;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/**
|
|
@@ -152,6 +152,11 @@ function repoStep(): DeployStep {
|
|
|
152
152
|
};
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
/** The remotes a host's git status actually carries: a host may omit the array altogether. */
|
|
156
|
+
interface ReportedRemotes {
|
|
157
|
+
remotes?: string[] | undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
155
160
|
function remoteStep(): DeployStep {
|
|
156
161
|
const { status } = shell.git;
|
|
157
162
|
if (status === null || !status.isRepo) {
|
|
@@ -165,7 +170,8 @@ function remoteStep(): DeployStep {
|
|
|
165
170
|
}
|
|
166
171
|
// A GitStatus from a host that reports no remotes array is not a repo with remotes — it is a
|
|
167
172
|
// Host that did not say. Reading through it took the whole status bar down with a TypeError.
|
|
168
|
-
|
|
173
|
+
const reported: ReportedRemotes = status;
|
|
174
|
+
if ((reported.remotes ?? []).length === 0) {
|
|
169
175
|
return {
|
|
170
176
|
command: "git.createGithubRepository",
|
|
171
177
|
detail: "This repository is local only — nothing outside this machine can build it.",
|