@jxsuite/studio 5.7.0 → 6.0.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.
- package/dist/chunks/{cf-account-picker-882a7ecm.js → cf-account-picker-bb2yq946.js} +2 -2
- package/dist/chunks/content-source-t0q184js.js +4 -0
- package/dist/chunks/{convert-to-repeater-grfep2w8.js → convert-to-repeater-vqkt7s3s.js} +2 -2
- package/dist/chunks/entry-commands-fxzgcc4k.js +4 -0
- package/dist/chunks/{extension-sections-dp8endhx.js → extension-sections-8beq9ac3.js} +2 -2
- package/dist/chunks/file-ops-2n77759h.js +4 -0
- package/dist/chunks/files-fjy7zpxt.js +4 -0
- package/dist/chunks/{format-host-e2pjvd25.js → format-host-wj3mf3n8.js} +2 -2
- package/dist/chunks/fs-events-7kcgn4e9.js +4 -0
- package/dist/chunks/git-panel-7z2mpt2d.js +4 -0
- package/dist/chunks/{grid-view-5amhg604.js → grid-view-ca10def6.js} +2 -2
- package/dist/chunks/{iframe-host-t819mcg5.js → iframe-host-a0zjd6xp.js} +2 -2
- package/dist/chunks/{layers-4bsr82wz.js → layers-p677nrh5.js} +2 -2
- package/dist/chunks/layers-panel-y4w1dq90.js +4 -0
- package/dist/chunks/media-picker-xg7yjpz9.js +4 -0
- package/dist/chunks/menu-fpekzj6w.js +4 -0
- package/dist/chunks/publish-panel-xtbfgg2r.js +4 -0
- package/dist/chunks/quick-search-d3a6m7j3.js +4 -0
- package/dist/chunks/right-panel-31vbk5xp.js +4 -0
- package/dist/chunks/studio-1q6amtph.js +5 -0
- package/dist/chunks/{studio-56z7evx4.js → studio-3ck2a5c4.js} +2 -2
- package/dist/chunks/{studio-gh97gngt.js → studio-4fde4a0x.js} +2 -2
- package/dist/chunks/{studio-gfn1kpxj.js → studio-4jj9gme2.js} +3 -3
- package/dist/chunks/{studio-zpnk016a.js → studio-4m50vh74.js} +3 -3
- package/dist/chunks/{studio-dkn3x3hz.js → studio-4r0sjtx8.js} +2 -2
- package/dist/chunks/{studio-a7xqhc3n.js → studio-5d7wfmnp.js} +2 -2
- package/dist/chunks/{studio-ceb34dxj.js → studio-5gs9th4b.js} +2 -2
- package/dist/chunks/{studio-j6gnhvaa.js → studio-5vy2wfm5.js} +2 -2
- package/dist/chunks/{studio-spf2skgc.js → studio-7qvs7v0m.js} +2 -2
- package/dist/chunks/{studio-e6re3rk1.js → studio-84rtc120.js} +2 -2
- package/dist/chunks/{studio-nt06yybj.js → studio-8xcwewjq.js} +2 -2
- package/dist/chunks/{studio-cxt150pj.js → studio-aekhcdzw.js} +2 -2
- package/dist/chunks/{studio-222rqyyc.js → studio-bftp4n4b.js} +2 -2
- package/dist/chunks/{studio-xta2vxp6.js → studio-capk0583.js} +2 -2
- package/dist/chunks/{studio-wma2c6g8.js → studio-cbr9czkn.js} +2 -2
- package/dist/chunks/{studio-c9d3pxf7.js → studio-chdmwwzw.js} +2 -2
- package/dist/chunks/{studio-0k9mvpgj.js → studio-cp1gbff9.js} +2 -2
- package/dist/chunks/{studio-1x8x26k3.js → studio-cqmtbg2p.js} +2 -2
- package/dist/chunks/{studio-c6w3tq7t.js → studio-e47215hh.js} +2 -2
- package/dist/chunks/{studio-frb0qbf7.js → studio-fbx6twps.js} +2 -2
- package/dist/chunks/{studio-xk0z6msk.js → studio-fthwn4kf.js} +2 -2
- package/dist/chunks/{studio-0scebvb9.js → studio-g8dsj3d2.js} +2 -2
- package/dist/chunks/{studio-54g077x3.js → studio-ge5fqjth.js} +2 -2
- package/dist/chunks/{studio-p7c1agz0.js → studio-gjknvzam.js} +3 -3
- package/dist/chunks/{studio-mwxgyn9h.js → studio-hnvnfbdv.js} +3 -3
- package/dist/chunks/{studio-9mqfamps.js → studio-mk00zd5d.js} +2 -2
- package/dist/chunks/{studio-skzanb0k.js → studio-qa73881a.js} +2 -2
- package/dist/chunks/{studio-xry7tk3z.js → studio-rmn2dz59.js} +2 -2
- package/dist/chunks/{studio-eh0rac07.js → studio-rr4xkv81.js} +2 -2
- package/dist/chunks/{studio-f195h2hq.js → studio-tmeq6mjb.js} +2 -2
- package/dist/chunks/{studio-cvbkkfqb.js → studio-x5g1xk77.js} +2 -2
- package/dist/chunks/{studio-65fhspdd.js → studio-xg1942as.js} +2 -2
- package/dist/chunks/{studio-888knnkc.js → studio-xkfs0dp2.js} +2 -2
- package/dist/chunks/{studio-xy3tv3az.js → studio-zev8ssp1.js} +3 -3
- package/dist/chunks/{studio-tw7rre6s.js → studio-ztvcxm3w.js} +2 -2
- package/dist/chunks/{workspace-b69mgm0e.js → workspace-5vmgsagj.js} +2 -2
- package/dist/iframe-entry.js +3 -3
- package/dist/manifest.json +36 -36
- package/dist/studio.js +10 -10
- package/package.json +11 -11
- package/src/ui/schema-form.ts +6 -2
- package/dist/chunks/content-source-37x3vsap.js +0 -4
- package/dist/chunks/entry-commands-c5h3nqck.js +0 -4
- package/dist/chunks/file-ops-937cvqk6.js +0 -4
- package/dist/chunks/files-tznwe1p1.js +0 -4
- package/dist/chunks/fs-events-fv64ak3s.js +0 -4
- package/dist/chunks/git-panel-gb713ttc.js +0 -4
- package/dist/chunks/layers-panel-b6shnaax.js +0 -4
- package/dist/chunks/media-picker-ej0kdh1j.js +0 -4
- package/dist/chunks/menu-rtxf9chb.js +0 -4
- package/dist/chunks/publish-panel-bq36xcmj.js +0 -4
- package/dist/chunks/quick-search-zm00h9dh.js +0 -4
- package/dist/chunks/right-panel-pq2f71q3.js +0 -4
- package/dist/chunks/studio-693nhyky.js +0 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{_k}from"./studio-
|
|
1
|
+
import{_k}from"./studio-cp1gbff9.js";import{T,R,vs,Nm}from"./studio-7qvs7v0m.js";import{v}from"./studio-fqq890ap.js";import{Oe}from"./studio-vavmwshr.js";var w={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMenu",$description:"A Studio menu: one jx-menu whose rows are a projection of command records the adapter hands in as `rows`. Nothing here decides what a row says; a row prints its record's title, chord, disabled reason and destructive flag, a divider falls where the adapter marked a group boundary, and a row with children owns a one-level submenu of the same shape. The chord and the reason are rendered only when present, so a row's text is its title.",tagName:"jx-menu",$props:{label:{$ref:"#/state/label"},x:{$ref:"#/state/x"},y:{$ref:"#/state/y"},floor:{$ref:"#/state/floor"},placement:{$ref:"#/state/placement"}},onselect:{$ref:"#/state/select"},children:[{$prototype:"Array",items:{$ref:"#/state/rows"},key:{$ref:"$map/item/id"},map:{tagName:"div",attributes:{role:"none"},children:[{tagName:"div",attributes:{role:"none"},$switch:{$ref:"$map/item/dividerAbove"},cases:{true:{tagName:"hr"}}},{tagName:"jx-menu-item",$props:{value:{$ref:"$map/item/id"},disabled:{$ref:"$map/item/disabled"},destructive:{$ref:"$map/item/destructive"},requires:{$ref:"$map/item/requires"},checked:{$ref:"$map/item/checked"},haspopup:{$ref:"$map/item/haspopup"}},attributes:{"data-command-id":"${$map.item.id}"},children:[{tagName:"span",textContent:"${$map.item.title}"},{tagName:"span",attributes:{slot:"value"},$switch:{$ref:"$map/item/noChord"},cases:{false:{tagName:"kbd",textContent:"${$map.item.chord}"}}},{tagName:"span",attributes:{slot:"description"},$switch:{$ref:"$map/item/enabled"},cases:{false:{tagName:"span",textContent:"Needs ${$map.item.requires}"}}},{tagName:"span",attributes:{slot:"submenu"},$switch:{$ref:"$map/item/haspopup"},cases:{true:{tagName:"jx-menu",$props:{label:{$ref:"$map/item/submenuLabel"}},children:[{$prototype:"Array",items:{$ref:"$map/item/children"},key:{$ref:"$map/item/id"},map:{tagName:"div",attributes:{role:"none"},children:[{tagName:"div",attributes:{role:"none"},$switch:{$ref:"$map/item/dividerAbove"},cases:{true:{tagName:"hr"}}},{tagName:"jx-menu-item",$props:{value:{$ref:"$map/item/id"},disabled:{$ref:"$map/item/disabled"},destructive:{$ref:"$map/item/destructive"},requires:{$ref:"$map/item/requires"},checked:{$ref:"$map/item/checked"}},attributes:{"data-command-id":"${$map.item.id}"},children:[{tagName:"span",textContent:"${$map.item.title}"},{tagName:"span",attributes:{slot:"value"},$switch:{$ref:"$map/item/noChord"},cases:{false:{tagName:"kbd",textContent:"${$map.item.chord}"}}},{tagName:"span",attributes:{slot:"description"},$switch:{$ref:"$map/item/enabled"},cases:{false:{tagName:"span",textContent:"Needs ${$map.item.requires}"}}}]}]}}]}}}]}]}}]};T("menu",w);var M="block-end span-inline-end";function j(e){if(e.placement!==void 0)return e.placement;return e.opener&&!e.origin&&!e.place&&!e.floor?M:""}function E(e){if(!e)return{x:0,y:0};let n=Oe(e);return{x:Math.round(n.left),y:Math.round(n.bottom)}}function p(e,n=0){let r=n===0?(e.children??[]).map((t)=>p(t,1)):[];return{...e,checked:e.checked??"",children:r,chord:e.chord??"",enabled:!e.disabled,haspopup:r.length>0,noChord:!e.chord,noDivider:!e.dividerAbove,requires:e.requires??"",submenuLabel:e.submenuLabel??e.title}}function N(e,n){for(let r of e){if(r.id===n)return r;let t=r.children.find((d)=>d.id===n);if(t)return t}return}var L={bottom:0,height:0,left:0,right:0,top:0,width:0,x:0,y:0};function Nt(e){let n=vs("popover",e.region),r=new AbortController,t=null,d=null,i=!1,f=()=>{if(i)return;i=!0,r.abort(),d?.(),d=null,Nm("popover",e.region),P(e.opener??null),e.onClosed?.(u)},h=e.place?e.place(L):e.origin??E(e.opener),l=v({floor:e.floor?.()??0,label:e.label,placement:j(e),rows:e.rows.map((o)=>p(o)),select:(o,m)=>{let a=String(m.detail),s=N(l.rows,a);if(!s)return;if(s.run)s.run();else e.run?.(a);u.close()},x:h.x,y:h.y}),b=()=>{if(i||!t||!e.place)return;let o=e.place(Oe(t));l.x=o.x,l.y=o.y},y=(async()=>{let o=await R("menu",l,n,{signal:r.signal});if(r.signal.aborted)return;if({dispose:d}=o,t=o.root,t.addEventListener("toggle",(a)=>{if(a.newState==="closed")f()}),!t.hasAttribute("popover"))await new Promise((a)=>{t.addEventListener("jx-ready",()=>a(),{once:!0})});if(r.signal.aborted)return;let m=e.opener instanceof HTMLElement&&e.opener!==document.body?e.opener:void 0;t.showPopover(m?{source:m}:void 0),b(),requestAnimationFrame(b)})(),u={close:()=>{if(i)return;if(t?.open)t.hidePopover();f()},host:n,ready:y,setRows:(o)=>{if(i)return;let a=document.activeElement?.closest("jx-menu"),s=a&&a!==t?a.parentElement?.closest("jx-menu-item")?.dataset.commandId:void 0;l.rows=o.map((c)=>p(c)),setTimeout(()=>{if(i||!t||t.contains(document.activeElement))return;let c=s?t.querySelector(`jx-menu-item[data-command-id="${s}"]`):null,g=c?.querySelector("jx-menu")??null;if(c&&!(g?.open&&g.querySelector("jx-menu-item")))c.focus();else _k(t)},0)}};return u}function P(e){let n=document.activeElement;if(e?.isConnected&&(!n||n===document.body))e.focus()}
|
|
2
2
|
export{Nt};
|
|
3
3
|
|
|
4
4
|
//# debugId=78207AFC52B59A5764756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-
|
|
5
|
+
//# sourceMappingURL=studio-8xcwewjq.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{p}from"./studio-y7jehjrp.js";import{lp}from"./studio-
|
|
1
|
+
import{p}from"./studio-y7jehjrp.js";import{lp}from"./studio-bftp4n4b.js";import{ge,Q,v,Hm}from"./studio-fqq890ap.js";import{ne}from"./studio-cp1gbff9.js";import{T,R}from"./studio-7qvs7v0m.js";import{Bi,y}from"./studio-4m50vh74.js";import{D}from"./studio-tp642n5g.js";function k({slug:e,adapter:t}){let o=new Date().toISOString().slice(0,10);return`${JSON.stringify(t==="cloudflare-workers"?{assets:{binding:"ASSETS",directory:"./dist"},compatibility_date:o,compatibility_flags:["nodejs_compat"],main:"./dist/worker.js",name:e}:{compatibility_date:o,compatibility_flags:["nodejs_compat"],name:e,pages_build_output_dir:"./dist"},null,"\t")}
|
|
2
2
|
`}function m(e,{slug:t,adapter:o}){if(!e)return{content:k({adapter:o,slug:t}),patched:!0};let n;try{n=JSON.parse(e)}catch{return{content:e,patched:!1}}if(n.name=t,o==="cloudflare-workers")delete n.pages_build_output_dir,n.main="./dist/worker.js",n.assets={binding:"ASSETS",directory:"./dist"};else delete n.main,delete n.assets,n.pages_build_output_dir="./dist";return{content:`${JSON.stringify(n,null,"\t")}
|
|
3
3
|
`,patched:!0}}function gd(){try{return typeof p().cfApi==="function"}catch{return!1}}async function l(e,t){let o=p().cfApi;if(!o)throw Error("This platform cannot reach the Cloudflare API");try{return await o(e,t)}catch(n){throw lp(n),n}}async function YE(){return l("/accounts")}async function j(e,t){try{return await l(`/accounts/${e}/pages/projects/${t}`)}catch{return null}}async function C(e){return l(`/accounts/${e.accountId}/pages/projects`,{method:"POST",body:{name:e.projectName,production_branch:e.productionBranch,build_config:{build_command:"bunx jx build",destination_dir:"dist"},source:{type:"github",config:{owner:e.owner,repo_name:e.repo,production_branch:e.productionBranch,deployments_enabled:!0}}}})}async function Zf(e){let t=await l(`/accounts/${e.accountId}/pages/projects/${e.projectName}/deployments`),[o]=t;if(!o)return null;return{id:o.id,url:o.url,environment:o.environment,stage:o.latest_stage?.name??"unknown",status:o.latest_stage?.status??"unknown",createdOn:o.created_on}}async function P1(e,t){let o={...e.build};if(t===null)delete o.deploy;else o.deploy=t;if(await Bi({build:o}),t!==null){let n=p(),i=null;try{i=await n.readFile("wrangler.jsonc")}catch{i=null}let w=o.adapter==="cloudflare-workers"?"cloudflare-workers":"cloudflare-pages",{content:x,patched:S}=m(i,{adapter:w,slug:t.projectName});if(S)await n.writeFile("wrangler.jsonc",x)}}async function ZE(e,t){let n=await j(t.accountId,t.projectName)??await C(t),i={provider:"cloudflare-pages",accountId:t.accountId,projectName:t.projectName,...n.subdomain?{productionUrl:`https://${n.subdomain}`}:{}};return await P1(e,i),i}var h={$schema:"https://jxsuite.com/schema/v1",$id:"StudioPanelDeployChecklist",$description:"The deploy checklist, drawn above the Activity feed in the Bottom dock's Activity tab: what is MISSING before this project can ship, as one row with the chain of prerequisites under it. `publish/deploy-checklist.ts` owns the chain — which link is forged, which is merely unasked, and which command forges the next one — and hands this document a row, four steps and at most one action. Nothing here reads source control, the project config or the command registry. It draws in the Activity tab's own vocabulary because a deploy is an ordered list of stages that finish, which is exactly what a row of that feed already is; a fifth visual idiom for it would be a second design of a thing the tab has.",tagName:"div",attributes:{part:"checklist"},style:{$description:"What `.activity-list`, `.activity-row`, `.activity-row--running`, `.activity-row--done`, `.activity-icon`, `.activity-body`, `.activity-head`, `.activity-title`, `.activity-source`, `.activity-status`, `.activity-steps`, `.activity-step`, `.activity-step--done` and `.activity-step-icon` said in `styles/panels.css`, keyed on `part`. This is the LAST reader of those rules — `surfaces/panel-activity.json` carried its own copy when the feed converted, and left the stylesheet standing because this file still drew from it — so the whole `.problem-*, .activity-*` block is dead once this lands. Three token names could not travel: `--spectrum-font-size-50`, `--spectrum-font-size-75` and `--spectrum-corner-radius-75` resolve only inside `<sp-theme>`, and a document mounted into the dock body is outside it, so each would silently have taken its hard-coded px fallback. They are the kit's own scale here. One thing changed meaning on purpose: the step's `data-state` is the checklist's own three-valued state rather than the two CSS classes it used to collapse into, so `unknown` — \"nobody has asked\" — is a state the styling can tell apart from `todo` the day it should.",display:"block",minWidth:"0",fontFamily:"var(--jx-font-sans)",color:"var(--fg)",'& [part="list"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-1)",margin:"0",padding:"0",listStyle:"none"},'& [part="row"]':{$description:"The left border is the state, at 3px, which is the one thing that must be legible without reading the row. Its default is the dim foreground so a state nobody has a colour for still draws a border rather than a gap.",display:"flex",alignItems:"flex-start",gap:"var(--jx-space-2)",padding:"6px var(--jx-space-2)",border:"1px solid var(--border)",borderLeft:"3px solid var(--fg-dim)",borderRadius:"var(--radius)",background:"var(--bg-panel)",color:"var(--fg)",fontSize:"var(--jx-text-md)"},'& [part="row"][data-state="running"]':{borderLeftColor:"var(--accent)"},'& [part="row"][data-state="done"]':{borderLeftColor:"var(--success)"},'& [part="state-icon"]':{$description:'Named `state-icon` rather than `icon`: `jx-button` puts `part="icon"` on the glyph slot of every button it draws, and the action button below is inside this same light-DOM tree — a rule on the bare name would reach into the kit\'s own drawing and a devtools query could not tell the two apart.',flex:"none",width:"14px",textAlign:"center",fontWeight:"700",lineHeight:"1.5"},'& [part="row"][data-state="running"] > [part="state-icon"]':{color:"var(--accent)"},'& [part="row"][data-state="done"] > [part="state-icon"]':{color:"var(--success)"},'& [part="row-body"]':{flex:"1",minWidth:"0",display:"flex",flexDirection:"column",alignItems:"flex-start",gap:"2px"},'& [part="head"]':{display:"flex",alignItems:"baseline",gap:"var(--jx-space-2)",alignSelf:"stretch",minWidth:"0"},'& [part="row-title"]':{fontWeight:"700",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},'& [part="source"]':{$description:"Pushed to the far edge, so the tab reads as a column of who raised what.",flex:"none",marginLeft:"auto",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"},'& [part="summary"]':{color:"var(--fg-dim)",overflowWrap:"anywhere"},'& [part="steps"]':{$description:'The chain, declared up front, so "which link is missing" is answered by looking rather than by reading the summary and remembering what came before it.',display:"flex",flexDirection:"column",gap:"1px",margin:"2px 0 0",padding:"0",listStyle:"none",fontSize:"var(--jx-text-sm)"},'& [part="step"]':{display:"flex",gap:"6px",color:"var(--fg-dim)"},'& [part="step"][data-state="done"] > [part="step-icon"]':{color:"var(--success)"},'& [part="step-icon"]':{flex:"none",width:"10px",textAlign:"center"},'& [part="action"]':{marginTop:"var(--jx-space-1)"}},children:[{tagName:"div",attributes:{part:"body-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasProject"},cases:{true:{tagName:"ul",attributes:{part:"list"},children:[{tagName:"li",attributes:{part:"row","data-state":"${state.rowState}"},children:[{tagName:"span",attributes:{part:"state-icon","aria-hidden":"true"},textContent:"${state.rowIcon}"},{tagName:"div",attributes:{part:"row-body"},children:[{tagName:"div",attributes:{part:"head"},children:[{tagName:"span",attributes:{part:"row-title"},textContent:"Deploy checklist"},{tagName:"span",attributes:{part:"source"},textContent:"Publish"}]},{tagName:"div",attributes:{part:"summary"},textContent:"${state.summary}"},{tagName:"ol",attributes:{part:"steps"},children:[{$prototype:"Array",items:{$ref:"#/state/steps"},key:{$ref:"$map/item/id"},map:{tagName:"li",attributes:{part:"step","data-step":"${$map.item.id}","data-state":"${$map.item.state}"},children:[{tagName:"span",attributes:{part:"step-icon","aria-hidden":"true"},textContent:"${$map.item.icon}"},{tagName:"span",attributes:{part:"step-text"},textContent:"${$map.item.text}"}]}}]},{tagName:"span",attributes:{part:"action-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasAction"},cases:{true:{tagName:"jx-button",$description:"The recovery button wears the command's own title, so it reads as a verb rather than as a decoration, and a refused command is dimmed with the reason it names in its tooltip. A command the registry does not have, or whose `when` is false, draws NOTHING rather than a dead label — a surface may choose whether to show a command, never whether it exists (§13).",$props:{size:"sm",disabled:{$ref:"#/state/actionDisabled"}},attributes:{part:"action",title:"${state.actionTitle}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/runAction"},value:[]}]},children:[{tagName:"span",textContent:"${state.actionLabel}"}]}}}]}]}]}}}]};T("panel-deploy-checklist",h);var d=null,c=null,a=null,r=null;function A(e,t){e.hasProject=t.hasProject,e.rowState=t.rowState,e.rowIcon=t.rowIcon,e.summary=t.summary,e.steps=t.steps,e.hasAction=t.hasAction,e.actionLabel=t.actionLabel,e.actionTitle=t.actionTitle,e.actionDisabled=t.actionDisabled}function N(e){if(d!==e)return!1;return r===null?a!==null:r.root.parentNode===e}function f(e,t){if(N(e))return;u(),d=e;let o=v({actionDisabled:!1,actionLabel:"",actionTitle:"",hasAction:!1,hasProject:!1,rowIcon:"",rowState:"running",runAction:t.runAction,steps:[],summary:""});c=ge(),c.run(()=>{Q(()=>{A(o,t.project())})});let n=R("panel-deploy-checklist",o,e);a=n,n.then((i)=>{if(a===n)r=i;else i.dispose()})}function u(){c?.stop(),c=null;let e=a;if(a=null,r)r.dispose(),r=null;else if(e)e.then((t)=>t.dispose());d=null}function I(){return D?.projectConfig??null}function ca(){return I()?.build?.deploy}var s=Hm({asked:!1,observed:null});function rp(e){s.observed=e,s.asked=!0}function _(){let{status:e}=y.git;if(e===null)return{command:"git.init",detail:"Source control has not reported on this project yet.",id:"repo",label:"Track this project with git",state:"unknown"};return e.isRepo?{command:"git.init",detail:`Tracked${e.branch?` — on branch ${e.branch}`:""}.`,id:"repo",label:"Track this project with git",state:"done"}:{command:"git.init",detail:"A deploy ships what the repository holds, so the repository comes first.",id:"repo",label:"Track this project with git",state:"todo"}}function L(){let{status:e}=y.git;if(e===null||!e.isRepo)return{command:"git.createGithubRepository",detail:"A remote is where the provider builds from.",id:"remote",label:"Push to a remote",state:e===null?"unknown":"todo"};if((e.remotes??[]).length===0)return{command:"git.createGithubRepository",detail:"This repository is local only — nothing outside this machine can build it.",id:"remote",label:"Push to a remote",state:"todo"};return e.ahead>0?{command:"git.push",detail:`${e.ahead} commit(s) are not on ${e.remotes[0]} yet, so a build would ship the older tree.`,id:"remote",label:"Push to a remote",state:"todo"}:{command:"git.push",detail:`Up to date with ${e.remotes[0]}.`,id:"remote",label:"Push to a remote",state:"done"}}function O(){let e=ca();if(e)return{command:"publish.setUp",detail:`Cloudflare Pages project ${e.projectName}.`,id:"provider",label:"Connect a deploy provider",state:"done"};return gd()?{command:"publish.setUp",detail:"Connecting one makes every commit build and publish on its own.",id:"provider",label:"Connect a deploy provider",state:"todo"}:{command:"publish.setUp",detail:"This platform cannot reach the Cloudflare API. Commit and push instead — your host "+"runs bunx jx build and serves dist/.",id:"provider",label:"Connect a deploy provider",state:"unknown"}}function E(){if(!ca())return{command:"publish.deploy",detail:"Nothing has been deployed, because no provider is connected.",id:"deployed",label:"Deploy",state:"todo"};if(!s.asked)return{command:"publish.deploy",detail:"Cloudflare has not been asked yet, so this is not a claim that nothing shipped.",id:"deployed",label:"Deploy",state:"unknown"};if(s.observed===null)return{command:"publish.deploy",detail:"Cloudflare reports no deployments for this project.",id:"deployed",label:"Deploy",state:"todo"};let{observed:e}=s;return e.status==="success"?{command:"publish.deploy",detail:`${e.environment} — ${e.url}`,id:"deployed",label:"Deploy",state:"done"}:{command:"publish.deploy",detail:`Last deployment ${e.stage}: ${e.status}.`,id:"deployed",label:"Deploy",state:"todo"}}function g(){return[_(),L(),O(),E()]}function b(){return g().find((e)=>e.state!=="done")??null}function XE(){if(!D)return null;let e=b();if(e)return{command:e.command,label:e.label,title:e.detail};return{command:"publish.openDashboard",label:"Deployed",title:ca()?.productionUrl??"Everything this project needs to ship is in place."}}var W={done:"✓",todo:"·",unknown:"?"};function V(e){return{icon:W[e.state],id:e.id,state:e.state,text:e.state==="done"?e.label:`${e.label} — ${e.detail}`}}function H(e){let t={actionDisabled:!1,actionLabel:"",actionTitle:"",hasAction:!1};if(!e)return t;let o=ne(),n=o?.get(e.command);if(!o||!n||!o.isVisible(e.command))return t;let i=o.disabledReason(e.command);return{actionDisabled:i!==void 0,actionLabel:n.title,actionTitle:i?`${n.title} — requires ${i}`:n.title,hasAction:!0}}function J(){if(!D)return{actionDisabled:!1,actionLabel:"",actionTitle:"",hasAction:!1,hasProject:!1,rowIcon:"",rowState:"running",steps:[],summary:""};let e=g(),t=e.find((o)=>o.state!=="done")??null;return{...H(t),hasProject:!0,rowIcon:t?"⋯":"✓",rowState:t?"running":"done",steps:e.map((o)=>V(o)),summary:t?t.detail:"Everything this project needs to ship is in place."}}function B(){let e=b();if(!e)return;ne()?.run(e.command)}var F={project:J,runAction:B};function QE(e){let t=e.querySelector("[data-deploy-checklist]");if(!t){u();return}f(t,F)}
|
|
4
4
|
export{gd,YE,Zf,P1,ZE,ca,rp,XE,QE};
|
|
5
5
|
|
|
6
6
|
//# debugId=32A006FBA9B78D4764756E2164756E21
|
|
7
|
-
//# sourceMappingURL=studio-
|
|
7
|
+
//# sourceMappingURL=studio-aekhcdzw.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{p,We}from"./studio-y7jehjrp.js";import{_t,Lr,aL,Xb,Qb,qr,cL,Hu}from"./studio-semd1s8s.js";import{k}from"./studio-fqq890ap.js";import{bs,Ct}from"./studio-spf2skgc.js";var s=null;async function bc(){if(!We()||typeof p().getAccountStatus!=="function"){s=null;return}try{s=await p().getAccountStatus?.()??null}catch{s=null}}function Ww(){return s}function Vw(){return s!==null&&s.installations.length===0&&Boolean(s.appInstallUrl)}function eT(){if(s===null)return null;let e=s.installations.flatMap((t)=>t.manageUrl?[{account:t.account??`Installation ${t.id}`,url:t.manageUrl}]:[]);if(e.length===0&&!s.appInstallUrl)return null;return{manage:e,...s.appInstallUrl?{installUrl:s.appInstallUrl}:{}}}function tT(){return s?.entries??[]}function F1(){return(s?.notices??[]).filter((e)=>e.display!=="toast")}var j=new Set;function I(){let e=(s?.notices??[]).filter((t)=>t.display==="toast"&&!j.has(t.id));for(let t of e)j.add(t.id);return e}var M="https://jxsuite.com/problems/";function Xf(e){if(typeof e!=="string"||!e.startsWith("https://jxsuite.com/problems/"))return null;let t=e.slice(29);return t===""?null:t}function Ro(e){if(typeof e==="string")return e.trim()===""?null:e;if(!e||typeof e!=="object")return null;let t=e;for(let o of[t.detail,t.error,t.title])if(typeof o==="string"&&o.trim()!=="")return o;return null}function Fs(e,t){return Ro(e)??(t===void 0?"Request failed":`Request failed (${t})`)}var a=(e,t,o,r)=>({status:t,title:o,type:`${M}${e}`,...r===void 0?{}:{extensions:r}}),re={invalidRequest:a("invalid-request",400,"The request was malformed or incomplete"),notFound:a("not-found",404,"The requested resource does not exist"),methodNotAllowed:a("method-not-allowed",405,"That method is not allowed on this route"),conflict:a("conflict",409,"The request conflicts with the current state",["conflicts"]),payloadTooLarge:a("payload-too-large",413,"The request body is too large"),unauthorized:a("unauthorized",401,"Credentials are missing or not accepted"),forbidden:a("forbidden",403,"The request was refused"),needsInstallationAccess:a("needs-installation-access",403,"The GitHub App is not installed for that account",["installUrl"]),pathOutsideProject:a("path-outside-project",403,"The path resolves outside the active project"),actionRequired:a("action-required",403,"An action is required first",["actions","heading","retry"]),noActiveProject:a("no-active-project",409,"No project is active on this backend"),capabilityUnavailable:a("capability-unavailable",501,"This backend does not provide that capability"),upstreamFailure:a("upstream-failure",502,"An upstream service failed",["upstream"]),internalError:a("internal-error",500,"The backend failed to complete the request")};var Uw=".jx-loc-id",n=(e,t,o,r)=>({method:e,path:t,optional:r!==void 0,summary:o,...r===void 0?{}:{degradation:r}}),se={activate:n("POST","/__studio/activate","Bind the backend to a project root"),project:n("GET","/__studio/project","Root project metadata {name, root}"),projectInfo:n("GET","/__studio/project-info","Probe a directory: {isSiteProject, projectConfig?, directories?}"),resolveSite:n("GET","/__studio/resolve-site","Resolve the owning site of a file path {sitePath, projectConfig?, fileRelPath?}"),sites:n("GET","/__studio/sites","Enumerate site projects [{config, path}] (backs listProjects)","The welcome screen's Projects catalogue stays hidden."),findProject:n("GET","/__studio/find-project","Locate a project directory by name outside the root","openProject falls back to config-matching only."),locateDirectory:n("GET","/__studio/locate-directory","Resolve the absolute path of a showDirectoryPicker() folder by the id in its .jx-loc-id","Browse… reports that the folder could not be placed; the Location is typed by hand."),createProject:n("POST","/__studio/create-project","Scaffold a project at a caller-chosen destination → {root, config}"),starters:n("GET","/__studio/starters","Starter templates (StarterInfo[])","The New Project picker offers only blank/templates."),importSite:n("POST","/__studio/import-site","Clone a live website into a project; streams NDJSON progress","The New Project Import tab is unavailable."),files:n("GET","/__studio/files","List a directory (DirEntry[]) in stable path order; an entry may carry an opaque content `version` the backend vouches for; with ?glob=<pattern>, search matching files project-wide"),fileRead:n("GET","/__studio/file","Read a file's text content"),filesRead:n("POST","/__studio/files/read","Read many files' text content {paths} → ReadFilesResult {files: [path, {content} | "+"{error: {status, code?, message}}][], omitted}. At most READ_FILES_MAX_PATHS (200) paths and a backend byte budget per call: the excess is listed in `omitted` (never a 400) and the first path is always answered. Per-path errors: 404 missing/deleted, 415 binary, 413 too large, 502 upstream. Allowed for read-only sessions; keeps fileRead's server-side effects","Adapters fall back to one fileRead per path."),fileWrite:n("PUT","/__studio/file","Write a file's text content"),fileDelete:n("DELETE","/__studio/file","Delete a file"),fileUpload:n("POST","/__studio/file/upload","Upload binary content to a path → UploadResult {path, size?}. `path` is the answer, not an "+"echo: a store that de-duplicates, suffixes, or normalizes names reports what it really wrote"),fileBytes:n("GET","/__studio/file/bytes","A project file's raw bytes, undecoded — the read side of `fileUpload`, for a caller that must "+"not go through UTF-8","Studio can only read a project file as text, so any surface that must decode one stays hidden."),documentRaw:n("GET","/__studio/raw/","A project file as its own bytes, at its own URL — the mount a canvas renders against when "+"the editor origin does not serve the site's URL space. The project-relative path is appended to this prefix","The canvas cannot address project files by URL, so a host whose origin does not serve the site URL space renders no component $refs and no images."),fileRename:n("POST","/__studio/file/rename","Rename/move (+ refactor report). `from`/`to` are server-root-relative; every path in the "+"report is relative to the active project (specs/server.md §4.1)"),references:n("GET","/__studio/references","Where a file or a component tag is used (?path=&tag=, at least one) → ReferencesResult "+"{files, filesReferencing, refsTotal} — the read side of the rename refactor's own walker, "+"cached until the backend's watcher sees the tree move (backs findReferences). `?path=` is server-root-relative and every path in the answer is relative to the active project; a "+"target outside that project is a 400, never a zero-result 200 (specs/server.md §4.1)",'Usage counts are hidden: no "Used on N pages" in the inspector, no Selection: Find Usages, and delete/rename confirmations state no reference count.'),locate:n("POST","/__studio/locate","Find a file by name → {path | null}"),collab:n("GET","/__studio/collab","Realtime co-editing: a WebSocket upgrade speaking the @jxsuite/collab wire envelope (one socket per project, documents multiplexed by path; y-protocols sync + project-level "+"awareness in lib0 binary frames — see @jxsuite/collab/envelope for the frame layout and "+"the docEpoch/doc-reset lifecycle). A plain GET (no Upgrade) answers {collab, protocols, version} as the capability probe, and `protocols` is the subprotocol negotiation: the client offers one of them as Sec-WebSocket-Protocol and the server echoes it, or the "+"client offers none when the server advertises none, because RFC 6455 §4.1 fails a "+"connection whose offer went unechoed.","Realtime co-editing is unavailable; Studio edits solo with file-level saves"),components:n("GET","/__studio/components","Discover components (ComponentMeta[])"),cem:n("GET","/__studio/cem","Custom-elements manifest of an npm dependency","Dependency components lose prop/slot metadata."),formats:n("GET","/__studio/formats","The project's format registry entries plus a sibling `extensions` array — per enabled "+"extension its manifest identity and project-section contributions (ExtensionsInfo[]; backs listFormats and listExtensions).","Only .json documents open (backs listFormats); descriptor-contributed settings sections do not appear."),extensionCatalog:n("GET","/__studio/catalog","Extensions this backend can OFFER (ExtensionCatalogEntry[]) — the shipped first-party "+"catalogue plus any package in the project's own dependencies exporting a jx-extension.json, each marked with whether the host resolves it without a project install and whether the project has it installed. A capability rather than a constant: a Worker ships a fixed set "+"of extension packages (specs/extensions.md §5.5). Backs listExtensionCatalog.","The Extensions section offers no catalogue; adding an extension stays a typed package name."),projectSchemas:n("GET","/__studio/project-schemas","The project's generated entry documents (project.schema.json / document.schema.json), "+"PRE-BUNDLED into self-contained schemas — {project, document} (backs fetchProjectSchemas). "+"Regenerated on demand when missing or older than project.json.","The JSON editor falls back to the bundled core schemas (extension sections get no editor validation/completion)."),format:n("POST","/__studio/format","Dispatch a format capability {format, action: parse|serialize, source?|doc?}","Non-JSON documents cannot be parsed/serialized (backs formatAction)."),pluginSchema:n("GET","/__studio/plugin-schema","Extract a $studio schema from a class source","Plugin property panels fall back to generic JSON editing."),codeFormat:n("POST","/__studio/code/format","Format posted source {code, path?} → {code, errors}","Code editors skip format-on-open/save (codeService returns null)."),codeMinify:n("POST","/__studio/code/minify","Minify posted source {code} → {code}","Compiled-output minification is skipped."),codeLint:n("POST","/__studio/code/lint","Lint posted source {code, path?} → {diagnostics}","Code editors show no lint markers."),buildSite:n("POST","/__studio/build","Build or render the site → {routes, files, errors, mode?, url}","Build Site reports that this target cannot build."),previewSite:n("POST","/__studio/preview","Preview the working tree at a route → {routes, files, errors, mode, url, reused}","Open in Browser falls back to buildSite."),previewOverlay:n("POST","/__studio/preview/overlay","Publish (POST) or retract (DELETE) a document's unsaved bytes → 204","A live preview shows the last saved state instead of the editor's."),packages:n("GET","/__studio/packages","List dependencies (PackageInfo[])"),packagesAdd:n("POST","/__studio/packages/add","Add a dependency"),packagesRemove:n("POST","/__studio/packages/remove","Remove a dependency"),packagesInstall:n("POST","/__studio/packages/install","Run the package manager install","Install/reinstall affordances are hidden; manifest-only edits still work."),packagesNeedsInstall:n("GET","/__studio/packages/needs-install","Whether node_modules is stale","The install-on-open prompt never shows."),packagesVersions:n("GET","/__studio/packages/versions","Newest published version of each dependency (PackageVersionInfo[])","The Latest column stays empty and the update affordances are hidden."),packagesSetVersions:n("POST","/__studio/packages/set-versions","Rewrite dependency ranges and install","Bulk version updates are hidden."),gitStatus:n("GET","/__studio/git/status","Working-tree status (GitStatusResult)"),gitBranches:n("GET","/__studio/git/branches","Branch list (GitBranchesResult)"),gitLog:n("GET","/__studio/git/log","Recent commits (GitLogEntry[])"),gitStage:n("POST","/__studio/git/stage","Stage files"),gitUnstage:n("POST","/__studio/git/unstage","Unstage files"),gitCommit:n("POST","/__studio/git/commit","Commit staged (else all dirty) files"),gitPush:n("POST","/__studio/git/push","Push (cloud: sync check — commits land on push)"),gitPull:n("POST","/__studio/git/pull","Pull/fast-forward; 409 {conflicts} on overlap"),gitFetch:n("POST","/__studio/git/fetch","Refresh remote tracking state"),gitCheckout:n("POST","/__studio/git/checkout","Switch branches"),gitCreateBranch:n("POST","/__studio/git/create-branch","Create a branch"),gitDiff:n("GET","/__studio/git/diff","Unified diff of dirty files (or one path)"),gitShow:n("GET","/__studio/git/show","File content at a ref"),gitDiscard:n("POST","/__studio/git/discard","Discard working changes"),gitInit:n("POST","/__studio/git/init","Initialize a repository"),gitAddRemote:n("POST","/__studio/git/add-remote","Add a remote"),gitClone:n("POST","/__studio/git/clone","Clone a repository","The welcome screen hides Clone Git Repository."),gitPr:n("POST","/__studio/git/pr","Open a pull request → PullRequestInfo","Studio falls back to a direct GitHub API call with the user's token."),dataConnections:n("GET","/__studio/data/connections","Connector connections with configured/missingSecrets/isDefault state, reachable table names, and registry-descriptor provider metadata (DataConnectionsResponse; backs dataConnections)","The connections settings section shows no status, and data-domain actions stay hidden."),dataConnectionTest:n("POST","/__studio/data/connections/test","Probe a connection {connection} → DataConnectionTestResult (backs dataConnectionTest)","The Test Connection action is hidden."),dataPush:n("POST","/__studio/data/push","Additive schema push {connection?, dryRun?} → DataPushResult (plan of DataPushStep[], "+"applied, warnings/errors; backs dataPush)","The Push Schema action is hidden; schemas deploy via `jx db push` instead."),dataRows:n("GET","/__studio/data/rows","Page a table (DataRowsQuery params) → DataRowsResult {rows, total, columns} (backs dataRows)","The data grid is unavailable."),dataInsertRow:n("POST","/__studio/data/rows","Insert a row {table, connection?, values} → {row} (backs dataInsertRow)","The data grid hides its add-row footer."),dataUpdateRow:n("PUT","/__studio/data/rows","Update a row keyed on its primary key {table, connection?, pk, set} → {row} (backs "+"dataUpdateRow)","Data grid cells are read-only."),dataDeleteRow:n("DELETE","/__studio/data/rows","Delete a row (?table=&pk=&connection=) → {ok} (backs dataDeleteRow)","The data grid hides row deletion."),secretsList:n("GET","/__studio/secrets","Configured secret env-var NAMES, never values (SecretsListResponse; backs listSecrets)","Secret fields cannot show set/unset state."),secretsSet:n("PUT","/__studio/secrets","Write/remove secrets in the backend store (.dev.vars locally) {set?, remove?} → names "+"(backs setSecrets)","The secret form control renders disabled; secrets are edited in .dev.vars by hand."),aiChat:n("POST","/__studio/ai/chat","StreamEvent SSE chat proxy {messages, tools, systemPrompt, model}"),aiModels:n("GET","/__studio/ai/models","Model catalogue (AiModelsResponse)"),cfProxy:n("POST","/__studio/cf/proxy","Allowlisted Cloudflare API passthrough {path, method?, body?} (backs cfApi)","The Publish panel explains the git-push publishing path instead.")};var j1=200;var K=new Set(["reload","repeat","none"]);function Du(e){if(!Array.isArray(e))return[];return e.flatMap((t)=>{let o=t;if(!o||typeof o.id!=="string"||!o.id||typeof o.label!=="string"||!o.label)return[];return[{id:o.id,label:o.label,...typeof o.href==="string"&&o.href?{href:o.href}:{},...o.primary===!0?{primary:!0}:{}}]})}function qw(e){return typeof e==="string"&&K.has(e)?e:void 0}function H(e){return e.replaceAll("_","-")}function x(e){if(!e||typeof e!=="object")return{};let{actions:t,code:o,heading:r,installUrl:c,retry:m,type:u}=e,f=qw(m),i=Xf(u)??(typeof o==="string"?H(o):null);return{...i===null?{}:{code:i},...typeof c==="string"?{installUrl:c}:{},...t===void 0?{}:{actions:Du(t)},...typeof r==="string"&&r?{heading:r}:{},...f===void 0?{}:{retry:f}}}function nT(e){let t=x(e);return t.code==="needs-installation-access"&&t.installUrl?t.installUrl:null}function iT(e){return x(e).code==="action-required"}function vc(){return Lr(_t.aiOpenAiKey)}function oT(e){qr(_t.aiOpenAiKey,e||"")}function kb(){return aL(_t.aiOpenAiKey)}function da(){return Lr(_t.aiBaseUrl)}function Sb(){return Lr(_t.aiModel)}function rT(e){qr(_t.aiModel,e||"")}function sT(e){cL([[_t.aiOpenAiKey,e.apiKey],[_t.aiBaseUrl,e.baseUrl],[_t.aiModel,e.model]])}function aT(e){return!sp(_t.aiOpenAiKey,e.apiKey,vc())||!sp(_t.aiBaseUrl,e.baseUrl,da())||!sp(_t.aiModel,e.model,Sb())}function sp(e,t,o){return Qb(e,t)===Qb(e,o)}function lT(){Hu([_t.aiOpenAiKey,_t.aiBaseUrl,_t.aiModel])}function Gw(){return{apiKey:vc(),baseUrl:da()}}function N(e){return`${e.apiKey}\x00${e.baseUrl}`}var g=null,R="",P=!1,_=!1,A="",T,v="",E=null,O=null,U=new Set,W=600000,b=0,L=!1;function Tr(){g=null,R="",P=!1,_=!1,A="",T=void 0,v="",E=null,O=null,b=0}var z=new Set([_t.aiOpenAiKey.key,_t.aiBaseUrl.key,_t.cfToken.key,_t.cfAccountId.key]);Xb((e)=>{if(e.some((t)=>z.has(t)))Tr()});function H1(e){return g&&R===N(e)?g:null}function B(e){return g?.find((t)=>t.id===e)}function B1(e){return B(e)?.toolSupport}function cT(e){return B(e)?.contextWindow}function Eb(e){if(e)U.add(e);O??=bd({force:!0}).catch(()=>{}).then(()=>{b=Date.now();for(let t of U)t()})}function V(){if(!_||b===0||Date.now()-b<W)return!1;return O=null,b=0,Eb(),!0}function J(){if(typeof window>"u"||L)return;L=!0,window.addEventListener("focus",()=>{V()})}J();function Qf(){return kb()||Kw()}function Kw(){return P}function dT(){return _}function ap(){return T}function uT(){return v}function Jw(){return E}function Y(){return A}function Ba(){return Sb()||Y()||_t.aiModel.default}function X(e,t){let o;try{o=new URL(e,"http://jx.invalid")}catch{return e}return o.pathname=o.pathname.replace(/[^/]*$/,t),/^https?:/i.test(e)?o.href:`${o.pathname}${o.search}`}async function bd(e={}){let t=e.credentials??Gw(),o=N(t);if(g&&R===o&&!e.force)return g;let r=p(),c=await Promise.resolve(r.aiChatUrl()),m=X(c,"models"),u={};if(t.apiKey)u["X-Api-Key"]=t.apiKey;if(t.baseUrl)u["X-Api-Base-URL"]=t.baseUrl;let f=await fetch(m,{headers:u});if(!f.ok)throw Error(`HTTP ${f.status}`);let i=await f.json();return P=i.configured===!0,_=i.managed===!0,A=i.defaultModel??"",T=i.code,v=i.upstreamError!==void 0?i.upstreamMessage??"":"",E=i.code==="action_required"?{actions:Du(i.actions),...typeof i.detail==="string"&&i.detail?{detail:i.detail}:{}}:null,g=(i.models||[]).map((l)=>{let h={id:l.id,name:l.name||l.id};if(typeof l.contextWindow==="number")h.contextWindow=l.contextWindow;if(typeof l.toolSupport==="boolean")h.toolSupport=l.toolSupport;return h}),R=o,g}var S=new Set,C=null;function hT(e){if(S.size===0){C=e;return}for(let t of S)t(e)}function G(e){S.add(e);let t=C;if(C=null,t)e(t);return()=>{S.delete(e)}}function Yw(){return We()&&typeof p().performAction==="function"}function z1(e){let t=e.find((r)=>r.primary)??e[0];if(!t)return null;let o=e.find((r)=>r!==t);return o?{lead:t,other:o}:{lead:t}}var w=null,q=!1;function Zw(e){let t=z1(e.actions);if(!Yw()||!t)return Promise.resolve(!1);return w??=Q(e,t).finally(()=>{w=null}),w}async function lp(e){let t=x(e);if(t.code!=="action-required"||!t.actions?.length)return!1;return Zw({actions:t.actions,detail:e instanceof Error?e.message:void 0,heading:t.heading,retry:t.retry})}async function F(){Tr(),await bc(),W1()}function Q(e,t){let o=e.detail??"This needs one more step first.";return new Promise((r)=>{let c="offer",m=(y)=>{if(c==="done")return;c="done",h.close(),r(y)},u=(y)=>{c="offer",h.update({cancelLabel:"Not now",confirmLabel:t.lead.label,message:y,secondaryLabel:t.other?.label??""})},f=(y)=>{if(c!=="offer")return;c="waiting";let D;try{D=p().performAction(y)}catch(d){u(d instanceof Error?d.message:String(d));return}h.update({cancelLabel:"Cancel",confirmLabel:"Waiting…",message:"Finish in the window that opened. This closes by itself once it is done.",secondaryLabel:""}),D.then(async(d)=>{if(d?.status==="done"){await F(),m(!0);return}if(c!=="waiting"||!d||d.status==="redirect")return;bc(),u(o)},(d)=>{if(c==="waiting")u(d instanceof Error?d.message:String(d))})},{lead:i,other:l}=t,h=bs({cancelLabel:"Not now",confirmLabel:i.label,headline:e.heading??"One more step",layer:Ct("dialog"),message:o,onCancel:()=>{q=!0,m(!1)},onClosed:()=>{m(!1)},onConfirm:()=>{f(i)},region:"account/action",...l?{onSecondary:()=>{f(l)},secondaryLabel:l.label}:{}})})}function Z(e){if(e==="reload")location.reload();else if(e==="repeat")k.info("Done. Run that again now.",{key:"account.action.retry",source:"Account"})}function pT(){return G((e)=>{if(q||w)return;Zw(e).then((t)=>{if(t)Z(e.retry)})})}async function Tb(e){if(!Yw())return!1;let t=p().performAction(e),o;try{o=await t}catch(r){return k.error(r instanceof Error?r.message:String(r),{key:"account.action",source:"Account",tier:"toast"}),!1}if(o?.status==="done")return await F(),!0;if(o?.status!=="redirect")await bc();return!1}function W1(){for(let e of I()){let t={key:`account.notice.${e.id}`,source:"Account"};if(e.level==="warning")k.warn(e.message,t);else k.info(e.message,t)}}
|
|
1
|
+
import{p,We}from"./studio-y7jehjrp.js";import{_t,Lr,aL,Xb,Qb,qr,cL,Hu}from"./studio-semd1s8s.js";import{k}from"./studio-fqq890ap.js";import{bs,Ct}from"./studio-7qvs7v0m.js";var s=null;async function bc(){if(!We()||typeof p().getAccountStatus!=="function"){s=null;return}try{s=await p().getAccountStatus?.()??null}catch{s=null}}function Ww(){return s}function Vw(){return s!==null&&s.installations.length===0&&Boolean(s.appInstallUrl)}function eT(){if(s===null)return null;let e=s.installations.flatMap((t)=>t.manageUrl?[{account:t.account??`Installation ${t.id}`,url:t.manageUrl}]:[]);if(e.length===0&&!s.appInstallUrl)return null;return{manage:e,...s.appInstallUrl?{installUrl:s.appInstallUrl}:{}}}function tT(){return s?.entries??[]}function F1(){return(s?.notices??[]).filter((e)=>e.display!=="toast")}var j=new Set;function I(){let e=(s?.notices??[]).filter((t)=>t.display==="toast"&&!j.has(t.id));for(let t of e)j.add(t.id);return e}var M="https://jxsuite.com/problems/";function Xf(e){if(typeof e!=="string"||!e.startsWith("https://jxsuite.com/problems/"))return null;let t=e.slice(29);return t===""?null:t}function Ro(e){if(typeof e==="string")return e.trim()===""?null:e;if(!e||typeof e!=="object")return null;let t=e;for(let o of[t.detail,t.error,t.title])if(typeof o==="string"&&o.trim()!=="")return o;return null}function Fs(e,t){return Ro(e)??(t===void 0?"Request failed":`Request failed (${t})`)}var a=(e,t,o,r)=>({status:t,title:o,type:`${M}${e}`,...r===void 0?{}:{extensions:r}}),re={invalidRequest:a("invalid-request",400,"The request was malformed or incomplete"),notFound:a("not-found",404,"The requested resource does not exist"),methodNotAllowed:a("method-not-allowed",405,"That method is not allowed on this route"),conflict:a("conflict",409,"The request conflicts with the current state",["conflicts"]),payloadTooLarge:a("payload-too-large",413,"The request body is too large"),unauthorized:a("unauthorized",401,"Credentials are missing or not accepted"),forbidden:a("forbidden",403,"The request was refused"),needsInstallationAccess:a("needs-installation-access",403,"The GitHub App is not installed for that account",["installUrl"]),pathOutsideProject:a("path-outside-project",403,"The path resolves outside the active project"),actionRequired:a("action-required",403,"An action is required first",["actions","heading","retry"]),noActiveProject:a("no-active-project",409,"No project is active on this backend"),capabilityUnavailable:a("capability-unavailable",501,"This backend does not provide that capability"),upstreamFailure:a("upstream-failure",502,"An upstream service failed",["upstream"]),internalError:a("internal-error",500,"The backend failed to complete the request")};var Uw=".jx-loc-id",n=(e,t,o,r)=>({method:e,path:t,optional:r!==void 0,summary:o,...r===void 0?{}:{degradation:r}}),se={activate:n("POST","/__studio/activate","Bind the backend to a project root"),project:n("GET","/__studio/project","Root project metadata {name, root}"),projectInfo:n("GET","/__studio/project-info","Probe a directory: {isSiteProject, projectConfig?, directories?}"),resolveSite:n("GET","/__studio/resolve-site","Resolve the owning site of a file path {sitePath, projectConfig?, fileRelPath?}"),sites:n("GET","/__studio/sites","Enumerate site projects [{config, path}] (backs listProjects)","The welcome screen's Projects catalogue stays hidden."),findProject:n("GET","/__studio/find-project","Locate a project directory by name outside the root","openProject falls back to config-matching only."),locateDirectory:n("GET","/__studio/locate-directory","Resolve the absolute path of a showDirectoryPicker() folder by the id in its .jx-loc-id","Browse… reports that the folder could not be placed; the Location is typed by hand."),createProject:n("POST","/__studio/create-project","Scaffold a project at a caller-chosen destination → {root, config}"),starters:n("GET","/__studio/starters","Starter templates (StarterInfo[])","The New Project picker offers only blank/templates."),importSite:n("POST","/__studio/import-site","Clone a live website into a project; streams NDJSON progress","The New Project Import tab is unavailable."),files:n("GET","/__studio/files","List a directory (DirEntry[]) in stable path order; an entry may carry an opaque content `version` the backend vouches for; with ?glob=<pattern>, search matching files project-wide"),fileRead:n("GET","/__studio/file","Read a file's text content"),filesRead:n("POST","/__studio/files/read","Read many files' text content {paths} → ReadFilesResult {files: [path, {content} | "+"{error: {status, code?, message}}][], omitted}. At most READ_FILES_MAX_PATHS (200) paths and a backend byte budget per call: the excess is listed in `omitted` (never a 400) and the first path is always answered. Per-path errors: 404 missing/deleted, 415 binary, 413 too large, 502 upstream. Allowed for read-only sessions; keeps fileRead's server-side effects","Adapters fall back to one fileRead per path."),fileWrite:n("PUT","/__studio/file","Write a file's text content"),fileDelete:n("DELETE","/__studio/file","Delete a file"),fileUpload:n("POST","/__studio/file/upload","Upload binary content to a path → UploadResult {path, size?}. `path` is the answer, not an "+"echo: a store that de-duplicates, suffixes, or normalizes names reports what it really wrote"),fileBytes:n("GET","/__studio/file/bytes","A project file's raw bytes, undecoded — the read side of `fileUpload`, for a caller that must "+"not go through UTF-8","Studio can only read a project file as text, so any surface that must decode one stays hidden."),documentRaw:n("GET","/__studio/raw/","A project file as its own bytes, at its own URL — the mount a canvas renders against when "+"the editor origin does not serve the site's URL space. The project-relative path is appended to this prefix","The canvas cannot address project files by URL, so a host whose origin does not serve the site URL space renders no component $refs and no images."),fileRename:n("POST","/__studio/file/rename","Rename/move (+ refactor report). `from`/`to` are server-root-relative; every path in the "+"report is relative to the active project (specs/server.md §4.1)"),references:n("GET","/__studio/references","Where a file or a component tag is used (?path=&tag=, at least one) → ReferencesResult "+"{files, filesReferencing, refsTotal} — the read side of the rename refactor's own walker, "+"cached until the backend's watcher sees the tree move (backs findReferences). `?path=` is server-root-relative and every path in the answer is relative to the active project; a "+"target outside that project is a 400, never a zero-result 200 (specs/server.md §4.1)",'Usage counts are hidden: no "Used on N pages" in the inspector, no Selection: Find Usages, and delete/rename confirmations state no reference count.'),locate:n("POST","/__studio/locate","Find a file by name → {path | null}"),collab:n("GET","/__studio/collab","Realtime co-editing: a WebSocket upgrade speaking the @jxsuite/collab wire envelope (one socket per project, documents multiplexed by path; y-protocols sync + project-level "+"awareness in lib0 binary frames — see @jxsuite/collab/envelope for the frame layout and "+"the docEpoch/doc-reset lifecycle). A plain GET (no Upgrade) answers {collab, protocols, version} as the capability probe, and `protocols` is the subprotocol negotiation: the client offers one of them as Sec-WebSocket-Protocol and the server echoes it, or the "+"client offers none when the server advertises none, because RFC 6455 §4.1 fails a "+"connection whose offer went unechoed.","Realtime co-editing is unavailable; Studio edits solo with file-level saves"),components:n("GET","/__studio/components","Discover components (ComponentMeta[])"),cem:n("GET","/__studio/cem","Custom-elements manifest of an npm dependency","Dependency components lose prop/slot metadata."),formats:n("GET","/__studio/formats","The project's format registry entries plus a sibling `extensions` array — per enabled "+"extension its manifest identity and project-section contributions (ExtensionsInfo[]; backs listFormats and listExtensions).","Only .json documents open (backs listFormats); descriptor-contributed settings sections do not appear."),extensionCatalog:n("GET","/__studio/catalog","Extensions this backend can OFFER (ExtensionCatalogEntry[]) — the shipped first-party "+"catalogue plus any package in the project's own dependencies exporting a jx-extension.json, each marked with whether the host resolves it without a project install and whether the project has it installed. A capability rather than a constant: a Worker ships a fixed set "+"of extension packages (specs/extensions.md §5.5). Backs listExtensionCatalog.","The Extensions section offers no catalogue; adding an extension stays a typed package name."),projectSchemas:n("GET","/__studio/project-schemas","The project's generated entry documents (project.schema.json / document.schema.json), "+"PRE-BUNDLED into self-contained schemas — {project, document} (backs fetchProjectSchemas). "+"Regenerated on demand when missing or older than project.json.","The JSON editor falls back to the bundled core schemas (extension sections get no editor validation/completion)."),format:n("POST","/__studio/format","Dispatch a format capability {format, action: parse|serialize, source?|doc?}","Non-JSON documents cannot be parsed/serialized (backs formatAction)."),pluginSchema:n("GET","/__studio/plugin-schema","Extract a $studio schema from a class source","Plugin property panels fall back to generic JSON editing."),codeFormat:n("POST","/__studio/code/format","Format posted source {code, path?} → {code, errors}","Code editors skip format-on-open/save (codeService returns null)."),codeMinify:n("POST","/__studio/code/minify","Minify posted source {code} → {code}","Compiled-output minification is skipped."),codeLint:n("POST","/__studio/code/lint","Lint posted source {code, path?} → {diagnostics}","Code editors show no lint markers."),buildSite:n("POST","/__studio/build","Build or render the site → {routes, files, errors, mode?, url}","Build Site reports that this target cannot build."),previewSite:n("POST","/__studio/preview","Preview the working tree at a route → {routes, files, errors, mode, url, reused}","Open in Browser falls back to buildSite."),previewOverlay:n("POST","/__studio/preview/overlay","Publish (POST) or retract (DELETE) a document's unsaved bytes → 204","A live preview shows the last saved state instead of the editor's."),packages:n("GET","/__studio/packages","List dependencies (PackageInfo[])"),packagesAdd:n("POST","/__studio/packages/add","Add a dependency"),packagesRemove:n("POST","/__studio/packages/remove","Remove a dependency"),packagesInstall:n("POST","/__studio/packages/install","Run the package manager install","Install/reinstall affordances are hidden; manifest-only edits still work."),packagesNeedsInstall:n("GET","/__studio/packages/needs-install","Whether node_modules is stale","The install-on-open prompt never shows."),packagesVersions:n("GET","/__studio/packages/versions","Newest published version of each dependency (PackageVersionInfo[])","The Latest column stays empty and the update affordances are hidden."),packagesSetVersions:n("POST","/__studio/packages/set-versions","Rewrite dependency ranges and install","Bulk version updates are hidden."),gitStatus:n("GET","/__studio/git/status","Working-tree status (GitStatusResult)"),gitBranches:n("GET","/__studio/git/branches","Branch list (GitBranchesResult)"),gitLog:n("GET","/__studio/git/log","Recent commits (GitLogEntry[])"),gitStage:n("POST","/__studio/git/stage","Stage files"),gitUnstage:n("POST","/__studio/git/unstage","Unstage files"),gitCommit:n("POST","/__studio/git/commit","Commit staged (else all dirty) files"),gitPush:n("POST","/__studio/git/push","Push (cloud: sync check — commits land on push)"),gitPull:n("POST","/__studio/git/pull","Pull/fast-forward; 409 {conflicts} on overlap"),gitFetch:n("POST","/__studio/git/fetch","Refresh remote tracking state"),gitCheckout:n("POST","/__studio/git/checkout","Switch branches"),gitCreateBranch:n("POST","/__studio/git/create-branch","Create a branch"),gitDiff:n("GET","/__studio/git/diff","Unified diff of dirty files (or one path)"),gitShow:n("GET","/__studio/git/show","File content at a ref"),gitDiscard:n("POST","/__studio/git/discard","Discard working changes"),gitInit:n("POST","/__studio/git/init","Initialize a repository"),gitAddRemote:n("POST","/__studio/git/add-remote","Add a remote"),gitClone:n("POST","/__studio/git/clone","Clone a repository","The welcome screen hides Clone Git Repository."),gitPr:n("POST","/__studio/git/pr","Open a pull request → PullRequestInfo","Studio falls back to a direct GitHub API call with the user's token."),dataConnections:n("GET","/__studio/data/connections","Connector connections with configured/missingSecrets/isDefault state, reachable table names, and registry-descriptor provider metadata (DataConnectionsResponse; backs dataConnections)","The connections settings section shows no status, and data-domain actions stay hidden."),dataConnectionTest:n("POST","/__studio/data/connections/test","Probe a connection {connection} → DataConnectionTestResult (backs dataConnectionTest)","The Test Connection action is hidden."),dataPush:n("POST","/__studio/data/push","Additive schema push {connection?, dryRun?} → DataPushResult (plan of DataPushStep[], "+"applied, warnings/errors; backs dataPush)","The Push Schema action is hidden; schemas deploy via `jx db push` instead."),dataRows:n("GET","/__studio/data/rows","Page a table (DataRowsQuery params) → DataRowsResult {rows, total, columns} (backs dataRows)","The data grid is unavailable."),dataInsertRow:n("POST","/__studio/data/rows","Insert a row {table, connection?, values} → {row} (backs dataInsertRow)","The data grid hides its add-row footer."),dataUpdateRow:n("PUT","/__studio/data/rows","Update a row keyed on its primary key {table, connection?, pk, set} → {row} (backs "+"dataUpdateRow)","Data grid cells are read-only."),dataDeleteRow:n("DELETE","/__studio/data/rows","Delete a row (?table=&pk=&connection=) → {ok} (backs dataDeleteRow)","The data grid hides row deletion."),secretsList:n("GET","/__studio/secrets","Configured secret env-var NAMES, never values (SecretsListResponse; backs listSecrets)","Secret fields cannot show set/unset state."),secretsSet:n("PUT","/__studio/secrets","Write/remove secrets in the backend store (.dev.vars locally) {set?, remove?} → names "+"(backs setSecrets)","The secret form control renders disabled; secrets are edited in .dev.vars by hand."),aiChat:n("POST","/__studio/ai/chat","StreamEvent SSE chat proxy {messages, tools, systemPrompt, model}"),aiModels:n("GET","/__studio/ai/models","Model catalogue (AiModelsResponse)"),cfProxy:n("POST","/__studio/cf/proxy","Allowlisted Cloudflare API passthrough {path, method?, body?} (backs cfApi)","The Publish panel explains the git-push publishing path instead.")};var j1=200;var K=new Set(["reload","repeat","none"]);function Du(e){if(!Array.isArray(e))return[];return e.flatMap((t)=>{let o=t;if(!o||typeof o.id!=="string"||!o.id||typeof o.label!=="string"||!o.label)return[];return[{id:o.id,label:o.label,...typeof o.href==="string"&&o.href?{href:o.href}:{},...o.primary===!0?{primary:!0}:{}}]})}function qw(e){return typeof e==="string"&&K.has(e)?e:void 0}function H(e){return e.replaceAll("_","-")}function x(e){if(!e||typeof e!=="object")return{};let{actions:t,code:o,heading:r,installUrl:c,retry:m,type:u}=e,f=qw(m),i=Xf(u)??(typeof o==="string"?H(o):null);return{...i===null?{}:{code:i},...typeof c==="string"?{installUrl:c}:{},...t===void 0?{}:{actions:Du(t)},...typeof r==="string"&&r?{heading:r}:{},...f===void 0?{}:{retry:f}}}function nT(e){let t=x(e);return t.code==="needs-installation-access"&&t.installUrl?t.installUrl:null}function iT(e){return x(e).code==="action-required"}function vc(){return Lr(_t.aiOpenAiKey)}function oT(e){qr(_t.aiOpenAiKey,e||"")}function kb(){return aL(_t.aiOpenAiKey)}function da(){return Lr(_t.aiBaseUrl)}function Sb(){return Lr(_t.aiModel)}function rT(e){qr(_t.aiModel,e||"")}function sT(e){cL([[_t.aiOpenAiKey,e.apiKey],[_t.aiBaseUrl,e.baseUrl],[_t.aiModel,e.model]])}function aT(e){return!sp(_t.aiOpenAiKey,e.apiKey,vc())||!sp(_t.aiBaseUrl,e.baseUrl,da())||!sp(_t.aiModel,e.model,Sb())}function sp(e,t,o){return Qb(e,t)===Qb(e,o)}function lT(){Hu([_t.aiOpenAiKey,_t.aiBaseUrl,_t.aiModel])}function Gw(){return{apiKey:vc(),baseUrl:da()}}function N(e){return`${e.apiKey}\x00${e.baseUrl}`}var g=null,R="",P=!1,_=!1,A="",T,v="",E=null,O=null,U=new Set,W=600000,b=0,L=!1;function Tr(){g=null,R="",P=!1,_=!1,A="",T=void 0,v="",E=null,O=null,b=0}var z=new Set([_t.aiOpenAiKey.key,_t.aiBaseUrl.key,_t.cfToken.key,_t.cfAccountId.key]);Xb((e)=>{if(e.some((t)=>z.has(t)))Tr()});function H1(e){return g&&R===N(e)?g:null}function B(e){return g?.find((t)=>t.id===e)}function B1(e){return B(e)?.toolSupport}function cT(e){return B(e)?.contextWindow}function Eb(e){if(e)U.add(e);O??=bd({force:!0}).catch(()=>{}).then(()=>{b=Date.now();for(let t of U)t()})}function V(){if(!_||b===0||Date.now()-b<W)return!1;return O=null,b=0,Eb(),!0}function J(){if(typeof window>"u"||L)return;L=!0,window.addEventListener("focus",()=>{V()})}J();function Qf(){return kb()||Kw()}function Kw(){return P}function dT(){return _}function ap(){return T}function uT(){return v}function Jw(){return E}function Y(){return A}function Ba(){return Sb()||Y()||_t.aiModel.default}function X(e,t){let o;try{o=new URL(e,"http://jx.invalid")}catch{return e}return o.pathname=o.pathname.replace(/[^/]*$/,t),/^https?:/i.test(e)?o.href:`${o.pathname}${o.search}`}async function bd(e={}){let t=e.credentials??Gw(),o=N(t);if(g&&R===o&&!e.force)return g;let r=p(),c=await Promise.resolve(r.aiChatUrl()),m=X(c,"models"),u={};if(t.apiKey)u["X-Api-Key"]=t.apiKey;if(t.baseUrl)u["X-Api-Base-URL"]=t.baseUrl;let f=await fetch(m,{headers:u});if(!f.ok)throw Error(`HTTP ${f.status}`);let i=await f.json();return P=i.configured===!0,_=i.managed===!0,A=i.defaultModel??"",T=i.code,v=i.upstreamError!==void 0?i.upstreamMessage??"":"",E=i.code==="action_required"?{actions:Du(i.actions),...typeof i.detail==="string"&&i.detail?{detail:i.detail}:{}}:null,g=(i.models||[]).map((l)=>{let h={id:l.id,name:l.name||l.id};if(typeof l.contextWindow==="number")h.contextWindow=l.contextWindow;if(typeof l.toolSupport==="boolean")h.toolSupport=l.toolSupport;return h}),R=o,g}var S=new Set,C=null;function hT(e){if(S.size===0){C=e;return}for(let t of S)t(e)}function G(e){S.add(e);let t=C;if(C=null,t)e(t);return()=>{S.delete(e)}}function Yw(){return We()&&typeof p().performAction==="function"}function z1(e){let t=e.find((r)=>r.primary)??e[0];if(!t)return null;let o=e.find((r)=>r!==t);return o?{lead:t,other:o}:{lead:t}}var w=null,q=!1;function Zw(e){let t=z1(e.actions);if(!Yw()||!t)return Promise.resolve(!1);return w??=Q(e,t).finally(()=>{w=null}),w}async function lp(e){let t=x(e);if(t.code!=="action-required"||!t.actions?.length)return!1;return Zw({actions:t.actions,detail:e instanceof Error?e.message:void 0,heading:t.heading,retry:t.retry})}async function F(){Tr(),await bc(),W1()}function Q(e,t){let o=e.detail??"This needs one more step first.";return new Promise((r)=>{let c="offer",m=(y)=>{if(c==="done")return;c="done",h.close(),r(y)},u=(y)=>{c="offer",h.update({cancelLabel:"Not now",confirmLabel:t.lead.label,message:y,secondaryLabel:t.other?.label??""})},f=(y)=>{if(c!=="offer")return;c="waiting";let D;try{D=p().performAction(y)}catch(d){u(d instanceof Error?d.message:String(d));return}h.update({cancelLabel:"Cancel",confirmLabel:"Waiting…",message:"Finish in the window that opened. This closes by itself once it is done.",secondaryLabel:""}),D.then(async(d)=>{if(d?.status==="done"){await F(),m(!0);return}if(c!=="waiting"||!d||d.status==="redirect")return;bc(),u(o)},(d)=>{if(c==="waiting")u(d instanceof Error?d.message:String(d))})},{lead:i,other:l}=t,h=bs({cancelLabel:"Not now",confirmLabel:i.label,headline:e.heading??"One more step",layer:Ct("dialog"),message:o,onCancel:()=>{q=!0,m(!1)},onClosed:()=>{m(!1)},onConfirm:()=>{f(i)},region:"account/action",...l?{onSecondary:()=>{f(l)},secondaryLabel:l.label}:{}})})}function Z(e){if(e==="reload")location.reload();else if(e==="repeat")k.info("Done. Run that again now.",{key:"account.action.retry",source:"Account"})}function pT(){return G((e)=>{if(q||w)return;Zw(e).then((t)=>{if(t)Z(e.retry)})})}async function Tb(e){if(!Yw())return!1;let t=p().performAction(e),o;try{o=await t}catch(r){return k.error(r instanceof Error?r.message:String(r),{key:"account.action",source:"Account",tier:"toast"}),!1}if(o?.status==="done")return await F(),!0;if(o?.status!=="redirect")await bc();return!1}function W1(){for(let e of I()){let t={key:`account.notice.${e.id}`,source:"Account"};if(e.level==="warning")k.warn(e.message,t);else k.info(e.message,t)}}
|
|
2
2
|
export{bc,Ww,Vw,eT,tT,F1,Xf,Ro,Fs,Uw,j1,Du,qw,nT,iT,vc,oT,kb,da,Sb,rT,sT,aT,sp,lT,Gw,Tr,H1,B1,cT,Eb,Qf,Kw,dT,ap,uT,Jw,Ba,bd,hT,Yw,z1,Zw,lp,pT,Tb,W1};
|
|
3
3
|
|
|
4
4
|
//# debugId=4FD39BF317B161DD64756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-
|
|
5
|
+
//# sourceMappingURL=studio-bftp4n4b.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{br}from"./studio-sxc0zvpt.js";import{un,rn}from"./studio-0k9mvpgj.js";import{ge,Q,v,Mo,k}from"./studio-fqq890ap.js";import{di}from"./studio-693nhyky.js";import{rt,zt,T,R,An,Ct}from"./studio-spf2skgc.js";import{Td}from"./studio-zpnk016a.js";import{QE}from"./studio-cxt150pj.js";import{qn}from"./studio-xry7tk3z.js";import{yc,js,tm}from"./studio-yr04mv2j.js";var y={$schema:"https://jxsuite.com/schema/v1",$id:"StudioPanelActivity",$description:'The Activity feed: one row per operation this session, newest last, drawn from the projection `panels/activity-panel.ts` hands in. A row is a glyph, a head line (what the operation is, who is running it, how long it has taken), the line it is doing now, the plan it declared, the log it captured and — only when the operation handed a callback over — its Cancel. Every conditional the row has is a boolean field on the projected item, because `$switch` over a value is the only conditional a document has and "is this entry cancellable" is a question the panel has already answered. Nothing here reads the activity store: the panel owns what an operation IS, and the surface owns what it looks like.',tagName:"div",attributes:{part:"panel"},style:{$description:"What `.activity-panel`, `.activity-actions`, `.activity-list`, `.activity-row`, `.activity-icon`, `.activity-body`, `.activity-head`, `.activity-title`, `.activity-source`, `.activity-duration`, `.activity-status`, `.activity-steps`, `.activity-step`, `.activity-step-icon`, `.activity-log-toggle` and `.activity-log` said in `styles/panels.css`, keyed on `part`. Two rules were DELETED rather than moved: `.activity-clear` and `.activity-cancel` drew a small bordered button by hand, and `jx-button` is that button — so the sizes, the border, the hover fill and the disabled state are the kit's now. Three token names changed meaning on the way: `--spectrum-font-size-50`, `--spectrum-font-size-75` and `--spectrum-corner-radius-75` resolve only inside `<sp-theme>`, and this document is mounted into the Bottom dock's body where that element is not an ancestor — every one of them would silently have taken its px fallback. They are the kit's own scale here (`--jx-text-sm`, `--jx-text-md`, `--jx-radius-xs`), which is the step each of them was. The `.activity-*` rules stay in the stylesheet regardless: `publish/deploy-checklist.ts` still draws the checklist above this feed in that same vocabulary, and it is a lit template until it converts.",display:"flex",flexDirection:"column",gap:"8px",padding:"8px",minWidth:"0",fontFamily:"var(--jx-font-sans)",color:"var(--fg)",'& [part="feed"]':{display:"flex",flexDirection:"column",gap:"8px",minWidth:"0"},'& [part="actions"]':{display:"flex",justifyContent:"flex-end"},'& [part="list"]':{display:"flex",flexDirection:"column",gap:"4px",margin:"0",padding:"0",listStyle:"none"},'& [part="row"]':{$description:"The left border is the state, at 3px, which is the one thing that must be legible in a column of twenty rows without reading any of them. Its default is the dim foreground so a state nobody has a colour for still draws a border rather than a gap.",display:"flex",alignItems:"flex-start",gap:"8px",padding:"6px 8px",border:"1px solid var(--border)",borderLeft:"3px solid var(--fg-dim)",borderRadius:"var(--radius)",background:"var(--bg-panel)",color:"var(--fg)",fontSize:"var(--jx-text-md)"},'& [part="row"][data-state="running"]':{borderLeftColor:"var(--accent)"},'& [part="row"][data-state="done"]':{borderLeftColor:"var(--success)"},'& [part="row"][data-state="failed"]':{borderLeftColor:"var(--danger)"},'& [part="row"][data-state="cancelled"]':{borderLeftColor:"var(--fg-dim)"},'& [part="icon"]':{flex:"none",width:"14px",textAlign:"center",fontWeight:"700",lineHeight:"1.5"},'& [part="row"][data-state="running"] [part="icon"]':{color:"var(--accent)"},'& [part="row"][data-state="done"] [part="icon"]':{color:"var(--success)"},'& [part="row"][data-state="failed"] [part="icon"]':{color:"var(--danger)"},'& [part="body"]':{flex:"1",minWidth:"0",display:"flex",flexDirection:"column",gap:"2px"},'& [part="head"]':{display:"flex",alignItems:"baseline",gap:"8px",minWidth:"0"},'& [part="row-title"]':{fontWeight:"700",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},'& [part="source"], & [part="duration"]':{flex:"none",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"},'& [part="duration"]':{$description:"Pushed to the far edge so a column of rows reads as a column of times.",marginLeft:"auto"},'& [part="status"]':{color:"var(--fg-dim)",overflowWrap:"anywhere"},'& [part="steps"]':{$description:'The plan, declared up front, so "which of the three steps is this on" is answered by looking rather than by reading the status line and remembering what came before it.',display:"flex",flexDirection:"column",gap:"1px",margin:"2px 0 0",padding:"0",listStyle:"none",fontSize:"var(--jx-text-sm)"},'& [part="step"]':{display:"flex",gap:"6px",color:"var(--fg-dim)"},'& [part="step"][data-state="running"]':{color:"var(--fg)"},'& [part="step"][data-state="done"] [part="step-icon"]':{color:"var(--success)"},'& [part="step"][data-state="failed"] [part="step-icon"]':{color:"var(--danger)"},'& [part="step-icon"]':{flex:"none",width:"10px",textAlign:"center"},'& [part="log-toggle"]':{$description:"A plain button rather than a kit one, and the one element here that is not the kit's. The control has to carry `aria-expanded` on the node the reader actually focuses, and a `jx-button` forwards a fixed set of ARIA properties to the control inside its shadow root — an attribute written on the host would name the wrapper and not the button. Its wording is the disclosure's whole state (`docs/studio/interface/problems-and-progress.md` calls it the Show log disclosure), so nothing else has to draw one.",alignSelf:"flex-start",padding:"0",border:"none",background:"none",color:"var(--accent)",font:"inherit",fontSize:"var(--jx-text-sm)",cursor:"pointer",":hover":{textDecoration:"underline"},":focus-visible":{outline:"var(--jx-focus-ring)",outlineOffset:"2px"}},'& [part="log"]':{$description:"The captured output the progress modal used to show once and then lose. It scrolls inside the row rather than growing it, so one 400-line `bun install` failure does not become the whole panel. It is selectable against the root's `user-select: none`, the one part of an activity row that is: the output is what a reader pastes into a bug report, and the row offers no copy action.",userSelect:"text",maxHeight:"180px",margin:"2px 0 0",padding:"6px",overflow:"auto",borderRadius:"var(--jx-radius-xs)",background:"var(--bg)",color:"var(--fg-dim)",fontFamily:"var(--font-mono)",fontSize:"var(--jx-text-sm)",whiteSpace:"pre-wrap"},'& [part="cancel"]':{flex:"none"},'& [part="empty"]':{$description:"The teaching empty state, drawn here rather than borrowed from `panels/empty-state.ts`: that helper is a lit template and a document cannot call one. What it says is what is kept — one sentence saying what the region is FOR, then where its content comes from — and this region's fill is an operation somebody else starts, so it offers no button.",display:"flex",flexDirection:"column",alignItems:"center",gap:"8px",padding:"24px",textAlign:"center",fontSize:"13px",color:"var(--fg-dim)"},'& [part="empty-message"], & [part="empty-detail"]':{margin:"0",maxWidth:"34ch",lineHeight:"1.5"},'& [part="empty-detail"]':{fontSize:"var(--jx-text-sm)",opacity:"0.8"}},children:[{tagName:"div",attributes:{part:"feed-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasRows"},cases:{true:{tagName:"div",attributes:{part:"feed"},children:[{tagName:"div",attributes:{part:"actions-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasFinished"},cases:{true:{tagName:"div",attributes:{part:"actions"},children:[{tagName:"jx-button",$props:{size:"sm",quiet:!0},attributes:{part:"clear"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/clearFinished"}}]},children:[{tagName:"span",textContent:"${state.clearLabel}"}]}]}}},{tagName:"ul",attributes:{part:"list"},children:[{$prototype:"Array",items:{$ref:"#/state/rows"},key:{$ref:"$map/item/id"},map:{tagName:"li",attributes:{part:"row","data-state":"${$map.item.state}"},children:[{tagName:"span",attributes:{part:"icon","aria-hidden":"true"},textContent:"${$map.item.icon}"},{tagName:"div",attributes:{part:"body"},children:[{tagName:"div",attributes:{part:"head"},children:[{tagName:"span",attributes:{part:"row-title"},textContent:"${$map.item.title}"},{tagName:"span",attributes:{part:"source-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasSource"},cases:{true:{tagName:"span",attributes:{part:"source"},textContent:"${$map.item.source}"}}},{tagName:"span",attributes:{part:"duration"},textContent:"${$map.item.duration}"}]},{tagName:"div",attributes:{part:"status-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasStatus"},cases:{true:{tagName:"div",attributes:{part:"status"},textContent:"${$map.item.status}"}}},{tagName:"div",attributes:{part:"steps-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasSteps"},cases:{true:{tagName:"ol",attributes:{part:"steps"},children:[{$prototype:"Array",items:{$ref:"$map/item/steps"},key:{$ref:"$map/item/key"},map:{tagName:"li",attributes:{part:"step","data-state":"${$map.item.state}"},children:[{tagName:"span",attributes:{part:"step-icon","aria-hidden":"true"},textContent:"${$map.item.icon}"},{tagName:"span",attributes:{part:"step-label"},textContent:"${$map.item.label}"}]}}]}}},{tagName:"div",attributes:{part:"log-toggle-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasLog"},cases:{true:{tagName:"button",attributes:{part:"log-toggle",type:"button","aria-expanded":"${$map.item.expanded ? 'true' : 'false'}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/toggleLog"},value:[{$ref:"$map/item/id"}]}]},textContent:"${$map.item.logLabel}"}}},{tagName:"div",attributes:{part:"log-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/showLog"},cases:{true:{tagName:"pre",attributes:{part:"log"},textContent:"${$map.item.logText}"}}}]},{tagName:"div",attributes:{part:"cancel-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/cancellable"},cases:{true:{tagName:"jx-button",$props:{size:"sm"},attributes:{part:"cancel",title:"Stop this operation"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/cancel"},value:[{$ref:"$map/item/id"}]}]},children:[{tagName:"span",textContent:"Cancel"}]}}}]}}]}]},false:{tagName:"div",attributes:{part:"empty"},children:[{tagName:"p",attributes:{part:"empty-message"},textContent:"Long operations show their progress, their log and their Cancel button here."},{tagName:"p",attributes:{part:"empty-detail"},textContent:"Installs, clones, publishes and imports report here while they run."}]}}}]};T("panel-activity",y);var g=null,h=null,p=null,d=null;function E(t,e){t.rows=e.rows,t.hasRows=e.hasRows,t.hasFinished=e.hasFinished,t.clearLabel=e.clearLabel}function j(t){if(g!==t)return!1;return d===null?p!==null:d.root.parentNode===t}function b(t,e){if(j(t))return;f(),g=t;let a=v({cancel:e.cancel,clearFinished:e.clearFinished,clearLabel:"",hasFinished:!1,hasRows:!1,rows:[],toggleLog:e.toggleLog});h=ge(),h.run(()=>{Q(()=>{E(a,e.project())})});let o=R("panel-activity",a,t);p=o,o.then((i)=>{if(p===o)d=i;else i.dispose()})}function f(){h?.stop(),h=null;let t=p;if(p=null,d)d.dispose(),d=null;else if(t)t.then((e)=>e.dispose());g=null}var s=v([]),I=20,u=new Map,w=0;function H(){return w+=1,`a${w}`}function c(t){return t.state!=="running"}function x(){let t=s.filter((e)=>c(e)).length-I;while(t>0){let e=s.findIndex((a)=>c(a));if(e===-1)return;u.delete(s[e].id),s.splice(e,1),t-=1}}function aa(t){let e={cancellable:t.cancel!==void 0,endedAt:null,expanded:!1,id:H(),log:[],startedAt:Mo(),state:"running",status:t.status??"",steps:(t.steps??[]).map((i)=>({label:i,state:"pending"})),title:t.title,...t.source===void 0?{}:{source:t.source}};if(t.cancel)u.set(e.id,t.cancel);s.push(e);let a=s.at(-1);x();let o=(i,r)=>{if(c(a))return;if(a.state=i,a.endedAt=Mo(),r!==void 0)a.status=r;for(let n of a.steps)n.state=n.state==="done"?"done":i==="done"?"done":"failed";a.cancellable=!1,u.delete(a.id),x()};return{done(i){o("done",i)},entry:a,fail(i,r={}){if(c(a))return;let n=a.log.join(`
|
|
1
|
+
import{br}from"./studio-sxc0zvpt.js";import{un,rn}from"./studio-cp1gbff9.js";import{ge,Q,v,Mo,k}from"./studio-fqq890ap.js";import{di}from"./studio-1q6amtph.js";import{rt,zt,T,R,An,Ct}from"./studio-7qvs7v0m.js";import{Td}from"./studio-4m50vh74.js";import{QE}from"./studio-aekhcdzw.js";import{qn}from"./studio-rmn2dz59.js";import{yc,js,tm}from"./studio-yr04mv2j.js";var y={$schema:"https://jxsuite.com/schema/v1",$id:"StudioPanelActivity",$description:'The Activity feed: one row per operation this session, newest last, drawn from the projection `panels/activity-panel.ts` hands in. A row is a glyph, a head line (what the operation is, who is running it, how long it has taken), the line it is doing now, the plan it declared, the log it captured and — only when the operation handed a callback over — its Cancel. Every conditional the row has is a boolean field on the projected item, because `$switch` over a value is the only conditional a document has and "is this entry cancellable" is a question the panel has already answered. Nothing here reads the activity store: the panel owns what an operation IS, and the surface owns what it looks like.',tagName:"div",attributes:{part:"panel"},style:{$description:"What `.activity-panel`, `.activity-actions`, `.activity-list`, `.activity-row`, `.activity-icon`, `.activity-body`, `.activity-head`, `.activity-title`, `.activity-source`, `.activity-duration`, `.activity-status`, `.activity-steps`, `.activity-step`, `.activity-step-icon`, `.activity-log-toggle` and `.activity-log` said in `styles/panels.css`, keyed on `part`. Two rules were DELETED rather than moved: `.activity-clear` and `.activity-cancel` drew a small bordered button by hand, and `jx-button` is that button — so the sizes, the border, the hover fill and the disabled state are the kit's now. Three token names changed meaning on the way: `--spectrum-font-size-50`, `--spectrum-font-size-75` and `--spectrum-corner-radius-75` resolve only inside `<sp-theme>`, and this document is mounted into the Bottom dock's body where that element is not an ancestor — every one of them would silently have taken its px fallback. They are the kit's own scale here (`--jx-text-sm`, `--jx-text-md`, `--jx-radius-xs`), which is the step each of them was. The `.activity-*` rules stay in the stylesheet regardless: `publish/deploy-checklist.ts` still draws the checklist above this feed in that same vocabulary, and it is a lit template until it converts.",display:"flex",flexDirection:"column",gap:"8px",padding:"8px",minWidth:"0",fontFamily:"var(--jx-font-sans)",color:"var(--fg)",'& [part="feed"]':{display:"flex",flexDirection:"column",gap:"8px",minWidth:"0"},'& [part="actions"]':{display:"flex",justifyContent:"flex-end"},'& [part="list"]':{display:"flex",flexDirection:"column",gap:"4px",margin:"0",padding:"0",listStyle:"none"},'& [part="row"]':{$description:"The left border is the state, at 3px, which is the one thing that must be legible in a column of twenty rows without reading any of them. Its default is the dim foreground so a state nobody has a colour for still draws a border rather than a gap.",display:"flex",alignItems:"flex-start",gap:"8px",padding:"6px 8px",border:"1px solid var(--border)",borderLeft:"3px solid var(--fg-dim)",borderRadius:"var(--radius)",background:"var(--bg-panel)",color:"var(--fg)",fontSize:"var(--jx-text-md)"},'& [part="row"][data-state="running"]':{borderLeftColor:"var(--accent)"},'& [part="row"][data-state="done"]':{borderLeftColor:"var(--success)"},'& [part="row"][data-state="failed"]':{borderLeftColor:"var(--danger)"},'& [part="row"][data-state="cancelled"]':{borderLeftColor:"var(--fg-dim)"},'& [part="icon"]':{flex:"none",width:"14px",textAlign:"center",fontWeight:"700",lineHeight:"1.5"},'& [part="row"][data-state="running"] [part="icon"]':{color:"var(--accent)"},'& [part="row"][data-state="done"] [part="icon"]':{color:"var(--success)"},'& [part="row"][data-state="failed"] [part="icon"]':{color:"var(--danger)"},'& [part="body"]':{flex:"1",minWidth:"0",display:"flex",flexDirection:"column",gap:"2px"},'& [part="head"]':{display:"flex",alignItems:"baseline",gap:"8px",minWidth:"0"},'& [part="row-title"]':{fontWeight:"700",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},'& [part="source"], & [part="duration"]':{flex:"none",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"},'& [part="duration"]':{$description:"Pushed to the far edge so a column of rows reads as a column of times.",marginLeft:"auto"},'& [part="status"]':{color:"var(--fg-dim)",overflowWrap:"anywhere"},'& [part="steps"]':{$description:'The plan, declared up front, so "which of the three steps is this on" is answered by looking rather than by reading the status line and remembering what came before it.',display:"flex",flexDirection:"column",gap:"1px",margin:"2px 0 0",padding:"0",listStyle:"none",fontSize:"var(--jx-text-sm)"},'& [part="step"]':{display:"flex",gap:"6px",color:"var(--fg-dim)"},'& [part="step"][data-state="running"]':{color:"var(--fg)"},'& [part="step"][data-state="done"] [part="step-icon"]':{color:"var(--success)"},'& [part="step"][data-state="failed"] [part="step-icon"]':{color:"var(--danger)"},'& [part="step-icon"]':{flex:"none",width:"10px",textAlign:"center"},'& [part="log-toggle"]':{$description:"A plain button rather than a kit one, and the one element here that is not the kit's. The control has to carry `aria-expanded` on the node the reader actually focuses, and a `jx-button` forwards a fixed set of ARIA properties to the control inside its shadow root — an attribute written on the host would name the wrapper and not the button. Its wording is the disclosure's whole state (`docs/studio/interface/problems-and-progress.md` calls it the Show log disclosure), so nothing else has to draw one.",alignSelf:"flex-start",padding:"0",border:"none",background:"none",color:"var(--accent)",font:"inherit",fontSize:"var(--jx-text-sm)",cursor:"pointer",":hover":{textDecoration:"underline"},":focus-visible":{outline:"var(--jx-focus-ring)",outlineOffset:"2px"}},'& [part="log"]':{$description:"The captured output the progress modal used to show once and then lose. It scrolls inside the row rather than growing it, so one 400-line `bun install` failure does not become the whole panel. It is selectable against the root's `user-select: none`, the one part of an activity row that is: the output is what a reader pastes into a bug report, and the row offers no copy action.",userSelect:"text",maxHeight:"180px",margin:"2px 0 0",padding:"6px",overflow:"auto",borderRadius:"var(--jx-radius-xs)",background:"var(--bg)",color:"var(--fg-dim)",fontFamily:"var(--font-mono)",fontSize:"var(--jx-text-sm)",whiteSpace:"pre-wrap"},'& [part="cancel"]':{flex:"none"},'& [part="empty"]':{$description:"The teaching empty state, drawn here rather than borrowed from `panels/empty-state.ts`: that helper is a lit template and a document cannot call one. What it says is what is kept — one sentence saying what the region is FOR, then where its content comes from — and this region's fill is an operation somebody else starts, so it offers no button.",display:"flex",flexDirection:"column",alignItems:"center",gap:"8px",padding:"24px",textAlign:"center",fontSize:"13px",color:"var(--fg-dim)"},'& [part="empty-message"], & [part="empty-detail"]':{margin:"0",maxWidth:"34ch",lineHeight:"1.5"},'& [part="empty-detail"]':{fontSize:"var(--jx-text-sm)",opacity:"0.8"}},children:[{tagName:"div",attributes:{part:"feed-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasRows"},cases:{true:{tagName:"div",attributes:{part:"feed"},children:[{tagName:"div",attributes:{part:"actions-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasFinished"},cases:{true:{tagName:"div",attributes:{part:"actions"},children:[{tagName:"jx-button",$props:{size:"sm",quiet:!0},attributes:{part:"clear"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/clearFinished"}}]},children:[{tagName:"span",textContent:"${state.clearLabel}"}]}]}}},{tagName:"ul",attributes:{part:"list"},children:[{$prototype:"Array",items:{$ref:"#/state/rows"},key:{$ref:"$map/item/id"},map:{tagName:"li",attributes:{part:"row","data-state":"${$map.item.state}"},children:[{tagName:"span",attributes:{part:"icon","aria-hidden":"true"},textContent:"${$map.item.icon}"},{tagName:"div",attributes:{part:"body"},children:[{tagName:"div",attributes:{part:"head"},children:[{tagName:"span",attributes:{part:"row-title"},textContent:"${$map.item.title}"},{tagName:"span",attributes:{part:"source-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasSource"},cases:{true:{tagName:"span",attributes:{part:"source"},textContent:"${$map.item.source}"}}},{tagName:"span",attributes:{part:"duration"},textContent:"${$map.item.duration}"}]},{tagName:"div",attributes:{part:"status-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasStatus"},cases:{true:{tagName:"div",attributes:{part:"status"},textContent:"${$map.item.status}"}}},{tagName:"div",attributes:{part:"steps-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasSteps"},cases:{true:{tagName:"ol",attributes:{part:"steps"},children:[{$prototype:"Array",items:{$ref:"$map/item/steps"},key:{$ref:"$map/item/key"},map:{tagName:"li",attributes:{part:"step","data-state":"${$map.item.state}"},children:[{tagName:"span",attributes:{part:"step-icon","aria-hidden":"true"},textContent:"${$map.item.icon}"},{tagName:"span",attributes:{part:"step-label"},textContent:"${$map.item.label}"}]}}]}}},{tagName:"div",attributes:{part:"log-toggle-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasLog"},cases:{true:{tagName:"button",attributes:{part:"log-toggle",type:"button","aria-expanded":"${$map.item.expanded ? 'true' : 'false'}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/toggleLog"},value:[{$ref:"$map/item/id"}]}]},textContent:"${$map.item.logLabel}"}}},{tagName:"div",attributes:{part:"log-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/showLog"},cases:{true:{tagName:"pre",attributes:{part:"log"},textContent:"${$map.item.logText}"}}}]},{tagName:"div",attributes:{part:"cancel-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/cancellable"},cases:{true:{tagName:"jx-button",$props:{size:"sm"},attributes:{part:"cancel",title:"Stop this operation"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/cancel"},value:[{$ref:"$map/item/id"}]}]},children:[{tagName:"span",textContent:"Cancel"}]}}}]}}]}]},false:{tagName:"div",attributes:{part:"empty"},children:[{tagName:"p",attributes:{part:"empty-message"},textContent:"Long operations show their progress, their log and their Cancel button here."},{tagName:"p",attributes:{part:"empty-detail"},textContent:"Installs, clones, publishes and imports report here while they run."}]}}}]};T("panel-activity",y);var g=null,h=null,p=null,d=null;function E(t,e){t.rows=e.rows,t.hasRows=e.hasRows,t.hasFinished=e.hasFinished,t.clearLabel=e.clearLabel}function j(t){if(g!==t)return!1;return d===null?p!==null:d.root.parentNode===t}function b(t,e){if(j(t))return;f(),g=t;let a=v({cancel:e.cancel,clearFinished:e.clearFinished,clearLabel:"",hasFinished:!1,hasRows:!1,rows:[],toggleLog:e.toggleLog});h=ge(),h.run(()=>{Q(()=>{E(a,e.project())})});let o=R("panel-activity",a,t);p=o,o.then((i)=>{if(p===o)d=i;else i.dispose()})}function f(){h?.stop(),h=null;let t=p;if(p=null,d)d.dispose(),d=null;else if(t)t.then((e)=>e.dispose());g=null}var s=v([]),I=20,u=new Map,w=0;function H(){return w+=1,`a${w}`}function c(t){return t.state!=="running"}function x(){let t=s.filter((e)=>c(e)).length-I;while(t>0){let e=s.findIndex((a)=>c(a));if(e===-1)return;u.delete(s[e].id),s.splice(e,1),t-=1}}function aa(t){let e={cancellable:t.cancel!==void 0,endedAt:null,expanded:!1,id:H(),log:[],startedAt:Mo(),state:"running",status:t.status??"",steps:(t.steps??[]).map((i)=>({label:i,state:"pending"})),title:t.title,...t.source===void 0?{}:{source:t.source}};if(t.cancel)u.set(e.id,t.cancel);s.push(e);let a=s.at(-1);x();let o=(i,r)=>{if(c(a))return;if(a.state=i,a.endedAt=Mo(),r!==void 0)a.status=r;for(let n of a.steps)n.state=n.state==="done"?"done":i==="done"?"done":"failed";a.cancellable=!1,u.delete(a.id),x()};return{done(i){o("done",i)},entry:a,fail(i,r={}){if(c(a))return;let n=a.log.join(`
|
|
2
2
|
`);o("failed",i),k.error(i,{source:a.source??a.title,...n===""?{}:{detail:n},...r.action===void 0?{}:{action:r.action},...r.path===void 0?{}:{path:r.path}})},id:a.id,log(i){let r=i.replace(/\s+$/,"");if(r!=="")a.log.push(r)},setStatus(i){if(!c(a))a.status=i},step(i){let r=a.steps.findIndex((n)=>n.label===i);if(r===-1)a.steps.push({label:i,state:"pending"}),r=a.steps.length-1;for(let[n,l]of a.steps.entries())l.state=n<r?"done":n===r?"running":l.state;a.status=i}}}function S(t){return s.find((e)=>e.id===t)}function m(){return s.filter((t)=>!c(t))}function F(t){let e=S(t),a=u.get(t);if(!e||!a||c(e))return!1;return a(),u.delete(t),e.state="cancelled",e.endedAt=Mo(),e.cancellable=!1,e.status="Cancelled",!0}function P(){let t=s.filter((a)=>!c(a)),e=s.length-t.length;return s.splice(0,s.length,...t),e}function qE(){return m().map((t)=>`activity: ${t.title} — ${t.status||"running"}`)}var M={cancelled:"⊘",done:"✓",failed:"✕",running:"⋯"},D={done:"✓",failed:"✕",pending:"·",running:"⋯"};function V(t,e=Mo()){let a=Math.max(0,(t.endedAt??e)-t.startedAt);if(a<1000)return`${a}ms`;let o=Math.round(a/1000);return o<60?`${o}s`:`${Math.floor(o/60)}m ${o%60}s`}function z(t,e){return{icon:D[t.state],key:`${e}:${t.label}`,label:t.label,state:t.state}}function _(t){let e=t.log.length;return{cancellable:t.cancellable,duration:V(t),expanded:t.expanded,hasLog:e>0,hasSource:(t.source??"")!=="",hasStatus:t.status!=="",hasSteps:t.steps.length>0,icon:M[t.state],id:t.id,logLabel:t.expanded?"Hide log":`Show log (${e} line(s))`,logText:t.log.join(`
|
|
3
3
|
`),showLog:t.expanded&&e>0,source:t.source??"",state:t.state,status:t.status,steps:t.steps.map((a,o)=>z(a,o)),title:t.title}}function O(){let t=s.filter((e)=>c(e)).length;return{clearLabel:`Clear ${t} finished`,hasFinished:t>0,hasRows:s.length>0,rows:s.map((e)=>_(e))}}var U={cancel:(t)=>{F(t)},clearFinished:()=>{P()},project:O,toggleLog:(t)=>{let e=S(t);if(e)e.expanded=!e.expanded}};function W(){return br`<div data-deploy-checklist></div>
|
|
4
4
|
<div data-activity-surface></div>`}function B(t){let e=t.querySelector("[data-activity-surface]");if(!e){f();return}b(e,U)}function GE(){qn({id:"activity",title:"Activity",level:"project",dock:"bottom",icon:"clock-counter-clockwise",rail:!1,badge:()=>m().length>0?m().length:null,render:()=>W(),afterRender:(t,e)=>{QE(e),B(e)}})}var q={message:"no media file to look for",status:"failed"};function A(t){let e=di(t);return e===""?null:{path:e}}function KE(t){let e=A(t);return e===null?null:yc(e)}async function Cb(t){let e=A(t);return e===null?q:js(e)}function JE(t){if(t===null)return"Counting references…";switch(t.status){case"unsupported":return null;case"pending":return"Counting references…";case"failed":return"Usage unknown";default:return tm(t.result)}}var L={$schema:"https://jxsuite.com/schema/v1",$id:"StudioProgressModal",$description:"The one surface in Studio that blocks while it works: the operation's name, a spinner, the line under it, and the two ways out. A `jx-dialog`, so the platform owns modality, the backdrop, focus restoration and Escape — which is what retired the `sp-underlay` this surface used to paint beside itself, and with it the fixed box, the panel, the shadow and the `z-index: 1000` that box needed to climb back out from under its own scrim. The two answers are the dialog's own: confirm is `Run in the background`, which stops the BLOCKING and leaves the work running in Activity, and the secondary answer is Cancel, drawn only when the operation handed one over. It is the secondary rather than the cancel answer for a reason that is behavioural, not cosmetic: the platform raises one `cancel` for Escape, for a light dismissal and for the cancel button alike, and a surface that cannot tell them apart would stop a dependency install on a keystroke. Escape therefore means what confirm means — stop blocking, not stop working — and the answer that stops the work is a button and only a button.",tagName:"jx-dialog",$props:{headline:{$ref:"#/state/title"},confirmLabel:"Run in the background",secondaryLabel:{$ref:"#/state/cancelLabel"},cancelLabel:"",size:"sm"},attributes:{part:"progress"},onconfirm:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/background"},value:[]}]},onsecondary:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/cancel"},value:[]}]},oncancel:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/background"},value:[]}]},onclose:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},style:{$description:"What is left once `jx-dialog` has drawn the dialog. `.progress-modal` is gone rather than moved — it positioned a fixed box, painted its panel, border, radius and shadow, capped its height and then lifted itself above the scrim it rendered beside — and a modal `<dialog>` in the top layer is every one of those. `.progress-title` went the same way: the operation's name is the dialog's headline, which is also its accessible name, so nothing here draws a title.",'& [part="row"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-4)"},'& [part="status"]':{$description:"`anywhere`, because a status line is usually a path or a package spec with no space in it, and one of those would otherwise be the thing that decides how wide the dialog is. `min-width: 0` is what lets it wrap at all: a flex item's automatic minimum is its content, so without this the row refuses to shrink and the text overflows instead.",minWidth:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-md)",overflowWrap:"anywhere"}},children:[{tagName:"div",attributes:{part:"row"},children:[{tagName:"jx-spinner",attributes:{part:"busy"},$props:{size:"lg"}},{tagName:"span",attributes:{part:"status","aria-live":"polite"},textContent:"${state.status}"}]}]};T("progress-modal",L);function N(t){let e=document.createElement("div");e.style.pointerEvents="auto",e.setAttribute(rt,zt("modal","progress")),t.layer.append(e);let a=!1,o=v({background:()=>{t.onBackground()},cancel:()=>{t.onCancel()},cancelLabel:t.cancellable?"Cancel":"",closed:()=>{t.onClosed()},status:t.status,title:t.title}),i=null,r=R("progress-modal",o,e).then(async(n)=>{let l=n.root;if(a)return n.dispose(),l;if(i=n,await An(l),a)return l;return un(l),l});return{close(){if(a)return;a=!0;let n=i?.root;if(n instanceof HTMLElement)rn(n);i?.dispose(),i=null,e.remove()},host:e,ready:r,setStatus(n){o.status=n}}}function la(t){let e=!1,a=aa({title:t.title,...t.status===void 0?{}:{status:t.status},...t.source===void 0?{}:{source:t.source},...t.cancel===void 0?{}:{cancel:t.cancel}}),o=()=>{if(e)return;e=!0,r.close()},i=()=>{o(),Td("activity")},r=N({cancellable:t.cancel!==void 0,layer:Ct("modal"),onBackground:i,onCancel:()=>{o(),t.cancel?.()},onClosed:o,status:t.status??"",title:t.title});return{activity:a,done(){a.done(),o()},fail(n){let l=(n??"").trim();if(l===""||l.includes(`
|
|
@@ -6,4 +6,4 @@ import{br}from"./studio-sxc0zvpt.js";import{un,rn}from"./studio-0k9mvpgj.js";imp
|
|
|
6
6
|
export{aa,qE,GE,la,KE,Cb,JE};
|
|
7
7
|
|
|
8
8
|
//# debugId=3D86C10737F90A3D64756E2164756E21
|
|
9
|
-
//# sourceMappingURL=studio-
|
|
9
|
+
//# sourceMappingURL=studio-capk0583.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{qt,wi,Zt,Dr,Us}from"./studio-1x8x26k3.js";import{ge,Q,v,k}from"./studio-fqq890ap.js";import{vi,q,Ol,ot,yi,li,Se,fa,oo,He,Dx,bp,Ml,xv,m,u,ci}from"./studio-cvbkkfqb.js";import{te}from"./studio-ery42sqr.js";import{ne}from"./studio-0k9mvpgj.js";import{Pw,Eu,fd,Tu}from"./studio-xy3tv3az.js";import{Zi,T,R}from"./studio-spf2skgc.js";import{fc,mb,Lu,Gf,FE,I1}from"./studio-65fhspdd.js";import{pr}from"./studio-zpnk016a.js";import{HE}from"./studio-skzanb0k.js";import{Tw,cb,sa,y1,CE}from"./studio-e6re3rk1.js";import{D}from"./studio-tp642n5g.js";import{Ae}from"./studio-evwgp1ym.js";import{me}from"./studio-0bbxhhce.js";var kw=["string","number","boolean","array","object","reference"],Sw=["","image","date","color"];function zf(e){if(e.$ref)return"reference";return e.type||"string"}function uc(e){if(e.type==="array"&&e.items?.format)return e.items.format;return e.format||""}function Ms(e,r){switch(e){case"number":return{type:"number"};case"boolean":return{type:"boolean"};case"array":return r?{items:{format:r,type:"string"},type:"array"}:{items:{type:"string"},type:"array"};case"object":return{properties:{},required:[],type:"object"};case"reference":return{$ref:"#/content/"};default:return r?{format:r,type:"string"}:{type:"string"}}}var U={$schema:"https://jxsuite.com/schema/v1",$id:"StudioSchemaBuilder",$description:'The `schema-builder` form control (specs/extensions.md §9.1): the visual editor for a JSON Schema object, drawn as one card per property. A descriptor names it with `"ui": { "<prop>": { "control": "schema-builder" } }`, and `ui/schema-form.ts` mounts it into the empty host its own document announces for that field. The adapter (`surfaces/schema-builder.ts`) hands in the fields already classified and every draft the reader is part-way through typing; `ui/form-controls.ts` decides what a field may be renamed to and what reaches the host\'s `onChange`. Nothing here reads a schema: a document that re-derived a field\'s type while drawing would be a second opinion about what one module already owns. **The card is `surfaces/settings-defs.json`\'s, part for part.** Data Shapes edits the project\'s `$defs` and this edits a content type\'s `schema`; they are the same object with the same six controls per row, so the row vocabulary — `card`, `field-row`, `field-label`, `field-name`, `field-type`, `field-format`, `field-required`, `field-delete`, `nested`, `nested-card`, `nested-add-name`/`-type`/`-button`, `ref-target`, `add-form` — is ONE vocabulary, and the row views it is drawn from are that surface\'s own types rather than a second declaration of them. What differs is only what encloses it: Data Shapes carries the two-column chrome that chooses WHICH shape is being edited, and this one is handed the object to edit.',tagName:"div",attributes:{part:"builder"},style:{$description:"What `.schema-builder`, `.schema-field-list`, `.schema-field-card`, `.schema-field-row`, `.schema-field-nested`, `.schema-field-name-input`, `.schema-nested-add`, `.schema-nested-add-name` and `.schema-add-field` said in `styles/overlays.css`, keyed on `part` and re-pointed at the studio token layer — the same translation `surfaces/settings-defs.json` carries, because it is the same card. Two values could not come with them. `.schema-field-card--nested` read `var(--spectrum-gray-300, #444)`, and the caption was an `sp-field-label` at whatever size Spectrum drew it; a document is mounted in the pane rather than inside `<sp-theme>`, so both would have taken their hard-coded fallback every time. The nested card takes the studio layer's `--border`, and the caption says what it is in the type ramp instead.",display:"block",'& [part="fields"]':{display:"flex",flexDirection:"column",gap:"4px",marginBottom:"12px"},'& [part="card"], & [part="nested-card"]':{border:"1px solid var(--border)",borderRadius:"var(--radius)",padding:"6px 10px"},'& [part="field-row"]':{display:"flex",alignItems:"center",gap:"8px"},'& [part="field-label"]':{$description:"The field's name in words: a caption on the row rather than a label for a control, since the raw key beside it is what the reader edits and what carries the accessible name.",flex:"none",minWidth:"84px",fontSize:"var(--jx-text-sm)",color:"var(--fg-dim)",overflowWrap:"anywhere"},'& [part="field-name"]':{flex:"1",maxWidth:"140px"},'& [part="nested"]':{marginLeft:"16px",marginTop:"6px",paddingLeft:"8px",borderLeft:"2px solid var(--border)",display:"flex",flexDirection:"column",gap:"4px"},'& [part="ref-target"]':{display:"flex",marginTop:"6px",maxWidth:"220px"},'& [part="nested-add"]':{display:"flex",alignItems:"center",gap:"6px",padding:"4px 0"},'& [part="nested-add-name"]':{flex:"1",maxWidth:"120px"},'& [part="add-form"]':{display:"flex",alignItems:"center",gap:"8px",padding:"8px 0"}},children:[{tagName:"div",attributes:{part:"fields"},children:[{$prototype:"Array",items:{$ref:"#/state/fields"},key:{$ref:"$map/item/key"},map:{tagName:"div",attributes:{part:"card","data-field":"${$map.item.key}"},children:[{tagName:"div",attributes:{part:"field-row"},children:[{tagName:"span",attributes:{part:"field-label"},textContent:"${$map.item.label}"},{tagName:"jx-textfield",attributes:{part:"field-name"},$props:{label:"Name for ${$map.item.label}",size:"sm",value:{$ref:"$map/item/name"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/renameField"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"jx-select",attributes:{part:"field-type"},$props:{label:"Type for ${$map.item.label}",size:"sm",options:{$ref:"#/state/typeOptions"},value:{$ref:"$map/item/type"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setType"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"div",attributes:{part:"format-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasFormat"},cases:{true:{tagName:"jx-select",attributes:{part:"field-format"},$props:{label:"Format for ${$map.item.label}",size:"sm",options:{$ref:"#/state/formatOptions"},value:{$ref:"$map/item/format"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setFormat"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}}}},{tagName:"jx-switch",$description:"Whether the object requires this field. The word on screen is the name: `Req` is slotted rather than passed as `label`, because the kit's switch wraps its control in the label the slot lands in, and a second name would be announced over the top of it. Which row it belongs to is the tooltip's job instead, which is what `hint` is.",attributes:{part:"field-required"},$props:{hint:"Require ${$map.item.label}",size:"sm",checked:{$ref:"$map/item/required"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setRequired"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Req"}]},{tagName:"jx-action-button",attributes:{part:"field-delete"},$props:{label:"Delete ${$map.item.label}",hint:"Delete ${$map.item.label}",icon:"trash",quiet:!0,size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/removeField"},value:[{$ref:"$map/item/key"}]}]}}]},{tagName:"div",attributes:{part:"extra-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/extra"},cases:{reference:{tagName:"div",attributes:{part:"ref-target"},children:[{tagName:"jx-select",attributes:{part:"ref-target-select"},$props:{label:"Target for ${$map.item.label}",size:"sm",options:{$ref:"#/state/targets"},value:{$ref:"$map/item/refTarget"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setTarget"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}}]},nested:{tagName:"div",attributes:{part:"nested"},children:[{$prototype:"Array",items:{$ref:"$map/item/children"},key:{$ref:"$map/item/key"},map:{tagName:"div",attributes:{part:"nested-card","data-nested":"${$map.item.key}"},children:[{tagName:"div",attributes:{part:"field-row"},children:[{tagName:"jx-textfield",attributes:{part:"field-name"},$props:{label:"Name for ${$map.item.parent}.${$map.item.key}",size:"sm",value:{$ref:"$map/item/name"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/renameNested"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"jx-select",attributes:{part:"field-type"},$props:{label:"Type for ${$map.item.parent}.${$map.item.key}",size:"sm",options:{$ref:"#/state/typeOptions"},value:{$ref:"$map/item/type"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setNestedType"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"div",attributes:{part:"format-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasFormat"},cases:{true:{tagName:"jx-select",attributes:{part:"field-format"},$props:{label:"Format for ${$map.item.parent}.${$map.item.key}",size:"sm",options:{$ref:"#/state/formatOptions"},value:{$ref:"$map/item/format"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setNestedFormat"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}}}},{tagName:"jx-switch",attributes:{part:"field-required"},$props:{hint:"Require ${$map.item.parent}.${$map.item.key}",size:"sm",checked:{$ref:"$map/item/required"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setNestedRequired"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"},{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Req"}]},{tagName:"jx-action-button",attributes:{part:"field-delete"},$props:{label:"Delete ${$map.item.parent}.${$map.item.key}",hint:"Delete ${$map.item.parent}.${$map.item.key}",icon:"trash",quiet:!0,size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/removeNested"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"}]}]}}]}]}},{tagName:"div",attributes:{part:"nested-add"},children:[{tagName:"jx-textfield",attributes:{part:"nested-add-name"},$props:{label:"New field in ${$map.item.label}",placeholder:"field name",size:"sm",value:{$ref:"$map/item/draftName"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editDraftName"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]},onkeydown:{$prototype:"Function",body:[{$switch:{$ref:"event#/key"},cases:{Enter:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/addNested"},value:[{$ref:"$map/item/key"}]}]}}]}},{tagName:"jx-select",attributes:{part:"nested-add-type"},$props:{label:"Type of the new field in ${$map.item.label}",size:"sm",options:{$ref:"#/state/typeOptions"},value:{$ref:"$map/item/draftType"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editDraftType"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"jx-action-button",attributes:{part:"nested-add-button"},$props:{label:"Add a field to ${$map.item.label}",hint:"Add a field to ${$map.item.label}",icon:"plus",quiet:!0,size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/addNested"},value:[{$ref:"$map/item/key"}]}]}}]}]}}}]}}]},{tagName:"div",attributes:{part:"add-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/addState"},cases:{closed:{tagName:"jx-action-button",attributes:{part:"add-open"},$props:{label:"Add Field",icon:"plus",quiet:!0,size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openAdd"},value:[]}]},children:[{tagName:"span",textContent:"Add Field"}]},open:{tagName:"div",attributes:{part:"add-form"},children:[{tagName:"jx-textfield",attributes:{part:"add-name"},$props:{label:"New field name",placeholder:"Field name",size:"sm",value:{$ref:"#/state/addName"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editAddName"},value:[{$ref:"event#/target/value"}]}]},onkeydown:{$prototype:"Function",body:[{$switch:{$ref:"event#/key"},cases:{Enter:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/confirmAdd"},value:[]}],Escape:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/cancelAdd"},value:[]}]}}]}},{tagName:"jx-select",attributes:{part:"add-type"},$props:{label:"Type of the new field",size:"sm",options:{$ref:"#/state/typeOptions"},value:{$ref:"#/state/addType"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editAddType"},value:[{$ref:"event#/target/value"}]}]}},{tagName:"div",attributes:{part:"add-format-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/addHasFormat"},cases:{true:{tagName:"jx-select",attributes:{part:"add-format"},$props:{label:"Format of the new field",size:"sm",options:{$ref:"#/state/formatOptions"},value:{$ref:"#/state/addFormat"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editAddFormat"},value:[{$ref:"event#/target/value"}]}]}}}},{tagName:"jx-switch",attributes:{part:"add-required"},$props:{hint:"Require the new field",size:"sm",checked:{$ref:"#/state/addRequired"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editAddRequired"},value:[{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Required"}]},{tagName:"jx-button",attributes:{part:"add-confirm"},$props:{size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/confirmAdd"},value:[]}]},children:[{tagName:"span",textContent:"Add"}]},{tagName:"jx-button",attributes:{part:"add-cancel"},$props:{size:"sm",quiet:!0},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/cancelAdd"},value:[]}]},children:[{tagName:"span",textContent:"Cancel"}]}]}}}]};T("schema-builder",U);function be(){return{addFormat:"",addHasFormat:!0,addName:"",addRequired:!1,addState:"closed",addType:"string",fields:[],formatOptions:[],targets:[],typeOptions:[]}}function Y(e,r){e.textContent="";let t=v({...be(),...r}),a=null,n=!0,s=!1,l=()=>R("schema-builder",t,e).then((o)=>{if(n=!1,s)return o.dispose(),o.root;return a=o,o.root}),p=l();return{dispose(){s=!0,a?.dispose(),a=null,e.textContent=""},host:e,ready:p,update(o){if(t.addFormat=o.addFormat,t.addHasFormat=o.addHasFormat,t.addName=o.addName,t.addRequired=o.addRequired,t.addState=o.addState,t.addType=o.addType,t.fields=o.fields,t.formatOptions=o.formatOptions,t.targets=o.targets,t.typeOptions=o.typeOptions,s||n||a!==null&&e.contains(a.root))return;a?.dispose(),a=null,n=!0,e.textContent="",l()}}}var G={$schema:"https://jxsuite.com/schema/v1",$id:"StudioReferenceField",$description:'The `reference` form control — site-architecture.md §6.1\'s `{ "$ref": "#/content/x" }` and site-architecture.md §7.4\'s entry picker. Registered once and dispatched to by `ui/schema-form.ts` for any property whose `$ref` names a collection, so the settings forms, the entry editor and an array-of-objects cell all draw the same control without any of them knowing it exists. `ui/form-controls.ts` decides which of the three states the field is in and what each gesture commits; nothing here reads a schema or lists a directory. The three states are drawn as three different controls on purpose: a picker while the entries are known, a TEXT field while they are not — a failed read leaves the value editable with the reason beside it, because swapping it for an empty dropdown would present "no entries" and "could not find out" as the same screen — and a disabled picker saying so while the read is in flight.',tagName:"div",attributes:{part:"reference",role:"none"},style:{$description:"The five `.reference-*` rules from `styles/inspector.css`, keyed on `part` and re-pointed at the studio token layer. Two values could not come with them. The note read `var(--spectrum-font-size-50, 11px)`, which resolves only inside `<sp-theme>` — this document is mounted in a settings pane, an entry editor or a frontmatter card, all outside that element, so it would silently have taken its hard-coded fallback every time. And `.reference-missing` coloured ONE row of the dropdown red; the kit's select offers a row a face, a swatch and a border style but no tone, so the dangling entry says what it is in words (\"— not found\") and the colour is not replaced by a second channel. The 6px gap comes onto the kit's spacing scale.",display:"flex",flex:"1",minWidth:"0",alignItems:"center",gap:"var(--jx-space-2)",'& [part="picker"], & [part="text"]':{flex:"1",minWidth:"0"},'& [part="note"]':{margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)",lineHeight:"1.4"},'& [part="note"][data-tone="danger"]':{$description:"A listing that failed is a FAULT rather than a fact about the project, and the two notes this control draws are otherwise the same sentence in the same place.",color:"var(--danger)"},'& [part="retry"]':{flex:"none"}},children:[{tagName:"div",attributes:{part:"control-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/kind"},cases:{picker:{$description:"The collection's entries. The empty row is `\"\"` rather than a sentinel, because the kit's select treats the empty string as a legal value a reader can arrow to; a dangling reference is kept in the list and marked, since blanking the field would delete the evidence and the value in one repaint. While the read is in flight the same control is disabled and offers one row saying so.",tagName:"jx-select",attributes:{part:"picker"},$props:{size:"sm",label:{$ref:"#/state/label"},options:{$ref:"#/state/options"},value:{$ref:"#/state/value"},disabled:{$ref:"#/state/disabled"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/choose"},value:[{$ref:"event#/target/value"}]}]}},text:{$description:"The id as the string it is: what a reader gets when the choices could not be listed, and when the control was named by a `ui.control` override on a property that references nothing. Refusing to draw anything would lose the value that is already there.",tagName:"jx-textfield",attributes:{part:"text"},$props:{size:"sm",label:{$ref:"#/state/label"},value:{$ref:"#/state/value"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/edit"},value:[{$ref:"event#/target/value"}]}]}}}},{tagName:"div",attributes:{part:"note-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasNote"},cases:{true:{tagName:"p",attributes:{part:"note","data-tone":"${state.noteTone}",role:"status"},textContent:"${state.note}"}}},{tagName:"div",attributes:{part:"retry-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/canRetry"},cases:{true:{$description:"Offered only where there is something to try again — a listing that failed. It used to be offered only where the HOST passed a repaint hook, because a template control cannot draw a second frame of its own and a button that cannot do the thing it is named after is worse than its absence. A mounted control redraws itself, so the condition is now the failure rather than the host.",tagName:"jx-action-button",attributes:{part:"retry"},$props:{size:"sm",quiet:!0,label:"Retry listing entries"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/retry"},value:[]}]},children:[{tagName:"span",textContent:"Retry"}]}}}]};T("reference-field",G);function ve(){return{canRetry:!1,disabled:!0,hasNote:!1,kind:"picker",label:"",note:"",noteTone:"dim",options:[],value:""}}function K(e,r){e.textContent="";let t=v({...ve(),...r}),a=null,n=!0,s=!1,l=()=>R("reference-field",t,e).then((o)=>{if(n=!1,s)return o.dispose(),o.root;return a=o,o.root}),p=l();return{dispose(){s=!0,a?.dispose(),a=null,e.textContent=""},host:e,ready:p,update(o){if(t.canRetry=o.canRetry,t.disabled=o.disabled,t.hasNote=o.hasNote,t.kind=o.kind,t.label=o.label,t.note=o.note,t.noteTone=o.noteTone,t.options=o.options,t.value=o.value,s||n||a!==null&&e.contains(a.root))return;a?.dispose(),a=null,n=!0,e.textContent="",l()}}}var X={$schema:"https://jxsuite.com/schema/v1",$id:"StudioSecretField",$description:'The `secret` form control (specs/extensions.md §9.1, §13): one password field whose VALUE goes to the platform\'s secret store and never to project.json. A descriptor names it with `"ui": { "<field>": { "control": "secret" } }`, and `ui/schema-form.ts` mounts it into the empty host its own document announces for that field. **A surface never renders back the secret it describes, and this document is where that is visible rather than remembered**: the only thing bound to the field\'s value is `#/state/shown`, a scope path whose whole purpose is to hold nothing. What the field is worth is said in the placeholder instead — the env NAME the store gave it, which is the only half of a secret a screen may carry. `ui/form-controls.ts` decides everything else: whether the host has a secret store at all, what the placeholder says, what a commit is worth and what the field persists.',tagName:"div",attributes:{part:"secret",role:"none"},style:{$description:"`.secret-field` carried no rule anywhere — it was one of `check-styles.ts`'s ALLOWED_ORPHANS, a class emitted only so a test could find the control — so there is nothing to translate and the wrapper takes no box of its own. The field takes the width of the control host the form drew, which is the flex item; a kit field is inline-flex by default and would otherwise sit at its intrinsic width in a row sized for it.",display:"contents",'& [part="field"]':{width:"100%"}},children:[{$description:"`autocomplete: new-password` because this is a place to PUT a secret rather than to prove one: without it a password manager offers to fill the field with a credential belonging to whatever site the reader last logged in to, and the offer is the manager's own UI drawn over an editor. The value binding is `#/state/shown` and nothing else ever writes to it — see the document description.",tagName:"jx-textfield",attributes:{part:"field"},$props:{type:"password",size:"sm",autocomplete:"new-password",label:{$ref:"#/state/label"},placeholder:{$ref:"#/state/placeholder"},disabled:{$ref:"#/state/disabled"},value:{$ref:"#/state/shown"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/commit"},value:[{$ref:"event#/target/value"}]}],description:"The change bubbles out of the field's own input, so what the reader typed is read off the event rather than off the element — and it is read here, handed to the flow, and never written back onto the scope."}}]};T("secret-field",X);function xe(){return{disabled:!0,label:"",placeholder:"Not set"}}function Z(e,r){e.textContent="";let t=v({...xe(),...r,shown:""}),a=null,n=!0,s=!1,l=()=>R("secret-field",t,e).then((o)=>{if(n=!1,s)return o.dispose(),o.root;return a=o,o.root}),p=l();return{clear(){t.shown=" ",t.shown=""},dispose(){s=!0,a?.dispose(),a=null,e.textContent=""},host:e,ready:p,update(o){if(t.disabled=o.disabled,t.label=o.label,t.placeholder=o.placeholder,s||n||a!==null&&e.contains(a.root))return;a?.dispose(),a=null,n=!0,e.textContent="",l()}}}var Fe=kw.map((e)=>({label:e,value:e})),Ne=Sw.map((e)=>({label:e||"(none)",value:e})),j={format:"",name:"",required:!1,type:"string"},ee=[],re=" ";function Te(e){let r=e.resolvePointer("#/$context/content"),t=r&&typeof r==="object"&&!Array.isArray(r)?Object.keys(r):[],a=t.join(" ");if(a!==re)re=a,ee=t.map((n)=>({label:n,value:n}));return ee}function N(e){return e==="string"||e==="array"}function ie(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{properties:{},required:[],type:"object"}}function Ee(e){let r=JSON.parse(JSON.stringify(ie(e)));return r.type??="object",r.properties??={},r.required??=[],r}function A(e){return`name:${e}`}function H(e){return`required:${e}`}function V(e,r){return`${e} ${r}`}function O(e,r,t){return e.echo?.id===r?e.echo.value:t}function ke(e,r,t,a,n){let s=V(r,t),l=zf(a);return{format:uc(a),hasFormat:N(l),key:t,name:O(e,A(s),t),parent:r,required:O(e,H(s),n),type:l}}function Ce(e,r,t,a,n){let s=zf(t),l=s==="object",p=e.drafts.get(r),o=t.required??[];return{children:l?Object.entries(t.properties??{}).map(([w,g])=>ke(e,r,w,g,o.includes(w))):[],draftName:p?.name??"",draftType:p?.type??"string",extra:s==="reference"&&n?"reference":l?"nested":"none",format:uc(t),hasFormat:N(s),key:r,label:Ml(r),name:O(e,A(r),r),refTarget:t.$ref?t.$ref.replace(/^#\/[^/]+\//,""):"",required:O(e,H(r),a),type:s}}function ae(e,r,t){let a={};for(let[n,s]of Object.entries(e))a[n===r?t:n]=s,delete e[n];Object.assign(e,a)}function M(e,r,t){e.required??=[];let a=e.required.indexOf(r);if(t&&a===-1)e.required.push(r);if(!t&&a!==-1)e.required.splice(a,1)}function Re(e,r){let t=r,a=null,n={add:{...j},addOpen:!1,drafts:new Map,echo:null},s=()=>a??ie(t.value),l=()=>{let i=s(),d=i.required??[],c=Te(t.ctx);return{addFormat:n.add.format,addHasFormat:N(n.add.type),addName:n.add.name,addRequired:n.add.required,addState:n.addOpen?"open":"closed",addType:n.add.type,fields:Object.entries(i.properties??{}).map(([f,h])=>Ce(n,f,h,d.includes(f),c.length>0)),formatOptions:Ne,targets:c,typeOptions:Fe}},p=()=>F.update(l()),o=(i,d)=>{n.echo={id:i,value:d},p()},w=()=>{n.echo=null,p()},g=(i)=>{let d=Ee(s());if(!i(d)){w();return}a=d,n.echo=null,t.onChange(d),p()},y=(i,d)=>i.properties[d],x=(i)=>{let d=n.drafts.get(i);if(!d)d={name:"",type:"string"},n.drafts.set(i,d);return d},F=Y(e,{addNested(i){let d=x(i),c=xv(d.name.trim());if(!c)return;g((f)=>{let h=y(f,i);if(!h)return!1;return h.properties??={},h.properties[c]=Ms(d.type||"string"),d.name="",!0})},cancelAdd(){n.addOpen=!1,n.add={...j},p()},confirmAdd(){let i=xv(n.add.name.trim());if(!i)return;let{format:d,required:c,type:f}=n.add;n.addOpen=!1,n.add={...j},g((h)=>{if(h.properties[i]=Ms(f,d||void 0),c)M(h,i,!0);return!0})},editAddFormat(i){n.add.format=i,p()},editAddName(i){n.add.name=i,p()},editAddRequired(i){n.add.required=i,p()},editAddType(i){n.add.type=i,p()},editDraftName(i,d){x(i).name=d,p()},editDraftType(i,d){x(i).type=d,p()},openAdd(){n.addOpen=!0,n.add={...j},p()},removeField(i){g((d)=>{if(!d.properties[i])return!1;return delete d.properties[i],d.required=d.required.filter((c)=>c!==i),!0})},removeNested(i,d){g((c)=>{let f=y(c,i);if(!f?.properties?.[d])return!1;if(delete f.properties[d],f.required)f.required=f.required.filter((h)=>h!==d);return!0})},renameField(i,d){o(A(i),d);let c=xv(d.trim());g((f)=>{if(!f.properties[i]||!c||c===i||f.properties[c])return!1;return ae(f.properties,i,c),f.required=f.required.map((h)=>h===i?c:h),!0})},renameNested(i,d,c){o(A(V(i,d)),c);let f=xv(c.trim());g((h)=>{let b=y(h,i);if(!b?.properties?.[d]||!f||f===d||b.properties[f])return!1;if(ae(b.properties,d,f),b.required)b.required=b.required.map((C)=>C===d?f:C);return!0})},setFormat(i,d){g((c)=>{let f=c.properties[i];if(!f)return!1;return c.properties[i]=Ms(f.type||"string",d||void 0),!0})},setNestedFormat(i,d,c){g((f)=>{let h=y(f,i),b=h?.properties?.[d];if(!h?.properties||!b)return!1;return h.properties[d]=Ms(b.type||"string",c||void 0),!0})},setNestedRequired(i,d,c){o(H(V(i,d)),c),g((f)=>{let h=y(f,i);if(!h)return!1;return M(h,d,c),!0})},setNestedType(i,d,c){g((f)=>{let h=y(f,i),b=h?.properties?.[d];if(!h?.properties||!b)return!1;let C=N(c)?uc(b):void 0;return h.properties[d]=Ms(c,C||void 0),!0})},setRequired(i,d){o(H(i),d),g((c)=>{if(!c.properties[i])return!1;return M(c,i,d),!0})},setTarget(i,d){g((c)=>{if(!c.properties[i])return!1;return c.properties[i]={$ref:`#/content/${d}`},!0})},setType(i,d){g((c)=>{let f=c.properties[i];if(!f)return!1;let h=N(d)?uc(f):void 0;return c.properties[i]=Ms(d,h||void 0),!0})}});return p(),{dispose:()=>F.dispose(),update(i){t=i,a=null,n.echo=null,p()}}}var je={mount:Re};Pw("schema-builder",je);function oe(e){return typeof e==="string"&&e?e:null}function De(e,r){let t=r,a=()=>{let s=oe(t.value);n.update({disabled:!t.ctx.commitSecret,label:t.key,placeholder:s?`Stored as ${s}`:"Not set"})},n=Z(e,{commit(s){let{commitSecret:l}=t.ctx;if(!l||!s)return;n.clear();let{key:p,onChange:o}=t,w=oe(t.value);Promise.resolve(l(p,s)).then((g)=>{if(typeof g==="string"&&g&&g!==w)o(g)})}});return a(),{dispose:()=>n.dispose(),update(s){t=s,a()}}}var qe={mount:De};Pw("secret",qe);var E=new Map,P=new Map,S=new Map;function B(e){if(e===void 0)E.clear(),P.clear(),S.clear();else E.delete(e),P.delete(e),S.delete(e)}function Oe(e){let r=E.get(e);if(r)return r;let t=(me("37x3vsap"),import("./content-source-37x3vsap.js")).then((a)=>a.listCollectionEntryIds(e));return E.set(e,t),t}function g1(e,r){let t=P.get(e);if(t)return t;let a=Oe(e),n=S.get(e);if(n){if(r)n.add(r);return null}S.set(e,new Set(r?[r]:[]));let s=(l)=>{if(E.get(e)!==a)return;let p=S.get(e);S.delete(e),P.set(e,l);for(let o of p??[])o()};return a.then((l)=>s({ids:l}),(l)=>s({error:te(l)})),null}function Pe(e,r){let t=typeof e.value==="string"?e.value:"",a={canRetry:!1,disabled:!1,hasNote:!1,label:e.key,note:"",noteTone:"dim",options:[],value:t},n=Eu(e.schema);if(n===null)return{...a,hasNote:!0,kind:"text",note:'No collection referenced — add "$ref": "#/content/<type>" to this field.'};let s=g1(n,r);if(s===null)return{...a,disabled:!0,kind:"picker",options:[{label:"Loading…",value:t}]};if("error"in s)return{...a,canRetry:!0,hasNote:!0,kind:"text",note:`Could not list ${n} entries — ${s.error}`,noteTone:"danger"};let l=t!==""&&!s.ids.includes(t);return{...a,hasNote:s.ids.length===0,kind:"picker",note:s.ids.length===0?`No ${n} entries yet.`:"",options:[{label:"—",value:""},...l?[{label:`${t} — not found`,value:t}]:[],...s.ids.map((p)=>({label:p,value:p}))]}}function Le(e,r){let t=r,a=!1,n=()=>{if(!a)s.update(Pe(t,n))},s=K(e,{choose(l){t.onChange(l===""?void 0:l)},edit(l){t.onChange(l.trim()||void 0)},retry(){let l=Eu(t.schema);if(l!==null)B(l);n()}});return n(),{dispose(){a=!0,s.dispose()},update(l){t=l,n()}}}var Me={mount:Le};Pw("reference",Me);var se={$schema:"https://jxsuite.com/schema/v1",$id:"StudioEntryEditor",$description:"The Entry editor (site-architecture.md §7.4) — one content entry's fields, in a pane, as a Jx document over the kit. The adapter (`surfaces/entry-editor.ts`) hands in a projection; `content/entry-editor.ts` decides everything in it — which collection the file belongs to, which record its fields live in, which required keys are absent and what a draft flag commits into. The FORM is an island: a schema is `ui/schema-form.ts`'s subject, so this document renders an empty `fields` node and the flow places the element that engine hands back (studio-ui-guidelines.md §9.3, §9.4). That is the whole of the difference between this and the card the lit version drew, and it is why the engine converting in batch 7 is what unblocked this one.",tagName:"div",attributes:{part:"entry","data-jx-region":"${state.region}"},style:{$description:"What `.entry-editor`, `.entry-editor-header`, `.entry-editor-collection`, `.entry-draft-switch`, `.entry-editor-fields`, `.entry-editor-note` and `.entry-editor-empty` said in `styles/overlays.css`, keyed on `part` and re-pointed at the studio token layer. This editor was the only emitter of all seven, so those rules are dead in the stylesheet from here; a central sweep removes them rather than this change, which owns no stylesheet. Every `--spectrum-font-size-*` reference is gone rather than renamed: those names resolve only inside `<sp-theme>`, and a pane editor is mounted outside it, so each would silently have taken its hard-coded fallback.",height:"100%",padding:"var(--jx-space-5)",overflowY:"auto",background:"var(--bg-panel)",'& [part="header"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-4)",marginBottom:"var(--jx-space-5)"},'& [part="name"]':{margin:"0",fontSize:"var(--jx-text-lg)",fontWeight:"600",color:"var(--fg)"},'& [part="collection"]':{padding:"1px var(--jx-space-3)",borderRadius:"var(--radius)",background:"var(--bg)",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"},'& [part="draft"]':{$description:"Pushed to the far end of the header rather than placed there: the heading and the collection chip are both content-width, so `margin-left: auto` is what keeps the switch on the right edge whatever the entry is called.",marginLeft:"auto"},'& [part="fields"]':{$description:"The schema form's host is `display: contents`, so its rows are the flex items of THIS box — which is why the column lives here and not inside the engine.",display:"flex",flexDirection:"column"},'& [part="note"]':{margin:"0 0 var(--jx-space-4)",color:"var(--fg-dim)",fontSize:"var(--jx-text-md)",lineHeight:"1.5"},'& [part="empty"]':{display:"flex",maxWidth:"46ch",flexDirection:"column",alignItems:"flex-start",gap:"var(--jx-space-3)",color:"var(--fg-dim)",fontSize:"var(--jx-text-md)",lineHeight:"1.5"}},children:[{tagName:"div",attributes:{part:"stage-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/stage"},cases:{entry:{tagName:"div",attributes:{part:"body",role:"none"},style:{display:"contents"},children:[{tagName:"div",attributes:{part:"header"},children:[{tagName:"h3",attributes:{part:"name"},textContent:"${state.name}"},{tagName:"span",attributes:{part:"collection"},textContent:"${state.collection}"},{tagName:"div",attributes:{part:"draft-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/draftAxis"},cases:{shown:{$description:"No `label`: the slotted word is on screen and carries the name, so an aria-label would be read twice. The tooltip is `hint`, which is what DRAFT_MEANING has always been.",tagName:"jx-switch",attributes:{part:"draft"},$props:{checked:{$ref:"#/state/draft"},hint:"${state.draftHint}",size:"sm"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setDraft"},value:[{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Draft"}]}}}]},{tagName:"div",attributes:{part:"note-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/noteState"},cases:{shown:{tagName:"p",attributes:{part:"note"},textContent:"${state.note}"}}},{$description:"An island: `ui/schema-form.ts` draws this entry's fields into this node, and nothing in this document knows what a schema is.",tagName:"div",attributes:{part:"fields","data-jx-region":"${state.fieldsRegion}"}}]},empty:{$description:"The mode is reachable from the palette and from `__jxAutomation` on any tab, so this state is real: it names the reason and the fix rather than drawing an empty form.",tagName:"div",attributes:{part:"empty"},children:[{tagName:"p",attributes:{part:"empty-line"},textContent:"${state.emptyLine}"},{tagName:"p",attributes:{part:"note"},children:[{tagName:"span",textContent:"A collection is a "},{tagName:"code",textContent:"content"},{tagName:"span",textContent:" entry in "},{tagName:"code",textContent:"project.json"},{tagName:"span",textContent:" whose "},{tagName:"code",textContent:"source"},{tagName:"span",textContent:" directory contains this file and which declares a "},{tagName:"code",textContent:"schema"},{tagName:"span",textContent:"."}]},{tagName:"jx-action-button",attributes:{part:"content-types"},$props:{label:"Content types",size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openContentTypes"},value:[]}]},children:[{tagName:"span",textContent:"Content types…"}]}]}}}]};T("entry-editor",se);function de(e,r){e.region=r.region,e.fieldsRegion=r.fieldsRegion,e.stage=r.stage,e.name=r.name,e.collection=r.collection,e.draftAxis=r.draftAxis,e.draft=r.draft,e.draftHint=r.draftHint,e.noteState=r.noteState,e.note=r.note,e.emptyLine=r.emptyLine}function Be(e){let t=e?.attributes?.part;return typeof t==="string"?t:""}function le(e,r,t,a){e.replaceChildren();let n=v({collection:"",draft:!1,draftAxis:"hidden",draftHint:"",emptyLine:"",fieldsRegion:"",name:"",note:"",noteState:"hidden",openContentTypes:t.openContentTypes,region:"",setDraft:t.setDraft,stage:"empty"});de(n,r);let s=null,l=!1,p=R("entry-editor",n,e,{onNodeCreated:(o,w,g)=>{if(o instanceof HTMLElement&&Be(g)==="fields")a.fieldsSlot(o)}}).then((o)=>{if(l)return o.dispose(),o.root;return s=o,o.root});return{attached:()=>{if(l)return!1;let o=s?.root;return o===void 0?!0:o instanceof HTMLElement&&e.contains(o)},dispose(){l=!0,s?.dispose(),s=null},ready:p,update:(o)=>de(n,o)}}function ce(e){return e.doc.sourceFormat==null&&e.doc.mode!=="content"}function Wf(e){return ce(e)?e.doc.document:e.doc.content?.frontmatter??{}}function ze(e,r,t){let a=e.doc.document,n=Object.hasOwn(a,r)?Ae(a[r]):void 0,s=t===void 0||t===null||t==="";if(s)delete a[r];else a[r]=t;let l=s?void 0:Ae(t);vi({forward:{key:r,op:"set-key",path:[],value:l},inverse:{key:r,op:"set-key",path:[],value:n}}),e.doc.dirty=!0,HE()}function z(e,r,t){if(ce(e))ze(e,r,t);else Ol(e,r,t)}function pe(e,r){q(e,(t)=>{for(let[a,n]of Object.entries(r))z(t,a,n)})}var fe="entry",Ie=[fe],L=new Map;function I(e){return L.get(e)??null}function b1(e,r){let t=I(e);return t!==null&&t.tabId===r.id&&t.wrap.isConnected&&t.surface.attached()}function lb(e){let r=L.get(e);if(!r)return;r.scope.stop(),r.surface.dispose(),L.delete(e)}function _(e,r){q(e,(t)=>z(t,fc,r))}function xE(e){let r=sa(e.documentPath),t=Wf(e);if(!r||!Gf(r.schema,t))return null;let a=Lu(t);return{draft:a,text:a?"Draft":"Published",title:a?mb:"Not marked a draft."}}function _e(e){return{fieldKeyPrefix:`entry:${e.id}`,resolvePointer:(r,t)=>Tu(r,{projectConfig:D?.projectConfig??{},scope:t})}}function We(e,r){let t={};for(let a of CE(e.schema,r))t[a]="Required — this entry does not have one.";return t}function Je(e){return`${e.documentPath??"This document"} is not an entry of any content collection, so there is no schema to draw a form from.`}function ue(e,r,t){let a=Zi(e,"entry"),n=Zi(e,"entry/fields");if(!t)return{collection:"",draft:!1,draftAxis:"hidden",draftHint:mb,emptyLine:Je(r),fieldsRegion:n,name:"",note:"",noteState:"hidden",region:a,stage:"empty"};let s=Wf(r),l=Lu(s);return{collection:t.name,draft:l,draftAxis:Gf(t.schema,s)?"shown":"hidden",draftHint:mb,emptyLine:"",fieldsRegion:n,name:r.documentPath?.split("/").pop()??"Untitled",note:mb,noteState:l?"shown":"hidden",region:a,stage:"entry"}}function _E(e,r){let{paneId:t,wrap:a}=e;if(b1(t,r))return;lb(t);let n=null,s=null,l=()=>{if(n!==null&&I(t)===n)o()},p=(y)=>{if(!s||!y)return;let x=Wf(r),F=fd(`entry:${t}`,y.schema,x,{context:_e(r),errors:We(y,x),onChange:(i)=>pe(r,i),rerender:l});if(F.parentNode!==s)s.replaceChildren(F)},o=()=>{let y=sa(r.documentPath);if(!y)s=null;n?.surface.update(ue(t,r,y)),p(y)},w=ge(),g=le(a,ue(t,r,sa(r.documentPath)),{openContentTypes:()=>{ne()?.run("settings.open",{section:"content"})},setDraft:(y)=>_(r,y)},{fieldsSlot:(y)=>{s=y,p(sa(r.documentPath))}});n={paneId:t,scope:w,surface:g,tabId:r.id,wrap:a},L.set(t,n),w.run(()=>{Q(()=>{if(I(t)!==n)return;r.doc.document,r.doc.content?.frontmatter,D?.projectConfig?.content,o()})})}async function W(e){let{openFileInTab:r}=await (me("tznwe1p1"),import("./files-tznwe1p1.js"));await r(e);for(let[t,a]of m.tabs.entries()){if(a.documentPath!==e)continue;for(let n of Ie)if(!a.capabilities.modes.includes(n))a.capabilities.modes.unshift(n);return a.session.ui.canvasMode=fe,a.session.ui.preview=!1,ci(t),a}return null}function J(){return cb().map((e)=>e.name)}async function Ue(e){let r=y1(e.schema),t=(e.def.format?wi(e.def.format)?.name:void 0)??Zt(`untitled${e.ext}`)?.name??Dr()?.name;if(e.ext===".json"||t===void 0)return pr(r,null);return Us(t,{...r,children:[]},{frontmatter:Object.keys(r).length>0,mode:"roundtrip"})}async function Ew(e,r={}){let t=Tw(e);if(!t)return k.error(`No content collection named "${e}" to create an entry in.`,{detail:"A collection needs a `content` entry in project.json whose `source` is a directory. A collection whose source names a single file (a CSV catalogue) has rows, not entry files.",source:"Content"}),null;await qt().catch(()=>{});let a;try{a=await Ue(t)}catch(o){return k.error(`Could not prepare a new ${t.name} entry.`,{detail:te(o),path:t.dir,source:"Content"}),null}let n=r.dir,s=n!==void 0&&bp(n)?.name===t.name?n:t.dir;if(s.includes(Dx))return k.error(`"${t.name}" is a localized collection.`,{detail:`Its entries live in one directory per language (${t.dir}). Open the folder for the language you are writing in and create the entry there.`,path:t.dir,source:"Content"}),null;let{createFileIn:l}=await (me("tznwe1p1"),import("./files-tznwe1p1.js")),p=await l({content:a,dir:s,format:{ext:t.ext,kind:"fixed"},source:"Content",suggestedName:"untitled",title:`New ${t.name} entry`});if(p===null)return null;return B(t.name),await W(p),p}function he(){let e=u.value;return e&&sa(e.documentPath)?e:null}function Ye(){return[{args:Se({collection:fa(J,"The content collection the entry is created in.")}),category:"File",id:"content.newEntry",level:"project",menus:["palette"],group:"1_file",requires:"a project with a directory-backed content collection",when:(e)=>e.project.open,enablement:()=>J().length>0,undo:"project",run:async(e,r)=>{let t=J();await Ew(li("content.newEntry",r,"collection",t))},title:"New Entry"},{args:Se({path:He("Project-relative path of the entry file to open.")}),category:"File",id:"content.openEntry",level:"project",menus:["context/file","palette"],group:"1_file",requires:"an open project",when:(e)=>e.project.open,run:async(e,r)=>{await W(ot("content.openEntry",r,"path"))},title:"Open Entry Form"},{args:Se({draft:oo("True marks the open entry a draft; false marks it published. Written as a `draft` field on the entry.")}),category:"Document",id:"content.setDraft",level:"document",menus:["context/tab","palette"],group:"3_document",requires:"a content entry open",when:(e)=>e.document.open,enablement:()=>he()!==null,undo:"document",run:(e,r)=>{let t=he();if(!t)throw Error("content.setDraft: the active document is not a content entry");_(t,yi("content.setDraft",r,"draft"))},title:"Set Draft"},{args:Se({include:oo("True lists entries marked `draft: true` alongside the rest.")}),category:"View",id:"content.setIncludeDrafts",level:"project",menus:["palette"],group:"2_view",requires:"an open project",when:(e)=>e.project.open,run:async(e,r)=>{FE(yi("content.setIncludeDrafts",r,"include")),await I1()},title:"Include Drafts"}]}function v1(e){e.registerAll(Ye())}
|
|
1
|
+
import{qt,wi,Zt,Dr,Us}from"./studio-cqmtbg2p.js";import{ge,Q,v,k}from"./studio-fqq890ap.js";import{vi,q,Ol,ot,yi,li,Se,fa,oo,He,Dx,bp,Ml,xv,m,u,ci}from"./studio-x5g1xk77.js";import{te}from"./studio-ery42sqr.js";import{ne}from"./studio-cp1gbff9.js";import{Pw,Eu,fd,Tu}from"./studio-zev8ssp1.js";import{Zi,T,R}from"./studio-7qvs7v0m.js";import{fc,mb,Lu,Gf,FE,I1}from"./studio-xg1942as.js";import{pr}from"./studio-4m50vh74.js";import{HE}from"./studio-qa73881a.js";import{Tw,cb,sa,y1,CE}from"./studio-84rtc120.js";import{D}from"./studio-tp642n5g.js";import{Ae}from"./studio-evwgp1ym.js";import{me}from"./studio-0bbxhhce.js";var kw=["string","number","boolean","array","object","reference"],Sw=["","image","date","color"];function zf(e){if(e.$ref)return"reference";return e.type||"string"}function uc(e){if(e.type==="array"&&e.items?.format)return e.items.format;return e.format||""}function Ms(e,r){switch(e){case"number":return{type:"number"};case"boolean":return{type:"boolean"};case"array":return r?{items:{format:r,type:"string"},type:"array"}:{items:{type:"string"},type:"array"};case"object":return{properties:{},required:[],type:"object"};case"reference":return{$ref:"#/content/"};default:return r?{format:r,type:"string"}:{type:"string"}}}var U={$schema:"https://jxsuite.com/schema/v1",$id:"StudioSchemaBuilder",$description:'The `schema-builder` form control (specs/extensions.md §9.1): the visual editor for a JSON Schema object, drawn as one card per property. A descriptor names it with `"ui": { "<prop>": { "control": "schema-builder" } }`, and `ui/schema-form.ts` mounts it into the empty host its own document announces for that field. The adapter (`surfaces/schema-builder.ts`) hands in the fields already classified and every draft the reader is part-way through typing; `ui/form-controls.ts` decides what a field may be renamed to and what reaches the host\'s `onChange`. Nothing here reads a schema: a document that re-derived a field\'s type while drawing would be a second opinion about what one module already owns. **The card is `surfaces/settings-defs.json`\'s, part for part.** Data Shapes edits the project\'s `$defs` and this edits a content type\'s `schema`; they are the same object with the same six controls per row, so the row vocabulary — `card`, `field-row`, `field-label`, `field-name`, `field-type`, `field-format`, `field-required`, `field-delete`, `nested`, `nested-card`, `nested-add-name`/`-type`/`-button`, `ref-target`, `add-form` — is ONE vocabulary, and the row views it is drawn from are that surface\'s own types rather than a second declaration of them. What differs is only what encloses it: Data Shapes carries the two-column chrome that chooses WHICH shape is being edited, and this one is handed the object to edit.',tagName:"div",attributes:{part:"builder"},style:{$description:"What `.schema-builder`, `.schema-field-list`, `.schema-field-card`, `.schema-field-row`, `.schema-field-nested`, `.schema-field-name-input`, `.schema-nested-add`, `.schema-nested-add-name` and `.schema-add-field` said in `styles/overlays.css`, keyed on `part` and re-pointed at the studio token layer — the same translation `surfaces/settings-defs.json` carries, because it is the same card. Two values could not come with them. `.schema-field-card--nested` read `var(--spectrum-gray-300, #444)`, and the caption was an `sp-field-label` at whatever size Spectrum drew it; a document is mounted in the pane rather than inside `<sp-theme>`, so both would have taken their hard-coded fallback every time. The nested card takes the studio layer's `--border`, and the caption says what it is in the type ramp instead.",display:"block",'& [part="fields"]':{display:"flex",flexDirection:"column",gap:"4px",marginBottom:"12px"},'& [part="card"], & [part="nested-card"]':{border:"1px solid var(--border)",borderRadius:"var(--radius)",padding:"6px 10px"},'& [part="field-row"]':{display:"flex",alignItems:"center",gap:"8px"},'& [part="field-label"]':{$description:"The field's name in words: a caption on the row rather than a label for a control, since the raw key beside it is what the reader edits and what carries the accessible name.",flex:"none",minWidth:"84px",fontSize:"var(--jx-text-sm)",color:"var(--fg-dim)",overflowWrap:"anywhere"},'& [part="field-name"]':{flex:"1",maxWidth:"140px"},'& [part="nested"]':{marginLeft:"16px",marginTop:"6px",paddingLeft:"8px",borderLeft:"2px solid var(--border)",display:"flex",flexDirection:"column",gap:"4px"},'& [part="ref-target"]':{display:"flex",marginTop:"6px",maxWidth:"220px"},'& [part="nested-add"]':{display:"flex",alignItems:"center",gap:"6px",padding:"4px 0"},'& [part="nested-add-name"]':{flex:"1",maxWidth:"120px"},'& [part="add-form"]':{display:"flex",alignItems:"center",gap:"8px",padding:"8px 0"}},children:[{tagName:"div",attributes:{part:"fields"},children:[{$prototype:"Array",items:{$ref:"#/state/fields"},key:{$ref:"$map/item/key"},map:{tagName:"div",attributes:{part:"card","data-field":"${$map.item.key}"},children:[{tagName:"div",attributes:{part:"field-row"},children:[{tagName:"span",attributes:{part:"field-label"},textContent:"${$map.item.label}"},{tagName:"jx-textfield",attributes:{part:"field-name"},$props:{label:"Name for ${$map.item.label}",size:"sm",value:{$ref:"$map/item/name"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/renameField"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"jx-select",attributes:{part:"field-type"},$props:{label:"Type for ${$map.item.label}",size:"sm",options:{$ref:"#/state/typeOptions"},value:{$ref:"$map/item/type"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setType"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"div",attributes:{part:"format-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasFormat"},cases:{true:{tagName:"jx-select",attributes:{part:"field-format"},$props:{label:"Format for ${$map.item.label}",size:"sm",options:{$ref:"#/state/formatOptions"},value:{$ref:"$map/item/format"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setFormat"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}}}},{tagName:"jx-switch",$description:"Whether the object requires this field. The word on screen is the name: `Req` is slotted rather than passed as `label`, because the kit's switch wraps its control in the label the slot lands in, and a second name would be announced over the top of it. Which row it belongs to is the tooltip's job instead, which is what `hint` is.",attributes:{part:"field-required"},$props:{hint:"Require ${$map.item.label}",size:"sm",checked:{$ref:"$map/item/required"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setRequired"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Req"}]},{tagName:"jx-action-button",attributes:{part:"field-delete"},$props:{label:"Delete ${$map.item.label}",hint:"Delete ${$map.item.label}",icon:"trash",quiet:!0,size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/removeField"},value:[{$ref:"$map/item/key"}]}]}}]},{tagName:"div",attributes:{part:"extra-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/extra"},cases:{reference:{tagName:"div",attributes:{part:"ref-target"},children:[{tagName:"jx-select",attributes:{part:"ref-target-select"},$props:{label:"Target for ${$map.item.label}",size:"sm",options:{$ref:"#/state/targets"},value:{$ref:"$map/item/refTarget"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setTarget"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}}]},nested:{tagName:"div",attributes:{part:"nested"},children:[{$prototype:"Array",items:{$ref:"$map/item/children"},key:{$ref:"$map/item/key"},map:{tagName:"div",attributes:{part:"nested-card","data-nested":"${$map.item.key}"},children:[{tagName:"div",attributes:{part:"field-row"},children:[{tagName:"jx-textfield",attributes:{part:"field-name"},$props:{label:"Name for ${$map.item.parent}.${$map.item.key}",size:"sm",value:{$ref:"$map/item/name"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/renameNested"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"jx-select",attributes:{part:"field-type"},$props:{label:"Type for ${$map.item.parent}.${$map.item.key}",size:"sm",options:{$ref:"#/state/typeOptions"},value:{$ref:"$map/item/type"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setNestedType"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"div",attributes:{part:"format-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/hasFormat"},cases:{true:{tagName:"jx-select",attributes:{part:"field-format"},$props:{label:"Format for ${$map.item.parent}.${$map.item.key}",size:"sm",options:{$ref:"#/state/formatOptions"},value:{$ref:"$map/item/format"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setNestedFormat"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}}}},{tagName:"jx-switch",attributes:{part:"field-required"},$props:{hint:"Require ${$map.item.parent}.${$map.item.key}",size:"sm",checked:{$ref:"$map/item/required"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setNestedRequired"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"},{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Req"}]},{tagName:"jx-action-button",attributes:{part:"field-delete"},$props:{label:"Delete ${$map.item.parent}.${$map.item.key}",hint:"Delete ${$map.item.parent}.${$map.item.key}",icon:"trash",quiet:!0,size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/removeNested"},value:[{$ref:"$map/item/parent"},{$ref:"$map/item/key"}]}]}}]}]}},{tagName:"div",attributes:{part:"nested-add"},children:[{tagName:"jx-textfield",attributes:{part:"nested-add-name"},$props:{label:"New field in ${$map.item.label}",placeholder:"field name",size:"sm",value:{$ref:"$map/item/draftName"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editDraftName"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]},onkeydown:{$prototype:"Function",body:[{$switch:{$ref:"event#/key"},cases:{Enter:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/addNested"},value:[{$ref:"$map/item/key"}]}]}}]}},{tagName:"jx-select",attributes:{part:"nested-add-type"},$props:{label:"Type of the new field in ${$map.item.label}",size:"sm",options:{$ref:"#/state/typeOptions"},value:{$ref:"$map/item/draftType"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editDraftType"},value:[{$ref:"$map/item/key"},{$ref:"event#/target/value"}]}]}},{tagName:"jx-action-button",attributes:{part:"nested-add-button"},$props:{label:"Add a field to ${$map.item.label}",hint:"Add a field to ${$map.item.label}",icon:"plus",quiet:!0,size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/addNested"},value:[{$ref:"$map/item/key"}]}]}}]}]}}}]}}]},{tagName:"div",attributes:{part:"add-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/addState"},cases:{closed:{tagName:"jx-action-button",attributes:{part:"add-open"},$props:{label:"Add Field",icon:"plus",quiet:!0,size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openAdd"},value:[]}]},children:[{tagName:"span",textContent:"Add Field"}]},open:{tagName:"div",attributes:{part:"add-form"},children:[{tagName:"jx-textfield",attributes:{part:"add-name"},$props:{label:"New field name",placeholder:"Field name",size:"sm",value:{$ref:"#/state/addName"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editAddName"},value:[{$ref:"event#/target/value"}]}]},onkeydown:{$prototype:"Function",body:[{$switch:{$ref:"event#/key"},cases:{Enter:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/confirmAdd"},value:[]}],Escape:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/cancelAdd"},value:[]}]}}]}},{tagName:"jx-select",attributes:{part:"add-type"},$props:{label:"Type of the new field",size:"sm",options:{$ref:"#/state/typeOptions"},value:{$ref:"#/state/addType"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editAddType"},value:[{$ref:"event#/target/value"}]}]}},{tagName:"div",attributes:{part:"add-format-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/addHasFormat"},cases:{true:{tagName:"jx-select",attributes:{part:"add-format"},$props:{label:"Format of the new field",size:"sm",options:{$ref:"#/state/formatOptions"},value:{$ref:"#/state/addFormat"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editAddFormat"},value:[{$ref:"event#/target/value"}]}]}}}},{tagName:"jx-switch",attributes:{part:"add-required"},$props:{hint:"Require the new field",size:"sm",checked:{$ref:"#/state/addRequired"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editAddRequired"},value:[{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Required"}]},{tagName:"jx-button",attributes:{part:"add-confirm"},$props:{size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/confirmAdd"},value:[]}]},children:[{tagName:"span",textContent:"Add"}]},{tagName:"jx-button",attributes:{part:"add-cancel"},$props:{size:"sm",quiet:!0},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/cancelAdd"},value:[]}]},children:[{tagName:"span",textContent:"Cancel"}]}]}}}]};T("schema-builder",U);function be(){return{addFormat:"",addHasFormat:!0,addName:"",addRequired:!1,addState:"closed",addType:"string",fields:[],formatOptions:[],targets:[],typeOptions:[]}}function Y(e,r){e.textContent="";let t=v({...be(),...r}),a=null,n=!0,s=!1,l=()=>R("schema-builder",t,e).then((o)=>{if(n=!1,s)return o.dispose(),o.root;return a=o,o.root}),p=l();return{dispose(){s=!0,a?.dispose(),a=null,e.textContent=""},host:e,ready:p,update(o){if(t.addFormat=o.addFormat,t.addHasFormat=o.addHasFormat,t.addName=o.addName,t.addRequired=o.addRequired,t.addState=o.addState,t.addType=o.addType,t.fields=o.fields,t.formatOptions=o.formatOptions,t.targets=o.targets,t.typeOptions=o.typeOptions,s||n||a!==null&&e.contains(a.root))return;a?.dispose(),a=null,n=!0,e.textContent="",l()}}}var G={$schema:"https://jxsuite.com/schema/v1",$id:"StudioReferenceField",$description:'The `reference` form control — site-architecture.md §6.1\'s `{ "$ref": "#/content/x" }` and site-architecture.md §7.4\'s entry picker. Registered once and dispatched to by `ui/schema-form.ts` for any property whose `$ref` names a collection, so the settings forms, the entry editor and an array-of-objects cell all draw the same control without any of them knowing it exists. `ui/form-controls.ts` decides which of the three states the field is in and what each gesture commits; nothing here reads a schema or lists a directory. The three states are drawn as three different controls on purpose: a picker while the entries are known, a TEXT field while they are not — a failed read leaves the value editable with the reason beside it, because swapping it for an empty dropdown would present "no entries" and "could not find out" as the same screen — and a disabled picker saying so while the read is in flight.',tagName:"div",attributes:{part:"reference",role:"none"},style:{$description:"The five `.reference-*` rules from `styles/inspector.css`, keyed on `part` and re-pointed at the studio token layer. Two values could not come with them. The note read `var(--spectrum-font-size-50, 11px)`, which resolves only inside `<sp-theme>` — this document is mounted in a settings pane, an entry editor or a frontmatter card, all outside that element, so it would silently have taken its hard-coded fallback every time. And `.reference-missing` coloured ONE row of the dropdown red; the kit's select offers a row a face, a swatch and a border style but no tone, so the dangling entry says what it is in words (\"— not found\") and the colour is not replaced by a second channel. The 6px gap comes onto the kit's spacing scale.",display:"flex",flex:"1",minWidth:"0",alignItems:"center",gap:"var(--jx-space-2)",'& [part="picker"], & [part="text"]':{flex:"1",minWidth:"0"},'& [part="note"]':{margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)",lineHeight:"1.4"},'& [part="note"][data-tone="danger"]':{$description:"A listing that failed is a FAULT rather than a fact about the project, and the two notes this control draws are otherwise the same sentence in the same place.",color:"var(--danger)"},'& [part="retry"]':{flex:"none"}},children:[{tagName:"div",attributes:{part:"control-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/kind"},cases:{picker:{$description:"The collection's entries. The empty row is `\"\"` rather than a sentinel, because the kit's select treats the empty string as a legal value a reader can arrow to; a dangling reference is kept in the list and marked, since blanking the field would delete the evidence and the value in one repaint. While the read is in flight the same control is disabled and offers one row saying so.",tagName:"jx-select",attributes:{part:"picker"},$props:{size:"sm",label:{$ref:"#/state/label"},options:{$ref:"#/state/options"},value:{$ref:"#/state/value"},disabled:{$ref:"#/state/disabled"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/choose"},value:[{$ref:"event#/target/value"}]}]}},text:{$description:"The id as the string it is: what a reader gets when the choices could not be listed, and when the control was named by a `ui.control` override on a property that references nothing. Refusing to draw anything would lose the value that is already there.",tagName:"jx-textfield",attributes:{part:"text"},$props:{size:"sm",label:{$ref:"#/state/label"},value:{$ref:"#/state/value"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/edit"},value:[{$ref:"event#/target/value"}]}]}}}},{tagName:"div",attributes:{part:"note-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasNote"},cases:{true:{tagName:"p",attributes:{part:"note","data-tone":"${state.noteTone}",role:"status"},textContent:"${state.note}"}}},{tagName:"div",attributes:{part:"retry-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/canRetry"},cases:{true:{$description:"Offered only where there is something to try again — a listing that failed. It used to be offered only where the HOST passed a repaint hook, because a template control cannot draw a second frame of its own and a button that cannot do the thing it is named after is worse than its absence. A mounted control redraws itself, so the condition is now the failure rather than the host.",tagName:"jx-action-button",attributes:{part:"retry"},$props:{size:"sm",quiet:!0,label:"Retry listing entries"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/retry"},value:[]}]},children:[{tagName:"span",textContent:"Retry"}]}}}]};T("reference-field",G);function ve(){return{canRetry:!1,disabled:!0,hasNote:!1,kind:"picker",label:"",note:"",noteTone:"dim",options:[],value:""}}function K(e,r){e.textContent="";let t=v({...ve(),...r}),a=null,n=!0,s=!1,l=()=>R("reference-field",t,e).then((o)=>{if(n=!1,s)return o.dispose(),o.root;return a=o,o.root}),p=l();return{dispose(){s=!0,a?.dispose(),a=null,e.textContent=""},host:e,ready:p,update(o){if(t.canRetry=o.canRetry,t.disabled=o.disabled,t.hasNote=o.hasNote,t.kind=o.kind,t.label=o.label,t.note=o.note,t.noteTone=o.noteTone,t.options=o.options,t.value=o.value,s||n||a!==null&&e.contains(a.root))return;a?.dispose(),a=null,n=!0,e.textContent="",l()}}}var X={$schema:"https://jxsuite.com/schema/v1",$id:"StudioSecretField",$description:'The `secret` form control (specs/extensions.md §9.1, §13): one password field whose VALUE goes to the platform\'s secret store and never to project.json. A descriptor names it with `"ui": { "<field>": { "control": "secret" } }`, and `ui/schema-form.ts` mounts it into the empty host its own document announces for that field. **A surface never renders back the secret it describes, and this document is where that is visible rather than remembered**: the only thing bound to the field\'s value is `#/state/shown`, a scope path whose whole purpose is to hold nothing. What the field is worth is said in the placeholder instead — the env NAME the store gave it, which is the only half of a secret a screen may carry. `ui/form-controls.ts` decides everything else: whether the host has a secret store at all, what the placeholder says, what a commit is worth and what the field persists.',tagName:"div",attributes:{part:"secret",role:"none"},style:{$description:"`.secret-field` carried no rule anywhere — it was one of `check-styles.ts`'s ALLOWED_ORPHANS, a class emitted only so a test could find the control — so there is nothing to translate and the wrapper takes no box of its own. The field takes the width of the control host the form drew, which is the flex item; a kit field is inline-flex by default and would otherwise sit at its intrinsic width in a row sized for it.",display:"contents",'& [part="field"]':{width:"100%"}},children:[{$description:"`autocomplete: new-password` because this is a place to PUT a secret rather than to prove one: without it a password manager offers to fill the field with a credential belonging to whatever site the reader last logged in to, and the offer is the manager's own UI drawn over an editor. The value binding is `#/state/shown` and nothing else ever writes to it — see the document description.",tagName:"jx-textfield",attributes:{part:"field"},$props:{type:"password",size:"sm",autocomplete:"new-password",label:{$ref:"#/state/label"},placeholder:{$ref:"#/state/placeholder"},disabled:{$ref:"#/state/disabled"},value:{$ref:"#/state/shown"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/commit"},value:[{$ref:"event#/target/value"}]}],description:"The change bubbles out of the field's own input, so what the reader typed is read off the event rather than off the element — and it is read here, handed to the flow, and never written back onto the scope."}}]};T("secret-field",X);function xe(){return{disabled:!0,label:"",placeholder:"Not set"}}function Z(e,r){e.textContent="";let t=v({...xe(),...r,shown:""}),a=null,n=!0,s=!1,l=()=>R("secret-field",t,e).then((o)=>{if(n=!1,s)return o.dispose(),o.root;return a=o,o.root}),p=l();return{clear(){t.shown=" ",t.shown=""},dispose(){s=!0,a?.dispose(),a=null,e.textContent=""},host:e,ready:p,update(o){if(t.disabled=o.disabled,t.label=o.label,t.placeholder=o.placeholder,s||n||a!==null&&e.contains(a.root))return;a?.dispose(),a=null,n=!0,e.textContent="",l()}}}var Fe=kw.map((e)=>({label:e,value:e})),Ne=Sw.map((e)=>({label:e||"(none)",value:e})),j={format:"",name:"",required:!1,type:"string"},ee=[],re=" ";function Te(e){let r=e.resolvePointer("#/$context/content"),t=r&&typeof r==="object"&&!Array.isArray(r)?Object.keys(r):[],a=t.join(" ");if(a!==re)re=a,ee=t.map((n)=>({label:n,value:n}));return ee}function N(e){return e==="string"||e==="array"}function ie(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{properties:{},required:[],type:"object"}}function Ee(e){let r=JSON.parse(JSON.stringify(ie(e)));return r.type??="object",r.properties??={},r.required??=[],r}function A(e){return`name:${e}`}function H(e){return`required:${e}`}function V(e,r){return`${e} ${r}`}function O(e,r,t){return e.echo?.id===r?e.echo.value:t}function ke(e,r,t,a,n){let s=V(r,t),l=zf(a);return{format:uc(a),hasFormat:N(l),key:t,name:O(e,A(s),t),parent:r,required:O(e,H(s),n),type:l}}function Ce(e,r,t,a,n){let s=zf(t),l=s==="object",p=e.drafts.get(r),o=t.required??[];return{children:l?Object.entries(t.properties??{}).map(([w,g])=>ke(e,r,w,g,o.includes(w))):[],draftName:p?.name??"",draftType:p?.type??"string",extra:s==="reference"&&n?"reference":l?"nested":"none",format:uc(t),hasFormat:N(s),key:r,label:Ml(r),name:O(e,A(r),r),refTarget:t.$ref?t.$ref.replace(/^#\/[^/]+\//,""):"",required:O(e,H(r),a),type:s}}function ae(e,r,t){let a={};for(let[n,s]of Object.entries(e))a[n===r?t:n]=s,delete e[n];Object.assign(e,a)}function M(e,r,t){e.required??=[];let a=e.required.indexOf(r);if(t&&a===-1)e.required.push(r);if(!t&&a!==-1)e.required.splice(a,1)}function Re(e,r){let t=r,a=null,n={add:{...j},addOpen:!1,drafts:new Map,echo:null},s=()=>a??ie(t.value),l=()=>{let i=s(),d=i.required??[],c=Te(t.ctx);return{addFormat:n.add.format,addHasFormat:N(n.add.type),addName:n.add.name,addRequired:n.add.required,addState:n.addOpen?"open":"closed",addType:n.add.type,fields:Object.entries(i.properties??{}).map(([f,h])=>Ce(n,f,h,d.includes(f),c.length>0)),formatOptions:Ne,targets:c,typeOptions:Fe}},p=()=>F.update(l()),o=(i,d)=>{n.echo={id:i,value:d},p()},w=()=>{n.echo=null,p()},g=(i)=>{let d=Ee(s());if(!i(d)){w();return}a=d,n.echo=null,t.onChange(d),p()},y=(i,d)=>i.properties[d],x=(i)=>{let d=n.drafts.get(i);if(!d)d={name:"",type:"string"},n.drafts.set(i,d);return d},F=Y(e,{addNested(i){let d=x(i),c=xv(d.name.trim());if(!c)return;g((f)=>{let h=y(f,i);if(!h)return!1;return h.properties??={},h.properties[c]=Ms(d.type||"string"),d.name="",!0})},cancelAdd(){n.addOpen=!1,n.add={...j},p()},confirmAdd(){let i=xv(n.add.name.trim());if(!i)return;let{format:d,required:c,type:f}=n.add;n.addOpen=!1,n.add={...j},g((h)=>{if(h.properties[i]=Ms(f,d||void 0),c)M(h,i,!0);return!0})},editAddFormat(i){n.add.format=i,p()},editAddName(i){n.add.name=i,p()},editAddRequired(i){n.add.required=i,p()},editAddType(i){n.add.type=i,p()},editDraftName(i,d){x(i).name=d,p()},editDraftType(i,d){x(i).type=d,p()},openAdd(){n.addOpen=!0,n.add={...j},p()},removeField(i){g((d)=>{if(!d.properties[i])return!1;return delete d.properties[i],d.required=d.required.filter((c)=>c!==i),!0})},removeNested(i,d){g((c)=>{let f=y(c,i);if(!f?.properties?.[d])return!1;if(delete f.properties[d],f.required)f.required=f.required.filter((h)=>h!==d);return!0})},renameField(i,d){o(A(i),d);let c=xv(d.trim());g((f)=>{if(!f.properties[i]||!c||c===i||f.properties[c])return!1;return ae(f.properties,i,c),f.required=f.required.map((h)=>h===i?c:h),!0})},renameNested(i,d,c){o(A(V(i,d)),c);let f=xv(c.trim());g((h)=>{let b=y(h,i);if(!b?.properties?.[d]||!f||f===d||b.properties[f])return!1;if(ae(b.properties,d,f),b.required)b.required=b.required.map((C)=>C===d?f:C);return!0})},setFormat(i,d){g((c)=>{let f=c.properties[i];if(!f)return!1;return c.properties[i]=Ms(f.type||"string",d||void 0),!0})},setNestedFormat(i,d,c){g((f)=>{let h=y(f,i),b=h?.properties?.[d];if(!h?.properties||!b)return!1;return h.properties[d]=Ms(b.type||"string",c||void 0),!0})},setNestedRequired(i,d,c){o(H(V(i,d)),c),g((f)=>{let h=y(f,i);if(!h)return!1;return M(h,d,c),!0})},setNestedType(i,d,c){g((f)=>{let h=y(f,i),b=h?.properties?.[d];if(!h?.properties||!b)return!1;let C=N(c)?uc(b):void 0;return h.properties[d]=Ms(c,C||void 0),!0})},setRequired(i,d){o(H(i),d),g((c)=>{if(!c.properties[i])return!1;return M(c,i,d),!0})},setTarget(i,d){g((c)=>{if(!c.properties[i])return!1;return c.properties[i]={$ref:`#/content/${d}`},!0})},setType(i,d){g((c)=>{let f=c.properties[i];if(!f)return!1;let h=N(d)?uc(f):void 0;return c.properties[i]=Ms(d,h||void 0),!0})}});return p(),{dispose:()=>F.dispose(),update(i){t=i,a=null,n.echo=null,p()}}}var je={mount:Re};Pw("schema-builder",je);function oe(e){return typeof e==="string"&&e?e:null}function De(e,r){let t=r,a=()=>{let s=oe(t.value);n.update({disabled:!t.ctx.commitSecret,label:t.key,placeholder:s?`Stored as ${s}`:"Not set"})},n=Z(e,{commit(s){let{commitSecret:l}=t.ctx;if(!l||!s)return;n.clear();let{key:p,onChange:o}=t,w=oe(t.value);Promise.resolve(l(p,s)).then((g)=>{if(typeof g==="string"&&g&&g!==w)o(g)})}});return a(),{dispose:()=>n.dispose(),update(s){t=s,a()}}}var qe={mount:De};Pw("secret",qe);var E=new Map,P=new Map,S=new Map;function B(e){if(e===void 0)E.clear(),P.clear(),S.clear();else E.delete(e),P.delete(e),S.delete(e)}function Oe(e){let r=E.get(e);if(r)return r;let t=(me("t0q184js"),import("./content-source-t0q184js.js")).then((a)=>a.listCollectionEntryIds(e));return E.set(e,t),t}function g1(e,r){let t=P.get(e);if(t)return t;let a=Oe(e),n=S.get(e);if(n){if(r)n.add(r);return null}S.set(e,new Set(r?[r]:[]));let s=(l)=>{if(E.get(e)!==a)return;let p=S.get(e);S.delete(e),P.set(e,l);for(let o of p??[])o()};return a.then((l)=>s({ids:l}),(l)=>s({error:te(l)})),null}function Pe(e,r){let t=typeof e.value==="string"?e.value:"",a={canRetry:!1,disabled:!1,hasNote:!1,label:e.key,note:"",noteTone:"dim",options:[],value:t},n=Eu(e.schema);if(n===null)return{...a,hasNote:!0,kind:"text",note:'No collection referenced — add "$ref": "#/content/<type>" to this field.'};let s=g1(n,r);if(s===null)return{...a,disabled:!0,kind:"picker",options:[{label:"Loading…",value:t}]};if("error"in s)return{...a,canRetry:!0,hasNote:!0,kind:"text",note:`Could not list ${n} entries — ${s.error}`,noteTone:"danger"};let l=t!==""&&!s.ids.includes(t);return{...a,hasNote:s.ids.length===0,kind:"picker",note:s.ids.length===0?`No ${n} entries yet.`:"",options:[{label:"—",value:""},...l?[{label:`${t} — not found`,value:t}]:[],...s.ids.map((p)=>({label:p,value:p}))]}}function Le(e,r){let t=r,a=!1,n=()=>{if(!a)s.update(Pe(t,n))},s=K(e,{choose(l){t.onChange(l===""?void 0:l)},edit(l){t.onChange(l.trim()||void 0)},retry(){let l=Eu(t.schema);if(l!==null)B(l);n()}});return n(),{dispose(){a=!0,s.dispose()},update(l){t=l,n()}}}var Me={mount:Le};Pw("reference",Me);var se={$schema:"https://jxsuite.com/schema/v1",$id:"StudioEntryEditor",$description:"The Entry editor (site-architecture.md §7.4) — one content entry's fields, in a pane, as a Jx document over the kit. The adapter (`surfaces/entry-editor.ts`) hands in a projection; `content/entry-editor.ts` decides everything in it — which collection the file belongs to, which record its fields live in, which required keys are absent and what a draft flag commits into. The FORM is an island: a schema is `ui/schema-form.ts`'s subject, so this document renders an empty `fields` node and the flow places the element that engine hands back (studio-ui-guidelines.md §9.3, §9.4). That is the whole of the difference between this and the card the lit version drew, and it is why the engine converting in batch 7 is what unblocked this one.",tagName:"div",attributes:{part:"entry","data-jx-region":"${state.region}"},style:{$description:"What `.entry-editor`, `.entry-editor-header`, `.entry-editor-collection`, `.entry-draft-switch`, `.entry-editor-fields`, `.entry-editor-note` and `.entry-editor-empty` said in `styles/overlays.css`, keyed on `part` and re-pointed at the studio token layer. This editor was the only emitter of all seven, so those rules are dead in the stylesheet from here; a central sweep removes them rather than this change, which owns no stylesheet. Every `--spectrum-font-size-*` reference is gone rather than renamed: those names resolve only inside `<sp-theme>`, and a pane editor is mounted outside it, so each would silently have taken its hard-coded fallback.",height:"100%",padding:"var(--jx-space-5)",overflowY:"auto",background:"var(--bg-panel)",'& [part="header"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-4)",marginBottom:"var(--jx-space-5)"},'& [part="name"]':{margin:"0",fontSize:"var(--jx-text-lg)",fontWeight:"600",color:"var(--fg)"},'& [part="collection"]':{padding:"1px var(--jx-space-3)",borderRadius:"var(--radius)",background:"var(--bg)",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"},'& [part="draft"]':{$description:"Pushed to the far end of the header rather than placed there: the heading and the collection chip are both content-width, so `margin-left: auto` is what keeps the switch on the right edge whatever the entry is called.",marginLeft:"auto"},'& [part="fields"]':{$description:"The schema form's host is `display: contents`, so its rows are the flex items of THIS box — which is why the column lives here and not inside the engine.",display:"flex",flexDirection:"column"},'& [part="note"]':{margin:"0 0 var(--jx-space-4)",color:"var(--fg-dim)",fontSize:"var(--jx-text-md)",lineHeight:"1.5"},'& [part="empty"]':{display:"flex",maxWidth:"46ch",flexDirection:"column",alignItems:"flex-start",gap:"var(--jx-space-3)",color:"var(--fg-dim)",fontSize:"var(--jx-text-md)",lineHeight:"1.5"}},children:[{tagName:"div",attributes:{part:"stage-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/stage"},cases:{entry:{tagName:"div",attributes:{part:"body",role:"none"},style:{display:"contents"},children:[{tagName:"div",attributes:{part:"header"},children:[{tagName:"h3",attributes:{part:"name"},textContent:"${state.name}"},{tagName:"span",attributes:{part:"collection"},textContent:"${state.collection}"},{tagName:"div",attributes:{part:"draft-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/draftAxis"},cases:{shown:{$description:"No `label`: the slotted word is on screen and carries the name, so an aria-label would be read twice. The tooltip is `hint`, which is what DRAFT_MEANING has always been.",tagName:"jx-switch",attributes:{part:"draft"},$props:{checked:{$ref:"#/state/draft"},hint:"${state.draftHint}",size:"sm"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setDraft"},value:[{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Draft"}]}}}]},{tagName:"div",attributes:{part:"note-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/noteState"},cases:{shown:{tagName:"p",attributes:{part:"note"},textContent:"${state.note}"}}},{$description:"An island: `ui/schema-form.ts` draws this entry's fields into this node, and nothing in this document knows what a schema is.",tagName:"div",attributes:{part:"fields","data-jx-region":"${state.fieldsRegion}"}}]},empty:{$description:"The mode is reachable from the palette and from `__jxAutomation` on any tab, so this state is real: it names the reason and the fix rather than drawing an empty form.",tagName:"div",attributes:{part:"empty"},children:[{tagName:"p",attributes:{part:"empty-line"},textContent:"${state.emptyLine}"},{tagName:"p",attributes:{part:"note"},children:[{tagName:"span",textContent:"A collection is a "},{tagName:"code",textContent:"content"},{tagName:"span",textContent:" entry in "},{tagName:"code",textContent:"project.json"},{tagName:"span",textContent:" whose "},{tagName:"code",textContent:"source"},{tagName:"span",textContent:" directory contains this file and which declares a "},{tagName:"code",textContent:"schema"},{tagName:"span",textContent:"."}]},{tagName:"jx-action-button",attributes:{part:"content-types"},$props:{label:"Content types",size:"sm"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openContentTypes"},value:[]}]},children:[{tagName:"span",textContent:"Content types…"}]}]}}}]};T("entry-editor",se);function de(e,r){e.region=r.region,e.fieldsRegion=r.fieldsRegion,e.stage=r.stage,e.name=r.name,e.collection=r.collection,e.draftAxis=r.draftAxis,e.draft=r.draft,e.draftHint=r.draftHint,e.noteState=r.noteState,e.note=r.note,e.emptyLine=r.emptyLine}function Be(e){let t=e?.attributes?.part;return typeof t==="string"?t:""}function le(e,r,t,a){e.replaceChildren();let n=v({collection:"",draft:!1,draftAxis:"hidden",draftHint:"",emptyLine:"",fieldsRegion:"",name:"",note:"",noteState:"hidden",openContentTypes:t.openContentTypes,region:"",setDraft:t.setDraft,stage:"empty"});de(n,r);let s=null,l=!1,p=R("entry-editor",n,e,{onNodeCreated:(o,w,g)=>{if(o instanceof HTMLElement&&Be(g)==="fields")a.fieldsSlot(o)}}).then((o)=>{if(l)return o.dispose(),o.root;return s=o,o.root});return{attached:()=>{if(l)return!1;let o=s?.root;return o===void 0?!0:o instanceof HTMLElement&&e.contains(o)},dispose(){l=!0,s?.dispose(),s=null},ready:p,update:(o)=>de(n,o)}}function ce(e){return e.doc.sourceFormat==null&&e.doc.mode!=="content"}function Wf(e){return ce(e)?e.doc.document:e.doc.content?.frontmatter??{}}function ze(e,r,t){let a=e.doc.document,n=Object.hasOwn(a,r)?Ae(a[r]):void 0,s=t===void 0||t===null||t==="";if(s)delete a[r];else a[r]=t;let l=s?void 0:Ae(t);vi({forward:{key:r,op:"set-key",path:[],value:l},inverse:{key:r,op:"set-key",path:[],value:n}}),e.doc.dirty=!0,HE()}function z(e,r,t){if(ce(e))ze(e,r,t);else Ol(e,r,t)}function pe(e,r){q(e,(t)=>{for(let[a,n]of Object.entries(r))z(t,a,n)})}var fe="entry",Ie=[fe],L=new Map;function I(e){return L.get(e)??null}function b1(e,r){let t=I(e);return t!==null&&t.tabId===r.id&&t.wrap.isConnected&&t.surface.attached()}function lb(e){let r=L.get(e);if(!r)return;r.scope.stop(),r.surface.dispose(),L.delete(e)}function _(e,r){q(e,(t)=>z(t,fc,r))}function xE(e){let r=sa(e.documentPath),t=Wf(e);if(!r||!Gf(r.schema,t))return null;let a=Lu(t);return{draft:a,text:a?"Draft":"Published",title:a?mb:"Not marked a draft."}}function _e(e){return{fieldKeyPrefix:`entry:${e.id}`,resolvePointer:(r,t)=>Tu(r,{projectConfig:D?.projectConfig??{},scope:t})}}function We(e,r){let t={};for(let a of CE(e.schema,r))t[a]="Required — this entry does not have one.";return t}function Je(e){return`${e.documentPath??"This document"} is not an entry of any content collection, so there is no schema to draw a form from.`}function ue(e,r,t){let a=Zi(e,"entry"),n=Zi(e,"entry/fields");if(!t)return{collection:"",draft:!1,draftAxis:"hidden",draftHint:mb,emptyLine:Je(r),fieldsRegion:n,name:"",note:"",noteState:"hidden",region:a,stage:"empty"};let s=Wf(r),l=Lu(s);return{collection:t.name,draft:l,draftAxis:Gf(t.schema,s)?"shown":"hidden",draftHint:mb,emptyLine:"",fieldsRegion:n,name:r.documentPath?.split("/").pop()??"Untitled",note:mb,noteState:l?"shown":"hidden",region:a,stage:"entry"}}function _E(e,r){let{paneId:t,wrap:a}=e;if(b1(t,r))return;lb(t);let n=null,s=null,l=()=>{if(n!==null&&I(t)===n)o()},p=(y)=>{if(!s||!y)return;let x=Wf(r),F=fd(`entry:${t}`,y.schema,x,{context:_e(r),errors:We(y,x),onChange:(i)=>pe(r,i),rerender:l});if(F.parentNode!==s)s.replaceChildren(F)},o=()=>{let y=sa(r.documentPath);if(!y)s=null;n?.surface.update(ue(t,r,y)),p(y)},w=ge(),g=le(a,ue(t,r,sa(r.documentPath)),{openContentTypes:()=>{ne()?.run("settings.open",{section:"content"})},setDraft:(y)=>_(r,y)},{fieldsSlot:(y)=>{s=y,p(sa(r.documentPath))}});n={paneId:t,scope:w,surface:g,tabId:r.id,wrap:a},L.set(t,n),w.run(()=>{Q(()=>{if(I(t)!==n)return;r.doc.document,r.doc.content?.frontmatter,D?.projectConfig?.content,o()})})}async function W(e){let{openFileInTab:r}=await (me("fjy7zpxt"),import("./files-fjy7zpxt.js"));await r(e);for(let[t,a]of m.tabs.entries()){if(a.documentPath!==e)continue;for(let n of Ie)if(!a.capabilities.modes.includes(n))a.capabilities.modes.unshift(n);return a.session.ui.canvasMode=fe,a.session.ui.preview=!1,ci(t),a}return null}function J(){return cb().map((e)=>e.name)}async function Ue(e){let r=y1(e.schema),t=(e.def.format?wi(e.def.format)?.name:void 0)??Zt(`untitled${e.ext}`)?.name??Dr()?.name;if(e.ext===".json"||t===void 0)return pr(r,null);return Us(t,{...r,children:[]},{frontmatter:Object.keys(r).length>0,mode:"roundtrip"})}async function Ew(e,r={}){let t=Tw(e);if(!t)return k.error(`No content collection named "${e}" to create an entry in.`,{detail:"A collection needs a `content` entry in project.json whose `source` is a directory. A collection whose source names a single file (a CSV catalogue) has rows, not entry files.",source:"Content"}),null;await qt().catch(()=>{});let a;try{a=await Ue(t)}catch(o){return k.error(`Could not prepare a new ${t.name} entry.`,{detail:te(o),path:t.dir,source:"Content"}),null}let n=r.dir,s=n!==void 0&&bp(n)?.name===t.name?n:t.dir;if(s.includes(Dx))return k.error(`"${t.name}" is a localized collection.`,{detail:`Its entries live in one directory per language (${t.dir}). Open the folder for the language you are writing in and create the entry there.`,path:t.dir,source:"Content"}),null;let{createFileIn:l}=await (me("fjy7zpxt"),import("./files-fjy7zpxt.js")),p=await l({content:a,dir:s,format:{ext:t.ext,kind:"fixed"},source:"Content",suggestedName:"untitled",title:`New ${t.name} entry`});if(p===null)return null;return B(t.name),await W(p),p}function he(){let e=u.value;return e&&sa(e.documentPath)?e:null}function Ye(){return[{args:Se({collection:fa(J,"The content collection the entry is created in.")}),category:"File",id:"content.newEntry",level:"project",menus:["palette"],group:"1_file",requires:"a project with a directory-backed content collection",when:(e)=>e.project.open,enablement:()=>J().length>0,undo:"project",run:async(e,r)=>{let t=J();await Ew(li("content.newEntry",r,"collection",t))},title:"New Entry"},{args:Se({path:He("Project-relative path of the entry file to open.")}),category:"File",id:"content.openEntry",level:"project",menus:["context/file","palette"],group:"1_file",requires:"an open project",when:(e)=>e.project.open,run:async(e,r)=>{await W(ot("content.openEntry",r,"path"))},title:"Open Entry Form"},{args:Se({draft:oo("True marks the open entry a draft; false marks it published. Written as a `draft` field on the entry.")}),category:"Document",id:"content.setDraft",level:"document",menus:["context/tab","palette"],group:"3_document",requires:"a content entry open",when:(e)=>e.document.open,enablement:()=>he()!==null,undo:"document",run:(e,r)=>{let t=he();if(!t)throw Error("content.setDraft: the active document is not a content entry");_(t,yi("content.setDraft",r,"draft"))},title:"Set Draft"},{args:Se({include:oo("True lists entries marked `draft: true` alongside the rest.")}),category:"View",id:"content.setIncludeDrafts",level:"project",menus:["palette"],group:"2_view",requires:"an open project",when:(e)=>e.project.open,run:async(e,r)=>{FE(yi("content.setIncludeDrafts",r,"include")),await I1()},title:"Include Drafts"}]}function v1(e){e.registerAll(Ye())}
|
|
2
2
|
export{kw,Sw,zf,uc,Ms,g1,Wf,b1,lb,xE,_E,Ew,v1};
|
|
3
3
|
|
|
4
4
|
//# debugId=78AC37E2BAC6191964756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-
|
|
5
|
+
//# sourceMappingURL=studio-cbr9czkn.js.map
|