@nice2dev/ui-forms 1.4.4 → 1.4.6
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 +8 -6
- package/dist/index.d.ts +283 -8
- package/dist/index.mjs +3938 -2784
- package/dist/studio.cjs +23 -7
- package/dist/studio.d.ts +277 -8
- package/dist/studio.mjs +928 -575
- package/dist/ui-forms.css +1 -1
- package/package.json +5 -5
package/dist/studio.cjs
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
|
|
1
|
+
"use strict";var qe=Object.defineProperty;var Ve=(e,t,n)=>t in e?qe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var se=(e,t,n)=>Ve(e,typeof t!="symbol"?t+"":t,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=()=>({version:1,sections:[],folders:[],placement:{}}),ze=(e,t)=>`${e}:${t}`,W=".studio.json",We=/^([^/]+?)\.(manifest|entities|views|workflows|permissions|rbac|seeds|datasources|scripts)\.json$/i,ae=e=>!e.includes("/")&&e.toLowerCase().endsWith(W);function Be(e){const t=e.find(n=>ae(n.path));if(t)return t.path;for(const n of e){const s=We.exec(n.path);if(s)return`${s[1]}${W}`}return`module${W}`}const N=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),b=e=>typeof e=="string"&&e?e:void 0;function He(e){if(!e)return M();let t;try{t=JSON.parse(e.replace(/^\uFEFF/,""))}catch{return M()}if(!N(t))return M();const n=(Array.isArray(t.sections)?t.sections:[]).filter(N).map(r=>({id:b(r.id),label:b(r.label)??b(r.id)})).filter(r=>!!r.id&&!!r.label),s=(Array.isArray(t.folders)?t.folders:[]).filter(N).map(r=>({id:b(r.id),label:b(r.label)??b(r.id),group:b(r.group),...b(r.parent)?{parent:b(r.parent)}:{},...b(r.section)?{section:b(r.section)}:{}})).filter(r=>!!r.id&&!!r.label&&!!r.group),i={};if(N(t.placement))for(const[r,a]of Object.entries(t.placement)){if(!N(a))continue;const l={};b(a.section)&&(l.section=b(a.section)),b(a.folder)&&(l.folder=b(a.folder)),typeof a.order=="number"&&Number.isFinite(a.order)&&(l.order=a.order),(l.section||l.folder||l.order!==void 0)&&(i[r]=l)}return{version:1,sections:n,folders:s,placement:i}}const Xe=e=>e.sections.length===0&&e.folders.length===0&&Object.keys(e.placement).length===0;function Ze(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 Ge=e=>e.toLowerCase().normalize("NFKD").replace(/[̀-ͯ]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"item";function ce(e,t){const n=Ge(e);let s=n;for(let i=2;t.has(s);i++)s=`${n}-${i}`;return s}function Ye(e,t){const n=ce(t,new Set(e.sections.map(s=>s.id)));return{layout:{...e,sections:[...e.sections,{id:n,label:t}]},id:n}}function Qe(e,t){const n=ce(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 et(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 tt(e,t){const n={};if(t.kind==="folder"){const s=e.folders.find(i=>i.id===t.id);for(const[i,r]of Object.entries(e.placement))n[i]=r.folder===t.id?{...r,folder:s==null?void 0:s.parent}:r,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:r,...a}=i;return a}return i}),placement:B(n)}}for(const[s,i]of Object.entries(e.placement))if(i.section===t.id){const{section:r,...a}=i;n[s]=a}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,...r}=s;return r}return s}),placement:B(n)}}function B(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 nt(e,t,n){var r;const s=(r=e.placement[t])==null?void 0:r.order,i={};if(n.folder){i.folder=n.folder;const a=e.folders.find(l=>l.id===n.folder);a!=null&&a.section&&(i.section=a.section)}else n.section&&(i.section=n.section);return s!==void 0&&(i.order=s),{...e,placement:B({...e.placement,[t]:i})}}function st(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 le="\uFEFF",de={bom:!1,eol:`
|
|
5
|
+
`,indent:" ",finalNewline:!0,colonSpace:!0};function q(e){const t=e.charCodeAt(0)===65279,n=e.includes(`\r
|
|
3
6
|
`)?`\r
|
|
4
7
|
`:`
|
|
5
|
-
`;let
|
|
8
|
+
`;let s=de.indent;const i=e.split(/\r?\n/);for(let a=1;a<i.length;a++){const l=/^([ \t]+)\S/.exec(i[a]);if(l){s=l[1];break}}const r=/"\s*:(\s?)/.exec(e);return{bom:t,eol:n,indent:s,finalNewline:/\n$/.test(e),colonSpace:r?r[1]!=="":!0}}function A(e){const t=q(e);return{value:JSON.parse(t.bom?e.slice(1):e),format:t}}function S(e,t){const n={...de,...t},s=E(e,n,"");return(n.bom?le:"")+s+(n.finalNewline?n.eol:"")}function fe(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=le+n),n}function F(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 r=t;return e.length===r.length&&e.every((a,l)=>F(a,r[l]))}const n=e,s=t,i=Object.keys(n);return i.length!==Object.keys(s).length?!1:i.every(r=>Object.prototype.hasOwnProperty.call(s,r)&&F(n[r],s[r]))}function Y(e,t,n){return ue(e,t,n).text}function ue(e,t,n){const s=q(e),i=o=>({text:S(t,s),exact:!1,reason:o});let r;try{r=new it(e).parseDocument()}catch(o){return i(o instanceof Error?o.message:String(o))}if(H(r))return i("duplicate keys");const a=[],l={text:e,format:s,edits:a,options:n,compact:!e.trimEnd().includes(`
|
|
11
|
+
`)};ee(l,r,t,"",!1);const f=rt(e,a);try{const o=JSON.parse(s.bom?f.slice(1):f);if(!F(o,t))return i("patch did not read back")}catch{return i("patch was not valid JSON")}return{text:f,exact:!0}}class it{constructor(t){se(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 r=this.text[this.pos++];if(r==="}")return{kind:"object",start:t,end:this.pos,members:n};if(r!==",")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 H(e){if(e.kind==="object"){const t=new Set;for(const n of e.members){if(t.has(n.key)||H(n.value))return!0;t.add(n.key)}}else if(e.kind==="array")return e.items.some(H);return!1}function P(e){if(e.kind==="scalar")return e.value;if(e.kind==="array")return e.items.map(P);const t={};for(const n of e.members)t[n.key]=P(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(a=>s+E(a,t,s)).join(`,${t.eol}`)}${t.eol}${n}]`;const r=Object.entries(e).filter(([,a])=>a!==void 0);return r.length===0?"{}":`{${t.eol}${r.map(([a,l])=>`${s}${JSON.stringify(a)}${i}${E(l,t,s)}`).join(`,${t.eol}`)}${t.eol}${n}}`}function I(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=>I(l,t,n)).join(i)}]`;const r=Object.entries(e).filter(([,l])=>l!==void 0),a=n?"":" ";return r.length===0?"{}":`{${a}${r.map(([l,f])=>`${JSON.stringify(l)}${s}${I(f,t,n)}`).join(i)}${a}}`}const pe=e=>e.compact?",":", ";function rt(e,t){let n=e;for(const s of[...t].sort((i,r)=>r.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 me(e,t){return!e.slice(t.start,t.end).includes(`
|
|
13
|
+
`)}function Q(e,t,n){return e.compact?!0:t.kind==="scalar"||(t.kind==="object"?t.members.length===0:t.items.length===0)?n:me(e.text,t)}function x(e,t,n,s){const i=Q(e,t,s);e.edits.push({start:t.start,end:t.end,text:i?I(n,e.format,e.compact):E(n,e.format,J(e.text,t.start))})}const ye=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function ee(e,t,n,s,i){if(t.kind==="scalar"){if(t.value===n)return;x(e,t,n,i);return}F(P(t),n)||(t.kind==="object"&&ye(n)?ot(e,t,n,s,i):t.kind==="array"&&Array.isArray(n)?lt(e,t,n,s,i):x(e,t,n,i))}function he(e,t,n){return n!==void 0?J(e.text,n):J(e.text,t.start)+e.format.indent}function ot(e,t,n,s,i){var d;const r=Q(e,t,i),a=t.members.filter(u=>Object.prototype.hasOwnProperty.call(n,u.key)&&n[u.key]!==void 0),l=Object.keys(n).filter(u=>n[u]!==void 0&&!t.members.some(y=>y.key===u));if(a.length===0&&t.members.length>0){x(e,t,n,i);return}for(const u of a)ee(e,u.value,n[u.key],`${s}/${ut(u.key)}`,r);if(ge(e,t.members.map(u=>({start:u.start,end:u.value.end})),t.members.map(u=>a.includes(u))),l.length===0)return;const f=e.format.colonSpace?": ":":";if(r){const u=l.map(y=>`${JSON.stringify(y)}${f}${I(n[y],e.format,e.compact)}`);ke(e,t,a.length>0?a[a.length-1].value.end:void 0,u);return}const o=he(e,t,(d=t.members[0])==null?void 0:d.start),c=l.map(u=>`${o}${JSON.stringify(u)}${f}${E(n[u],e.format,o)}`);be(e,t,a.length>0?a[a.length-1].value.end:void 0,c)}const at=["name","id","code","key","slug","state","Id"];function ct(e,t,n,s){var f,o;const i=[...n,...s];if(i.length===0||!i.every(ye))return;const r=(c,d)=>{const u=c.map(y=>y[d]);return u.every(y=>typeof y=="string"||typeof y=="number")&&new Set(u).size===u.length},a=(o=(f=e.options)==null?void 0:f.arrayKey)==null?void 0:o.call(f,t);return(a?[a]:at).find(c=>r(n,c)&&r(s,c))}function lt(e,t,n,s,i){var g;const r=Q(e,t,i),a=t.items.map(P),l=ct(e,s,a,n),f=p=>p[l],o=l!==void 0?a.map(p=>{const m=f(p);return n.findIndex(k=>f(k)===m)}):ft(a,n);{const p=new Set(o.filter(m=>m>=0));for(let m=0;m<o.length;m++){if(o[m]>=0)continue;let k=-1;for(let h=m-1;h>=0;h--)if(o[h]>=0){k=o[h];break}let j=n.length;for(let h=m+1;h<o.length;h++)if(o[h]>=0){j=o[h];break}for(let h=k+1;h<j;h++)if(!p.has(h)){o[m]=h,p.add(h);break}}}const c=o.filter(p=>p>=0);if(c.some((p,m)=>m>0&&p<c[m-1])){x(e,t,n,i);return}if(c.length===0&&t.items.length>0){x(e,t,n,i);return}t.items.forEach((p,m)=>{o[m]>=0&&ee(e,p,n[o[m]],`${s}/${o[m]}`,r)}),ge(e,t.items.map(p=>({start:p.start,end:p.end})),o.map(p=>p>=0));const d=t.items.length>0&&t.items.every(p=>p.kind!=="scalar"&&me(e.text,p)),u=he(e,t,(g=t.items[0])==null?void 0:g.start),y=new Map;n.forEach((p,m)=>{if(o.includes(m))return;let k;for(let K=t.items.length-1;K>=0;K--)if(o[K]>=0&&o[K]<m){k=K;break}const j=r?I(p,e.format,e.compact):d?`${u}${I(p,e.format)}`:`${u}${E(p,e.format,u)}`,h=y.get(k)??[];h.push(j),y.set(k,h)});for(const[p,m]of y){const k=p===void 0?void 0:t.items[p].end;if(p===void 0&&c.length>0){const j=t.items[o.findIndex(K=>K>=0)],h=r?pe(e):`,${e.format.eol}`;e.edits.push({start:j.start,end:j.start,text:r?m.join(h)+h:m.join(h).trimStart()+h+u});continue}r?ke(e,t,k,m):be(e,t,k,m)}}const dt=4e6;function ft(e,t){const n=e.length,s=t.length;if(n*s>dt)return e.map((c,d)=>d<s?d:-1);const i=e.map(c=>JSON.stringify(c)),r=t.map(c=>JSON.stringify(c)),a=Array.from({length:n+1},()=>new Uint32Array(s+1));for(let c=n-1;c>=0;c--)for(let d=s-1;d>=0;d--)a[c][d]=i[c]===r[d]?a[c+1][d+1]+1:Math.max(a[c+1][d],a[c][d+1]);const l=new Array(n).fill(-1);let f=0,o=0;for(;f<n&&o<s;)i[f]===r[o]?l[f++]=o++:a[f+1][o]>=a[f][o+1]?f++:o++;return l}function ge(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 be(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 r=t.end-1;if((t.kind==="object"?t.members.length:t.items.length)===0)e.edits.push({start:t.start+1,end:r,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 ke(e,t,n,s){const i=pe(e);if(n!==void 0){e.edits.push({start:n,end:n,text:`${i}${s.join(i)}`});return}const r=t.kind==="object"&&!e.compact?" ":"";e.edits.push({start:t.start+1,end:t.end-1,text:`${r}${s.join(i)}${r}`})}function ut(e){return e.replace(/~/g,"~0").replace(/\//g,"~1")}const O=e=>e.slice(e.lastIndexOf("/")+1),pt=e=>e.charCodeAt(0)===65279?e.slice(1):e;function L(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(A(t[0].text).value,n)},encode(t,n,s){const i=n[0].text,r=A(i).value,a=e.assign(r,t,s);return{files:[{path:n[0].path,text:Y(i,a,{arrayKey:e.arrayKey})}]}}}}const D=L({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}),_={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:fe(e,t[0].text)}]})};function Se(e,t){return e.find(n=>n.match(t))??(D.match(t)?D:_)}function mt(e,t,n){for(const s of[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:O(e.path),model:i,error:t}}catch{}return{key:`text:${e.path}`,kind:_,paths:[e.path],label:O(e.path),model:e.text,error:t}}function yt(e,t,n,s){var l,f;const i=e.encode(t,n,s),r=new Map(n.map(o=>[o.path,o.text])),a=((l=i.files.find(o=>r.get(o.path)!==o.text))==null?void 0:l.path)??((f=i.deleted)==null?void 0:f.find(o=>r.has(o)));if(a!==void 0)throw new Error(`${O(a)} would not be stored as it is`)}function ht(e,t,n){const s=new Map;for(const r of t){const a=Se(e,r.path),l=a.group?a.group(r.path):r.path,f=`${a.id}:${l}`,o=s.get(f)??{kind:a,group:l,files:[]};o.files.push(r),s.set(f,o)}const i=[];for(const[r,{kind:a,group:l,files:f}]of s){const o=f.map(d=>d.path).sort(),c=O(a.group?l:o[0]);try{const d=a.decode(f,n);yt(a,d,f,n),i.push({key:r,kind:a,paths:o,label:c,model:d})}catch(d){const u=d instanceof Error?d.message:String(d);for(const y of f)i.push(mt(y,u,n))}}return i.sort((r,a)=>r.label.localeCompare(a.label))}function gt(e,t,n,s){const i=n.filter(f=>e.paths.includes(f.path)),r=e.kind.encode(t,i,s),a=new Map(n.map(f=>[f.path,f])),l=[];for(const f of r.files){const o=a.get(f.path);o&&o.text===f.text||l.push({type:"write",path:f.path,text:f.text,baseVersion:o==null?void 0:o.version})}for(const f of r.deleted??[]){const o=a.get(f);o&&l.push({type:"delete",path:f,baseVersion:o.version})}return l}function ve(e,t){try{return JSON.parse(pt(e))}catch{return t}}const v=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),w=(...e)=>t=>{const n=t.toLowerCase();return e.some(s=>n.endsWith(s.toLowerCase()))};function C(e){return L({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 te(e){const t=C(e);return{...t,decode:(n,s)=>t.decode(n,s).map((i,r)=>e.toItem(i,r)),encode:(n,s,i)=>t.encode(n.map(r=>e.fromItem(r)),s,i)}}function ne(e){return L({...e,select:t=>v(t)?t:{},assign:(t,n)=>n})}const bt=/^(.*)\.([a-z]{2,3}(?:-[A-Za-z]{2,4})?)\.i18n\.json$/i,kt=e=>{const t=bt.exec(e);return t?{group:t[1],locale:t[2]}:null},X=e=>v(e)&&Object.values(e).every(t=>typeof t=="string");function we(e){if(v(e)){for(const t of["translations","keys"])if(t in e){if(X(e[t]))return e[t];throw new Error(`"${t}" is not a flat map of texts`)}if(X(e))return e}throw new Error("no translations in this file")}function Z(e,t){return v(e)?v(e.translations)?{...e,translations:t}:v(e.keys)?{...e,keys:t}:X(e)?t:{...e,translations:t}:{translations:t}}function $e(e={}){const t=e.parse??kt,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 r of s){const a=t(r.path);a&&(i[a.locale]={...we(A(r.text).value)})}return i},encode(s,i){const r=new Map;let a="";for(const c of i){const d=t(c.path);d&&(r.set(d.locale,c),a=d.group)}const l=r.get("en")??i[0],f=[];for(const[c,d]of Object.entries(s)){const u=r.get(c);if(u){const g=A(u.text).value;f.push({path:u.path,text:Y(u.text,Z(g,d))});continue}const y=n(a||O((l==null?void 0:l.path)??"module"),c);if(l){const g=A(l.text).value,p=v(g)&&"locale"in g?{...g,locale:c}:g;f.push({path:y,text:S(Z(p,d),q(l.text))})}else f.push({path:y,text:S({locale:c,translations:d})})}const o=[...r.entries()].filter(([c])=>!(c in s)).map(([,c])=>c.path);return{files:f,deleted:o}}}}const $=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),je=["frontend","backend","noCode","sql"],St=["preInstall","postInstall","preUninstall","postUninstall"];function Ke(e){switch(e){case"frontend":return["typescript","javascript"];case"backend":return["csharp","javascript"];case"sql":return["sql"];case"noCode":return[]}}const vt=new Set(["read","filter","map","aggregate","set","if","forEach","write","callScript","return"]),Oe=e=>Array.isArray(e)&&e.every(t=>$(t)&&typeof t.id=="string"&&vt.has(String(t.type)));function R(e){if(je.includes(e.kind))return e.kind;if(e.source===void 0&&Oe(e.steps))return"noCode";const t=typeof e.language=="string"?e.language.toLowerCase():"";return t.endsWith("sql")||e.source===void 0&&typeof e.sql=="string"?"sql":/^(csharp|c#|cs\b)/.test(t)?"backend":"frontend"}const Ae=["id","displayName","description","language","category","trigger","returnType","source","sourcePath"],wt=e=>Array.isArray(e)&&e.every(t=>$(t)&&typeof t.name=="string");function Ee(e,t){const n=`#${t+1}`;if(!$(e)||typeof e.name!="string"||!e.name){const l=$(e)&&typeof e.displayName=="string"?e.displayName:n;return{key:`#${t}`,label:l,rawReason:"no name",source:e}}const s=e.name,i=typeof e.displayName=="string"&&e.displayName?e.displayName:s,r=l=>({key:s,label:i,rawReason:l,source:e}),a={name:s,kind:R(e)};for(const l of Ae){const f=e[l];if(f!==void 0){if(typeof f!="string")return r(`"${l}" is not text`);a[l]=f}}if(e.parameters!==void 0){if(!wt(e.parameters))return r('"parameters" is not a list of named parameters');a.parameters=e.parameters}if(a.kind==="noCode"){if(e.steps!==void 0&&!Oe(e.steps))return r('"steps" are not no-code steps');a.steps=e.steps??[]}return{key:s,label:i,definition:a,source:e}}function Ie(e){const t=e.definition;if(!t)return e.source;const n=$(e.source)?e.source:{},s={...n,name:t.name};for(const i of Ae)t[i]===void 0?delete s[i]:s[i]=t[i];return t.parameters===void 0?delete s.parameters:s.parameters=t.parameters,t.kind==="noCode"?s.steps=t.steps??[]:R(n)==="noCode"&&delete s.steps,delete s.kind,("kind"in n||R(s)!==t.kind)&&(s.kind=t.kind),s}function z(e){const t=new Set;return e.map((n,s)=>{const i=Ee(n,s);return t.has(i.key)&&(i.key=`${i.key}#${s}`),t.add(i.key),i})}function ie(e,t){if(!$(e)||!Object.values(e).every(n=>Array.isArray(n)&&n.every(s=>typeof s=="string")))throw new Error(`"${t}" is not lists of SQL statements per phase`);return e}function Ne(e){const t=e.property??"scripts",n=e.phasesProperty??"phases",s=t===n,i=r=>r.scripts.map(Ie);return L({id:e.id??"scripts",label:e.label??"Scripts",labelKey:e.labelKey??"devStudio.kind.scripts",icon:e.icon??"code",editor:"scriptList",match:e.match,select:r=>{if(Array.isArray(r))return{scripts:z(r),...s?{holds:"scripts"}:{}};if(!$(r)||r[t]===void 0&&r[n]===void 0)throw new Error(`no "${t}" in this file`);const a=r[t];if(s)return Array.isArray(a)?{scripts:z(a),holds:"scripts"}:{scripts:[],phases:ie(a,t),holds:"phases"};if(a!==void 0&&!Array.isArray(a))throw new Error(`"${t}" is not a list`);const l=r[n];return{scripts:z(a??[]),...l!==void 0?{phases:ie(l,n)}:{}}},assign:(r,a)=>{if(a.holds==="phases"&&a.scripts.length>0)throw new Error("This file holds database scripts only; add scripts to another file.");if(Array.isArray(r)&&a.phases===void 0)return i(a);const l=$(r)?r:{};if(s)return{...l,[t]:a.holds==="phases"?a.phases??{}:i(a)};const f={...l};return(t in l||a.scripts.length>0)&&(f[t]=i(a)),a.phases===void 0?delete f[n]:f[n]=a.phases,f},arrayKey:r=>r===`/${t}`?"name":void 0})}function Te(e){const n=e.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").split(/[^A-Za-z0-9]+/).filter(Boolean).map((s,i)=>i===0?s[0].toLowerCase()+s.slice(1):s[0].toUpperCase()+s.slice(1)).join("");return/^[A-Za-z_]/.test(n)?n:`script${n}`}function $t(e){const t=Te(e.name),n=e.language??Ke(e.kind)[0],s={name:t,kind:e.kind,...e.name!==t?{displayName:e.name}:{},...n?{language:n}:{},...e.category?{category:e.category}:{},...e.trigger?{trigger:e.trigger}:{},parameters:[]},i=t[0].toUpperCase()+t.slice(1);switch(e.kind){case"noCode":return{...s,steps:[]};case"sql":return{...s,source:`-- ${e.name}
|
|
14
|
+
SELECT 1;
|
|
15
|
+
`};case"backend":return{...s,returnType:"object",source:n==="csharp"?`public static object ${i}(IDictionary<string, object> args)
|
|
16
|
+
{
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
`:`function ${t}(args) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
`};case"frontend":return{...s,returnType:"void",source:n==="typescript"?`export function ${t}(): void {
|
|
23
|
+
}
|
|
24
|
+
`:`export function ${t}() {
|
|
25
|
+
}
|
|
26
|
+
`}}}const T=e=>JSON.parse(JSON.stringify(e));function jt(e){const t=e.revisions!==!1;let n=0;const s=e.workspaces.map(o=>({meta:{id:o.id,label:o.label,description:o.description,icon:o.icon,readOnly:o.readOnly},packages:new Map((o.packages??[]).map(c=>[c.id,{...c,workspaceId:o.id}])),modules:new Map(o.modules.map(c=>[c.id,{...c,files:new Map(Object.entries(c.files).map(([d,u])=>[d,{text:u,version:++n}])),revisions:[]}]))}));let i=(e.templates??[]).map(o=>T(o));const r=o=>{const c=s.find(d=>d.meta.id===o);if(!c)throw new Error(`Unknown workspace "${o}"`);return c},a=o=>{const c=r(o.workspaceId).modules.get(o.id);if(!c)throw new Error(`Unknown module "${o.id}"`);return c},l=(o,c)=>({workspaceId:o,id:c.id,packageId:c.packageId,label:c.label??c.id,description:c.description,icon:c.icon,version:c.version,readOnly:c.readOnly||r(o).meta.readOnly,files:[...c.files.keys()].sort()}),f=(o,c)=>({path:o,text:c.text,version:String(c.version)});return{async listWorkspaces(){return s.map(o=>({...o.meta}))},async listModules(o){return[...r(o).modules.values()].map(d=>l(o,d))},async listPackages(o){const c=r(o),d=[...c.packages.values()],u=[...new Set([...c.modules.values()].map(y=>y.packageId).filter(Boolean))].filter(y=>!c.packages.has(y)).map(y=>({id:y,workspaceId:o,label:y,derived:!0}));return[...d,...u]},async readModule(o){return[...a(o).files.entries()].map(([d,u])=>f(d,u))},async writeModule(o,c){const d=a(o);if(d.readOnly||r(o.workspaceId).meta.readOnly)throw new Error(`Module "${o.id}" is read-only`);const u=c.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(u.length>0)return{ok:!1,conflicts:u};let y;if(t){const p={};for(const[m,k]of d.files)p[m]=k.text;y=`r${++n}`,d.revisions.unshift({id:y,timestamp:Date.now(),label:y,summary:c.map(m=>`${m.type} ${m.path}`).join(", "),files:p})}const g={};for(const p of c)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:y}},async createModule(o){const c=r(o.workspaceId);if(c.meta.readOnly)throw new Error(`Workspace "${o.workspaceId}" is read-only`);if(c.modules.has(o.id))throw new Error(`Module "${o.id}" already exists`);const d={id:o.id,packageId:o.packageId,files:new Map(o.files.map(u=>[u.path,{text:u.text,version:++n}])),revisions:[]};return c.modules.set(o.id,d),l(o.workspaceId,d)},async deleteModule(o){const c=r(o.workspaceId);if(c.meta.readOnly)throw new Error(`Workspace "${o.workspaceId}" is read-only`);c.modules.delete(o.id)},async savePackage(o){return r(o.workspaceId).packages.set(o.id,{...o,derived:!1}),{...o,derived:!1}},async deletePackage(o){r(o.workspaceId).packages.delete(o.id)},async listTemplates(){return i.map(o=>T(o))},async saveTemplate(o,c){const d=(c==null?void 0:c.previousId)??o.id,u=T(o),y=i.findIndex(g=>g.id===d);return i=y>=0?i.map((g,p)=>p===y?u:g):[...i,u],T(u)},async deleteTemplate(o){i=i.filter(c=>c.id!==o)},async listRevisions(o,c){return a(o).revisions.filter(d=>!c||c in d.files).map(({files:d,...u})=>({...u,...c?{path:c}:{}}))},async readRevision(o,c,d){const u=a(o).revisions.find(y=>y.id===c);if(!u)throw new Error(`Unknown revision "${c}"`);return d?u.files[d]??"":JSON.stringify(u.files,null,2)},async rollback(o,c,d){const u=a(o),y=u.revisions.find(p=>p.id===c);if(!y)throw new Error(`Unknown revision "${c}"`);const g=d?{[d]:y.files[d]}:y.files;if(!d)for(const p of[...u.files.keys()])p in g||u.files.delete(p);for(const[p,m]of Object.entries(g))m!==void 0&&u.files.set(p,{text:m,version:++n})},snapshot(){return{workspaces:s.map(o=>({...o.meta,packages:[...o.packages.values()].map(({workspaceId:c,...d})=>d),modules:[...o.modules.values()].map(c=>({id:c.id,packageId:c.packageId,label:c.label,description:c.description,icon:c.icon,version:c.version,readOnly:c.readOnly,files:Object.fromEntries([...c.files.entries()].map(([d,u])=>[d,u.text]))}))})),templates:i.map(o=>T(o)),revisions:t}}}}function Kt(e){return e}function U(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=>U(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&&U(i,n[s]))}default:return!0}}function Ot(e,t){var a;const n=(e.fields??[]).map(l=>l.name),s=(a=e.schema)==null?void 0:a.properties;if(!e.schema||!s)return{section:e,keys:n};const i=Object.entries(s).filter(([l,f])=>!(l in t)||U(t[l],f)),r=i.map(([l])=>l);return{section:{...e,schema:{...e.schema,properties:Object.fromEntries(i),...e.schema.required?{required:e.schema.required.filter(l=>r.includes(l))}:{}}},keys:[...r,...n]}}function At(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 Et(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 It(e){const t=e.manifest??{},n=String(t.displayName||t.packageName||"Module"),s=(e.views??[]).map(r=>({id:`view:${r.id}`,label:r.name,type:"view"})),i=(e.entities??[]).map(r=>{const a=String(r.name??"Entity");return{id:`entity:${a}`,label:a,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 V=ne({id:"manifest",label:"Manifest",labelKey:"devStudio.kind.manifest",icon:"file",editor:"manifest",match:w(".manifest.json")}),Fe=C({id:"entities",label:"Entities",labelKey:"devStudio.kind.entities",icon:"database",editor:"entities",match:w(".entities.json"),property:"entities",itemKey:"name"}),xe=$e();function Le(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 Ce=te({id:"views",label:"Views",labelKey:"devStudio.kind.views",icon:"grid",editor:"views",match:w(".views.json"),property:"views",itemKey:"id",toItem:(e,t)=>Le(e,t),fromItem:e=>e.definition??e.source}),Me=te({id:"workflows",label:"Workflows",labelKey:"devStudio.kind.workflows",icon:"git-branch",editor:"workflows",match:w(".workflows.json"),property:"workflows",itemKey:"id",toItem:(e,t)=>Le(e,t),fromItem:e=>e.definition??e.source}),Pe=C({id:"dataSources",label:"Data sources",labelKey:"devStudio.kind.dataSources",icon:"database",editor:"dataSources",match:w(".datasources.json"),property:"dataSources",itemKey:"key"}),Je=ne({id:"rbac",label:"Access",labelKey:"devStudio.kind.rbac",icon:"shield",editor:"rbac",match:w(".rbac.json")}),De=C({id:"hooks",label:"Lifecycle hooks",labelKey:"devStudio.kind.hooks",icon:"zap",editor:"hooks",match:w(".hooks.json"),property:"bindings",itemKey:"id"}),_e=Ne({match:w(".scripts.json")}),Re=[V,Fe,xe,Ce,Me,Pe,Je,De,_e];function G(e){return e.normalize("NFKD").replace(/[̀-ͯ]/g,"").replace(/ł/g,"l").replace(/Ł/g,"L").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"module"}const re=e=>{const t=e.find(n=>V.match(n.path));return t?ve(t.text,void 0):void 0};function Ue(e){const t=e.find(n=>V.match(n.path));return t?O(t.path).replace(/\.manifest\.json$/i,""):"module"}const oe=e=>Array.isArray(e.fields)?e.fields:[],Nt={id:"native",kinds:Re,locales:["en","pl","de","fr","es","uk"],requiredLocales:["en"],moduleId:e=>{const t=re(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=re(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=Ue(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:[]}],scripts:["scripts.json",{scripts:[]}]}[e];return i?{path:`${n}.${i[0]}`,text:S(i[1])}:void 0},generateModule:async(e,{existingIds:t})=>{let n=G(e.name);for(let i=2;t.has(n);i++)n=`${G(e.name)}-${i}`;const s=[{path:`${n}.manifest.json`,text:S({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:S({entities:e.entities})}];for(const i of e.locales){const r={"module.displayName":e.name};for(const a of e.entities){const l=String(a.name??"");r[`entity.${l}.displayName`]=l;for(const f of oe(a))r[`field.${l}.${String(f.name)}.label`]=String(f.name)}s.push({path:`${n}.${i}.i18n.json`,text:S({locale:i,translations:r})})}if(e.views){const i=e.entities.map(r=>{const a=String(r.name??"Item");return{id:`${a}List`,name:`${a} list`,kind:"grid",version:2,columns:12,dataSources:[{key:"rows",type:"entity",entity:a,autoLoad:!0}],rows:[{id:"r1",cells:[{id:"grid",controlType:"dataGrid",colSpan:12,props:{columns:oe(r).map(l=>({field:String(l.name),header:String(l.name)}))},bindings:{data:{source:"rows",field:""}}}]}]}});s.push({path:`${n}.views.json`,text:S({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(r=>({id:`entity:${String(r.name)}`,label:String(r.name),type:"entity"})),grants:{}};s.push({path:`${n}.rbac.json`,text:S(i)})}return{id:n,packageId:e.packageId,files:s}}};exports.NICE_STUDIO_SCRIPT_KINDS=je;exports.NICE_STUDIO_SCRIPT_PHASES=St;exports.addStudioFolder=Qe;exports.addStudioSection=Ye;exports.arrayFileKind=C;exports.buildDocuments=ht;exports.createMemoryStudioProvider=jt;exports.defineManifestSection=Kt;exports.deriveDefaultRbac=It;exports.detectJsonTextFormat=q;exports.emptyStudioLayout=M;exports.encodeDocument=gt;exports.endsWithAny=w;exports.entitiesToSchemas=Et;exports.fileName=O;exports.fitManifestSection=Ot;exports.fromStudioScriptItem=Ie;exports.i18nFileKind=$e;exports.inferStudioScriptKind=R;exports.isEmptyStudioLayout=Xe;exports.isStudioLayoutPath=ae;exports.itemsFileKind=te;exports.jsonFallbackKind=D;exports.jsonFileKind=L;exports.jsonValueFitsSchema=U;exports.jsonValuesEqual=F;exports.keepTextFormat=fe;exports.manifestSectionKeys=At;exports.modulePrefix=Ue;exports.nativeDataSourcesKind=Pe;exports.nativeEntitiesKind=Fe;exports.nativeFileKinds=Re;exports.nativeHooksKind=De;exports.nativeI18nKind=xe;exports.nativeManifestKind=V;exports.nativeRbacKind=Je;exports.nativeScriptsKind=_e;exports.nativeStudioPreset=Nt;exports.nativeViewsKind=Ce;exports.nativeWorkflowsKind=Me;exports.newStudioScript=$t;exports.objectFileKind=ne;exports.parseJsonText=A;exports.parseStudioLayout=He;exports.patchJsonText=Y;exports.patchJsonTextDetailed=ue;exports.placeStudioEntry=nt;exports.readTranslations=we;exports.removeStudioLayoutNode=tt;exports.renameStudioEntryRef=st;exports.renameStudioLayoutNode=et;exports.resolveFileKind=Se;exports.safeJson=ve;exports.scriptsFileKind=Ne;exports.serializeStudioLayout=Ze;exports.slugifyModuleId=G;exports.stringifyJsonText=S;exports.studioEntryRef=ze;exports.studioLayoutPath=Be;exports.studioScriptIdentifier=Te;exports.studioScriptLanguages=Ke;exports.textFallbackKind=_;exports.toStudioScriptItem=Ee;exports.writeTranslations=Z;
|
package/dist/studio.d.ts
CHANGED
|
@@ -3,10 +3,23 @@ import { NiceDataSourceDef } from '@nice2dev/ui';
|
|
|
3
3
|
import { NiceDataSourceSchemaTable } from '@nice2dev/ui';
|
|
4
4
|
import { NiceFormItem } from '@nice2dev/ui';
|
|
5
5
|
import { NiceHookBinding } from '@nice2dev/ui';
|
|
6
|
+
import { NiceNoCodeStep } from '@nice2dev/ui';
|
|
6
7
|
import { NiceRbacModel } from '@nice2dev/ui';
|
|
7
8
|
import { NiceViewDefinition } from '@nice2dev/ui';
|
|
8
9
|
import { NiceWorkflowDefinition } from '@nice2dev/ui';
|
|
9
10
|
|
|
11
|
+
/** The layout with a new folder in `group` (inside `parent` / `section`); returns its id too. */
|
|
12
|
+
export declare function addStudioFolder(layout: NiceStudioLayout, folder: Omit<NiceStudioLayoutFolder, 'id'>): {
|
|
13
|
+
layout: NiceStudioLayout;
|
|
14
|
+
id: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** The layout with a new section; returns the layout and the section's id. */
|
|
18
|
+
export declare function addStudioSection(layout: NiceStudioLayout, label: string): {
|
|
19
|
+
layout: NiceStudioLayout;
|
|
20
|
+
id: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
10
23
|
/** A file holding one array, either bare or under `property`; the rest of the file is kept. */
|
|
11
24
|
export declare function arrayFileKind<T>(o: NiceArrayFileKindOptions): NiceStudioFileKind<T[]>;
|
|
12
25
|
|
|
@@ -29,17 +42,20 @@ export declare function defineManifestSection<TSchema extends JsonSchema>(sectio
|
|
|
29
42
|
|
|
30
43
|
/** A starter access model: admin / user × view / create / edit / delete over the module's views and entities. */
|
|
31
44
|
export declare function deriveDefaultRbac(module: {
|
|
32
|
-
manifest?:
|
|
45
|
+
manifest?: Row_2;
|
|
33
46
|
views?: ReadonlyArray<{
|
|
34
47
|
id: string;
|
|
35
48
|
name: string;
|
|
36
49
|
}>;
|
|
37
|
-
entities?: readonly
|
|
50
|
+
entities?: readonly Row_2[];
|
|
38
51
|
}): NiceRbacModel;
|
|
39
52
|
|
|
40
53
|
/** Reads how `text` is written: BOM, line breaks, indentation, final newline, colon spacing. */
|
|
41
54
|
export declare function detectJsonTextFormat(text: string): NiceJsonTextFormat;
|
|
42
55
|
|
|
56
|
+
/** An empty layout: no sections, no folders — the flat tree. */
|
|
57
|
+
export declare const emptyStudioLayout: () => NiceStudioLayout;
|
|
58
|
+
|
|
43
59
|
/**
|
|
44
60
|
* The file changes that store a document's new model: only files whose text differs from what
|
|
45
61
|
* was read, plus files the encoder adds or removes.
|
|
@@ -50,7 +66,7 @@ export declare function encodeDocument(doc: NiceStudioDocument, model: unknown,
|
|
|
50
66
|
export declare const endsWithAny: (...suffixes: string[]) => (path: string) => boolean;
|
|
51
67
|
|
|
52
68
|
/** The module's entities as the tables NiceDataSourceBuilder queries. */
|
|
53
|
-
export declare function entitiesToSchemas(entities: readonly
|
|
69
|
+
export declare function entitiesToSchemas(entities: readonly Row_2[]): NiceDataSourceSchemaTable[];
|
|
54
70
|
|
|
55
71
|
/** The file name of a path. */
|
|
56
72
|
export declare const fileName: (path: string) => string;
|
|
@@ -131,12 +147,27 @@ declare interface FormFieldValidation {
|
|
|
131
147
|
message?: string;
|
|
132
148
|
}
|
|
133
149
|
|
|
150
|
+
/** A list item back as the stored script: its definition merged onto the entry as stored. */
|
|
151
|
+
export declare function fromStudioScriptItem(item: NiceStudioItem<NiceStudioScriptDef>): unknown;
|
|
152
|
+
|
|
134
153
|
/**
|
|
135
154
|
* Translations split into one file per language, edited as one document. A new language gets a
|
|
136
155
|
* file shaped and formatted like its siblings; a language removed in the editor loses its file.
|
|
137
156
|
*/
|
|
138
157
|
export declare function i18nFileKind(o?: NiceI18nFileKindOptions): NiceStudioFileKind<NiceStudioTranslations>;
|
|
139
158
|
|
|
159
|
+
/**
|
|
160
|
+
* The kind of a stored script: its `kind`, else from what it holds — no-code steps, a SQL language
|
|
161
|
+
* or `sql` text, a C# language (server) — else browser code.
|
|
162
|
+
*/
|
|
163
|
+
export declare function inferStudioScriptKind(raw: Row): NiceStudioScriptKind;
|
|
164
|
+
|
|
165
|
+
/** Whether a layout holds nothing (its file can go). */
|
|
166
|
+
export declare const isEmptyStudioLayout: (layout: NiceStudioLayout) => boolean;
|
|
167
|
+
|
|
168
|
+
/** Whether a path is a module's layout file. */
|
|
169
|
+
export declare const isStudioLayoutPath: (path: string) => boolean;
|
|
170
|
+
|
|
140
171
|
/**
|
|
141
172
|
* A file holding a list of entries edited one at a time (views, workflows). Entries the editor
|
|
142
173
|
* does not understand stay raw and round-trip as they are.
|
|
@@ -198,7 +229,7 @@ export declare function modulePrefix(files: readonly NiceStudioFile[]): string;
|
|
|
198
229
|
|
|
199
230
|
export declare const nativeDataSourcesKind: NiceStudioFileKind<NiceDataSourceDef[]>;
|
|
200
231
|
|
|
201
|
-
export declare const nativeEntitiesKind: NiceStudioFileKind<
|
|
232
|
+
export declare const nativeEntitiesKind: NiceStudioFileKind<Row_3[]>;
|
|
202
233
|
|
|
203
234
|
/** The file kinds of the native format, in matching order. */
|
|
204
235
|
export declare const nativeFileKinds: NiceStudioFileKind[];
|
|
@@ -207,17 +238,29 @@ export declare const nativeHooksKind: NiceStudioFileKind<NiceHookBinding[]>;
|
|
|
207
238
|
|
|
208
239
|
export declare const nativeI18nKind: NiceStudioFileKind<NiceStudioTranslations>;
|
|
209
240
|
|
|
210
|
-
export declare const nativeManifestKind: NiceStudioFileKind<
|
|
241
|
+
export declare const nativeManifestKind: NiceStudioFileKind<Row_3>;
|
|
211
242
|
|
|
212
243
|
export declare const nativeRbacKind: NiceStudioFileKind<NiceRbacModel>;
|
|
213
244
|
|
|
214
|
-
/**
|
|
245
|
+
/** `{id}.scripts.json`: `{ scripts: [...], phases: { postInstall: [...] } }` (1.4.6). */
|
|
246
|
+
export declare const nativeScriptsKind: NiceStudioFileKind<NiceStudioScripts>;
|
|
247
|
+
|
|
248
|
+
/** The studio's own format: manifest, entities, translations, views, workflows, data sources, access, hooks, scripts. */
|
|
215
249
|
export declare const nativeStudioPreset: NiceStudioPreset;
|
|
216
250
|
|
|
217
251
|
export declare const nativeViewsKind: NiceStudioFileKind<NiceStudioItem<NiceViewDefinition>[]>;
|
|
218
252
|
|
|
219
253
|
export declare const nativeWorkflowsKind: NiceStudioFileKind<NiceStudioItem<NiceWorkflowDefinition>[]>;
|
|
220
254
|
|
|
255
|
+
/** A new script of a kind, with a starting body in its language. */
|
|
256
|
+
export declare function newStudioScript(spec: NiceStudioNewScript): NiceStudioScriptDef;
|
|
257
|
+
|
|
258
|
+
/** The script kinds, in the order "Add script" offers them. */
|
|
259
|
+
export declare const NICE_STUDIO_SCRIPT_KINDS: readonly NiceStudioScriptKind[];
|
|
260
|
+
|
|
261
|
+
/** Install phases offered for database scripts when the preset names none. */
|
|
262
|
+
export declare const NICE_STUDIO_SCRIPT_PHASES: readonly string[];
|
|
263
|
+
|
|
221
264
|
/** Options of {@link arrayFileKind}. */
|
|
222
265
|
export declare interface NiceArrayFileKindOptions {
|
|
223
266
|
id: string;
|
|
@@ -381,6 +424,27 @@ export declare interface NiceObjectFileKindOptions {
|
|
|
381
424
|
match(path: string): boolean;
|
|
382
425
|
}
|
|
383
426
|
|
|
427
|
+
/** Options of {@link scriptsFileKind}. */
|
|
428
|
+
export declare interface NiceScriptsFileKindOptions {
|
|
429
|
+
id?: string;
|
|
430
|
+
label?: string;
|
|
431
|
+
labelKey?: string;
|
|
432
|
+
icon?: string;
|
|
433
|
+
match(path: string): boolean;
|
|
434
|
+
/** The property holding the scripts list. Default `scripts`; the file may also be the bare list. */
|
|
435
|
+
property?: string;
|
|
436
|
+
/**
|
|
437
|
+
* The property holding the database scripts per phase. Default `phases`. The same as `property`:
|
|
438
|
+
* that property holds either — a list of scripts or an object of phases (OmniVerk).
|
|
439
|
+
*/
|
|
440
|
+
phasesProperty?: string;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/** The studio's own editors. */
|
|
444
|
+
export declare type NiceStudioBuiltinEditorId = 'manifest' | 'entities' | 'i18n' | 'views' | 'workflows' | 'permissions' | 'rbac' | 'dataSources' | 'seeds' | 'hooks' | 'script'
|
|
445
|
+
/** A list of named scripts and database scripts per phase ({@link NiceStudioScripts}, 1.4.6). */
|
|
446
|
+
| 'scriptList' | 'json' | 'text';
|
|
447
|
+
|
|
384
448
|
/** What a file kind's decode and encode know about the module. */
|
|
385
449
|
export declare interface NiceStudioCodecContext {
|
|
386
450
|
moduleId: string;
|
|
@@ -402,8 +466,11 @@ export declare interface NiceStudioDocument<M = unknown> {
|
|
|
402
466
|
error?: string;
|
|
403
467
|
}
|
|
404
468
|
|
|
405
|
-
/**
|
|
406
|
-
|
|
469
|
+
/**
|
|
470
|
+
* The editors a file kind can open in: a built-in one, or the id of an editor the host registers
|
|
471
|
+
* (1.4.5 — the union was closed; an unknown id opens as raw JSON / text until one is registered).
|
|
472
|
+
*/
|
|
473
|
+
export declare type NiceStudioEditorId = NiceStudioBuiltinEditorId | (string & {});
|
|
407
474
|
|
|
408
475
|
/** New and removed files of an encoded document. */
|
|
409
476
|
export declare interface NiceStudioEncoded {
|
|
@@ -463,6 +530,11 @@ export declare interface NiceStudioFileKind<M = unknown> {
|
|
|
463
530
|
/** The document a file belongs to (files with the same group open together). Default: the path. */
|
|
464
531
|
group?(path: string): string;
|
|
465
532
|
editor: NiceStudioEditorId;
|
|
533
|
+
/**
|
|
534
|
+
* The tree group its documents are listed under (1.4.5): one of the preset's `groups`, or a
|
|
535
|
+
* built-in group id. Default: the built-in group of its editor (none for raw JSON / text).
|
|
536
|
+
*/
|
|
537
|
+
treeGroup?: string;
|
|
466
538
|
/** The files of one document → the editor's model. Throwing opens the files as raw JSON / text. */
|
|
467
539
|
decode(files: readonly NiceStudioFile[], ctx: NiceStudioCodecContext): M;
|
|
468
540
|
/** The model → the document's files (only their text; unchanged files may be returned as they were). */
|
|
@@ -479,6 +551,20 @@ export declare interface NiceStudioGeneratedModule {
|
|
|
479
551
|
}>;
|
|
480
552
|
}
|
|
481
553
|
|
|
554
|
+
/**
|
|
555
|
+
* A group of the tree a preset adds (1.4.5): its documents — of the kinds whose `treeGroup` names
|
|
556
|
+
* it — are listed one per row under it, like scripts.
|
|
557
|
+
*/
|
|
558
|
+
export declare interface NiceStudioGroupDef {
|
|
559
|
+
id: string;
|
|
560
|
+
label: string;
|
|
561
|
+
labelKey?: string;
|
|
562
|
+
/** NiceIcon name. */
|
|
563
|
+
icon?: string;
|
|
564
|
+
/** Where it goes among the groups (the built-in ones are 10, 20, … 100). Default: after them. */
|
|
565
|
+
order?: number;
|
|
566
|
+
}
|
|
567
|
+
|
|
482
568
|
/** A problem found in a module. */
|
|
483
569
|
export declare interface NiceStudioIssue {
|
|
484
570
|
severity: 'error' | 'warning' | 'info';
|
|
@@ -512,6 +598,40 @@ export declare interface NiceStudioItem<D> {
|
|
|
512
598
|
rawReason?: string;
|
|
513
599
|
}
|
|
514
600
|
|
|
601
|
+
/** The layout of a module — the content of its `{prefix}.studio.json`. */
|
|
602
|
+
export declare interface NiceStudioLayout {
|
|
603
|
+
version: 1;
|
|
604
|
+
sections: NiceStudioLayoutSection[];
|
|
605
|
+
folders: NiceStudioLayoutFolder[];
|
|
606
|
+
/** By entry ref, `group:key` — `entities:Customer`, `views:customer-list`. */
|
|
607
|
+
placement: Record<string, NiceStudioLayoutPlacement>;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/** A folder inside one group of a module (entities, views…), optionally nested and in a section. */
|
|
611
|
+
export declare interface NiceStudioLayoutFolder {
|
|
612
|
+
id: string;
|
|
613
|
+
label: string;
|
|
614
|
+
/** The group it belongs to: `entities`, `views`, `workflows`, a preset's own group… */
|
|
615
|
+
group: string;
|
|
616
|
+
/** The folder it sits in. */
|
|
617
|
+
parent?: string;
|
|
618
|
+
/** The section it sits in (absent: the module's own groups). */
|
|
619
|
+
section?: string;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/** Where one entry sits: a section, a folder, an order among its siblings. */
|
|
623
|
+
export declare interface NiceStudioLayoutPlacement {
|
|
624
|
+
section?: string;
|
|
625
|
+
folder?: string;
|
|
626
|
+
order?: number;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/** A section of a module: a band of the tree that holds groups (Sales, Warehouse…). */
|
|
630
|
+
export declare interface NiceStudioLayoutSection {
|
|
631
|
+
id: string;
|
|
632
|
+
label: string;
|
|
633
|
+
}
|
|
634
|
+
|
|
515
635
|
/** What validators and generators get. */
|
|
516
636
|
export declare interface NiceStudioModuleContext {
|
|
517
637
|
key: NiceStudioModuleKey;
|
|
@@ -569,6 +689,16 @@ export declare interface NiceStudioModuleSpec {
|
|
|
569
689
|
permissions?: boolean;
|
|
570
690
|
}
|
|
571
691
|
|
|
692
|
+
/** What "Add script" asks for. */
|
|
693
|
+
export declare interface NiceStudioNewScript {
|
|
694
|
+
kind: NiceStudioScriptKind;
|
|
695
|
+
/** The display name; the script's `name` is made from it. */
|
|
696
|
+
name: string;
|
|
697
|
+
language?: string;
|
|
698
|
+
category?: string;
|
|
699
|
+
trigger?: string;
|
|
700
|
+
}
|
|
701
|
+
|
|
572
702
|
/** A group of modules in a workspace (a category, a product line). */
|
|
573
703
|
export declare interface NiceStudioPackage {
|
|
574
704
|
id: string;
|
|
@@ -579,6 +709,11 @@ export declare interface NiceStudioPackage {
|
|
|
579
709
|
/** Computed from the modules (e.g. their `category`) rather than stored: it cannot be edited. */
|
|
580
710
|
derived?: boolean;
|
|
581
711
|
readOnly?: boolean;
|
|
712
|
+
/**
|
|
713
|
+
* The package it sits in (1.4.5): packages nest in the tree. An id with `/` (`Finance/Banking`, an
|
|
714
|
+
* OmniVerk category path) nests under the part before its last `/` without it.
|
|
715
|
+
*/
|
|
716
|
+
parentId?: string;
|
|
582
717
|
}
|
|
583
718
|
|
|
584
719
|
/** The model of the `permissions` editor: permission codes and the groups (roles) granting them. */
|
|
@@ -604,6 +739,8 @@ export declare interface NiceStudioPreset {
|
|
|
604
739
|
id: string;
|
|
605
740
|
/** Tried in order; a path no kind matches opens as raw JSON (`*.json`) or text. */
|
|
606
741
|
kinds: NiceStudioFileKind[];
|
|
742
|
+
/** Groups of the tree the preset adds to the built-in ones (1.4.5). */
|
|
743
|
+
groups?: NiceStudioGroupDef[];
|
|
607
744
|
/** The manifest's sections, each a form over part of the manifest. */
|
|
608
745
|
manifestSections?: NiceManifestSection[];
|
|
609
746
|
entities?: NiceStudioEntityOptions;
|
|
@@ -627,6 +764,8 @@ export declare interface NiceStudioPreset {
|
|
|
627
764
|
path: string;
|
|
628
765
|
text: string;
|
|
629
766
|
} | undefined;
|
|
767
|
+
/** Kinds, categories, triggers and phases of the module's scripts (1.4.6). */
|
|
768
|
+
scripts?: NiceStudioScriptOptions;
|
|
630
769
|
/** Lifecycle triggers offered by a `hooks` document. */
|
|
631
770
|
hooks?: {
|
|
632
771
|
triggers: Array<{
|
|
@@ -698,6 +837,73 @@ export declare interface NiceStudioRevision {
|
|
|
698
837
|
path?: string;
|
|
699
838
|
}
|
|
700
839
|
|
|
840
|
+
/** A named script of a module (1.4.6). Fields the studio does not edit stay in the stored entry. */
|
|
841
|
+
export declare interface NiceStudioScriptDef {
|
|
842
|
+
id?: string;
|
|
843
|
+
/** The name other scripts and the app call it by (unique in the module). */
|
|
844
|
+
name: string;
|
|
845
|
+
displayName?: string;
|
|
846
|
+
description?: string;
|
|
847
|
+
kind: NiceStudioScriptKind;
|
|
848
|
+
/** `typescript`, `javascript`, `csharp`, `sql`… (none for a no-code script). */
|
|
849
|
+
language?: string;
|
|
850
|
+
/** Free grouping: `formatting`, `validation`, `integration`… */
|
|
851
|
+
category?: string;
|
|
852
|
+
/** What runs it: an event, a schedule, a button (one of the preset's `scripts.triggers`). */
|
|
853
|
+
trigger?: string;
|
|
854
|
+
parameters?: NiceStudioScriptParameter[];
|
|
855
|
+
returnType?: string;
|
|
856
|
+
/** The code (frontend, backend, SQL). */
|
|
857
|
+
source?: string;
|
|
858
|
+
/** A file of the module holding the code instead of `source`. */
|
|
859
|
+
sourcePath?: string;
|
|
860
|
+
/** The steps of a no-code script. */
|
|
861
|
+
steps?: NiceNoCodeStep[];
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* What a script is (1.4.6): code run in the browser (`frontend`), code run on the server
|
|
866
|
+
* (`backend`), no-code steps (`noCode`, run by `runNoCodeScript`) or a SQL query or procedure.
|
|
867
|
+
*/
|
|
868
|
+
export declare type NiceStudioScriptKind = 'frontend' | 'backend' | 'noCode' | 'sql';
|
|
869
|
+
|
|
870
|
+
/** How a preset's scripts look (1.4.6). */
|
|
871
|
+
export declare interface NiceStudioScriptOptions {
|
|
872
|
+
/** The kinds "Add script" offers. Default: all four. */
|
|
873
|
+
kinds?: NiceStudioScriptKind[];
|
|
874
|
+
/** Categories offered (the module's own are offered too). */
|
|
875
|
+
categories?: string[];
|
|
876
|
+
/** What can run a script. */
|
|
877
|
+
triggers?: Array<{
|
|
878
|
+
id: string;
|
|
879
|
+
label: string;
|
|
880
|
+
description?: string;
|
|
881
|
+
}>;
|
|
882
|
+
/** Install phases offered for database scripts. Default: preInstall, postInstall, preUninstall, postUninstall. */
|
|
883
|
+
phases?: string[];
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/** A parameter of a script. */
|
|
887
|
+
export declare interface NiceStudioScriptParameter {
|
|
888
|
+
name: string;
|
|
889
|
+
/** Its type as the script's language writes it (`string`, `Date | string`, `decimal`). */
|
|
890
|
+
type?: string;
|
|
891
|
+
description?: string;
|
|
892
|
+
default?: unknown;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/** The model of the `scriptList` editor (1.4.6): named scripts and database scripts per phase. */
|
|
896
|
+
export declare interface NiceStudioScripts {
|
|
897
|
+
scripts: Array<NiceStudioItem<NiceStudioScriptDef>>;
|
|
898
|
+
/** SQL statements per install phase: `{ postInstall: ['CREATE INDEX …'] }`. */
|
|
899
|
+
phases?: Record<string, string[]>;
|
|
900
|
+
/**
|
|
901
|
+
* What the file can hold when one property keeps either (OmniVerk's `scripts` is a list of
|
|
902
|
+
* scripts or an object of phases): only named scripts, or only phases. Absent: both.
|
|
903
|
+
*/
|
|
904
|
+
holds?: 'scripts' | 'phases';
|
|
905
|
+
}
|
|
906
|
+
|
|
701
907
|
/** The model of the `seeds` editor: rows per entity, plus demo rows. */
|
|
702
908
|
export declare interface NiceStudioSeeds {
|
|
703
909
|
seeds: Record<string, Array<Record<string, unknown>>>;
|
|
@@ -767,6 +973,12 @@ export declare function parseJsonText(text: string): {
|
|
|
767
973
|
format: NiceJsonTextFormat;
|
|
768
974
|
};
|
|
769
975
|
|
|
976
|
+
/**
|
|
977
|
+
* A layout from its file's text — what it can read of it: unknown fields and broken entries are
|
|
978
|
+
* dropped, a text that does not parse gives the empty layout.
|
|
979
|
+
*/
|
|
980
|
+
export declare function parseStudioLayout(text: string | undefined): NiceStudioLayout;
|
|
981
|
+
|
|
770
982
|
/**
|
|
771
983
|
* `previous` with its content replaced by `next`, changing as few bytes as possible. Falls back
|
|
772
984
|
* to {@link stringifyJsonText} in the file's own format when the text cannot be patched (invalid
|
|
@@ -777,9 +989,36 @@ export declare function patchJsonText(previous: string, next: unknown, options?:
|
|
|
777
989
|
/** {@link patchJsonText}, also telling whether the patch was exact. */
|
|
778
990
|
export declare function patchJsonTextDetailed(previous: string, next: unknown, options?: NiceJsonPatchOptions): NiceJsonPatchResult;
|
|
779
991
|
|
|
992
|
+
/**
|
|
993
|
+
* The layout with an entry put somewhere: into a folder (its section follows the folder's), into a
|
|
994
|
+
* section (out of any folder), or back to its group (`{}`).
|
|
995
|
+
*/
|
|
996
|
+
export declare function placeStudioEntry(layout: NiceStudioLayout, ref: string, target: {
|
|
997
|
+
folder?: string;
|
|
998
|
+
section?: string;
|
|
999
|
+
}): NiceStudioLayout;
|
|
1000
|
+
|
|
780
1001
|
/** The translations inside a file: `translations`, `keys`, or the whole file when it is a flat map. */
|
|
781
1002
|
export declare function readTranslations(root: unknown): Record<string, string>;
|
|
782
1003
|
|
|
1004
|
+
/**
|
|
1005
|
+
* The layout without a section or folder. What it held moves up: a folder's entries and folders go
|
|
1006
|
+
* to its parent (or the group), a section's folders and entries back to the module's own groups.
|
|
1007
|
+
*/
|
|
1008
|
+
export declare function removeStudioLayoutNode(layout: NiceStudioLayout, node: {
|
|
1009
|
+
kind: 'section' | 'folder';
|
|
1010
|
+
id: string;
|
|
1011
|
+
}): NiceStudioLayout;
|
|
1012
|
+
|
|
1013
|
+
/** The layout after an entry was renamed — its placement follows it (`entities:Old` → `entities:New`). */
|
|
1014
|
+
export declare function renameStudioEntryRef(layout: NiceStudioLayout, from: string, to: string): NiceStudioLayout;
|
|
1015
|
+
|
|
1016
|
+
/** The layout with a section or folder renamed. */
|
|
1017
|
+
export declare function renameStudioLayoutNode(layout: NiceStudioLayout, node: {
|
|
1018
|
+
kind: 'section' | 'folder';
|
|
1019
|
+
id: string;
|
|
1020
|
+
}, label: string): NiceStudioLayout;
|
|
1021
|
+
|
|
783
1022
|
/** The kind a path opens with: the first that matches, else JSON or text. */
|
|
784
1023
|
export declare function resolveFileKind(kinds: readonly NiceStudioFileKind[], path: string): NiceStudioFileKind;
|
|
785
1024
|
|
|
@@ -787,18 +1026,48 @@ declare type Row = Record<string, unknown>;
|
|
|
787
1026
|
|
|
788
1027
|
declare type Row_2 = Record<string, unknown>;
|
|
789
1028
|
|
|
1029
|
+
declare type Row_3 = Record<string, unknown>;
|
|
1030
|
+
|
|
790
1031
|
/** Parses JSON without a BOM and returns `fallback` when the text is not JSON. */
|
|
791
1032
|
export declare function safeJson<T = unknown>(text: string, fallback: T): T;
|
|
792
1033
|
|
|
1034
|
+
/**
|
|
1035
|
+
* A file of named scripts and database scripts per phase (the `scriptList` editor). Scripts the
|
|
1036
|
+
* form does not understand stay raw and round-trip as they are; a file whose phases are not lists
|
|
1037
|
+
* of SQL text opens as raw JSON.
|
|
1038
|
+
*/
|
|
1039
|
+
export declare function scriptsFileKind(o: NiceScriptsFileKindOptions): NiceStudioFileKind<NiceStudioScripts>;
|
|
1040
|
+
|
|
1041
|
+
/** A layout's file text: two-space JSON with a final newline, in the line ending of `previous`. */
|
|
1042
|
+
export declare function serializeStudioLayout(layout: NiceStudioLayout, previous?: string): string;
|
|
1043
|
+
|
|
793
1044
|
/** A file-name-safe id out of a display name: "Bike rental" → `bike-rental`. */
|
|
794
1045
|
export declare function slugifyModuleId(name: string): string;
|
|
795
1046
|
|
|
796
1047
|
/** Writes `value` in a given format (defaults: two spaces, LF, final newline, no BOM). */
|
|
797
1048
|
export declare function stringifyJsonText(value: unknown, format?: Partial<NiceJsonTextFormat>): string;
|
|
798
1049
|
|
|
1050
|
+
/** The ref of an entry in a layout: `group:key`. */
|
|
1051
|
+
export declare const studioEntryRef: (group: string, key: string) => string;
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* The path of a module's layout file: the one it has, else `{prefix}.studio.json` after the prefix
|
|
1055
|
+
* of its files, else `module.studio.json`.
|
|
1056
|
+
*/
|
|
1057
|
+
export declare function studioLayoutPath(files: readonly NiceStudioFile[]): string;
|
|
1058
|
+
|
|
1059
|
+
/** `"Send invoice"` → `sendInvoice`: a name usable as a function's. */
|
|
1060
|
+
export declare function studioScriptIdentifier(name: string): string;
|
|
1061
|
+
|
|
1062
|
+
/** The languages of a kind, the first being the default (none for no-code). */
|
|
1063
|
+
export declare function studioScriptLanguages(kind: NiceStudioScriptKind): string[];
|
|
1064
|
+
|
|
799
1065
|
/** Any other file, edited as text. */
|
|
800
1066
|
export declare const textFallbackKind: NiceStudioFileKind<string>;
|
|
801
1067
|
|
|
1068
|
+
/** A stored script as a list item: with a definition when the form can keep every field it edits. */
|
|
1069
|
+
export declare function toStudioScriptItem(raw: unknown, index: number): NiceStudioItem<NiceStudioScriptDef>;
|
|
1070
|
+
|
|
802
1071
|
/** The file with its translations replaced, in the same place they were. */
|
|
803
1072
|
export declare function writeTranslations(root: unknown, entries: Record<string, string>): unknown;
|
|
804
1073
|
|