@visulima/vis 1.0.0-alpha.21 → 1.0.0-alpha.23
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/CHANGELOG.md +103 -0
- package/LICENSE.md +204 -9
- package/README.md +21 -4
- package/dashboard/dist/index.html +152 -0
- package/dist/bin.js +1 -1
- package/dist/binx.js +3 -0
- package/dist/config/index.d.ts +208 -28
- package/dist/config/index.js +1 -1
- package/dist/packem_chunks/bin.js +360 -354
- package/dist/packem_chunks/bloom-status.js +2 -0
- package/dist/packem_chunks/bloom-sync.js +2 -0
- package/dist/packem_chunks/cache-attestation.js +1 -0
- package/dist/packem_chunks/config.js +15 -15
- package/dist/packem_chunks/doctor-probe.js +2 -2
- package/dist/packem_chunks/fix.js +3 -3
- package/dist/packem_chunks/handler.js +1 -1
- package/dist/packem_chunks/handler10.js +2 -1
- package/dist/packem_chunks/handler11.js +1 -5
- package/dist/packem_chunks/handler12.js +5 -1
- package/dist/packem_chunks/handler13.js +1 -27
- package/dist/packem_chunks/handler14.js +28 -5
- package/dist/packem_chunks/handler15.js +5 -1
- package/dist/packem_chunks/handler16.js +1 -1
- package/dist/packem_chunks/handler17.js +1 -1
- package/dist/packem_chunks/handler18.js +1 -1
- package/dist/packem_chunks/handler19.js +1 -1
- package/dist/packem_chunks/handler2.js +4 -2
- package/dist/packem_chunks/handler20.js +1 -5
- package/dist/packem_chunks/handler21.js +5 -2
- package/dist/packem_chunks/handler22.js +2 -2
- package/dist/packem_chunks/handler23.js +2 -18
- package/dist/packem_chunks/handler24.js +1 -1
- package/dist/packem_chunks/handler25.js +1 -1
- package/dist/packem_chunks/handler26.js +5 -5
- package/dist/packem_chunks/handler27.js +1 -1
- package/dist/packem_chunks/handler28.js +1 -1
- package/dist/packem_chunks/handler29.js +1 -1
- package/dist/packem_chunks/handler3.js +4 -4
- package/dist/packem_chunks/handler30.js +3 -3
- package/dist/packem_chunks/handler31.js +4 -4
- package/dist/packem_chunks/handler32.js +3 -3
- package/dist/packem_chunks/handler33.js +1 -1
- package/dist/packem_chunks/handler34.js +24 -24
- package/dist/packem_chunks/handler35.js +5 -3
- package/dist/packem_chunks/handler36.js +21 -6
- package/dist/packem_chunks/handler37.js +60 -21
- package/dist/packem_chunks/handler38.js +6 -428
- package/dist/packem_chunks/handler39.js +708 -6
- package/dist/packem_chunks/handler4.js +6 -8
- package/dist/packem_chunks/handler40.js +11 -11
- package/dist/packem_chunks/handler41.js +286 -10
- package/dist/packem_chunks/handler42.js +11 -11
- package/dist/packem_chunks/handler43.js +10 -25
- package/dist/packem_chunks/handler44.js +25 -24
- package/dist/packem_chunks/handler45.js +23 -212
- package/dist/packem_chunks/handler46.js +2 -2
- package/dist/packem_chunks/handler47.js +1 -1
- package/dist/packem_chunks/handler48.js +53 -46
- package/dist/packem_chunks/handler49.js +6 -6
- package/dist/packem_chunks/handler5.js +8 -1
- package/dist/packem_chunks/handler6.js +1 -1
- package/dist/packem_chunks/handler7.js +1 -1
- package/dist/packem_chunks/handler8.js +1 -1
- package/dist/packem_chunks/handler9.js +1 -2
- package/dist/packem_chunks/heal-accept.js +4 -4
- package/dist/packem_chunks/heal.js +1 -1
- package/dist/packem_chunks/help-command.js +16 -16
- package/dist/packem_chunks/index.js +2 -2
- package/dist/packem_chunks/keys-refresh.js +1 -1
- package/dist/packem_chunks/list.js +2 -2
- package/dist/packem_chunks/loader.js +4 -1
- package/dist/packem_chunks/loader2.js +1 -0
- package/dist/packem_chunks/prune.js +1 -1
- package/dist/packem_chunks/run.js +1 -1
- package/dist/packem_chunks/status.js +2 -2
- package/dist/packem_chunks/sync.js +2 -2
- package/dist/packem_chunks/sync2.js +2 -2
- package/dist/packem_chunks/tripwire.js +2 -2
- package/dist/packem_chunks/verify-lockfile.js +2 -0
- package/dist/packem_shared/{advisories-DsynpacV.js → advisories-U1QKY_tg.js} +1 -1
- package/dist/packem_shared/{ai-analysis-uYuTIIXi.js → ai-analysis-B8pDCOuT.js} +2 -2
- package/dist/packem_shared/ai-fix-DiGSrGKv.js +43 -0
- package/dist/packem_shared/anolilab-text-CAM_E6uK.js +13 -0
- package/dist/packem_shared/applyDefaults-KxZkvlp3.js +1 -0
- package/dist/packem_shared/build-scripts-3E2pmscY.js +1 -0
- package/dist/packem_shared/cyclonedx-B293T7R0.js +4 -0
- package/dist/packem_shared/dependency-scan-BbtivycX.js +1 -0
- package/dist/packem_shared/docker-BhBBfWfc.js +60 -0
- package/dist/packem_shared/failure-log-B0Uh-65U.js +2 -0
- package/dist/packem_shared/index-C1w1GXdS.js +1 -0
- package/dist/packem_shared/index-CZX_II5N.js +29 -0
- package/dist/packem_shared/index.server-B7ETiT4C.js +2 -0
- package/dist/packem_shared/license-zZU7aavK.js +1 -0
- package/dist/packem_shared/{lifecycle-Dv3nAtoD.js → lifecycle-wRE7ymVc.js} +2 -2
- package/dist/packem_shared/{lockfile-C5DYMHVq.js → lockfile-CQLFNyVa.js} +1 -1
- package/dist/packem_shared/manifests-Z3spBpxv.js +1 -0
- package/dist/packem_shared/{min-release-age-BFozFonQ.js → min-release-age-Cz6HbF-I.js} +2 -2
- package/dist/packem_shared/{native-config-sync-Dvi1g2nQ.js → native-config-sync-BOeuyrBj.js} +5 -5
- package/dist/packem_shared/osv-bloom-CyCDpXBl.js +2 -0
- package/dist/packem_shared/pm-runner-CVliR6Ie.js +1 -0
- package/dist/packem_shared/provenance-BcldGs02.js +1 -0
- package/dist/packem_shared/readFileSync-CGmzMUF2-D6rUjGDn.js +1 -0
- package/dist/packem_shared/registry-keys-pemEkRM9.js +1 -0
- package/dist/packem_shared/resolve-explicit-2G-2HWtR.js +5 -0
- package/dist/packem_shared/runtime-check-DgXsKCsv.js +1 -0
- package/dist/packem_shared/s1ngularity-Boxkax0D.js +1 -0
- package/dist/packem_shared/scan-progress-EbvmIh4i.js +2 -0
- package/dist/packem_shared/{selectors-B2ISH581.js → selectors-BE2BCnTR.js} +1 -1
- package/dist/packem_shared/signatures-SO-fyExV.js +2 -0
- package/dist/packem_shared/toolchain-Jx2lkAYy.js +5 -0
- package/dist/packem_shared/typosquats-CioMnpnb.js +1 -0
- package/dist/packem_shared/verify-C8EAHql6.js +1 -0
- package/dist/packem_shared/{vis-update-app-CFrlJ3mW.js → vis-update-app-BWA1kA1q.js} +1 -1
- package/index.d.ts +78 -0
- package/index.js +57 -53
- package/package.json +34 -13
- package/schemas/project.schema.json +37 -7
- package/schemas/vis-config.schema.json +2395 -1996
- package/dist/packem_shared/ai-cache-DuwHYx2O.js +0 -1
- package/dist/packem_shared/ai-fix-DzrA-dVz.js +0 -43
- package/dist/packem_shared/applyDefaults-BOVDw1jD.js +0 -1
- package/dist/packem_shared/build-scripts-DsWMSWDs.js +0 -1
- package/dist/packem_shared/cache-directory-DQak1Vjc.js +0 -1
- package/dist/packem_shared/cyclonedx-CiHXuG8M.js +0 -4
- package/dist/packem_shared/dependency-scan-DC3nAFHS.js +0 -1
- package/dist/packem_shared/docker-B-CIN_nj.js +0 -60
- package/dist/packem_shared/failure-log-C3LEMmkq.js +0 -2
- package/dist/packem_shared/flakiness-Dq6K4ymq.js +0 -1
- package/dist/packem_shared/manifests-B0fMp872.js +0 -1
- package/dist/packem_shared/registry-keys-CewRFW0e.js +0 -1
- package/dist/packem_shared/resolve-explicit-CC4Kifk5.js +0 -5
- package/dist/packem_shared/run-summary-utils-BaBGP3bo.js +0 -1
- package/dist/packem_shared/runtime-check-BusAwPb2.js +0 -1
- package/dist/packem_shared/scan-progress-CMynp3eA.js +0 -2
- package/dist/packem_shared/signatures-5ZdjJ2Pu.js +0 -2
- package/dist/packem_shared/toolchain-Cc3cwyLP.js +0 -5
- package/dist/packem_shared/typosquats-BCeR-sLf.js +0 -1
- package/dist/packem_shared/verify-07kUNTuP.js +0 -1
- package/dist/packem_shared/xxh3-DrAUNq4n.js +0 -1
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),
|
|
3
|
-
`)}
|
|
1
|
+
var ae=Object.defineProperty;var j=(t,e)=>ae(t,"name",{value:e,configurable:!0});import{createRequire as ce}from"node:module";import{E as p,j as b,q as T}from"../packem_shared/index.server-B7ETiT4C.js";import{i as _,M as N,K as Y,a as L,z as Q,y as pe,C as fe}from"../packem_shared/readFileSync-CGmzMUF2-D6rUjGDn.js";import{am as X,p as l}from"./bin.js";import{f as $e}from"../packem_shared/giget-CcEy_Elm.js";import{b as Z,B as ye}from"./config.js";const le=ce(import.meta.url),x=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,P=j(t=>{if(typeof x<"u"&&x.versions&&x.versions.node){const[e,r]=x.versions.node.split(".").map(Number);if(e>22||e===22&&r>=3||e===20&&r>=16)return x.getBuiltinModule(t)}return le(t)},"__cjs_getBuiltinModule"),{fileURLToPath:ue}=P("node:url"),{createInterface:de}=P("node:readline"),{mkdtempSync:me,rmSync:he}=P("node:fs"),{tmpdir:ge}=P("node:os"),{spawnSync:we}=P("node:child_process");var ve=Object.defineProperty,y=j((t,e)=>ve(t,"name",{value:e,configurable:!0}),"i");const ee=[".ts",".mts",".cts",".js",".mjs",".cjs"],be="template.yml",Te=[".d",".test",".spec",".config",".bench",".stories"],Se=[".d.ts",".d.mts",".d.cts",".js.map",".mjs.map",".cjs.map",".ts.map"],te=y(t=>{for(const e of ee)if(t.endsWith(e))return t.slice(0,-e.length);return t},"stripExtension"),Oe=y(t=>{if(Se.some(r=>t.endsWith(r))||!ee.some(r=>t.endsWith(r)))return!1;const e=te(t);return!Te.some(r=>e.endsWith(r))},"isNativeFile"),J=y((t,e)=>{const r=[];if(!_(t))return r;for(const s of X(t,{includeDirs:!1,includeSymlinks:!1,maxDepth:1})){if(!Oe(s.name))continue;const n=te(s.name);r.push({load:y(()=>Ne(s.path),"load"),name:n,path:s.path,source:e})}return r},"scanNativeDirectory"),q=y((t,e)=>{const r=[];if(!_(t))return r;for(const s of X(t,{includeFiles:!1,includeSymlinks:!1,maxDepth:1})){if(s.path===t)continue;const n=N(s.path,be);_(n)&&r.push({load:y(()=>Re(s.path,s.name),"load"),name:s.name,path:s.path,source:e})}return r},"scanMoonDirectory"),je=y(()=>{try{const t=ue(import.meta.url),e=N(Y(t),"..","..","templates");return _(e)?e:void 0}catch{return}},"resolveBuiltinTemplatesDirectory"),I=y(t=>{const{extraDirectories:e=[],onWarning:r,workspaceRoot:s}=t,n=[...J(N(s,".vis","templates"),"native"),...q(N(s,".vis","templates"),"moon"),...q(N(s,".moon","templates"),"moon")];for(const o of e)n.push(...q(o,"config")),n.push(...J(o,"config"));const i=je();i&&n.push(...q(i,"builtin"));const a=new Map;for(const o of n){const c=a.get(o.name);if(!c){a.set(o.name,o);continue}r&&r(`Template "${o.name}" exists in multiple sources — using ${c.source} (${c.path}), ignoring ${o.source} (${o.path}).`)}return[...a.values()].sort((o,c)=>o.name.localeCompare(c.name))},"discoverTemplates"),Ne=y(async t=>{const{loadNativeTemplate:e}=await import("./loader2.js");return e(t)},"loadNativeFromPath"),Re=y(async(t,e)=>{const{loadMoonTemplate:r}=await import("./index.js");return r(t,e)},"loadMoonFromPath");var Ee=Object.defineProperty,v=j((t,e)=>Ee(t,"name",{value:e,configurable:!0}),"c");const M=v((t,e)=>new Promise(r=>{t.question(e,s=>{r(s.trim())})}),"ask"),ke=v(async(t,e,r)=>{const s=await M(t,` ${e} ${p(r?"[Y/n]":"[y/N]")} `);return s===""?r:s.toLowerCase()==="y"||s.toLowerCase()==="yes"},"confirm"),xe=v(async(t,e,r,s)=>{process.stderr.write(` ${e}
|
|
2
|
+
`);for(const[n,i]of r.entries()){const a=b(T(` ${String(n+1)}.`)),o=i===s?p(" (default)"):"";process.stderr.write(`${a} ${i}${o}
|
|
3
|
+
`)}for(;;){const n=await M(t,`
|
|
4
|
+
${p(`Enter choice (1-${String(r.length)}):`)} `);if(n===""&&s!==void 0)return s;const i=Number.parseInt(n,10);if(Number.isInteger(i)&&i>=1&&i<=r.length)return r[i-1];const a=r.find(o=>o===n);if(a)return a;process.stderr.write(` ${p("Invalid choice. Try again.")}
|
|
5
|
+
`)}},"selectOne"),_e=v(async(t,e,r,s)=>{process.stderr.write(` ${e} ${p("(comma-separated numbers)")}
|
|
6
|
+
`);for(const[n,i]of r.entries()){const a=b(T(` ${String(n+1)}.`)),o=s.includes(i)?p(" (default)"):"";process.stderr.write(`${a} ${i}${o}
|
|
7
|
+
`)}for(;;){const n=await M(t,`
|
|
8
|
+
${p("Enter choices:")} `);if(n===""&&s.length>0)return s;const i=n.split(",").map(a=>Number.parseInt(a.trim(),10)).filter(a=>Number.isInteger(a)&&a>=1&&a<=r.length);if(i.length>0)return i.map(a=>r[a-1]);process.stderr.write(` ${p("Invalid choice. Try again.")}
|
|
9
|
+
`)}},"selectMany"),Pe=v(t=>` ${p(`${t}:`)} `,"promptText"),De=v((t,e)=>e.prompt??t,"variableLabel"),We=v(t=>Object.entries(t).sort(([e,r],[s,n])=>{const i=r.order??0,a=n.order??0;return i!==a?i-a:e.localeCompare(s)}),"sortVariables"),H=v((t,e)=>{switch(t.type){case"array":return e.split(",").map(r=>r.trim()).filter(Boolean);case"boolean":return e==="true"||e==="1"||e==="yes"||e==="y";case"enum":return t.multiple?e.split(",").map(r=>r.trim()).filter(Boolean):e;case"number":{const r=Number(e);if(Number.isNaN(r))throw new TypeError(`Expected a number, got "${e}"`);return r}default:return e}},"parseValue"),F=v((t,e,r)=>{if(e.type==="enum"){const s=Array.isArray(r)?r:[r];for(const n of s)if(typeof n!="string"||!e.values.includes(n))throw new Error(`Variable "${t}" must be one of: ${e.values.join(", ")} (got "${String(n)}")`)}},"validateValue"),Be=v(async t=>{const{defaults:e,interactive:r,overrides:s,variables:n}=t,i={},a=r?de({input:process.stdin,output:process.stderr}):null;try{for(const[o,c]of We(n)){if(Object.hasOwn(s,o)){const $=H(c,s[o]??"");F(o,c,$),i[o]=$;continue}if(e||!r||c.internal){if(c.default!==void 0){F(o,c,c.default),i[o]=c.default;continue}if(c.required)throw new Error(`Required variable "${o}" not provided. Pass --${o}=<value> or remove --defaults.`);continue}const g=De(o,c);let m;if(c.type==="boolean")m=await ke(a,g,!!(c.default??!1));else if(c.type==="enum")if(c.multiple){const $=Array.isArray(c.default)?c.default:[];m=await _e(a,g,c.values,$)}else{const $=typeof c.default=="string"?c.default:void 0;m=await xe(a,g,c.values,$)}else{const $=c.default===void 0?"":` (${String(c.default)})`,S=await M(a,Pe(`${g}${$}`));if(S===""&&c.default!==void 0)m=c.default;else if(S===""){if(c.required)throw new Error(`Variable "${o}" is required`);continue}else m=H(c,S)}F(o,c,m),i[o]=m}return i}finally{a?.close()}},"collectOptions");var qe=Object.defineProperty,V=j((t,e)=>qe(t,"name",{value:e,configurable:!0}),"o");const Ie=["git://","npm://","https://","github:","gitlab:","bitbucket:","sourcehut:"],Me=V(t=>Ie.some(e=>t.startsWith(e)),"isRemoteSource"),Ce=V(async(t,e={})=>{const r=e.targetDirectory===void 0,s=e.targetDirectory??me(N(ge(),"vis-generate-")),n=V(()=>{if(r)try{he(s,{force:!0,recursive:!0})}catch{}},"cleanup");l.info(`Downloading ${t}…`);try{const i=await $e(t,{auth:e.auth||process.env.GIGET_AUTH||process.env.GITHUB_TOKEN||process.env.GH_TOKEN||void 0,dir:s,force:!0,preferOffline:e.preferOffline});return{cleanup:n,directory:i.dir}}catch(i){n();const a=i instanceof Error?i.message:String(i);throw l.warn(`Failed to download template: ${a}`),i}},"fetchRemoteTemplate");var Ae=Object.defineProperty,R=j((t,e)=>Ae(t,"name",{value:e,configurable:!0}),"a");const re=R((t,e="")=>{const r=[];for(const[s,n]of Object.entries(t)){const i=e?`${e}/${s}`:s;typeof n=="string"||Buffer.isBuffer(n)?r.push({content:n,path:i}):n&&typeof n=="object"&&r.push(...re(n,i))}return r},"flattenTree"),Fe=R(t=>t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`,"formatSize"),Le=R((t,e)=>{if(L(e))throw new Error(`Refusing to write outside destination: template produced absolute path "${e}".`);const r=N(t,e),s=Q(t,r);if(s===".."||s.startsWith(`..${pe}`)||L(s))throw new Error(`Refusing to write outside destination: "${e}" resolves to "${r}" which escapes "${t}".`);return r},"safeJoinDestination"),Ve=R((t,e)=>{Z(Y(t)),ye(t,e)},"writeOne"),Ke=R((t,e,r=!1)=>{const s=typeof t=="string"?[t]:t.commands,n=typeof t=="string"?r:t.silent??r;for(const i of s){n||l.info(`$ ${i}`);const a=we(i,{cwd:e,shell:!0,stdio:n?"ignore":"inherit"});if(a.status!==0)return l.warn(`Script failed (exit ${String(a.status)}): ${i}`),!1}return!0},"runScript"),ze=R(t=>{const e=new Map;for(const r of t){const s=typeof r=="string"?0:r.phase??0,n=e.get(s);n?n.push(r):e.set(s,[r])}return[...e.entries()].sort(([r],[s])=>r-s)},"groupByPhase"),Ue=R(async(t,e)=>{const r={builtins:{dest_dir:e.destination,dest_rel_dir:Q(e.workspaceRoot,e.destination)||".",working_dir:e.cwd,workspace_root:e.workspaceRoot},options:e.options},s=await t.produce(r),n=s.files?re(s.files):[],i=s.filesMeta??{},a=[];for(const o of n){const c=Le(e.destination,o.path);a.push({file:o,meta:i[o.path]??{},target:c})}if(e.dryRun){l.info(`${b(T("Plan"))} ${p("(dry-run, no files written)")}`);for(const o of a){const c=Buffer.isBuffer(o.file.content)?o.file.content.length:Buffer.byteLength(o.file.content,"utf8");process.stderr.write(` ${p("write")} ${o.file.path} ${p(`(${Fe(c)})`)}
|
|
10
|
+
`)}}else{Z(e.destination);let o=0,c=0;for(const g of a){const{file:m,meta:$,target:S}=g,C=_(S),O=e.force||$.force===!0;if(C&&!O){l.warn(`Skipped existing file: ${m.path} (use --force or set frontmatter force: true to overwrite)`),c+=1;continue}Ve(S,m.content),o+=1}l.success(`Wrote ${String(o)} file${o===1?"":"s"}${c>0?`, skipped ${String(c)}`:""}`)}if(!e.dryRun&&!e.skipScripts&&s.scripts&&s.scripts.length>0){const o=ze(s.scripts);l.info(`Running ${String(s.scripts.length)} script${s.scripts.length===1?"":"s"} across ${String(o.length)} phase${o.length===1?"":"s"}…`);for(const[,c]of o)if((await Promise.all(c.map(g=>Promise.resolve(Ke(g,e.destination))))).includes(!1))throw new Error("Script failed — aborting.")}if(s.suggestions&&s.suggestions.length>0){process.stderr.write(`
|
|
11
|
+
`),l.notice("Next steps:");for(const o of s.suggestions)process.stderr.write(` ${p("•")} ${o}
|
|
12
|
+
`)}},"runTemplate");var Ge=Object.defineProperty,w=j((t,e)=>Ge(t,"name",{value:e,configurable:!0}),"u");const Je=w(async t=>{let e;try{e=(await t.load()).about?.description}catch{}return{description:e,name:t.name,path:t.path,source:t.source}},"toListEntry"),He=w((t,e)=>{const r={default:e.default,name:t,order:e.order,prompt:e.prompt,required:e.required,type:e.type};return e.type==="enum"&&(r.multiple=e.multiple,r.values=e.values),r},"summarizeVariable"),Ye=w(async t=>{const e=await t.load(),r=Object.entries(e.options??{}).sort(([s,n],[i,a])=>{const o=n.order??0,c=a.order??0;return o===c?s.localeCompare(i):o-c}).map(([s,n])=>He(s,n));return{description:e.about?.description??"",destination:e.destination,name:t.name,path:t.path,source:t.source,variables:r}},"describeTemplate"),Qe=w(t=>{if(t.length===0){l.info("No templates found."),l.notice("Create one at .vis/templates/<name>.ts (programmatic) or .vis/templates/<name>/ (moon-format with template.yml).");return}l.info("Available templates:");for(const e of t){const r=p(`(${e.source})`);process.stderr.write(` ${b(T(e.name))} ${r}
|
|
13
|
+
`)}},"printList"),Xe=w(t=>{const e={},r=[];for(const s of t){if(!s.startsWith("--")){r.push(s);continue}const n=s.indexOf("=");if(n===-1){const o=s.slice(2);o.startsWith("no-")?e[o.slice(3)]="false":e[o]="true";continue}const i=s.slice(2,n),a=s.slice(n+1);e[i]=a}return{overrides:e,remaining:r}},"parsePassthroughOverrides"),Ze=w(async t=>{const{createInterface:e}=await import("node:readline"),r=e({input:process.stdin,output:process.stderr});try{process.stderr.write(` ${b(T("vis generate"))} ${p("— pick a template")}
|
|
4
14
|
|
|
5
|
-
`}${
|
|
6
|
-
`
|
|
7
|
-
|
|
15
|
+
`);for(const[s,n]of t.entries()){const i=b(T(` ${String(s+1)}.`));process.stderr.write(`${i} ${n.name} ${p(`(${n.source})`)}
|
|
16
|
+
`)}return new Promise((s,n)=>{r.question(`
|
|
17
|
+
${p(`Enter choice (1-${String(t.length)}):`)} `,i=>{const a=Number.parseInt(i.trim(),10);Number.isInteger(a)&&a>=1&&a<=t.length?s(t[a-1].name):n(new Error("Invalid choice."))})})}finally{r.close()}},"pickInteractive"),at=w(async({argument:t,options:e,rawUnknown:r,visConfig:s,workspaceRoot:n})=>{const i=e.cwd||n||process.cwd(),a=n??i,o=s?.generator,c=Array.isArray(t)?t:t?[t]:[];if(e.list){const u=I({extraDirectories:o?.templates??[],onWarning:w(f=>{l.warn(f)},"onWarning"),workspaceRoot:a});if(e.json){const f=await Promise.all(u.map(d=>Je(d)));process.stdout.write(`${JSON.stringify(f,null,2)}
|
|
18
|
+
`);return}Qe(u);return}if(e.describe){const u=c[0];if(!u)throw new Error("`--describe` requires a template name. Run `vis generate --list` to see available templates.");const f=I({extraDirectories:o?.templates??[],onWarning:w(h=>{l.warn(h)},"onWarning"),workspaceRoot:a}).find(h=>h.name===u);if(!f)throw new Error(`Template "${u}" not found. Run \`vis generate --list\` to see available templates.`);const d=await Ye(f);if(e.json){process.stdout.write(`${JSON.stringify(d,null,2)}
|
|
19
|
+
`);return}if(l.info(`Template: ${b(T(d.name))} ${p(`(${d.source})`)}`),d.description&&l.info(d.description),d.destination&&l.info(`Destination: ${p(d.destination)}`),d.variables.length===0)l.info("No variables.");else{l.info("Variables:");for(const h of d.variables){const B=[h.type];h.required&&B.push("required"),h.default!==void 0&&B.push(`default=${JSON.stringify(h.default)}`),h.values&&B.push(`values=${h.values.join("|")}`),process.stderr.write(` ${b(T(h.name))} ${p(`(${B.join(", ")})`)}
|
|
20
|
+
`)}}return}let g=[...r??[]];if(g.length===0){const u=process.argv.slice(2),f=u.indexOf("--");f!==-1&&(g=u.slice(f+1))}const m=c.indexOf("--"),$=m===-1?[]:c.slice(m+1),S=m===-1?c:c.slice(0,m),{overrides:C}=Xe([...$,...g]);let O,D,W;const k=S[0];let A;if(k&&Me(k)){const u=await Ce(k,{auth:o?.auth,preferOffline:!!e.preferOffline||o?.preferOffline});A=u.cleanup;try{const f=I({extraDirectories:[u.directory],workspaceRoot:a}).find(d=>d.path.startsWith(u.directory));if(!f)throw new Error(`Downloaded template at ${u.directory} contains no template.yml or *.ts entrypoint.`);O=await f.load(),D=f.name,W=O.destination}catch(f){throw A(),f}}else{const u=I({extraDirectories:o?.templates??[],onWarning:w(h=>{l.warn(h)},"onWarning"),workspaceRoot:a});if(u.length===0)throw new Error("No templates found. Create one at .vis/templates/<name>.ts or .vis/templates/<name>/template.yml.");let f;if(k)f=k;else{if(e.interactive===!1||!process.stdin.isTTY)throw new Error("No template specified. Pass a template name (see `vis generate --list`) or run interactively in a terminal.");f=await Ze(u)}const d=u.find(h=>h.name===f);if(!d)throw new Error(`Template "${f}" not found. Run 'vis generate --list' to see available templates.`);O=await d.load(),D=d.name,W=O.destination}const K=e.to,z=!!e.dryRun,se=!!e.force,U=!!e.defaults,oe=!!e.skipScripts,ne=e.interactive!==!1&&!!process.stdin.isTTY&&!U;let E;K?E=K:W?E=W:E=".";const G=L(E)?E:fe(i,E);l.info(`Template: ${b(T(D))}`),l.info(`Target: ${p(G)}`),process.stderr.write(`
|
|
21
|
+
`);const ie=await Be({defaults:U,interactive:ne,overrides:C,variables:O.options??{}});try{await Ue(O,{cwd:i,destination:G,dryRun:z,force:se,options:ie,skipScripts:oe,workspaceRoot:a}),z||(process.stderr.write(`
|
|
22
|
+
`),l.success(`Template '${D}' applied.`))}finally{A?.()}},"execute");export{at as default};
|
|
@@ -1,22 +1,61 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)
|
|
3
|
-
`)}
|
|
4
|
-
${f(`Enter choice (1-${String(r.length)}):`)} `);if(n===""&&s!==void 0)return s;const i=Number.parseInt(n,10);if(Number.isInteger(i)&&i>=1&&i<=r.length)return r[i-1];const a=r.find(o=>o===n);if(a)return a;process.stderr.write(` ${f("Invalid choice. Try again.")}
|
|
5
|
-
`)}},"selectOne"),_e=v(async(t,e,r,s)=>{process.stderr.write(` ${e} ${f("(comma-separated numbers)")}
|
|
6
|
-
`);for(const[n,i]of r.entries()){const a=b(T(` ${String(n+1)}.`)),o=s.includes(i)?f(" (default)"):"";process.stderr.write(`${a} ${i}${o}
|
|
7
|
-
`)}for(;;){const n=await M(t,`
|
|
8
|
-
${f("Enter choices:")} `);if(n===""&&s.length>0)return s;const i=n.split(",").map(a=>Number.parseInt(a.trim(),10)).filter(a=>Number.isInteger(a)&&a>=1&&a<=r.length);if(i.length>0)return i.map(a=>r[a-1]);process.stderr.write(` ${f("Invalid choice. Try again.")}
|
|
9
|
-
`)}},"selectMany"),Pe=v(t=>` ${f(`${t}:`)} `,"promptText"),De=v((t,e)=>e.prompt??t,"variableLabel"),We=v(t=>Object.entries(t).sort(([e,r],[s,n])=>{const i=r.order??0,a=n.order??0;return i!==a?i-a:e.localeCompare(s)}),"sortVariables"),H=v((t,e)=>{switch(t.type){case"array":return e.split(",").map(r=>r.trim()).filter(Boolean);case"boolean":return e==="true"||e==="1"||e==="yes"||e==="y";case"enum":return t.multiple?e.split(",").map(r=>r.trim()).filter(Boolean):e;case"number":{const r=Number(e);if(Number.isNaN(r))throw new TypeError(`Expected a number, got "${e}"`);return r}default:return e}},"parseValue"),F=v((t,e,r)=>{if(e.type==="enum"){const s=Array.isArray(r)?r:[r];for(const n of s)if(typeof n!="string"||!e.values.includes(n))throw new Error(`Variable "${t}" must be one of: ${e.values.join(", ")} (got "${String(n)}")`)}},"validateValue"),Be=v(async t=>{const{defaults:e,interactive:r,overrides:s,variables:n}=t,i={},a=r?me({input:process.stdin,output:process.stderr}):null;try{for(const[o,c]of We(n)){if(Object.hasOwn(s,o)){const $=H(c,s[o]??"");F(o,c,$),i[o]=$;continue}if(e||!r||c.internal){if(c.default!==void 0){F(o,c,c.default),i[o]=c.default;continue}if(c.required)throw new Error(`Required variable "${o}" not provided. Pass --${o}=<value> or remove --defaults.`);continue}const g=De(o,c);let m;if(c.type==="boolean")m=await ke(a,g,!!(c.default??!1));else if(c.type==="enum")if(c.multiple){const $=Array.isArray(c.default)?c.default:[];m=await _e(a,g,c.values,$)}else{const $=typeof c.default=="string"?c.default:void 0;m=await xe(a,g,c.values,$)}else{const $=c.default===void 0?"":` (${String(c.default)})`,S=await M(a,Pe(`${g}${$}`));if(S===""&&c.default!==void 0)m=c.default;else if(S===""){if(c.required)throw new Error(`Variable "${o}" is required`);continue}else m=H(c,S)}F(o,c,m),i[o]=m}return i}finally{a?.close()}},"collectOptions");var qe=Object.defineProperty,V=j((t,e)=>qe(t,"name",{value:e,configurable:!0}),"o");const Ie=["git://","npm://","https://","github:","gitlab:","bitbucket:","sourcehut:"],Me=V(t=>Ie.some(e=>t.startsWith(e)),"isRemoteSource"),Ce=V(async(t,e={})=>{const r=e.targetDirectory===void 0,s=e.targetDirectory??he(N($e(),"vis-generate-")),n=V(()=>{if(r)try{ge(s,{force:!0,recursive:!0})}catch{}},"cleanup");l.info(`Downloading ${t}…`);try{const i=await we(t,{auth:e.auth||process.env.GIGET_AUTH||process.env.GITHUB_TOKEN||process.env.GH_TOKEN||void 0,dir:s,force:!0,preferOffline:e.preferOffline});return{cleanup:n,directory:i.dir}}catch(i){n();const a=i instanceof Error?i.message:String(i);throw l.warn(`Failed to download template: ${a}`),i}},"fetchRemoteTemplate");var Ae=Object.defineProperty,R=j((t,e)=>Ae(t,"name",{value:e,configurable:!0}),"a");const re=R((t,e="")=>{const r=[];for(const[s,n]of Object.entries(t)){const i=e?`${e}/${s}`:s;typeof n=="string"||Buffer.isBuffer(n)?r.push({content:n,path:i}):n&&typeof n=="object"&&r.push(...re(n,i))}return r},"flattenTree"),Fe=R(t=>t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`,"formatSize"),Le=R((t,e)=>{if(L(e))throw new Error(`Refusing to write outside destination: template produced absolute path "${e}".`);const r=N(t,e),s=X(t,r);if(s===".."||s.startsWith(`..${fe}`)||L(s))throw new Error(`Refusing to write outside destination: "${e}" resolves to "${r}" which escapes "${t}".`);return r},"safeJoinDestination"),Ve=R((t,e)=>{Z(Q(t)),pe(t,e)},"writeOne"),ze=R((t,e,r=!1)=>{const s=typeof t=="string"?[t]:t.commands,n=typeof t=="string"?r:t.silent??r;for(const i of s){n||l.info(`$ ${i}`);const a=ye(i,{cwd:e,shell:!0,stdio:n?"ignore":"inherit"});if(a.status!==0)return l.warn(`Script failed (exit ${String(a.status)}): ${i}`),!1}return!0},"runScript"),Ke=R(t=>{const e=new Map;for(const r of t){const s=typeof r=="string"?0:r.phase??0,n=e.get(s);n?n.push(r):e.set(s,[r])}return[...e.entries()].sort(([r],[s])=>r-s)},"groupByPhase"),Ue=R(async(t,e)=>{const r={builtins:{dest_dir:e.destination,dest_rel_dir:X(e.workspaceRoot,e.destination)||".",working_dir:e.cwd,workspace_root:e.workspaceRoot},options:e.options},s=await t.produce(r),n=s.files?re(s.files):[],i=s.filesMeta??{},a=[];for(const o of n){const c=Le(e.destination,o.path);a.push({file:o,meta:i[o.path]??{},target:c})}if(e.dryRun){l.info(`${b(T("Plan"))} ${f("(dry-run, no files written)")}`);for(const o of a){const c=Buffer.isBuffer(o.file.content)?o.file.content.length:Buffer.byteLength(o.file.content,"utf8");process.stderr.write(` ${f("write")} ${o.file.path} ${f(`(${Fe(c)})`)}
|
|
10
|
-
`)}}else{Z(e.destination);let o=0,c=0;for(const g of a){const{file:m,meta:$,target:S}=g,C=_(S),O=e.force||$.force===!0;if(C&&!O){l.warn(`Skipped existing file: ${m.path} (use --force or set frontmatter force: true to overwrite)`),c+=1;continue}Ve(S,m.content),o+=1}l.success(`Wrote ${String(o)} file${o===1?"":"s"}${c>0?`, skipped ${String(c)}`:""}`)}if(!e.dryRun&&!e.skipScripts&&s.scripts&&s.scripts.length>0){const o=Ke(s.scripts);l.info(`Running ${String(s.scripts.length)} script${s.scripts.length===1?"":"s"} across ${String(o.length)} phase${o.length===1?"":"s"}…`);for(const[,c]of o)if((await Promise.all(c.map(g=>Promise.resolve(ze(g,e.destination))))).includes(!1))throw new Error("Script failed — aborting.")}if(s.suggestions&&s.suggestions.length>0){process.stderr.write(`
|
|
11
|
-
`),l.notice("Next steps:");for(const o of s.suggestions)process.stderr.write(` ${f("•")} ${o}
|
|
12
|
-
`)}},"runTemplate");var Ge=Object.defineProperty,w=j((t,e)=>Ge(t,"name",{value:e,configurable:!0}),"u");const Je=w(async t=>{let e;try{e=(await t.load()).about?.description}catch{}return{description:e,name:t.name,path:t.path,source:t.source}},"toListEntry"),He=w((t,e)=>{const r={default:e.default,name:t,order:e.order,prompt:e.prompt,required:e.required,type:e.type};return e.type==="enum"&&(r.multiple=e.multiple,r.values=e.values),r},"summarizeVariable"),Ye=w(async t=>{const e=await t.load(),r=Object.entries(e.options??{}).sort(([s,n],[i,a])=>{const o=n.order??0,c=a.order??0;return o===c?s.localeCompare(i):o-c}).map(([s,n])=>He(s,n));return{description:e.about?.description??"",destination:e.destination,name:t.name,path:t.path,source:t.source,variables:r}},"describeTemplate"),Qe=w(t=>{if(t.length===0){l.info("No templates found."),l.notice("Create one at .vis/templates/<name>.ts (programmatic) or .vis/templates/<name>/ (moon-format with template.yml).");return}l.info("Available templates:");for(const e of t){const r=f(`(${e.source})`);process.stderr.write(` ${b(T(e.name))} ${r}
|
|
13
|
-
`)}},"printList"),Xe=w(t=>{const e={},r=[];for(const s of t){if(!s.startsWith("--")){r.push(s);continue}const n=s.indexOf("=");if(n===-1){const o=s.slice(2);o.startsWith("no-")?e[o.slice(3)]="false":e[o]="true";continue}const i=s.slice(2,n),a=s.slice(n+1);e[i]=a}return{overrides:e,remaining:r}},"parsePassthroughOverrides"),Ze=w(async t=>{const{createInterface:e}=await import("node:readline"),r=e({input:process.stdin,output:process.stderr});try{process.stderr.write(` ${b(T("vis generate"))} ${f("— pick a template")}
|
|
1
|
+
var H=Object.defineProperty;var j=(e,t)=>H(e,"name",{value:t,configurable:!0});import{createRequire as K}from"node:module";import{b as V,B as A,w as X}from"./config.js";import{$ as Y,K as D,z as T,M as C}from"../packem_shared/readFileSync-CGmzMUF2-D6rUjGDn.js";import{o as Z}from"../packem_shared/index-DH-5hsrC.js";import{aF as P,C as ee,aG as te,X as oe}from"./bin.js";import{i as re}from"../packem_shared/glob-MHJQjR39-CQ2GC0b_.js";import{n as ne}from"../packem_shared/manifests-Z3spBpxv.js";const z=K(import.meta.url),O=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,Q=j(e=>{if(typeof O<"u"&&O.versions&&O.versions.node){const[t,o]=O.versions.node.split(".").map(Number);if(t>22||t===22&&o>=3||t===20&&o>=16)return O.getBuiltinModule(e)}return z(e)},"__cjs_getBuiltinModule"),{readFileSync:L}=Q("node:fs");var se=Object.defineProperty,y=j((e,t)=>se(e,"name",{value:t,configurable:!0}),"c");const ie=y((e,t)=>{const o=t.replace(/^\.?\//,"");return o===""||o==="."?`/${e}/`:e===""||e==="."?`/${o}`:`/${e}/${o}`},"toWorkspacePath"),_=y((e,t,o=[])=>{const s=[],r=new Set;for(const[i,n]of Object.entries(t?.globalPaths??{}))s.push({owners:n,path:i,source:"project-json"}),r.add(i);for(const[i,n]of Object.entries(e.projects)){const a=n.owners??[];for(const c of a){const l=ie(n.root??i,c.path);s.push({channel:c.channel,owners:c.owners,path:l,projectId:i,source:"project-json"}),r.add(l)}}for(const i of o)r.has(i.path)||(s.push(i),r.add(i.path));return(t?.orderBy??"file-source")==="project-id"?s.sort((i,n)=>(i.projectId??"").localeCompare(n.projectId??"")||i.path.localeCompare(n.path)):s.sort((i,n)=>i.path.localeCompare(n.path)),s},"buildCodeownersLines"),ae="Update each project's project.json `owners` field and re-run the command.",ce=y(e=>["# CODEOWNERS — generated by `vis sync codeowners`. Do not edit by hand.",e?`# Re-run with: ${e}`:`# ${ae}`,""],"buildHeader"),M=y(e=>{const t=[];for(const o of e){const s=o.owners.join(" "),r=o.channel?` # notify: ${o.channel}`:"";t.push(`${o.path} ${s}${r}`)}return t},"renderEntries"),de=y((e,t={})=>[...ce(t.regenerationCommand),...M(e),""].join(`
|
|
2
|
+
`),"renderCodeowners"),S={begin:"# BEGIN vis-codeowners",end:"# END vis-codeowners"},le=y((e,t=S,o={})=>{const s=o.regenerationCommand?`# Generated by vis sync codeowners — re-run with: ${o.regenerationCommand}`:"# Generated by `vis sync codeowners` — do not edit by hand.";return[t.begin,s,...M(e),t.end].join(`
|
|
3
|
+
`)},"renderCodeownersBlock"),ue=y((e,t,o=S)=>{const s=e.indexOf(o.begin),r=e.indexOf(o.end);if(s!==-1&&r!==-1&&r>s){const n=e.slice(0,s),a=r+o.end.length,c=e.slice(a);return`${n}${t}${c}`}const i=e.replace(/\s+$/u,"");return`${i.length===0?"":`${i}
|
|
14
4
|
|
|
15
|
-
`
|
|
16
|
-
`)}return new
|
|
17
|
-
|
|
18
|
-
`);return
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
`}${t}
|
|
6
|
+
`},"mergeIntoExisting");var fe=Object.defineProperty,G=j((e,t)=>fe(e,"name",{value:t,configurable:!0}),"f$1");const pe=["**/CODEOWNERS"],he=["**/node_modules/**","**/dist/**","**/build/**","**/coverage/**","**/.git/**","**/.next/**","**/.nuxt/**"],ge=G(e=>{const t=[];for(const o of e.split(/\r?\n/u)){const s=o.indexOf("#"),r=(s===-1?o:o.slice(0,s)).trim();if(r.length===0)continue;const i=r.split(/\s+/u);if(i.length<2)continue;const[n,...a]=i,c=a.filter(l=>l.length>0);!n||c.length===0||t.push({owners:c,path:n})}return t},"parseCodeownersFile"),me=G((e,t)=>{const o=t.replace(/^\.\/?/,"").replace(/\/$/,"");return e.startsWith("/")?o===""?e:`/${o}${e}`:o===""?`/${e}`:`/${o}/${e}`},"rewriteNestedPath"),we=G(async(e,t,o)=>{const s=t&&t.length>0?[...t]:[...pe],r=[...he];if(o){const a=o.replace(/^\.\/?/,"").replace(/^\/+/,"");a.length>0&&r.push(a)}const i=await re(s,{absolute:!0,cwd:e,ignore:r}),n=[];for(const a of i){let c;try{c=Y(a)}catch{continue}const l=D(a),p=T(e,l);for(const m of ge(c))n.push({owners:m.owners,path:me(m.path,p)})}return n},"collectNestedCodeownersLines"),be=/^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/?#]+)/iu,$e=G(e=>{if(!e)return;const t=e.match(be);if(!t?.[1])return;const o=t[1].trim();if(!(o===""||o.includes(" ")))return`@${o.replace(/^@/,"")}`},"extractGitHubHandle"),je=G((e,t)=>{const o=[];for(const[s,r]of Object.entries(e.projects)){if(r.owners&&r.owners.length>0)continue;const i=r.root??s,n=C(t,i,"package.json"),a=P(n);if(!a)continue;const c=ne(a.maintainers);if(!c||c.length===0)continue;const l=[],p=new Set;for(const m of c){const w=$e(m.url);w&&!p.has(w)&&(p.add(w),l.push(w))}l.length!==0&&o.push({owners:l,path:i===""||i==="."?"/":`/${i}/`,projectId:s})}return o},"collectMaintainerLines");var ye=Object.defineProperty,v=j((e,t)=>ye(e,"name",{value:t,configurable:!0}),"s");const ke=["author","bugs","homepage","license","repository","engines"],I=v(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isPlainObject"),R=v((e,t)=>{if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null)return!1;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(const[o,s]of e.entries())if(!R(s,t[o]))return!1;return!0}if(typeof e=="object"&&typeof t=="object"){const o=Object.keys(e),s=Object.keys(t);if(o.length!==s.length)return!1;for(const r of o)if(!R(e[r],t[r]))return!1;return!0}return!1},"deepEqual"),x=v(e=>e===void 0?e:structuredClone(e),"cloneJson"),Ce=v((e,t,o)=>{if(e==="repository"&&I(t)&&I(o)){const s={};for(const[r,i]of Object.entries(t))r!=="directory"&&(s[r]=x(i));return typeof o.directory=="string"&&(s.directory=o.directory),s}return x(t)},"buildTargetValue"),ve=v((e,t,o)=>{const s=[];for(const r of o.fields){if(!Object.hasOwn(e,r))continue;const i=e[r],n=t[r],a=Ce(r,i,n);R(a,n)||s.push({after:a,before:n,field:r,packageJsonPath:""})}return s},"computeFieldChanges"),Ee=v((e,t)=>{for(const o of t)e[o.field]=o.after},"applyFieldChanges");var Oe=Object.defineProperty,N=j((e,t)=>Oe(e,"name",{value:t,configurable:!0}),"n");const U="Generated by `vis sync codeowners --write-guard`. Do not edit by hand.",Ge=N(e=>{const t=e.replace(/^\.?\/+/u,"").replace(/\/+$/u,"");return t===""||t==="."?"**":`${t}/**`},"toPathGlob"),q=N(e=>{const t=new Set,o=[];for(const s of[...e].sort((r,i)=>r.name.localeCompare(i.name))){const r=Ge(s.root);t.has(r)||(t.add(r),o.push(r))}return o},"resolveGlobs"),Ne=N(e=>{const t=q(e),o=t.map(r=>` - "${r}"`).join(`
|
|
7
|
+
`),s=t.map(r=>` ${r}`).join(`
|
|
8
|
+
`);return`# ${U}
|
|
9
|
+
name: Write Guard
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
pull_request:
|
|
13
|
+
paths:
|
|
14
|
+
${o}
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
pull-requests: read
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
write-guard:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 0
|
|
27
|
+
- uses: geritol/write-guard@v1
|
|
28
|
+
with:
|
|
29
|
+
codeowners: CODEOWNERS
|
|
30
|
+
paths: |
|
|
31
|
+
${s}
|
|
32
|
+
`},"renderGithubWriteGuard"),Pe=N(e=>{const t=q(e).map(o=>` - "${o}/*"`).join(`
|
|
33
|
+
`);return`# ${U}
|
|
34
|
+
#
|
|
35
|
+
# SOFT GUARD ONLY — this job does NOT block a merge by itself.
|
|
36
|
+
# It verifies the generated CODEOWNERS is in sync and flags that a
|
|
37
|
+
# restricted path changed. GitLab CI cannot portably gate a merge on
|
|
38
|
+
# code-owner *approval* from a job, so REAL ENFORCEMENT REQUIRES the
|
|
39
|
+
# native GitLab setting:
|
|
40
|
+
# Settings -> Repository -> Protected branches ->
|
|
41
|
+
# "Require approval from Code Owners" (GitLab Premium / Ultimate)
|
|
42
|
+
# https://docs.gitlab.com/ee/user/project/codeowners/
|
|
43
|
+
# Without that setting enabled, this job is advisory only.
|
|
44
|
+
write-guard:
|
|
45
|
+
stage: test
|
|
46
|
+
image: node:22-alpine
|
|
47
|
+
rules:
|
|
48
|
+
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
49
|
+
changes:
|
|
50
|
+
${t}
|
|
51
|
+
script:
|
|
52
|
+
- corepack enable
|
|
53
|
+
- pnpm install --frozen-lockfile
|
|
54
|
+
- pnpm vis sync codeowners --check
|
|
55
|
+
- >-
|
|
56
|
+
echo "SOFT GUARD: a restricted path changed. This job does NOT enforce
|
|
57
|
+
code-owner approval. Enable 'Require approval from Code Owners' on the
|
|
58
|
+
protected branch (GitLab Premium/Ultimate) for a real merge gate:
|
|
59
|
+
https://docs.gitlab.com/ee/user/project/codeowners/"
|
|
60
|
+
`},"renderGitlabWriteGuard"),Re=N(e=>e.length===0?[]:[{content:Ne(e),path:".github/workflows/write-guard.yml"},{content:Pe(e),path:".gitlab/write-guard.gitlab-ci.yml"}],"buildWriteGuardArtifacts");var Se=Object.defineProperty,k=j((e,t)=>Se(e,"name",{value:t,configurable:!0}),"m");const B=new Set(["nested-codeowners","package-json-maintainers","project-json"]),J=k((e,t,o)=>{const s=new Set,r=[];for(const i of e??[])for(const n of i.split(",")){const a=n.trim();if(a.length===0)continue;if(o&&!o(a))throw new Error(`Unknown codeowners source: "${a}". Known: ${[...B].join(", ")}.`);const c=a;s.has(c)||(s.add(c),r.push(c))}return r.length>0?r:[...t]},"parseCsvOption"),We=k(e=>B.has(e),"isCodeownersSource"),F=["codeowners","package-json-fields"],_e=k((e,t)=>t.some(o=>Z(o,e)),"matchesAnyGlob"),Ie=k((e,t,o,s)=>{const r=Object.entries(o.projects).filter(([,n])=>n.restricted===!0).map(([n,a])=>({name:n,root:a.root??n})),i=Re(r);if(i.length===0){e.info("No projects flagged `restricted: true` in project.json. Skipping Write Guard.");return}if(s){let n=!1;for(const a of i){const c=C(t,a.path);let l="";try{l=L(c,"utf8")}catch(p){if(p.code!=="ENOENT")throw p}l.trim()!==a.content.trim()&&(e.error(`${a.path} is out of date. Run \`vis sync codeowners --write-guard\` to update it.`),n=!0)}n?process.exitCode=1:e.info(`Write Guard CI is up to date (${i.length} files, ${r.length} restricted projects).`);return}for(const n of i){const a=C(t,n.path);V(D(a)),A(a,n.content),e.info(`Wrote ${n.path}`)}e.info(`Write Guard CI scoped to ${r.length} restricted project${r.length===1?"":"s"}.`)},"handleWriteGuard"),xe=k(async({logger:e,options:t,visConfig:o,workspaceRoot:s})=>{const r=s,{workspace:i}=ee(r,o),n=o?.codeowners;t.writeGuard===!0&&Ie(e,r,i,t.check===!0);const a=J(t.from,n?.sources??["project-json"],We),c=t.regenerationCommand??n?.regenerationCommand,l=t.preserveBlock===!0||n?.preserveBlock===!0,p=n?.blockMarker??S,m=t.nestedIncludes??n?.nestedIncludes,w=t.out??"CODEOWNERS",f=[];if(a.includes("nested-codeowners")){const g=await we(r,m,w);for(const $ of g)f.push({...$,source:"nested"})}if(a.includes("package-json-maintainers")){const g=je(i,r);for(const $ of g)f.push({...$,source:"maintainers"})}const b=a.includes("project-json")?_(i,n,f):_({projects:{}},n,f);if(b.length===0){e.info("No `owners` entries found in any source. Nothing to sync.");return}const u=C(r,w);let E="";try{E=L(u,"utf8")}catch(g){if(g.code!=="ENOENT")throw g}const d={regenerationCommand:c},h=l?ue(E,le(b,p,d),p):de(b,d);if(t.check){if(E.trim()!==h.trim()){e.error(`${u} is out of date. Run \`vis sync codeowners\` to update it.`),process.exitCode=1;return}e.info(`${u} is up to date.`);return}A(u,h),e.info(`Wrote ${b.length} entries to ${u}`)},"runCodeowners"),Fe=k(({logger:e,options:t,visConfig:o,workspaceRoot:s})=>{const r=s,i=o?.editorconfig??!0,n=P(C(r,"package.json"));if(!n){e.error("Could not read root package.json. Nothing to sync."),process.exitCode=1;return}const a=J(t.fields,ke),c=t.ignorePackageName??[],l=t.check===!0,p=(t.format??"human").toLowerCase(),m=t.quiet===!0,w=te(r).filter(d=>d!=="."),f=[];let b=0;for(const d of w){const h=C(r,d,"package.json"),g=P(h);if(!g)continue;const $=typeof g.name=="string"?g.name:void 0;if($!==void 0&&c.length>0&&_e($,c))continue;b+=1;const W=ve(n,g,{fields:a});W.length!==0&&f.push({filePath:h,packageJsonPath:T(r,h),packageName:$,pkg:g,pkgChanges:W})}if(!l)for(const d of f)Ee(d.pkg,d.pkgChanges),X(d.filePath,d.pkg,{indent:oe(d.filePath,{useEditorconfig:i}),overwrite:!0});const u=f.flatMap(d=>d.pkgChanges.map(h=>({after:h.after,before:h.before,field:h.field,packageJsonPath:d.packageJsonPath,packageName:d.packageName}))),E={changes:u,fields:a,kind:"package-json-fields",mode:l?"check":"write",totalChanges:u.length,totalPackages:b};if(p==="json")process.stdout.write(`${JSON.stringify(E,null,4)}
|
|
61
|
+
`);else if(u.length===0)e.info(`All ${b} package${b===1?"":"s"} in sync (fields: ${a.join(", ")}).`);else if(l){if(!m)for(const d of u)e.error(`${d.packageJsonPath}: ${d.field} drifts from root`);e.error(`Found ${u.length} field drift${u.length===1?"":"s"} across ${f.length} package${f.length===1?"":"s"}. Run \`vis sync package-json-fields\` to fix.`)}else{if(!m)for(const d of f)e.info(`${d.packageJsonPath}: synced ${d.pkgChanges.map(h=>h.field).join(", ")}`);e.info(`Synced ${u.length} field${u.length===1?"":"s"} across ${f.length} package${f.length===1?"":"s"}.`)}l&&u.length>0&&(process.exitCode=1)},"runPackageJsonFields"),Je=k(async e=>{const t=e.argument[0];if(!t)throw new Error(`Missing sync kind. Usage: vis sync <kind> (known kinds: ${F.join(", ")})`);if(!e.workspaceRoot)throw new Error("Could not determine workspace root. Run inside a monorepo.");if(t==="codeowners"){await xe(e);return}if(t==="package-json-fields"){Fe(e);return}throw new Error(`Unknown sync kind: "${t}". Known kinds: ${F.join(", ")}.`)},"execute");export{Je as default};
|