@vtj/coder
Version:
VTJ 是一款基于 Vue3 + Typescript 的低代码页面可视化设计器。内置低代码引擎、渲染器和代码生成器,面向前端开发者,开箱即用。 无缝嵌入本地开发工程,不改变前端开发流程和编码习惯。
103 lines (101 loc) • 16.6 kB
JavaScript
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("@vtj/base"),D=require("prettier/standalone"),K=require("prettier/plugins/html"),ee=require("prettier/plugins/babel"),te=require("prettier/plugins/postcss"),se=require("prettier/plugins/estree");function F(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const s in t)if(s!=="default"){const n=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,n.get?n:{enumerable:!0,get:()=>t[s]})}}return e.default=t,Object.freeze(e)}const ne=F(K),q=F(ee),M=F(te),U=F(se);/**!
* Copyright (c) 2025, VTJ.PRO All rights reserved.
* @name @vtj/coder
* @author CHC chenhuachun1549@dingtalk.com
* @version 0.13.13
* @license <a href="https://vtj.pro/license.html">MIT License</a>
*/const re="0.13.13";/**!
* Copyright (c) 2025, VTJ.PRO All rights reserved.
* @name @vtj/core
* @author CHC chenhuachun1549@dingtalk.com
* @version 0.13.13
* @license <a href="https://vtj.pro/license.html">MIT License</a>
*/const ie=["slot","template","component","img","div","p","h1","h2","h3","span","a"];f.mitt();const T={arrowParens:"always",bracketSpacing:!0,bracketSameLine:!0,endOfLine:"lf",htmlWhitespaceSensitivity:"css",insertPragma:!1,jsxBracketSameLine:!0,jsxSingleQuote:!0,printWidth:80,proseWrap:"preserve",quoteProps:"as-needed",requirePragma:!1,semi:!0,singleQuote:!0,tabWidth:2,trailingComma:"none",useTabs:!1,vueIndentScriptAndStyle:!0};async function B(t,e){return e?t:await D.format(t,{parser:"vue",...T,plugins:[ne,q,U,M]})}async function V(t,e){if(e)return t;try{return(await D.format(t,{parser:"babel-ts",...T,plugins:[q,U]})).replace(/;\n$/gi,"")}catch(s){return console.warn(s),t}}async function N(t,e){return e?t:D.format(t,{parser:"scss",...T,plugins:[M]})}function k(t){return t&&t.type==="JSExpression"}function I(t){return typeof t=="object"&&t&&t.type==="JSFunction"}function j(t){return k(t)||I(t)}function H(t){return t.replace(new RegExp("this.","g"),"")}function L(t){return t.replace(/this\.context\??\./g,"")}function d(t,e=!0,s=!0,n=[]){let i=j(t)?t.value.trim().replace(/;$/,""):e?JSON.stringify(t):t;return i=w(i,n),s?H(L(i)):L(i)}function w(t="",e=[]){let s=t;for(const n of e)s=s.replace(new RegExp(`this.${n}.value`,"g"),`this.${n}`);return s}function Q(t){let e=t.trim().replace(/;$/,"");if(e=/^\((\(|async|function)/.test(e)?e.substring(1,e.length-1):e,e.startsWith("{"))return e;if(e.startsWith("async function"))e=e.replace(/^async function/,"async");else if(e.startsWith("function"))e=e.replace(/^function/,"");else{const i=/^(async\s)?\([\w]*\)\s+\=\>\s([\w\W]+)/,r=e.match(i);r&&r[2]&&(r[2].startsWith("{")||(e=e.replace(r[2],`{ return ${r[2]} }`))),e=e.replace("=>","")}return e}function oe(t={}){return Object.entries(t).map(([e,s])=>`"${e}": ${d(s)}`)}function z(t={},e=!1){const s=Object.keys(t);return e?s.map(n=>"."+n):s}function ae(t){let e="";for(var s in t)if(t.hasOwnProperty(s)){var n=t[s];e+=s+": "+n+";"}return e}function ce(t=[],e=[]){return t.filter(s=>!e.includes(s))}function R(t){return f.base64(JSON.stringify(t))}class le{constructor(e,s){this.dsl=e,this.dependencies=s,this.libraryRegex=this.collectLibrary(),this.walk(e),this.walkNodes(e),this.members=this.getLibraryMember()}imports={};context={};style={};members=[];urlSchemas={};blockPlugins={};libraryRegex=[];collectLibrary(){return this.dependencies.filter(e=>!!e.library).map(e=>new RegExp(`(this.\\$libs.${e.library}.([\\w]+))`,"g"))}collectImport(e){const s=e.split(".");if(s.length===4){const n=s.pop(),i=s.join(".")+".",r=s.pop();if(n&&r){const o=this.dependencies.find(a=>a.library===r)?.package;o&&(this.imports[o]||(this.imports[o]=new Set)).add(n)}return{name:n,path:i,library:r}}return null}replaceLibraryPath(e){const{libraryRegex:s}=this;let n=e.value;for(const i of s){const r=e.value?.match(i)||[];for(const o of r){const a=this.collectImport(o);if(a){const m=a.path.replace(/\$/g,"\\$");n=n.replace(new RegExp(m,"g"),"")}}}return n}walk(e){const s=n=>{if(!n||typeof n!="object")return;if(Array.isArray(n)){for(let r of n)s(r);return}const i=Object.values(n);for(const r of i)j(r)?r.value=this.replaceLibraryPath(r):s(r)};s(e)}getLibraryMember(e=[]){let s=[...e];const n={...this.imports};delete n["uni-h5"],delete n["@dcloudio/uni-h5"],delete n["uni-ui"],delete n["@dcloudio/uni-ui"];for(const i of Object.values(n))s=s.concat(Array.from(i));return f.dedupArray(s)}collectContext(e,s){const n=new Set(s?.id?this.context[s.id]:[]),i=(e.directives||[]).find(a=>a.name==="vFor");let r=new Set(Array.from(n));if(i){const{item:a="item",index:m="index"}=i.iterator||{};r=new Set([a,m,...Array.from(r)])}const o=e.slot;if(o){const a=typeof o=="string"?[]:o.params||[],m=a.length?a:[`scope_${s?.id}`];r=new Set([...m,...Array.from(r)])}this.context[e.id]=r}collectStyle(e){e.id&&e.props?.style&&Object.keys(e.props.style).length&&!j(e.props.style)&&(this.style[`.${e.name}_${e.id}`]=e.props.style)}collectUrlSchema(e){typeof e.from=="object"&&e.from.type==="UrlSchema"&&(this.urlSchemas[e.name]=e.from)}collectBlockPlugin(e){typeof e.from=="object"&&e.from.type==="Plugin"&&(this.blockPlugins[e.name]=e.from)}walkNodes(e){const s=(n,i)=>{this.collectContext(n,i),this.collectStyle(n),this.collectUrlSchema(n),this.collectBlockPlugin(n),Array.isArray(n.children)&&n.children.forEach(r=>s(r,n))};Array.isArray(e.nodes)&&e.nodes.forEach(n=>s(n))}}function ue(t={}){return Object.entries(t).map(([e,s])=>{const n=d(s,!1);return`${e}:${n}`})}function pe(t=[]){return t.map(e=>`${e.name}: {
from: '${e.from||e.name}',
default: ${d(e.default,!0,!1)}
}`)}function fe(t=[]){const e=s=>s?`[${f.toArray(s).map(r=>r.replace(/\'|\"/gi,"")).join(",")}]`:void 0;return t.map(s=>typeof s=="string"?`${s}: {}`:(j(s.default)&&!s.default.value&&(s.default.value="undefined"),`${s.name}: {
type:${e(s.type)},
required: ${d(!!s.required,!0,!1)},
default: ${d(s.default,!0,!1)}
}`))}function me(t=[]){return t.map(e=>`'${typeof e=="string"?e:e.name}'`)}function A(t={},e=[]){return Object.entries(t).map(([s,n])=>{let i=Q(d(n,!1,!1));return i=w(i,e)?.trim(),i.startsWith("async")?`async ${s}${i.replace(/^async/,"")}`:i.startsWith("(")||i.startsWith("{")?`${s}${i}`:null}).filter(s=>!!s)}function he(t=[],e=[]){const s=t.reduce((r,o)=>(o.id&&I(o.source)&&(r[`watcher_${o.id}`]=o.source),r),{}),n=A(s,e),i=t.map(r=>r.handler&&r.handler.value?`watcher_${r.id}: {
deep: ${r.deep},
immediate:${r.immediate},
handler${Q(r.handler.value)}
}`:null).filter(r=>!!r);return{computed:n,watches:i}}function de(t={}){return Object.values(t).map(e=>{if(e.type==="mock"){const s=I(e.mockTemplate)&&e.mockTemplate.value||"(params) => ({})";return`async ${e.name}(...args) {
// DataSource: ${R(e)}
const mock = this.provider.createMock(${s});
return await mock.apply(this, args);
}`}else{const s=I(e.transform)&&e.transform.value||"(res) => res";return`async ${e.name}(...args) {
// DataSource: ${R(e)}
return await this.provider.apis['${e.ref}'].apply(this, args).then(${s});
}`}})}const ye=["img","input","br","hr","area","base","col","embed","link","meta","param","source","track","wbr"],J=["vIf","vElseIf","vElse","vShow","vModel","vFor","vBind","vHtml"];function G(t,e,s=[],n={},i){const r=[];let o={},a=[];const m=[];let u=[];return ve(t).forEach(c=>{const v=[];for(const h of c.children){let{id:y,name:$,invisible:b,from:g}=h;if(b)continue;const C=$e($,e,g);C&&a.push(C),X(g)&&u.push({id:g.id,name:$});const{props:P,events:O,handlers:E}=we(h,y,h.props,h.events,n,s),W=Ce(h.directives,s,m).join(" "),S=h.children?Oe(h.children,s,e,n,h):"";Object.assign(o,E);let x="";typeof S=="string"?x=S:(x=(S?.nodes||[]).join(`
`),Object.assign(o,S?.methods||{}),a=a.concat(S?.components||[]),u=u.concat(S?.importBlocks||[]));const _=["@dcloudio/uni-h5","@dcloudio/uni-ui"].includes(g||e.get($)?.package)?f.kebabCase($):Y(g)||Z(g)?"component":$;v.push(ye.includes(_)?`<${_} ${W} ${P} ${O} />`:`<${_} ${W} ${P} ${O}>${x?`
`+x.trim():""}</${_}>`)}const p=Ee(c.slot,v.join(`
`),i?.id);r.push(p)}),{nodes:r,methods:o,directives:ge(m),components:f.dedupArray(a),importBlocks:f.dedupArray(u,"id")}}function ge(t){return f.dedupArray(t).map(e=>`${e.startsWith("v")?e.substring(1):e}:${e}`)}function ve(t=[]){const e=new Map;for(const s of t){const n=typeof s.slot=="string"?s.slot:s.slot?.name,i=e.get(n);i?i.children.push(s):e.set(n,{slot:s.slot,children:[s]})}return e}function $e(t,e,s){if(ie.includes(t))return null;const n=e.get(t);if(n&&n.alias){const i=n.parent?`${n.parent}.${n.alias}`:n.alias;return`${t}: ${i}`}return X(s)||n?t:null}function X(t){return!!t&&typeof t=="object"&&t.type==="Schema"}function Y(t){return typeof t=="object"&&t.type==="UrlSchema"}function Z(t){return typeof t=="object"&&t.type==="Plugin"}function be(t,e,s=[]){return t==="style"?j(e)?`:style="${d({...e,value:w(e.value,s)})}"`:"":t==="__class"&&j(e)?`:class="${d({...e,value:w(e.value,s)})}"`:typeof e=="string"?`${t}="${e}"`:j(e)?`:${t}="${d({...e,value:w(e.value,s)})}"`:f.isPlainObject(e)?`:${t}='{${oe(e).join(", ")}}'`:`:${t}='${JSON.stringify(e)}'`}function je(t,e={},s=[]){if(!!Object.keys(e.style||{}).length){const r=`${t.name}_${t.id}`;e.class?typeof e.class=="string"?e.class=[e.class,r].join(" "):(e.__class=e.class,e.class=r):e.class=r,j(e.style)||delete e.style}const i=t.from;return(Y(i)||Z(i))&&(e.is={type:"JSExpression",value:t.name}),Object.entries(e).map(([r,o])=>be(r,o,s))}function Se(t,e,s,n,i){const r=z(e.modifiers,!0);return i?`@${t}${r.join("")}="${s}"`:n&&n.length>0?`@${t}${r.join("")}="(...args:any[]) => ${s}"`:`@${t}${r.join("")}="${s}"`}function ke(t,e={},s={}){const n={},i=Array.from(s[t]||new Set([])),r=i.length?`({${i.join(", ")}}, args)`:"";return{binders:Object.entries(e).map(([a,m])=>{const u=m.handler.value.startsWith("this."),l=u?H(m.handler.value):`${f.camelCase(a)}_${t}${r}`;return u||(n[l]=i.length?{type:"JSFunction",value:`{
return (${m.handler.value}).apply(this, args);
}`}:m.handler),Se(a,m,l,i,u)}),handlers:n}}function we(t,e,s={},n={},i={},r){const{binders:o,handlers:a}=ke(e,n,i);return{props:je(t,s,r).join(" "),handlers:a,binders:o,events:o.join(" ")}}function Ce(t=[],e=[],s=[]){const n=[],{vIf:i,vElse:r,vElseIf:o,vShow:a,vModels:m,vFor:u,vBind:l,vHtml:c,customDirectives:v}=Pe(t);if(i&&n.push(`v-if="${d(i.value,!0,!0,e)}"`),o&&n.push(`v-else-if="${d(o.value,!0,!0,e)}"`),r&&n.push("v-else"),a&&n.push(`v-show="${d(a.value,!0,!0,e)}"`),l&&n.push(`v-bind="${d(l.value,!0,!0,e)}"`),m.forEach(p=>{const h=z(p.modifiers,!0),y=p.arg?k(p.arg)?`:[${d(p.arg,!0,!0,e)}]`:`:${p.arg}`:"";n.push(`v-model${y}${h}="${d(p.value,!0,!0,e)}"`)}),u){const{item:p,index:h}={item:"item",index:"index",...u.iterator};n.push(`v-for="(${p}, ${h}) in ${d(u.value,!0,!0,e)}"`)}return c&&n.push(`v-html="${d(c.value,!0,!0,e)}"`),v&&v.length&&v.forEach(p=>{if(!p.name)return;let h="",y="";k(p.name)?(y=d(p.name,!0,!0,e),s.push(y)):y=p.name;const $=y?.startsWith("v")?f.kebabCase(y):f.kebabCase("v-"+y);if(h+=$,p.arg&&(k(p.arg)?h+=`:[${d(p.name,!0,!0,e)}]`:h+=`:${p.arg}`),p.modifiers){const b=Object.keys(p.modifiers);b.length&&(h+=b.map(g=>"."+g))}p.value?n.push(`${h}="${d(p.value,!0,!0,e)}"`):n.push(h)}),n}function Pe(t=[]){const e=t.filter(c=>J.includes(c.name)),s=t.filter(c=>!J.includes(c.name)),n=e.find(c=>f.camelCase(c.name)==="vIf"),i=e.find(c=>f.camelCase(c.name)==="vElseIf"),r=e.find(c=>f.camelCase(c.name)==="vElse"),o=e.find(c=>f.camelCase(c.name)==="vFor"),a=e.find(c=>f.camelCase(c.name)==="vShow"),m=e.find(c=>f.camelCase(c.name)==="vBind"),u=e.find(c=>f.camelCase(c.name)==="vHtml"),l=e.filter(c=>f.camelCase(c.name)==="vModel");return{vIf:n,vElseIf:i,vElse:r,vFor:o,vShow:a,vModels:l,vBind:m,vHtml:u,customDirectives:s}}function Oe(t,e,s,n,i){return typeof t=="string"?t:k(t)?`{{ ${d(t,!1,!0,e)} }}`:Array.isArray(t)?G(t,s,e,n,i):""}function Ee(t,e,s){if(!t)return e;const n=typeof t=="string"?{name:t,params:[],scope:""}:{params:[],scope:"",...t};return`<template ${`#${n.name}="${n.scope?n.scope:n.params?.length>0?`{${n.params?.join(",")}}`:`scope_${s}`}"`}>
${e}
</template>`}function xe(t,e=[],s=[],n={},i="web"){const r=["@dcloudio/uni-h5","uni-h5","@dcloudio/uni-ui","uni-ui"],o={vue:["defineComponent","reactive"]},a=[];for(const u of e){const l=t.get(u.split(":")[0]);if(l&&l.package){const c=o[l.package]??(o[l.package]=[]),v=l.parent||(l.alias||"").split(".")[0]||l.name;c.push(v),i==="uniapp"&&r.includes(l.package)&&a.push(v)}}for(const[u,l]of Object.entries(n))(o[u]??(o[u]=[])).push(...Array.from(l)),i==="uniapp"&&r.includes(u)&&a.push(...Array.from(l));return{imports:Object.entries(o).filter(([u,l])=>i==="uniapp"?!r.includes(u)&&!!l.length:!!l.length).map(([u,l])=>`import { ${f.dedupArray(l).join(",")}} from '${u}';`).concat(s),uniComponents:a}}function _e(t={}){const e=[];for(const[s,n]of Object.entries(t))e.push(`
${s} {
${ae(n)}
}
`);return e.join(`
`)}function Ae(t={}){const e=[];return Object.entries(t).forEach(([s,n])=>{e.push(`const ${s} = provider.defineUrlSchemaComponent('${n.url}');`)}),e}function Ie(t={}){const e=[];return Object.entries(t).forEach(([s,n])=>{e.push(`const ${s} = provider.definePluginComponent(${JSON.stringify(n)});`)}),e}function Fe(t,e,s="web"){const{dsl:n}=t,i=Object.keys(n.computed||{}),r=A(n.lifeCycles,i),o=A(n.computed,i),a=he(n.watch,i),m=de(n.dataSources),{methods:u,nodes:l,components:c,importBlocks:v,directives:p}=G(n.nodes||[],e,i,t.context),h=[...o,...a.computed],y=A({...u,...n.methods||{}},i),$=v.map(E=>`import ${E.name} from './${E.id}.vue';`);let{imports:b,uniComponents:g}=xe(e,c,$,t.imports,s);const C=Object.keys({...t.urlSchemas,...t.blockPlugins}),P=Ae(t.urlSchemas),O=Ie(t.blockPlugins);return{id:n.id,version:n.__VERSION__,name:n.name,state:ue(n.state).join(","),inject:pe(n.inject).join(","),props:fe(n.props).join(","),emits:me(n.emits).join(","),watch:a.watches.join(","),lifeCycles:r.join(","),computed:h.join(","),methods:[...m,...y].join(","),imports:`
`+b.join(`
`),components:ce(c,g).join(","),directives:p.join(","),returns:t.members.join(","),template:l.join(`
`),css:n.css||"",style:_e(t.style),urlSchemas:P.join(`
`),blockPlugins:O.join(`
`),asyncComponents:C.join(","),uniComponents:g,renderer:s==="uniapp"?"@vtj/uni-app":"@vtj/renderer"}}const Ne=`
// @ts-nocheck
<%= imports %>
import { useProvider } from '<%= renderer %>';
export default defineComponent({
name: '<%= name %>',
<% if(inject) { %> inject: { <%= inject %>}, <% } %>
<% if(components) { %> components: { <%= components %> }, <% } %>
<% if(directives) { %> directives: { <%= directives %> }, <% } %>
<% if(props) { %> props: { <%= props %> }, <% } %>
<% if(emits) {%> emits: [<%= emits %>], <% } %>
setup(props) {
const provider = useProvider({
id: '<%= id %>',
version: '<%= version %>'
});
const state = reactive({ <%= state %> });
<%= urlSchemas %>
<%= blockPlugins %>
return {
state,
props,
provider
<% if(asyncComponents) { %>, <%= asyncComponents %> <% }%>
<% if(returns) { %>, <%= returns %> <% } %>
};
},
<% if(computed) { %> computed: { <%= computed %> }, <% } %>
<% if(methods) { %> methods: { <%= methods %> }, <% } %>
<% if(watch) { %> watch: { <%= watch %> }, <% } %> <%= lifeCycles %>
});
`.replace(/(\n|\r|\t)/g,""),De=`
<template>
<%= template %>
</template>
<script lang="<%= scriptLang %>">
<%= script %>
<\/script>
<style lang="<%= styleLang %>" scoped>
<%= css %>
<%= style %>
</style>
`,Te=f.template(Ne),Be=f.template(De);async function We(t,e=new Map,s=[],n="web",i){const r=t,o=typeof r.dsl=="object"&&arguments.length===1?r:{dsl:t,componentMap:e,dependencies:s,platform:n,formatterDisabled:i},{dsl:a,componentMap:m=new Map,dependencies:u=[],platform:l="web",formatterDisabled:c=!1,ts:v=!0,scss:p=!1}=o,h=new le(f.cloneDeep(a),u),y=Fe(h,m,l),$=Te(y),b=Be({template:y.template,css:await N(y.css,c),script:await V($,c),style:await N(y.style,c),scriptLang:v?"ts":"js",styleLang:p?"scss":"css"});return await B(b,c).catch(g=>(g.content=b,Promise.reject(g)))}async function Le(t){const e=`
<template>
<div>
<h3>源码模式页面</h3>
<div>文件路径:/.vtj/vue/${t.id}.vue</div>
</div>
</template>
<script lang="ts" setup>
<\/script>
<style scoped lang="scss">
</style>
`;return await B(e)}exports.VTJ_CODER_VERSION=re;exports.createEmptyPage=Le;exports.cssFormatter=N;exports.generator=We;exports.tsFormatter=V;exports.vueFormatter=B;