@nice2dev/ui-forms 1.4.4 → 1.4.5
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/index.cjs +6 -6
- package/dist/index.d.ts +134 -2
- package/dist/index.mjs +2809 -2447
- package/dist/studio.cjs +10 -7
- package/dist/studio.d.ts +134 -2
- package/dist/studio.mjs +696 -552
- package/package.json +5 -5
package/dist/studio.cjs
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
|
|
1
|
+
"use strict";var Fe=Object.defineProperty;var xe=(e,t,n)=>t in e?Fe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ee=(e,t,n)=>xe(e,typeof t!="symbol"?t+"":t,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=()=>({version:1,sections:[],folders:[],placement:{}}),Ie=(e,t)=>`${e}:${t}`,_=".studio.json",Me=/^([^/]+?)\.(manifest|entities|views|workflows|permissions|rbac|seeds|datasources|scripts)\.json$/i,se=e=>!e.includes("/")&&e.toLowerCase().endsWith(_);function Te(e){const t=e.find(n=>se(n.path));if(t)return t.path;for(const n of e){const s=Me.exec(n.path);if(s)return`${s[1]}${_}`}return`module${_}`}const N=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),b=e=>typeof e=="string"&&e?e:void 0;function Le(e){if(!e)return T();let t;try{t=JSON.parse(e.replace(/^\uFEFF/,""))}catch{return T()}if(!N(t))return T();const n=(Array.isArray(t.sections)?t.sections:[]).filter(N).map(o=>({id:b(o.id),label:b(o.label)??b(o.id)})).filter(o=>!!o.id&&!!o.label),s=(Array.isArray(t.folders)?t.folders:[]).filter(N).map(o=>({id:b(o.id),label:b(o.label)??b(o.id),group:b(o.group),...b(o.parent)?{parent:b(o.parent)}:{},...b(o.section)?{section:b(o.section)}:{}})).filter(o=>!!o.id&&!!o.label&&!!o.group),i={};if(N(t.placement))for(const[o,c]of Object.entries(t.placement)){if(!N(c))continue;const l={};b(c.section)&&(l.section=b(c.section)),b(c.folder)&&(l.folder=b(c.folder)),typeof c.order=="number"&&Number.isFinite(c.order)&&(l.order=c.order),(l.section||l.folder||l.order!==void 0)&&(i[o]=l)}return{version:1,sections:n,folders:s,placement:i}}const Je=e=>e.sections.length===0&&e.folders.length===0&&Object.keys(e.placement).length===0;function Pe(e,t){const n=JSON.stringify(e,null,2)+`
|
|
2
|
+
`;return t!=null&&t.includes(`\r
|
|
3
|
+
`)?n.replace(/\n/g,`\r
|
|
4
|
+
`):n}const De=e=>e.toLowerCase().normalize("NFKD").replace(/[̀-ͯ]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"item";function ie(e,t){const n=De(e);let s=n;for(let i=2;t.has(s);i++)s=`${n}-${i}`;return s}function Re(e,t){const n=ie(t,new Set(e.sections.map(s=>s.id)));return{layout:{...e,sections:[...e.sections,{id:n,label:t}]},id:n}}function Ce(e,t){const n=ie(t.label,new Set(e.folders.map(i=>i.id))),s={id:n,label:t.label,group:t.group};return t.parent&&(s.parent=t.parent),t.section&&(s.section=t.section),{layout:{...e,folders:[...e.folders,s]},id:n}}function Ve(e,t,n){return t.kind==="section"?{...e,sections:e.sections.map(s=>s.id===t.id?{...s,label:n}:s)}:{...e,folders:e.folders.map(s=>s.id===t.id?{...s,label:n}:s)}}function Ue(e,t){const n={};if(t.kind==="folder"){const s=e.folders.find(i=>i.id===t.id);for(const[i,o]of Object.entries(e.placement))n[i]=o.folder===t.id?{...o,folder:s==null?void 0:s.parent}:o,n[i].folder||delete n[i].folder;return{...e,folders:e.folders.filter(i=>i.id!==t.id).map(i=>i.parent===t.id?{...i,parent:s==null?void 0:s.parent}:i).map(i=>{if(!i.parent){const{parent:o,...c}=i;return c}return i}),placement:z(n)}}for(const[s,i]of Object.entries(e.placement))if(i.section===t.id){const{section:o,...c}=i;n[s]=c}else n[s]=i;return{...e,sections:e.sections.filter(s=>s.id!==t.id),folders:e.folders.map(s=>{if(s.section===t.id){const{section:i,...o}=s;return o}return s}),placement:z(n)}}function z(e){const t={};for(const[n,s]of Object.entries(e))(s.section||s.folder||s.order!==void 0)&&(t[n]=s);return t}function _e(e,t,n){var o;const s=(o=e.placement[t])==null?void 0:o.order,i={};if(n.folder){i.folder=n.folder;const c=e.folders.find(l=>l.id===n.folder);c!=null&&c.section&&(i.section=c.section)}else n.section&&(i.section=n.section);return s!==void 0&&(i.order=s),{...e,placement:z({...e.placement,[t]:i})}}function ze(e,t,n){if(t===n||!e.placement[t])return e;const s={...e.placement,[n]:e.placement[t]};return delete s[t],{...e,placement:s}}const re="\uFEFF",oe={bom:!1,eol:`
|
|
5
|
+
`,indent:" ",finalNewline:!0,colonSpace:!0};function C(e){const t=e.charCodeAt(0)===65279,n=e.includes(`\r
|
|
3
6
|
`)?`\r
|
|
4
7
|
`:`
|
|
5
|
-
`;let
|
|
8
|
+
`;let s=oe.indent;const i=e.split(/\r?\n/);for(let c=1;c<i.length;c++){const l=/^([ \t]+)\S/.exec(i[c]);if(l){s=l[1];break}}const o=/"\s*:(\s?)/.exec(e);return{bom:t,eol:n,indent:s,finalNewline:/\n$/.test(e),colonSpace:o?o[1]!=="":!0}}function O(e){const t=C(e);return{value:JSON.parse(t.bom?e.slice(1):e),format:t}}function k(e,t){const n={...oe,...t},s=E(e,n,"");return(n.bom?re:"")+s+(n.finalNewline?n.eol:"")}function ae(e,t){if(t===void 0)return e;let n=t.includes(`\r
|
|
6
9
|
`)?e.replace(/\r?\n/g,`\r
|
|
7
|
-
`):e;return t.charCodeAt(0)===65279&&n.charCodeAt(0)!==65279&&(n=
|
|
8
|
-
`)};
|
|
9
|
-
`,t-1)+1;return((
|
|
10
|
-
`)}function _(e,t,n){return e.compact?!0:t.kind==="scalar"||(t.kind==="object"?t.members.length===0:t.items.length===0)?n:se(e.text,t)}function N(e,t,n,i){const r=_(e,t,i);e.edits.push({start:t.start,end:t.end,text:r?A(n,e.format,e.compact):O(n,e.format,F(e.text,t.start))})}const ie=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function z(e,t,n,i,r){if(t.kind==="scalar"){if(t.value===n)return;N(e,t,n,r);return}x(M(t),n)||(t.kind==="object"&&ie(n)?Ae(e,t,n,i,r):t.kind==="array"&&Array.isArray(n)?Ne(e,t,n,i,r):N(e,t,n,r))}function re(e,t,n){return n!==void 0?F(e.text,n):F(e.text,t.start)+e.format.indent}function Ae(e,t,n,i,r){var l;const a=_(e,t,r),c=t.members.filter(f=>Object.prototype.hasOwnProperty.call(n,f.key)&&n[f.key]!==void 0),d=Object.keys(n).filter(f=>n[f]!==void 0&&!t.members.some(h=>h.key===f));if(c.length===0&&t.members.length>0){N(e,t,n,r);return}for(const f of c)z(e,f.value,n[f.key],`${i}/${Fe(f.key)}`,a);if(oe(e,t.members.map(f=>({start:f.start,end:f.value.end})),t.members.map(f=>c.includes(f))),d.length===0)return;const u=e.format.colonSpace?": ":":";if(a){const f=d.map(h=>`${JSON.stringify(h)}${u}${A(n[h],e.format,e.compact)}`);ce(e,t,c.length>0?c[c.length-1].value.end:void 0,f);return}const s=re(e,t,(l=t.members[0])==null?void 0:l.start),o=d.map(f=>`${s}${JSON.stringify(f)}${u}${O(n[f],e.format,s)}`);ae(e,t,c.length>0?c[c.length-1].value.end:void 0,o)}const Ee=["name","id","code","key","slug","state","Id"];function xe(e,t,n,i){var u,s;const r=[...n,...i];if(r.length===0||!r.every(ie))return;const a=(o,l)=>{const f=o.map(h=>h[l]);return f.every(h=>typeof h=="string"||typeof h=="number")&&new Set(f).size===f.length},c=(s=(u=e.options)==null?void 0:u.arrayKey)==null?void 0:s.call(u,t);return(c?[c]:Ee).find(o=>a(n,o)&&a(i,o))}function Ne(e,t,n,i,r){var g;const a=_(e,t,r),c=t.items.map(M),d=xe(e,i,c,n),u=p=>p[d],s=d!==void 0?c.map(p=>{const m=u(p);return n.findIndex(b=>u(b)===m)}):Me(c,n);{const p=new Set(s.filter(m=>m>=0));for(let m=0;m<s.length;m++){if(s[m]>=0)continue;let b=-1;for(let y=m-1;y>=0;y--)if(s[y]>=0){b=s[y];break}let $=n.length;for(let y=m+1;y<s.length;y++)if(s[y]>=0){$=s[y];break}for(let y=b+1;y<$;y++)if(!p.has(y)){s[m]=y,p.add(y);break}}}const o=s.filter(p=>p>=0);if(o.some((p,m)=>m>0&&p<o[m-1])){N(e,t,n,r);return}if(o.length===0&&t.items.length>0){N(e,t,n,r);return}t.items.forEach((p,m)=>{s[m]>=0&&z(e,p,n[s[m]],`${i}/${s[m]}`,a)}),oe(e,t.items.map(p=>({start:p.start,end:p.end})),s.map(p=>p>=0));const l=t.items.length>0&&t.items.every(p=>p.kind!=="scalar"&&se(e.text,p)),f=re(e,t,(g=t.items[0])==null?void 0:g.start),h=new Map;n.forEach((p,m)=>{if(s.includes(m))return;let b;for(let S=t.items.length-1;S>=0;S--)if(s[S]>=0&&s[S]<m){b=S;break}const $=a?A(p,e.format,e.compact):l?`${f}${A(p,e.format)}`:`${f}${O(p,e.format,f)}`,y=h.get(b)??[];y.push($),h.set(b,y)});for(const[p,m]of h){const b=p===void 0?void 0:t.items[p].end;if(p===void 0&&o.length>0){const $=t.items[s.findIndex(S=>S>=0)],y=a?ne(e):`,${e.format.eol}`;e.edits.push({start:$.start,end:$.start,text:a?m.join(y)+y:m.join(y).trimStart()+y+f});continue}a?ce(e,t,b,m):ae(e,t,b,m)}}const Ie=4e6;function Me(e,t){const n=e.length,i=t.length;if(n*i>Ie)return e.map((o,l)=>l<i?l:-1);const r=e.map(o=>JSON.stringify(o)),a=t.map(o=>JSON.stringify(o)),c=Array.from({length:n+1},()=>new Uint32Array(i+1));for(let o=n-1;o>=0;o--)for(let l=i-1;l>=0;l--)c[o][l]=r[o]===a[l]?c[o+1][l+1]+1:Math.max(c[o+1][l],c[o][l+1]);const d=new Array(n).fill(-1);let u=0,s=0;for(;u<n&&s<i;)r[u]===a[s]?d[u++]=s++:c[u+1][s]>=c[u][s+1]?u++:s++;return d}function oe(e,t,n){for(let i=0;i<t.length;i++){if(n[i])continue;let r=i;for(;r+1<t.length&&!n[r+1];)r++;r+1<t.length?e.edits.push({start:t[i].start,end:t[r+1].start,text:""}):i>0?e.edits.push({start:t[i-1].end,end:t[r].end,text:""}):e.edits.push({start:t[i].start,end:t[r].end,text:""}),i=r}}function ae(e,t,n,i){const r=e.format.eol;if(n!==void 0){e.edits.push({start:n,end:n,text:`,${r}${i.join(`,${r}`)}`});return}const a=t.end-1;if((t.kind==="object"?t.members.length:t.items.length)===0)e.edits.push({start:t.start+1,end:a,text:`${r}${i.join(`,${r}`)}${r}${F(e.text,t.start)}`});else{const d=t.kind==="object"?t.members[0].start:t.items[0].start;e.edits.push({start:d,end:d,text:`${i.join(`,${r}`).trimStart()}`})}}function ce(e,t,n,i){const r=ne(e);if(n!==void 0){e.edits.push({start:n,end:n,text:`${r}${i.join(r)}`});return}const a=t.kind==="object"&&!e.compact?" ":"";e.edits.push({start:t.start+1,end:t.end-1,text:`${a}${i.join(r)}${a}`})}function Fe(e){return e.replace(/~/g,"~0").replace(/\//g,"~1")}const j=e=>e.slice(e.lastIndexOf("/")+1),Te=e=>e.charCodeAt(0)===65279?e.slice(1):e;function V(e){return{id:e.id,label:e.label,labelKey:e.labelKey,icon:e.icon,match:e.match,editor:e.editor,decode(t,n){return e.select(K(t[0].text).value,n)},encode(t,n,i){const r=n[0].text,a=K(r).value,c=e.assign(a,t,i);return{files:[{path:n[0].path,text:q(r,c,{arrayKey:e.arrayKey})}]}}}}const T=V({id:"json",label:"JSON",labelKey:"devStudio.kind.json",icon:"code",match:e=>e.toLowerCase().endsWith(".json"),editor:"json",select:e=>e,assign:(e,t)=>t}),J={id:"text",label:"Text",labelKey:"devStudio.kind.text",icon:"file",match:()=>!0,editor:"text",decode:e=>e[0].text,encode:(e,t)=>({files:[{path:t[0].path,text:ee(e,t[0].text)}]})};function le(e,t){return e.find(n=>n.match(t))??(T.match(t)?T:J)}function Je(e,t,n){for(const i of[T,J])if(i.match(e.path))try{const r=i.decode([e],n);return{key:`${i.id}:${e.path}`,kind:i,paths:[e.path],label:j(e.path),model:r,error:t}}catch{}return{key:`text:${e.path}`,kind:J,paths:[e.path],label:j(e.path),model:e.text,error:t}}function De(e,t,n,i){var d,u;const r=e.encode(t,n,i),a=new Map(n.map(s=>[s.path,s.text])),c=((d=r.files.find(s=>a.get(s.path)!==s.text))==null?void 0:d.path)??((u=r.deleted)==null?void 0:u.find(s=>a.has(s)));if(c!==void 0)throw new Error(`${j(c)} would not be stored as it is`)}function Pe(e,t,n){const i=new Map;for(const a of t){const c=le(e,a.path),d=c.group?c.group(a.path):a.path,u=`${c.id}:${d}`,s=i.get(u)??{kind:c,group:d,files:[]};s.files.push(a),i.set(u,s)}const r=[];for(const[a,{kind:c,group:d,files:u}]of i){const s=u.map(l=>l.path).sort(),o=j(c.group?d:s[0]);try{const l=c.decode(u,n);De(c,l,u,n),r.push({key:a,kind:c,paths:s,label:o,model:l})}catch(l){const f=l instanceof Error?l.message:String(l);for(const h of u)r.push(Je(h,f,n))}}return r.sort((a,c)=>a.label.localeCompare(c.label))}function Ve(e,t,n,i){const r=n.filter(u=>e.paths.includes(u.path)),a=e.kind.encode(t,r,i),c=new Map(n.map(u=>[u.path,u])),d=[];for(const u of a.files){const s=c.get(u.path);s&&s.text===u.text||d.push({type:"write",path:u.path,text:u.text,baseVersion:s==null?void 0:s.version})}for(const u of a.deleted??[]){const s=c.get(u);s&&d.push({type:"delete",path:u,baseVersion:s.version})}return d}function de(e,t){try{return JSON.parse(Te(e))}catch{return t}}const k=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),v=(...e)=>t=>{const n=t.toLowerCase();return e.some(i=>n.endsWith(i.toLowerCase()))};function I(e){return V({id:e.id,label:e.label,labelKey:e.labelKey,icon:e.icon,editor:e.editor,match:e.match,select:t=>{if(Array.isArray(t))return t;const n=k(t)?t[e.property]:void 0;return Array.isArray(n)?n:[]},assign:(t,n)=>Array.isArray(t)?n:k(t)&&!(e.property in t)&&n.length===0?t:{...k(t)?t:{},[e.property]:n},arrayKey:e.itemKey?()=>e.itemKey:void 0})}function B(e){const t=I(e);return{...t,decode:(n,i)=>t.decode(n,i).map((r,a)=>e.toItem(r,a)),encode:(n,i,r)=>t.encode(n.map(a=>e.fromItem(a)),i,r)}}function G(e){return V({...e,select:t=>k(t)?t:{},assign:(t,n)=>n})}const Le=/^(.*)\.([a-z]{2,3}(?:-[A-Za-z]{2,4})?)\.i18n\.json$/i,Ce=e=>{const t=Le.exec(e);return t?{group:t[1],locale:t[2]}:null},R=e=>k(e)&&Object.values(e).every(t=>typeof t=="string");function fe(e){if(k(e)){for(const t of["translations","keys"])if(t in e){if(R(e[t]))return e[t];throw new Error(`"${t}" is not a flat map of texts`)}if(R(e))return e}throw new Error("no translations in this file")}function U(e,t){return k(e)?k(e.translations)?{...e,translations:t}:k(e.keys)?{...e,keys:t}:R(e)?t:{...e,translations:t}:{translations:t}}function ue(e={}){const t=e.parse??Ce,n=e.pathFor??((i,r)=>`${i}.${r}.i18n.json`);return{id:e.id??"i18n",label:e.label??"Translations",labelKey:e.labelKey??"devStudio.kind.i18n",icon:"globe",editor:"i18n",match:i=>t(i)!==null,group:i=>{var r;return((r=t(i))==null?void 0:r.group)??i},decode(i){const r={};for(const a of i){const c=t(a.path);c&&(r[c.locale]={...fe(K(a.text).value)})}return r},encode(i,r){const a=new Map;let c="";for(const o of r){const l=t(o.path);l&&(a.set(l.locale,o),c=l.group)}const d=a.get("en")??r[0],u=[];for(const[o,l]of Object.entries(i)){const f=a.get(o);if(f){const g=K(f.text).value;u.push({path:f.path,text:q(f.text,U(g,l))});continue}const h=n(c||j((d==null?void 0:d.path)??"module"),o);if(d){const g=K(d.text).value,p=k(g)&&"locale"in g?{...g,locale:o}:g;u.push({path:h,text:w(U(p,l),P(d.text))})}else u.push({path:h,text:w({locale:o,translations:l})})}const s=[...a.entries()].filter(([o])=>!(o in i)).map(([,o])=>o.path);return{files:u,deleted:s}}}}const E=e=>JSON.parse(JSON.stringify(e));function Re(e){const t=e.revisions!==!1;let n=0;const i=e.workspaces.map(s=>({meta:{id:s.id,label:s.label,description:s.description,icon:s.icon,readOnly:s.readOnly},packages:new Map((s.packages??[]).map(o=>[o.id,{...o,workspaceId:s.id}])),modules:new Map(s.modules.map(o=>[o.id,{...o,files:new Map(Object.entries(o.files).map(([l,f])=>[l,{text:f,version:++n}])),revisions:[]}]))}));let r=(e.templates??[]).map(s=>E(s));const a=s=>{const o=i.find(l=>l.meta.id===s);if(!o)throw new Error(`Unknown workspace "${s}"`);return o},c=s=>{const o=a(s.workspaceId).modules.get(s.id);if(!o)throw new Error(`Unknown module "${s.id}"`);return o},d=(s,o)=>({workspaceId:s,id:o.id,packageId:o.packageId,label:o.label??o.id,description:o.description,icon:o.icon,version:o.version,readOnly:o.readOnly||a(s).meta.readOnly,files:[...o.files.keys()].sort()}),u=(s,o)=>({path:s,text:o.text,version:String(o.version)});return{async listWorkspaces(){return i.map(s=>({...s.meta}))},async listModules(s){return[...a(s).modules.values()].map(l=>d(s,l))},async listPackages(s){const o=a(s),l=[...o.packages.values()],f=[...new Set([...o.modules.values()].map(h=>h.packageId).filter(Boolean))].filter(h=>!o.packages.has(h)).map(h=>({id:h,workspaceId:s,label:h,derived:!0}));return[...l,...f]},async readModule(s){return[...c(s).files.entries()].map(([l,f])=>u(l,f))},async writeModule(s,o){const l=c(s);if(l.readOnly||a(s.workspaceId).meta.readOnly)throw new Error(`Module "${s.id}" is read-only`);const f=o.filter(p=>p.baseVersion!==void 0).filter(p=>{const m=l.files.get(p.path);return m?String(m.version)!==p.baseVersion:!1}).map(p=>{var m;return{path:p.path,currentVersion:String((m=l.files.get(p.path))==null?void 0:m.version)}});if(f.length>0)return{ok:!1,conflicts:f};let h;if(t){const p={};for(const[m,b]of l.files)p[m]=b.text;h=`r${++n}`,l.revisions.unshift({id:h,timestamp:Date.now(),label:h,summary:o.map(m=>`${m.type} ${m.path}`).join(", "),files:p})}const g={};for(const p of o)if(p.type==="delete")l.files.delete(p.path);else{const m=++n;l.files.set(p.path,{text:p.text,version:m}),g[p.path]=String(m)}return{ok:!0,versions:g,revision:h}},async createModule(s){const o=a(s.workspaceId);if(o.meta.readOnly)throw new Error(`Workspace "${s.workspaceId}" is read-only`);if(o.modules.has(s.id))throw new Error(`Module "${s.id}" already exists`);const l={id:s.id,packageId:s.packageId,files:new Map(s.files.map(f=>[f.path,{text:f.text,version:++n}])),revisions:[]};return o.modules.set(s.id,l),d(s.workspaceId,l)},async deleteModule(s){const o=a(s.workspaceId);if(o.meta.readOnly)throw new Error(`Workspace "${s.workspaceId}" is read-only`);o.modules.delete(s.id)},async savePackage(s){return a(s.workspaceId).packages.set(s.id,{...s,derived:!1}),{...s,derived:!1}},async deletePackage(s){a(s.workspaceId).packages.delete(s.id)},async listTemplates(){return r.map(s=>E(s))},async saveTemplate(s,o){const l=(o==null?void 0:o.previousId)??s.id,f=E(s),h=r.findIndex(g=>g.id===l);return r=h>=0?r.map((g,p)=>p===h?f:g):[...r,f],E(f)},async deleteTemplate(s){r=r.filter(o=>o.id!==s)},async listRevisions(s,o){return c(s).revisions.filter(l=>!o||o in l.files).map(({files:l,...f})=>({...f,...o?{path:o}:{}}))},async readRevision(s,o,l){const f=c(s).revisions.find(h=>h.id===o);if(!f)throw new Error(`Unknown revision "${o}"`);return l?f.files[l]??"":JSON.stringify(f.files,null,2)},async rollback(s,o,l){const f=c(s),h=f.revisions.find(p=>p.id===o);if(!h)throw new Error(`Unknown revision "${o}"`);const g=l?{[l]:h.files[l]}:h.files;if(!l)for(const p of[...f.files.keys()])p in g||f.files.delete(p);for(const[p,m]of Object.entries(g))m!==void 0&&f.files.set(p,{text:m,version:++n})},snapshot(){return{workspaces:i.map(s=>({...s.meta,packages:[...s.packages.values()].map(({workspaceId:o,...l})=>l),modules:[...s.modules.values()].map(o=>({id:o.id,packageId:o.packageId,label:o.label,description:o.description,icon:o.icon,version:o.version,readOnly:o.readOnly,files:Object.fromEntries([...o.files.entries()].map(([l,f])=>[l,f.text]))}))})),templates:r.map(s=>E(s)),revisions:t}}}}function Ue(e){return e}function D(e,t){if(!t||e===void 0||e===null)return!0;if(t.enum&&!t.enum.includes(e))return!1;switch(t.type){case"string":return typeof e=="string";case"number":return typeof e=="number";case"integer":return Number.isInteger(e);case"boolean":return typeof e=="boolean";case"array":return Array.isArray(e)&&(!t.items||e.every(n=>D(n,t.items)));case"object":{if(typeof e!="object"||Array.isArray(e))return!1;const n=t.properties;return!n||Object.entries(e).every(([i,r])=>i in n&&D(r,n[i]))}default:return!0}}function We(e,t){var c;const n=(e.fields??[]).map(d=>d.name),i=(c=e.schema)==null?void 0:c.properties;if(!e.schema||!i)return{section:e,keys:n};const r=Object.entries(i).filter(([d,u])=>!(d in t)||D(t[d],u)),a=r.map(([d])=>d);return{section:{...e,schema:{...e.schema,properties:Object.fromEntries(r),...e.schema.required?{required:e.schema.required.filter(d=>a.includes(d))}:{}}},keys:[...a,...n]}}function qe(e){var n;const t=new Set;for(const i of e){for(const r of Object.keys(((n=i.schema)==null?void 0:n.properties)??{}))t.add(r);for(const r of i.fields??[])t.add(r.name)}return t}function _e(e){return e.map(t=>{const n=t;return{name:String(n.tableName||n.name||"Entity"),columns:(Array.isArray(n.fields)?n.fields:[]).map(i=>({name:String(i.name??""),dataType:String(i.dataType??i.type??"string"),isPrimaryKey:!!i.isPrimaryKey,isForeignKey:!!(i.isForeignKey??i.foreignKey)}))}})}function ze(e){const t=e.manifest??{},n=String(t.displayName||t.packageName||"Module"),i=(e.views??[]).map(a=>({id:`view:${a.id}`,label:a.name,type:"view"})),r=(e.entities??[]).map(a=>{const c=String(a.name??"Entity");return{id:`entity:${c}`,label:c,type:"entity"}});return{roles:[{id:"admin",label:"Admin"},{id:"user",label:"User"}],actions:[{id:"view",label:"View"},{id:"create",label:"Create"},{id:"edit",label:"Edit"},{id:"delete",label:"Delete"}],resources:[{id:"module",label:n,type:"module",children:[...i.length?[{id:"views",label:"Views",type:"group",children:i}]:[],...r.length?[{id:"entities",label:"Entities",type:"group",children:r}]:[]]}],grants:{}}}const L=G({id:"manifest",label:"Manifest",labelKey:"devStudio.kind.manifest",icon:"file",editor:"manifest",match:v(".manifest.json")}),pe=I({id:"entities",label:"Entities",labelKey:"devStudio.kind.entities",icon:"database",editor:"entities",match:v(".entities.json"),property:"entities",itemKey:"name"}),me=ue();function he(e,t){const n=e,i=typeof e=="object"&&e!==null&&typeof n.id=="string";return{key:i?n.id:`#${t}`,label:i&&n.name||(i?n.id:`#${t+1}`),...i?{definition:n}:{rawReason:"no id"},source:e}}const ye=B({id:"views",label:"Views",labelKey:"devStudio.kind.views",icon:"grid",editor:"views",match:v(".views.json"),property:"views",itemKey:"id",toItem:(e,t)=>he(e,t),fromItem:e=>e.definition??e.source}),ge=B({id:"workflows",label:"Workflows",labelKey:"devStudio.kind.workflows",icon:"git-branch",editor:"workflows",match:v(".workflows.json"),property:"workflows",itemKey:"id",toItem:(e,t)=>he(e,t),fromItem:e=>e.definition??e.source}),be=I({id:"dataSources",label:"Data sources",labelKey:"devStudio.kind.dataSources",icon:"database",editor:"dataSources",match:v(".datasources.json"),property:"dataSources",itemKey:"key"}),we=G({id:"rbac",label:"Access",labelKey:"devStudio.kind.rbac",icon:"shield",editor:"rbac",match:v(".rbac.json")}),ke=I({id:"hooks",label:"Lifecycle hooks",labelKey:"devStudio.kind.hooks",icon:"zap",editor:"hooks",match:v(".hooks.json"),property:"bindings",itemKey:"id"}),ve=[L,pe,me,ye,ge,be,we,ke];function W(e){return e.normalize("NFKD").replace(/[̀-ͯ]/g,"").replace(/ł/g,"l").replace(/Ł/g,"L").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"module"}const X=e=>{const t=e.find(n=>L.match(n.path));return t?de(t.text,void 0):void 0};function $e(e){const t=e.find(n=>L.match(n.path));return t?j(t.path).replace(/\.manifest\.json$/i,""):"module"}const Y=e=>Array.isArray(e.fields)?e.fields:[],Be={id:"native",kinds:ve,locales:["en","pl","de","fr","es","uk"],requiredLocales:["en"],moduleId:e=>{const t=X(e),n=(t==null?void 0:t.id)??(t==null?void 0:t.packageName);return typeof n=="string"?n:void 0},validateModule:({files:e})=>{const t=X(e);return t?["id","name","version"].filter(n=>typeof t[n]!="string"||!t[n]).map(n=>({severity:"error",code:"manifest.required",message:`The manifest needs "${n}".`,messageKey:"devStudio.issue.manifestRequired",params:{field:n},pointer:`/${n}`})):[{severity:"error",code:"manifest.missing",message:"The module has no manifest.",messageKey:"devStudio.issue.manifestMissing"}]},newFile:(e,{files:t})=>{const n=$e(t),r={entities:["entities.json",{entities:[]}],views:["views.json",{views:[]}],workflows:["workflows.json",{workflows:[]}],dataSources:["datasources.json",{dataSources:[]}],rbac:["rbac.json",{roles:[],actions:[],resources:[],grants:{}}],hooks:["hooks.json",{bindings:[]}]}[e];return r?{path:`${n}.${r[0]}`,text:w(r[1])}:void 0},generateModule:async(e,{existingIds:t})=>{let n=W(e.name);for(let r=2;t.has(n);r++)n=`${W(e.name)}-${r}`;const i=[{path:`${n}.manifest.json`,text:w({id:n,name:e.name,version:"1.0.0",...e.description?{description:e.description}:{},...e.icon?{icon:e.icon}:{},...e.packageId?{category:e.packageId}:{}})},{path:`${n}.entities.json`,text:w({entities:e.entities})}];for(const r of e.locales){const a={"module.displayName":e.name};for(const c of e.entities){const d=String(c.name??"");a[`entity.${d}.displayName`]=d;for(const u of Y(c))a[`field.${d}.${String(u.name)}.label`]=String(u.name)}i.push({path:`${n}.${r}.i18n.json`,text:w({locale:r,translations:a})})}if(e.views){const r=e.entities.map(a=>{const c=String(a.name??"Item");return{id:`${c}List`,name:`${c} list`,kind:"grid",version:2,columns:12,dataSources:[{key:"rows",type:"entity",entity:c,autoLoad:!0}],rows:[{id:"r1",cells:[{id:"grid",controlType:"dataGrid",colSpan:12,props:{columns:Y(a).map(d=>({field:String(d.name),header:String(d.name)}))},bindings:{data:{source:"rows",field:""}}}]}]}});i.push({path:`${n}.views.json`,text:w({views:r})})}if(e.permissions){const r={roles:[{id:"viewer",label:"Viewer"},{id:"editor",label:"Editor"},{id:"admin",label:"Admin"}],actions:[{id:"view",label:"View"},{id:"edit",label:"Edit"},{id:"delete",label:"Delete"}],resources:e.entities.map(a=>({id:`entity:${String(a.name)}`,label:String(a.name),type:"entity"})),grants:{}};i.push({path:`${n}.rbac.json`,text:w(r)})}return{id:n,packageId:e.packageId,files:i}}};exports.arrayFileKind=I;exports.buildDocuments=Pe;exports.createMemoryStudioProvider=Re;exports.defineManifestSection=Ue;exports.deriveDefaultRbac=ze;exports.detectJsonTextFormat=P;exports.encodeDocument=Ve;exports.endsWithAny=v;exports.entitiesToSchemas=_e;exports.fileName=j;exports.fitManifestSection=We;exports.i18nFileKind=ue;exports.itemsFileKind=B;exports.jsonFallbackKind=T;exports.jsonFileKind=V;exports.jsonValueFitsSchema=D;exports.jsonValuesEqual=x;exports.keepTextFormat=ee;exports.manifestSectionKeys=qe;exports.modulePrefix=$e;exports.nativeDataSourcesKind=be;exports.nativeEntitiesKind=pe;exports.nativeFileKinds=ve;exports.nativeHooksKind=ke;exports.nativeI18nKind=me;exports.nativeManifestKind=L;exports.nativeRbacKind=we;exports.nativeStudioPreset=Be;exports.nativeViewsKind=ye;exports.nativeWorkflowsKind=ge;exports.objectFileKind=G;exports.parseJsonText=K;exports.patchJsonText=q;exports.patchJsonTextDetailed=te;exports.readTranslations=fe;exports.resolveFileKind=le;exports.safeJson=de;exports.slugifyModuleId=W;exports.stringifyJsonText=w;exports.textFallbackKind=J;exports.writeTranslations=U;
|
|
10
|
+
`):e;return t.charCodeAt(0)===65279&&n.charCodeAt(0)!==65279&&(n=re+n),n}function x(e,t){if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!="object"||Array.isArray(e)!==Array.isArray(t))return!1;if(Array.isArray(e)){const o=t;return e.length===o.length&&e.every((c,l)=>x(c,o[l]))}const n=e,s=t,i=Object.keys(n);return i.length!==Object.keys(s).length?!1:i.every(o=>Object.prototype.hasOwnProperty.call(s,o)&&x(n[o],s[o]))}function G(e,t,n){return ce(e,t,n).text}function ce(e,t,n){const s=C(e),i=r=>({text:k(t,s),exact:!1,reason:r});let o;try{o=new We(e).parseDocument()}catch(r){return i(r instanceof Error?r.message:String(r))}if(W(o))return i("duplicate keys");const c=[],l={text:e,format:s,edits:c,options:n,compact:!e.trimEnd().includes(`
|
|
11
|
+
`)};Y(l,o,t,"",!1);const u=qe(e,c);try{const r=JSON.parse(s.bom?u.slice(1):u);if(!x(r,t))return i("patch did not read back")}catch{return i("patch was not valid JSON")}return{text:u,exact:!0}}class We{constructor(t){ee(this,"pos",0);this.text=t}parseDocument(){this.text.charCodeAt(0)===65279&&(this.pos=1);const t=this.value();if(this.ws(),this.pos<this.text.length)throw new Error(`Unexpected text at ${this.pos}`);return t}ws(){for(;this.pos<this.text.length&&/\s/.test(this.text[this.pos]);)this.pos++}value(){this.ws();const t=this.text[this.pos];if(t==="{")return this.object();if(t==="[")return this.array();const n=this.pos;if(t==='"')return{kind:"scalar",start:n,end:this.stringEnd(),value:JSON.parse(this.slice(n))};const s=/^(?:-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|true|false|null)/.exec(this.text.slice(n,n+64));if(!s)throw new Error(`Unexpected token at ${n}`);return this.pos=n+s[0].length,{kind:"scalar",start:n,end:this.pos,value:JSON.parse(s[0])}}slice(t){return this.text.slice(t,this.pos)}stringEnd(){for(this.pos++;this.pos<this.text.length;){const t=this.text[this.pos];if(t==="\\"){this.pos+=2;continue}if(this.pos++,t==='"')return this.pos}throw new Error("Unterminated string")}object(){const t=this.pos++,n=[];if(this.ws(),this.text[this.pos]==="}")return{kind:"object",start:t,end:++this.pos,members:n};for(;;){this.ws();const s=this.pos;if(this.text[this.pos]!=='"')throw new Error(`Expected a key at ${this.pos}`);const i=JSON.parse(this.text.slice(s,this.stringEnd()));if(this.ws(),this.text[this.pos]!==":")throw new Error(`Expected ':' at ${this.pos}`);this.pos++,n.push({key:i,start:s,value:this.value()}),this.ws();const o=this.text[this.pos++];if(o==="}")return{kind:"object",start:t,end:this.pos,members:n};if(o!==",")throw new Error(`Expected ',' or '}' at ${this.pos-1}`)}}array(){const t=this.pos++,n=[];if(this.ws(),this.text[this.pos]==="]")return{kind:"array",start:t,end:++this.pos,items:n};for(;;){n.push(this.value()),this.ws();const s=this.text[this.pos++];if(s==="]")return{kind:"array",start:t,end:this.pos,items:n};if(s!==",")throw new Error(`Expected ',' or ']' at ${this.pos-1}`)}}}function W(e){if(e.kind==="object"){const t=new Set;for(const n of e.members){if(t.has(n.key)||W(n.value))return!0;t.add(n.key)}}else if(e.kind==="array")return e.items.some(W);return!1}function L(e){if(e.kind==="scalar")return e.value;if(e.kind==="array")return e.items.map(L);const t={};for(const n of e.members)t[n.key]=L(n.value);return t}function E(e,t,n){if(e===null||typeof e!="object")return e===void 0?"null":JSON.stringify(e);const s=n+t.indent,i=t.colonSpace?": ":":";if(Array.isArray(e))return e.length===0?"[]":`[${t.eol}${e.map(c=>s+E(c,t,s)).join(`,${t.eol}`)}${t.eol}${n}]`;const o=Object.entries(e).filter(([,c])=>c!==void 0);return o.length===0?"{}":`{${t.eol}${o.map(([c,l])=>`${s}${JSON.stringify(c)}${i}${E(l,t,s)}`).join(`,${t.eol}`)}${t.eol}${n}}`}function A(e,t,n=!1){if(e===null||typeof e!="object")return e===void 0?"null":JSON.stringify(e);const s=t.colonSpace?": ":":",i=n?",":", ";if(Array.isArray(e))return`[${e.map(l=>A(l,t,n)).join(i)}]`;const o=Object.entries(e).filter(([,l])=>l!==void 0),c=n?"":" ";return o.length===0?"{}":`{${c}${o.map(([l,u])=>`${JSON.stringify(l)}${s}${A(u,t,n)}`).join(i)}${c}}`}const le=e=>e.compact?",":", ";function qe(e,t){let n=e;for(const s of[...t].sort((i,o)=>o.start-i.start))n=n.slice(0,s.start)+s.text+n.slice(s.end);return n}function J(e,t){var s;const n=e.lastIndexOf(`
|
|
12
|
+
`,t-1)+1;return((s=/^[ \t]*/.exec(e.slice(n,t)))==null?void 0:s[0])??""}function de(e,t){return!e.slice(t.start,t.end).includes(`
|
|
13
|
+
`)}function H(e,t,n){return e.compact?!0:t.kind==="scalar"||(t.kind==="object"?t.members.length===0:t.items.length===0)?n:de(e.text,t)}function I(e,t,n,s){const i=H(e,t,s);e.edits.push({start:t.start,end:t.end,text:i?A(n,e.format,e.compact):E(n,e.format,J(e.text,t.start))})}const fe=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function Y(e,t,n,s,i){if(t.kind==="scalar"){if(t.value===n)return;I(e,t,n,i);return}x(L(t),n)||(t.kind==="object"&&fe(n)?Be(e,t,n,s,i):t.kind==="array"&&Array.isArray(n)?He(e,t,n,s,i):I(e,t,n,i))}function ue(e,t,n){return n!==void 0?J(e.text,n):J(e.text,t.start)+e.format.indent}function Be(e,t,n,s,i){var d;const o=H(e,t,i),c=t.members.filter(f=>Object.prototype.hasOwnProperty.call(n,f.key)&&n[f.key]!==void 0),l=Object.keys(n).filter(f=>n[f]!==void 0&&!t.members.some(h=>h.key===f));if(c.length===0&&t.members.length>0){I(e,t,n,i);return}for(const f of c)Y(e,f.value,n[f.key],`${s}/${Qe(f.key)}`,o);if(pe(e,t.members.map(f=>({start:f.start,end:f.value.end})),t.members.map(f=>c.includes(f))),l.length===0)return;const u=e.format.colonSpace?": ":":";if(o){const f=l.map(h=>`${JSON.stringify(h)}${u}${A(n[h],e.format,e.compact)}`);he(e,t,c.length>0?c[c.length-1].value.end:void 0,f);return}const r=ue(e,t,(d=t.members[0])==null?void 0:d.start),a=l.map(f=>`${r}${JSON.stringify(f)}${u}${E(n[f],e.format,r)}`);me(e,t,c.length>0?c[c.length-1].value.end:void 0,a)}const Xe=["name","id","code","key","slug","state","Id"];function Ge(e,t,n,s){var u,r;const i=[...n,...s];if(i.length===0||!i.every(fe))return;const o=(a,d)=>{const f=a.map(h=>h[d]);return f.every(h=>typeof h=="string"||typeof h=="number")&&new Set(f).size===f.length},c=(r=(u=e.options)==null?void 0:u.arrayKey)==null?void 0:r.call(u,t);return(c?[c]:Xe).find(a=>o(n,a)&&o(s,a))}function He(e,t,n,s,i){var g;const o=H(e,t,i),c=t.items.map(L),l=Ge(e,s,c,n),u=p=>p[l],r=l!==void 0?c.map(p=>{const m=u(p);return n.findIndex(w=>u(w)===m)}):Ze(c,n);{const p=new Set(r.filter(m=>m>=0));for(let m=0;m<r.length;m++){if(r[m]>=0)continue;let w=-1;for(let y=m-1;y>=0;y--)if(r[y]>=0){w=r[y];break}let $=n.length;for(let y=m+1;y<r.length;y++)if(r[y]>=0){$=r[y];break}for(let y=w+1;y<$;y++)if(!p.has(y)){r[m]=y,p.add(y);break}}}const a=r.filter(p=>p>=0);if(a.some((p,m)=>m>0&&p<a[m-1])){I(e,t,n,i);return}if(a.length===0&&t.items.length>0){I(e,t,n,i);return}t.items.forEach((p,m)=>{r[m]>=0&&Y(e,p,n[r[m]],`${s}/${r[m]}`,o)}),pe(e,t.items.map(p=>({start:p.start,end:p.end})),r.map(p=>p>=0));const d=t.items.length>0&&t.items.every(p=>p.kind!=="scalar"&&de(e.text,p)),f=ue(e,t,(g=t.items[0])==null?void 0:g.start),h=new Map;n.forEach((p,m)=>{if(r.includes(m))return;let w;for(let j=t.items.length-1;j>=0;j--)if(r[j]>=0&&r[j]<m){w=j;break}const $=o?A(p,e.format,e.compact):d?`${f}${A(p,e.format)}`:`${f}${E(p,e.format,f)}`,y=h.get(w)??[];y.push($),h.set(w,y)});for(const[p,m]of h){const w=p===void 0?void 0:t.items[p].end;if(p===void 0&&a.length>0){const $=t.items[r.findIndex(j=>j>=0)],y=o?le(e):`,${e.format.eol}`;e.edits.push({start:$.start,end:$.start,text:o?m.join(y)+y:m.join(y).trimStart()+y+f});continue}o?he(e,t,w,m):me(e,t,w,m)}}const Ye=4e6;function Ze(e,t){const n=e.length,s=t.length;if(n*s>Ye)return e.map((a,d)=>d<s?d:-1);const i=e.map(a=>JSON.stringify(a)),o=t.map(a=>JSON.stringify(a)),c=Array.from({length:n+1},()=>new Uint32Array(s+1));for(let a=n-1;a>=0;a--)for(let d=s-1;d>=0;d--)c[a][d]=i[a]===o[d]?c[a+1][d+1]+1:Math.max(c[a+1][d],c[a][d+1]);const l=new Array(n).fill(-1);let u=0,r=0;for(;u<n&&r<s;)i[u]===o[r]?l[u++]=r++:c[u+1][r]>=c[u][r+1]?u++:r++;return l}function pe(e,t,n){for(let s=0;s<t.length;s++){if(n[s])continue;let i=s;for(;i+1<t.length&&!n[i+1];)i++;i+1<t.length?e.edits.push({start:t[s].start,end:t[i+1].start,text:""}):s>0?e.edits.push({start:t[s-1].end,end:t[i].end,text:""}):e.edits.push({start:t[s].start,end:t[i].end,text:""}),s=i}}function me(e,t,n,s){const i=e.format.eol;if(n!==void 0){e.edits.push({start:n,end:n,text:`,${i}${s.join(`,${i}`)}`});return}const o=t.end-1;if((t.kind==="object"?t.members.length:t.items.length)===0)e.edits.push({start:t.start+1,end:o,text:`${i}${s.join(`,${i}`)}${i}${J(e.text,t.start)}`});else{const l=t.kind==="object"?t.members[0].start:t.items[0].start;e.edits.push({start:l,end:l,text:`${s.join(`,${i}`).trimStart()}`})}}function he(e,t,n,s){const i=le(e);if(n!==void 0){e.edits.push({start:n,end:n,text:`${i}${s.join(i)}`});return}const o=t.kind==="object"&&!e.compact?" ":"";e.edits.push({start:t.start+1,end:t.end-1,text:`${o}${s.join(i)}${o}`})}function Qe(e){return e.replace(/~/g,"~0").replace(/\//g,"~1")}const K=e=>e.slice(e.lastIndexOf("/")+1),et=e=>e.charCodeAt(0)===65279?e.slice(1):e;function V(e){return{id:e.id,label:e.label,labelKey:e.labelKey,icon:e.icon,match:e.match,editor:e.editor,decode(t,n){return e.select(O(t[0].text).value,n)},encode(t,n,s){const i=n[0].text,o=O(i).value,c=e.assign(o,t,s);return{files:[{path:n[0].path,text:G(i,c,{arrayKey:e.arrayKey})}]}}}}const P=V({id:"json",label:"JSON",labelKey:"devStudio.kind.json",icon:"code",match:e=>e.toLowerCase().endsWith(".json"),editor:"json",select:e=>e,assign:(e,t)=>t}),D={id:"text",label:"Text",labelKey:"devStudio.kind.text",icon:"file",match:()=>!0,editor:"text",decode:e=>e[0].text,encode:(e,t)=>({files:[{path:t[0].path,text:ae(e,t[0].text)}]})};function ye(e,t){return e.find(n=>n.match(t))??(P.match(t)?P:D)}function tt(e,t,n){for(const s of[P,D])if(s.match(e.path))try{const i=s.decode([e],n);return{key:`${s.id}:${e.path}`,kind:s,paths:[e.path],label:K(e.path),model:i,error:t}}catch{}return{key:`text:${e.path}`,kind:D,paths:[e.path],label:K(e.path),model:e.text,error:t}}function nt(e,t,n,s){var l,u;const i=e.encode(t,n,s),o=new Map(n.map(r=>[r.path,r.text])),c=((l=i.files.find(r=>o.get(r.path)!==r.text))==null?void 0:l.path)??((u=i.deleted)==null?void 0:u.find(r=>o.has(r)));if(c!==void 0)throw new Error(`${K(c)} would not be stored as it is`)}function st(e,t,n){const s=new Map;for(const o of t){const c=ye(e,o.path),l=c.group?c.group(o.path):o.path,u=`${c.id}:${l}`,r=s.get(u)??{kind:c,group:l,files:[]};r.files.push(o),s.set(u,r)}const i=[];for(const[o,{kind:c,group:l,files:u}]of s){const r=u.map(d=>d.path).sort(),a=K(c.group?l:r[0]);try{const d=c.decode(u,n);nt(c,d,u,n),i.push({key:o,kind:c,paths:r,label:a,model:d})}catch(d){const f=d instanceof Error?d.message:String(d);for(const h of u)i.push(tt(h,f,n))}}return i.sort((o,c)=>o.label.localeCompare(c.label))}function it(e,t,n,s){const i=n.filter(u=>e.paths.includes(u.path)),o=e.kind.encode(t,i,s),c=new Map(n.map(u=>[u.path,u])),l=[];for(const u of o.files){const r=c.get(u.path);r&&r.text===u.text||l.push({type:"write",path:u.path,text:u.text,baseVersion:r==null?void 0:r.version})}for(const u of o.deleted??[]){const r=c.get(u);r&&l.push({type:"delete",path:u,baseVersion:r.version})}return l}function ge(e,t){try{return JSON.parse(et(e))}catch{return t}}const v=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),S=(...e)=>t=>{const n=t.toLowerCase();return e.some(s=>n.endsWith(s.toLowerCase()))};function M(e){return V({id:e.id,label:e.label,labelKey:e.labelKey,icon:e.icon,editor:e.editor,match:e.match,select:t=>{if(Array.isArray(t))return t;const n=v(t)?t[e.property]:void 0;return Array.isArray(n)?n:[]},assign:(t,n)=>Array.isArray(t)?n:v(t)&&!(e.property in t)&&n.length===0?t:{...v(t)?t:{},[e.property]:n},arrayKey:e.itemKey?()=>e.itemKey:void 0})}function Z(e){const t=M(e);return{...t,decode:(n,s)=>t.decode(n,s).map((i,o)=>e.toItem(i,o)),encode:(n,s,i)=>t.encode(n.map(o=>e.fromItem(o)),s,i)}}function Q(e){return V({...e,select:t=>v(t)?t:{},assign:(t,n)=>n})}const rt=/^(.*)\.([a-z]{2,3}(?:-[A-Za-z]{2,4})?)\.i18n\.json$/i,ot=e=>{const t=rt.exec(e);return t?{group:t[1],locale:t[2]}:null},q=e=>v(e)&&Object.values(e).every(t=>typeof t=="string");function be(e){if(v(e)){for(const t of["translations","keys"])if(t in e){if(q(e[t]))return e[t];throw new Error(`"${t}" is not a flat map of texts`)}if(q(e))return e}throw new Error("no translations in this file")}function B(e,t){return v(e)?v(e.translations)?{...e,translations:t}:v(e.keys)?{...e,keys:t}:q(e)?t:{...e,translations:t}:{translations:t}}function we(e={}){const t=e.parse??ot,n=e.pathFor??((s,i)=>`${s}.${i}.i18n.json`);return{id:e.id??"i18n",label:e.label??"Translations",labelKey:e.labelKey??"devStudio.kind.i18n",icon:"globe",editor:"i18n",match:s=>t(s)!==null,group:s=>{var i;return((i=t(s))==null?void 0:i.group)??s},decode(s){const i={};for(const o of s){const c=t(o.path);c&&(i[c.locale]={...be(O(o.text).value)})}return i},encode(s,i){const o=new Map;let c="";for(const a of i){const d=t(a.path);d&&(o.set(d.locale,a),c=d.group)}const l=o.get("en")??i[0],u=[];for(const[a,d]of Object.entries(s)){const f=o.get(a);if(f){const g=O(f.text).value;u.push({path:f.path,text:G(f.text,B(g,d))});continue}const h=n(c||K((l==null?void 0:l.path)??"module"),a);if(l){const g=O(l.text).value,p=v(g)&&"locale"in g?{...g,locale:a}:g;u.push({path:h,text:k(B(p,d),C(l.text))})}else u.push({path:h,text:k({locale:a,translations:d})})}const r=[...o.entries()].filter(([a])=>!(a in s)).map(([,a])=>a.path);return{files:u,deleted:r}}}}const F=e=>JSON.parse(JSON.stringify(e));function at(e){const t=e.revisions!==!1;let n=0;const s=e.workspaces.map(r=>({meta:{id:r.id,label:r.label,description:r.description,icon:r.icon,readOnly:r.readOnly},packages:new Map((r.packages??[]).map(a=>[a.id,{...a,workspaceId:r.id}])),modules:new Map(r.modules.map(a=>[a.id,{...a,files:new Map(Object.entries(a.files).map(([d,f])=>[d,{text:f,version:++n}])),revisions:[]}]))}));let i=(e.templates??[]).map(r=>F(r));const o=r=>{const a=s.find(d=>d.meta.id===r);if(!a)throw new Error(`Unknown workspace "${r}"`);return a},c=r=>{const a=o(r.workspaceId).modules.get(r.id);if(!a)throw new Error(`Unknown module "${r.id}"`);return a},l=(r,a)=>({workspaceId:r,id:a.id,packageId:a.packageId,label:a.label??a.id,description:a.description,icon:a.icon,version:a.version,readOnly:a.readOnly||o(r).meta.readOnly,files:[...a.files.keys()].sort()}),u=(r,a)=>({path:r,text:a.text,version:String(a.version)});return{async listWorkspaces(){return s.map(r=>({...r.meta}))},async listModules(r){return[...o(r).modules.values()].map(d=>l(r,d))},async listPackages(r){const a=o(r),d=[...a.packages.values()],f=[...new Set([...a.modules.values()].map(h=>h.packageId).filter(Boolean))].filter(h=>!a.packages.has(h)).map(h=>({id:h,workspaceId:r,label:h,derived:!0}));return[...d,...f]},async readModule(r){return[...c(r).files.entries()].map(([d,f])=>u(d,f))},async writeModule(r,a){const d=c(r);if(d.readOnly||o(r.workspaceId).meta.readOnly)throw new Error(`Module "${r.id}" is read-only`);const f=a.filter(p=>p.baseVersion!==void 0).filter(p=>{const m=d.files.get(p.path);return m?String(m.version)!==p.baseVersion:!1}).map(p=>{var m;return{path:p.path,currentVersion:String((m=d.files.get(p.path))==null?void 0:m.version)}});if(f.length>0)return{ok:!1,conflicts:f};let h;if(t){const p={};for(const[m,w]of d.files)p[m]=w.text;h=`r${++n}`,d.revisions.unshift({id:h,timestamp:Date.now(),label:h,summary:a.map(m=>`${m.type} ${m.path}`).join(", "),files:p})}const g={};for(const p of a)if(p.type==="delete")d.files.delete(p.path);else{const m=++n;d.files.set(p.path,{text:p.text,version:m}),g[p.path]=String(m)}return{ok:!0,versions:g,revision:h}},async createModule(r){const a=o(r.workspaceId);if(a.meta.readOnly)throw new Error(`Workspace "${r.workspaceId}" is read-only`);if(a.modules.has(r.id))throw new Error(`Module "${r.id}" already exists`);const d={id:r.id,packageId:r.packageId,files:new Map(r.files.map(f=>[f.path,{text:f.text,version:++n}])),revisions:[]};return a.modules.set(r.id,d),l(r.workspaceId,d)},async deleteModule(r){const a=o(r.workspaceId);if(a.meta.readOnly)throw new Error(`Workspace "${r.workspaceId}" is read-only`);a.modules.delete(r.id)},async savePackage(r){return o(r.workspaceId).packages.set(r.id,{...r,derived:!1}),{...r,derived:!1}},async deletePackage(r){o(r.workspaceId).packages.delete(r.id)},async listTemplates(){return i.map(r=>F(r))},async saveTemplate(r,a){const d=(a==null?void 0:a.previousId)??r.id,f=F(r),h=i.findIndex(g=>g.id===d);return i=h>=0?i.map((g,p)=>p===h?f:g):[...i,f],F(f)},async deleteTemplate(r){i=i.filter(a=>a.id!==r)},async listRevisions(r,a){return c(r).revisions.filter(d=>!a||a in d.files).map(({files:d,...f})=>({...f,...a?{path:a}:{}}))},async readRevision(r,a,d){const f=c(r).revisions.find(h=>h.id===a);if(!f)throw new Error(`Unknown revision "${a}"`);return d?f.files[d]??"":JSON.stringify(f.files,null,2)},async rollback(r,a,d){const f=c(r),h=f.revisions.find(p=>p.id===a);if(!h)throw new Error(`Unknown revision "${a}"`);const g=d?{[d]:h.files[d]}:h.files;if(!d)for(const p of[...f.files.keys()])p in g||f.files.delete(p);for(const[p,m]of Object.entries(g))m!==void 0&&f.files.set(p,{text:m,version:++n})},snapshot(){return{workspaces:s.map(r=>({...r.meta,packages:[...r.packages.values()].map(({workspaceId:a,...d})=>d),modules:[...r.modules.values()].map(a=>({id:a.id,packageId:a.packageId,label:a.label,description:a.description,icon:a.icon,version:a.version,readOnly:a.readOnly,files:Object.fromEntries([...a.files.entries()].map(([d,f])=>[d,f.text]))}))})),templates:i.map(r=>F(r)),revisions:t}}}}function ct(e){return e}function R(e,t){if(!t||e===void 0||e===null)return!0;if(t.enum&&!t.enum.includes(e))return!1;switch(t.type){case"string":return typeof e=="string";case"number":return typeof e=="number";case"integer":return Number.isInteger(e);case"boolean":return typeof e=="boolean";case"array":return Array.isArray(e)&&(!t.items||e.every(n=>R(n,t.items)));case"object":{if(typeof e!="object"||Array.isArray(e))return!1;const n=t.properties;return!n||Object.entries(e).every(([s,i])=>s in n&&R(i,n[s]))}default:return!0}}function lt(e,t){var c;const n=(e.fields??[]).map(l=>l.name),s=(c=e.schema)==null?void 0:c.properties;if(!e.schema||!s)return{section:e,keys:n};const i=Object.entries(s).filter(([l,u])=>!(l in t)||R(t[l],u)),o=i.map(([l])=>l);return{section:{...e,schema:{...e.schema,properties:Object.fromEntries(i),...e.schema.required?{required:e.schema.required.filter(l=>o.includes(l))}:{}}},keys:[...o,...n]}}function dt(e){var n;const t=new Set;for(const s of e){for(const i of Object.keys(((n=s.schema)==null?void 0:n.properties)??{}))t.add(i);for(const i of s.fields??[])t.add(i.name)}return t}function ft(e){return e.map(t=>{const n=t;return{name:String(n.tableName||n.name||"Entity"),columns:(Array.isArray(n.fields)?n.fields:[]).map(s=>({name:String(s.name??""),dataType:String(s.dataType??s.type??"string"),isPrimaryKey:!!s.isPrimaryKey,isForeignKey:!!(s.isForeignKey??s.foreignKey)}))}})}function ut(e){const t=e.manifest??{},n=String(t.displayName||t.packageName||"Module"),s=(e.views??[]).map(o=>({id:`view:${o.id}`,label:o.name,type:"view"})),i=(e.entities??[]).map(o=>{const c=String(o.name??"Entity");return{id:`entity:${c}`,label:c,type:"entity"}});return{roles:[{id:"admin",label:"Admin"},{id:"user",label:"User"}],actions:[{id:"view",label:"View"},{id:"create",label:"Create"},{id:"edit",label:"Edit"},{id:"delete",label:"Delete"}],resources:[{id:"module",label:n,type:"module",children:[...s.length?[{id:"views",label:"Views",type:"group",children:s}]:[],...i.length?[{id:"entities",label:"Entities",type:"group",children:i}]:[]]}],grants:{}}}const U=Q({id:"manifest",label:"Manifest",labelKey:"devStudio.kind.manifest",icon:"file",editor:"manifest",match:S(".manifest.json")}),ke=M({id:"entities",label:"Entities",labelKey:"devStudio.kind.entities",icon:"database",editor:"entities",match:S(".entities.json"),property:"entities",itemKey:"name"}),ve=we();function Se(e,t){const n=e,s=typeof e=="object"&&e!==null&&typeof n.id=="string";return{key:s?n.id:`#${t}`,label:s&&n.name||(s?n.id:`#${t+1}`),...s?{definition:n}:{rawReason:"no id"},source:e}}const $e=Z({id:"views",label:"Views",labelKey:"devStudio.kind.views",icon:"grid",editor:"views",match:S(".views.json"),property:"views",itemKey:"id",toItem:(e,t)=>Se(e,t),fromItem:e=>e.definition??e.source}),je=Z({id:"workflows",label:"Workflows",labelKey:"devStudio.kind.workflows",icon:"git-branch",editor:"workflows",match:S(".workflows.json"),property:"workflows",itemKey:"id",toItem:(e,t)=>Se(e,t),fromItem:e=>e.definition??e.source}),Ke=M({id:"dataSources",label:"Data sources",labelKey:"devStudio.kind.dataSources",icon:"database",editor:"dataSources",match:S(".datasources.json"),property:"dataSources",itemKey:"key"}),Oe=Q({id:"rbac",label:"Access",labelKey:"devStudio.kind.rbac",icon:"shield",editor:"rbac",match:S(".rbac.json")}),Ee=M({id:"hooks",label:"Lifecycle hooks",labelKey:"devStudio.kind.hooks",icon:"zap",editor:"hooks",match:S(".hooks.json"),property:"bindings",itemKey:"id"}),Ae=[U,ke,ve,$e,je,Ke,Oe,Ee];function X(e){return e.normalize("NFKD").replace(/[̀-ͯ]/g,"").replace(/ł/g,"l").replace(/Ł/g,"L").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"module"}const te=e=>{const t=e.find(n=>U.match(n.path));return t?ge(t.text,void 0):void 0};function Ne(e){const t=e.find(n=>U.match(n.path));return t?K(t.path).replace(/\.manifest\.json$/i,""):"module"}const ne=e=>Array.isArray(e.fields)?e.fields:[],pt={id:"native",kinds:Ae,locales:["en","pl","de","fr","es","uk"],requiredLocales:["en"],moduleId:e=>{const t=te(e),n=(t==null?void 0:t.id)??(t==null?void 0:t.packageName);return typeof n=="string"?n:void 0},validateModule:({files:e})=>{const t=te(e);return t?["id","name","version"].filter(n=>typeof t[n]!="string"||!t[n]).map(n=>({severity:"error",code:"manifest.required",message:`The manifest needs "${n}".`,messageKey:"devStudio.issue.manifestRequired",params:{field:n},pointer:`/${n}`})):[{severity:"error",code:"manifest.missing",message:"The module has no manifest.",messageKey:"devStudio.issue.manifestMissing"}]},newFile:(e,{files:t})=>{const n=Ne(t),i={entities:["entities.json",{entities:[]}],views:["views.json",{views:[]}],workflows:["workflows.json",{workflows:[]}],dataSources:["datasources.json",{dataSources:[]}],rbac:["rbac.json",{roles:[],actions:[],resources:[],grants:{}}],hooks:["hooks.json",{bindings:[]}]}[e];return i?{path:`${n}.${i[0]}`,text:k(i[1])}:void 0},generateModule:async(e,{existingIds:t})=>{let n=X(e.name);for(let i=2;t.has(n);i++)n=`${X(e.name)}-${i}`;const s=[{path:`${n}.manifest.json`,text:k({id:n,name:e.name,version:"1.0.0",...e.description?{description:e.description}:{},...e.icon?{icon:e.icon}:{},...e.packageId?{category:e.packageId}:{}})},{path:`${n}.entities.json`,text:k({entities:e.entities})}];for(const i of e.locales){const o={"module.displayName":e.name};for(const c of e.entities){const l=String(c.name??"");o[`entity.${l}.displayName`]=l;for(const u of ne(c))o[`field.${l}.${String(u.name)}.label`]=String(u.name)}s.push({path:`${n}.${i}.i18n.json`,text:k({locale:i,translations:o})})}if(e.views){const i=e.entities.map(o=>{const c=String(o.name??"Item");return{id:`${c}List`,name:`${c} list`,kind:"grid",version:2,columns:12,dataSources:[{key:"rows",type:"entity",entity:c,autoLoad:!0}],rows:[{id:"r1",cells:[{id:"grid",controlType:"dataGrid",colSpan:12,props:{columns:ne(o).map(l=>({field:String(l.name),header:String(l.name)}))},bindings:{data:{source:"rows",field:""}}}]}]}});s.push({path:`${n}.views.json`,text:k({views:i})})}if(e.permissions){const i={roles:[{id:"viewer",label:"Viewer"},{id:"editor",label:"Editor"},{id:"admin",label:"Admin"}],actions:[{id:"view",label:"View"},{id:"edit",label:"Edit"},{id:"delete",label:"Delete"}],resources:e.entities.map(o=>({id:`entity:${String(o.name)}`,label:String(o.name),type:"entity"})),grants:{}};s.push({path:`${n}.rbac.json`,text:k(i)})}return{id:n,packageId:e.packageId,files:s}}};exports.addStudioFolder=Ce;exports.addStudioSection=Re;exports.arrayFileKind=M;exports.buildDocuments=st;exports.createMemoryStudioProvider=at;exports.defineManifestSection=ct;exports.deriveDefaultRbac=ut;exports.detectJsonTextFormat=C;exports.emptyStudioLayout=T;exports.encodeDocument=it;exports.endsWithAny=S;exports.entitiesToSchemas=ft;exports.fileName=K;exports.fitManifestSection=lt;exports.i18nFileKind=we;exports.isEmptyStudioLayout=Je;exports.isStudioLayoutPath=se;exports.itemsFileKind=Z;exports.jsonFallbackKind=P;exports.jsonFileKind=V;exports.jsonValueFitsSchema=R;exports.jsonValuesEqual=x;exports.keepTextFormat=ae;exports.manifestSectionKeys=dt;exports.modulePrefix=Ne;exports.nativeDataSourcesKind=Ke;exports.nativeEntitiesKind=ke;exports.nativeFileKinds=Ae;exports.nativeHooksKind=Ee;exports.nativeI18nKind=ve;exports.nativeManifestKind=U;exports.nativeRbacKind=Oe;exports.nativeStudioPreset=pt;exports.nativeViewsKind=$e;exports.nativeWorkflowsKind=je;exports.objectFileKind=Q;exports.parseJsonText=O;exports.parseStudioLayout=Le;exports.patchJsonText=G;exports.patchJsonTextDetailed=ce;exports.placeStudioEntry=_e;exports.readTranslations=be;exports.removeStudioLayoutNode=Ue;exports.renameStudioEntryRef=ze;exports.renameStudioLayoutNode=Ve;exports.resolveFileKind=ye;exports.safeJson=ge;exports.serializeStudioLayout=Pe;exports.slugifyModuleId=X;exports.stringifyJsonText=k;exports.studioEntryRef=Ie;exports.studioLayoutPath=Te;exports.textFallbackKind=D;exports.writeTranslations=B;
|
package/dist/studio.d.ts
CHANGED
|
@@ -7,6 +7,18 @@ import { NiceRbacModel } from '@nice2dev/ui';
|
|
|
7
7
|
import { NiceViewDefinition } from '@nice2dev/ui';
|
|
8
8
|
import { NiceWorkflowDefinition } from '@nice2dev/ui';
|
|
9
9
|
|
|
10
|
+
/** The layout with a new folder in `group` (inside `parent` / `section`); returns its id too. */
|
|
11
|
+
export declare function addStudioFolder(layout: NiceStudioLayout, folder: Omit<NiceStudioLayoutFolder, 'id'>): {
|
|
12
|
+
layout: NiceStudioLayout;
|
|
13
|
+
id: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** The layout with a new section; returns the layout and the section's id. */
|
|
17
|
+
export declare function addStudioSection(layout: NiceStudioLayout, label: string): {
|
|
18
|
+
layout: NiceStudioLayout;
|
|
19
|
+
id: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
10
22
|
/** A file holding one array, either bare or under `property`; the rest of the file is kept. */
|
|
11
23
|
export declare function arrayFileKind<T>(o: NiceArrayFileKindOptions): NiceStudioFileKind<T[]>;
|
|
12
24
|
|
|
@@ -40,6 +52,9 @@ export declare function deriveDefaultRbac(module: {
|
|
|
40
52
|
/** Reads how `text` is written: BOM, line breaks, indentation, final newline, colon spacing. */
|
|
41
53
|
export declare function detectJsonTextFormat(text: string): NiceJsonTextFormat;
|
|
42
54
|
|
|
55
|
+
/** An empty layout: no sections, no folders — the flat tree. */
|
|
56
|
+
export declare const emptyStudioLayout: () => NiceStudioLayout;
|
|
57
|
+
|
|
43
58
|
/**
|
|
44
59
|
* The file changes that store a document's new model: only files whose text differs from what
|
|
45
60
|
* was read, plus files the encoder adds or removes.
|
|
@@ -137,6 +152,12 @@ declare interface FormFieldValidation {
|
|
|
137
152
|
*/
|
|
138
153
|
export declare function i18nFileKind(o?: NiceI18nFileKindOptions): NiceStudioFileKind<NiceStudioTranslations>;
|
|
139
154
|
|
|
155
|
+
/** Whether a layout holds nothing (its file can go). */
|
|
156
|
+
export declare const isEmptyStudioLayout: (layout: NiceStudioLayout) => boolean;
|
|
157
|
+
|
|
158
|
+
/** Whether a path is a module's layout file. */
|
|
159
|
+
export declare const isStudioLayoutPath: (path: string) => boolean;
|
|
160
|
+
|
|
140
161
|
/**
|
|
141
162
|
* A file holding a list of entries edited one at a time (views, workflows). Entries the editor
|
|
142
163
|
* does not understand stay raw and round-trip as they are.
|
|
@@ -381,6 +402,9 @@ export declare interface NiceObjectFileKindOptions {
|
|
|
381
402
|
match(path: string): boolean;
|
|
382
403
|
}
|
|
383
404
|
|
|
405
|
+
/** The studio's own editors. */
|
|
406
|
+
export declare type NiceStudioBuiltinEditorId = 'manifest' | 'entities' | 'i18n' | 'views' | 'workflows' | 'permissions' | 'rbac' | 'dataSources' | 'seeds' | 'hooks' | 'script' | 'json' | 'text';
|
|
407
|
+
|
|
384
408
|
/** What a file kind's decode and encode know about the module. */
|
|
385
409
|
export declare interface NiceStudioCodecContext {
|
|
386
410
|
moduleId: string;
|
|
@@ -402,8 +426,11 @@ export declare interface NiceStudioDocument<M = unknown> {
|
|
|
402
426
|
error?: string;
|
|
403
427
|
}
|
|
404
428
|
|
|
405
|
-
/**
|
|
406
|
-
|
|
429
|
+
/**
|
|
430
|
+
* The editors a file kind can open in: a built-in one, or the id of an editor the host registers
|
|
431
|
+
* (1.4.5 — the union was closed; an unknown id opens as raw JSON / text until one is registered).
|
|
432
|
+
*/
|
|
433
|
+
export declare type NiceStudioEditorId = NiceStudioBuiltinEditorId | (string & {});
|
|
407
434
|
|
|
408
435
|
/** New and removed files of an encoded document. */
|
|
409
436
|
export declare interface NiceStudioEncoded {
|
|
@@ -463,6 +490,11 @@ export declare interface NiceStudioFileKind<M = unknown> {
|
|
|
463
490
|
/** The document a file belongs to (files with the same group open together). Default: the path. */
|
|
464
491
|
group?(path: string): string;
|
|
465
492
|
editor: NiceStudioEditorId;
|
|
493
|
+
/**
|
|
494
|
+
* The tree group its documents are listed under (1.4.5): one of the preset's `groups`, or a
|
|
495
|
+
* built-in group id. Default: the built-in group of its editor (none for raw JSON / text).
|
|
496
|
+
*/
|
|
497
|
+
treeGroup?: string;
|
|
466
498
|
/** The files of one document → the editor's model. Throwing opens the files as raw JSON / text. */
|
|
467
499
|
decode(files: readonly NiceStudioFile[], ctx: NiceStudioCodecContext): M;
|
|
468
500
|
/** The model → the document's files (only their text; unchanged files may be returned as they were). */
|
|
@@ -479,6 +511,20 @@ export declare interface NiceStudioGeneratedModule {
|
|
|
479
511
|
}>;
|
|
480
512
|
}
|
|
481
513
|
|
|
514
|
+
/**
|
|
515
|
+
* A group of the tree a preset adds (1.4.5): its documents — of the kinds whose `treeGroup` names
|
|
516
|
+
* it — are listed one per row under it, like scripts.
|
|
517
|
+
*/
|
|
518
|
+
export declare interface NiceStudioGroupDef {
|
|
519
|
+
id: string;
|
|
520
|
+
label: string;
|
|
521
|
+
labelKey?: string;
|
|
522
|
+
/** NiceIcon name. */
|
|
523
|
+
icon?: string;
|
|
524
|
+
/** Where it goes among the groups (the built-in ones are 10, 20, … 100). Default: after them. */
|
|
525
|
+
order?: number;
|
|
526
|
+
}
|
|
527
|
+
|
|
482
528
|
/** A problem found in a module. */
|
|
483
529
|
export declare interface NiceStudioIssue {
|
|
484
530
|
severity: 'error' | 'warning' | 'info';
|
|
@@ -512,6 +558,40 @@ export declare interface NiceStudioItem<D> {
|
|
|
512
558
|
rawReason?: string;
|
|
513
559
|
}
|
|
514
560
|
|
|
561
|
+
/** The layout of a module — the content of its `{prefix}.studio.json`. */
|
|
562
|
+
export declare interface NiceStudioLayout {
|
|
563
|
+
version: 1;
|
|
564
|
+
sections: NiceStudioLayoutSection[];
|
|
565
|
+
folders: NiceStudioLayoutFolder[];
|
|
566
|
+
/** By entry ref, `group:key` — `entities:Customer`, `views:customer-list`. */
|
|
567
|
+
placement: Record<string, NiceStudioLayoutPlacement>;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/** A folder inside one group of a module (entities, views…), optionally nested and in a section. */
|
|
571
|
+
export declare interface NiceStudioLayoutFolder {
|
|
572
|
+
id: string;
|
|
573
|
+
label: string;
|
|
574
|
+
/** The group it belongs to: `entities`, `views`, `workflows`, a preset's own group… */
|
|
575
|
+
group: string;
|
|
576
|
+
/** The folder it sits in. */
|
|
577
|
+
parent?: string;
|
|
578
|
+
/** The section it sits in (absent: the module's own groups). */
|
|
579
|
+
section?: string;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/** Where one entry sits: a section, a folder, an order among its siblings. */
|
|
583
|
+
export declare interface NiceStudioLayoutPlacement {
|
|
584
|
+
section?: string;
|
|
585
|
+
folder?: string;
|
|
586
|
+
order?: number;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/** A section of a module: a band of the tree that holds groups (Sales, Warehouse…). */
|
|
590
|
+
export declare interface NiceStudioLayoutSection {
|
|
591
|
+
id: string;
|
|
592
|
+
label: string;
|
|
593
|
+
}
|
|
594
|
+
|
|
515
595
|
/** What validators and generators get. */
|
|
516
596
|
export declare interface NiceStudioModuleContext {
|
|
517
597
|
key: NiceStudioModuleKey;
|
|
@@ -579,6 +659,11 @@ export declare interface NiceStudioPackage {
|
|
|
579
659
|
/** Computed from the modules (e.g. their `category`) rather than stored: it cannot be edited. */
|
|
580
660
|
derived?: boolean;
|
|
581
661
|
readOnly?: boolean;
|
|
662
|
+
/**
|
|
663
|
+
* The package it sits in (1.4.5): packages nest in the tree. An id with `/` (`Finance/Banking`, an
|
|
664
|
+
* OmniVerk category path) nests under the part before its last `/` without it.
|
|
665
|
+
*/
|
|
666
|
+
parentId?: string;
|
|
582
667
|
}
|
|
583
668
|
|
|
584
669
|
/** The model of the `permissions` editor: permission codes and the groups (roles) granting them. */
|
|
@@ -604,6 +689,8 @@ export declare interface NiceStudioPreset {
|
|
|
604
689
|
id: string;
|
|
605
690
|
/** Tried in order; a path no kind matches opens as raw JSON (`*.json`) or text. */
|
|
606
691
|
kinds: NiceStudioFileKind[];
|
|
692
|
+
/** Groups of the tree the preset adds to the built-in ones (1.4.5). */
|
|
693
|
+
groups?: NiceStudioGroupDef[];
|
|
607
694
|
/** The manifest's sections, each a form over part of the manifest. */
|
|
608
695
|
manifestSections?: NiceManifestSection[];
|
|
609
696
|
entities?: NiceStudioEntityOptions;
|
|
@@ -767,6 +854,12 @@ export declare function parseJsonText(text: string): {
|
|
|
767
854
|
format: NiceJsonTextFormat;
|
|
768
855
|
};
|
|
769
856
|
|
|
857
|
+
/**
|
|
858
|
+
* A layout from its file's text — what it can read of it: unknown fields and broken entries are
|
|
859
|
+
* dropped, a text that does not parse gives the empty layout.
|
|
860
|
+
*/
|
|
861
|
+
export declare function parseStudioLayout(text: string | undefined): NiceStudioLayout;
|
|
862
|
+
|
|
770
863
|
/**
|
|
771
864
|
* `previous` with its content replaced by `next`, changing as few bytes as possible. Falls back
|
|
772
865
|
* to {@link stringifyJsonText} in the file's own format when the text cannot be patched (invalid
|
|
@@ -777,9 +870,36 @@ export declare function patchJsonText(previous: string, next: unknown, options?:
|
|
|
777
870
|
/** {@link patchJsonText}, also telling whether the patch was exact. */
|
|
778
871
|
export declare function patchJsonTextDetailed(previous: string, next: unknown, options?: NiceJsonPatchOptions): NiceJsonPatchResult;
|
|
779
872
|
|
|
873
|
+
/**
|
|
874
|
+
* The layout with an entry put somewhere: into a folder (its section follows the folder's), into a
|
|
875
|
+
* section (out of any folder), or back to its group (`{}`).
|
|
876
|
+
*/
|
|
877
|
+
export declare function placeStudioEntry(layout: NiceStudioLayout, ref: string, target: {
|
|
878
|
+
folder?: string;
|
|
879
|
+
section?: string;
|
|
880
|
+
}): NiceStudioLayout;
|
|
881
|
+
|
|
780
882
|
/** The translations inside a file: `translations`, `keys`, or the whole file when it is a flat map. */
|
|
781
883
|
export declare function readTranslations(root: unknown): Record<string, string>;
|
|
782
884
|
|
|
885
|
+
/**
|
|
886
|
+
* The layout without a section or folder. What it held moves up: a folder's entries and folders go
|
|
887
|
+
* to its parent (or the group), a section's folders and entries back to the module's own groups.
|
|
888
|
+
*/
|
|
889
|
+
export declare function removeStudioLayoutNode(layout: NiceStudioLayout, node: {
|
|
890
|
+
kind: 'section' | 'folder';
|
|
891
|
+
id: string;
|
|
892
|
+
}): NiceStudioLayout;
|
|
893
|
+
|
|
894
|
+
/** The layout after an entry was renamed — its placement follows it (`entities:Old` → `entities:New`). */
|
|
895
|
+
export declare function renameStudioEntryRef(layout: NiceStudioLayout, from: string, to: string): NiceStudioLayout;
|
|
896
|
+
|
|
897
|
+
/** The layout with a section or folder renamed. */
|
|
898
|
+
export declare function renameStudioLayoutNode(layout: NiceStudioLayout, node: {
|
|
899
|
+
kind: 'section' | 'folder';
|
|
900
|
+
id: string;
|
|
901
|
+
}, label: string): NiceStudioLayout;
|
|
902
|
+
|
|
783
903
|
/** The kind a path opens with: the first that matches, else JSON or text. */
|
|
784
904
|
export declare function resolveFileKind(kinds: readonly NiceStudioFileKind[], path: string): NiceStudioFileKind;
|
|
785
905
|
|
|
@@ -790,12 +910,24 @@ declare type Row_2 = Record<string, unknown>;
|
|
|
790
910
|
/** Parses JSON without a BOM and returns `fallback` when the text is not JSON. */
|
|
791
911
|
export declare function safeJson<T = unknown>(text: string, fallback: T): T;
|
|
792
912
|
|
|
913
|
+
/** A layout's file text: two-space JSON with a final newline, in the line ending of `previous`. */
|
|
914
|
+
export declare function serializeStudioLayout(layout: NiceStudioLayout, previous?: string): string;
|
|
915
|
+
|
|
793
916
|
/** A file-name-safe id out of a display name: "Bike rental" → `bike-rental`. */
|
|
794
917
|
export declare function slugifyModuleId(name: string): string;
|
|
795
918
|
|
|
796
919
|
/** Writes `value` in a given format (defaults: two spaces, LF, final newline, no BOM). */
|
|
797
920
|
export declare function stringifyJsonText(value: unknown, format?: Partial<NiceJsonTextFormat>): string;
|
|
798
921
|
|
|
922
|
+
/** The ref of an entry in a layout: `group:key`. */
|
|
923
|
+
export declare const studioEntryRef: (group: string, key: string) => string;
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* The path of a module's layout file: the one it has, else `{prefix}.studio.json` after the prefix
|
|
927
|
+
* of its files, else `module.studio.json`.
|
|
928
|
+
*/
|
|
929
|
+
export declare function studioLayoutPath(files: readonly NiceStudioFile[]): string;
|
|
930
|
+
|
|
799
931
|
/** Any other file, edited as text. */
|
|
800
932
|
export declare const textFallbackKind: NiceStudioFileKind<string>;
|
|
801
933
|
|