@vitnode/core 2.0.0-canary.1 → 2.0.0-canary.3
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/scripts/scripts.js +50 -46
- package/dist/src/config.js +1 -1
- package/dist/src/framework/vite/index.d.ts +2 -0
- package/dist/src/framework/vite/index.d.ts.map +1 -1
- package/dist/src/framework/vite/index.js +1 -1
- package/dist/src/framework/vite/optimize-deps.d.ts +1 -1
- package/dist/src/framework/vite/optimize-deps.d.ts.map +1 -1
- package/dist/src/framework/vite/optimize-deps.js +1 -1
- package/dist/src/framework/vite/vitnode.d.ts +7 -0
- package/dist/src/framework/vite/vitnode.d.ts.map +1 -0
- package/dist/src/framework/vite/vitnode.js +1 -0
- package/dist/src/tanstack/i18n/messages.d.ts +3 -1
- package/dist/src/tanstack/i18n/messages.d.ts.map +1 -1
- package/dist/src/tanstack/i18n/messages.js +1 -1
- package/dist/src/tanstack/i18n/server.d.ts +1 -1
- package/dist/src/tanstack/i18n/server.d.ts.map +1 -1
- package/dist/src/tanstack/start/create-start.d.ts +9 -0
- package/dist/src/tanstack/start/create-start.d.ts.map +1 -0
- package/dist/src/tanstack/start/create-start.js +1 -0
- package/dist/src/tanstack/start/document-headers.d.ts +4 -0
- package/dist/src/tanstack/start/document-headers.d.ts.map +1 -0
- package/dist/src/tanstack/start/document-headers.js +1 -0
- package/dist/src/tanstack/start/index.d.ts +4 -0
- package/dist/src/tanstack/start/index.d.ts.map +1 -0
- package/dist/src/tanstack/start/index.js +1 -0
- package/dist/src/tanstack/start/locale-middleware.d.ts +3 -0
- package/dist/src/tanstack/start/locale-middleware.d.ts.map +1 -0
- package/dist/src/tanstack/start/locale-middleware.js +1 -0
- package/dist/src/tanstack/start/locale-request.d.ts +6 -0
- package/dist/src/tanstack/start/locale-request.d.ts.map +1 -0
- package/dist/src/tanstack/start/locale-request.js +1 -0
- package/dist/src/vitnode.config.d.ts +8 -2
- package/dist/src/vitnode.config.d.ts.map +1 -1
- package/dist/src/vitnode.config.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/test-fixtures/config-split/vitnode.config.ts +23 -0
- package/test-fixtures/config-split/vitnode.server.config.ts +13 -0
package/dist/scripts/scripts.js
CHANGED
|
@@ -2,22 +2,27 @@
|
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
const require = createRequire(import.meta.url);
|
|
4
4
|
|
|
5
|
-
import{config as co}from"dotenv";import{spawn as An}from"child_process";var z=async(e,n=[])=>await new Promise((o,t)=>{let r=An(e,n,{stdio:"inherit",shell:!0,env:process.env});r.on("error",s=>{t(s)}),r.on("close",s=>{s!==0?t(new Error(`Command failed with exit code ${s}`)):o(!0)})});var Fe=async()=>{await z("tsc",["-p","tsconfig.build.json"]),await z("swc",["src","-d","dist","--config-file",".swcrc","--copy-files"]),await z("tsc-alias",["-p","tsconfig.build.json"])};var be={build:{flags:[],positional:0,usage:"vitnode build"},"db:prepare":{flags:[],positional:0,usage:"vitnode db:prepare"},dev:{flags:[],positional:0,usage:"vitnode dev"},"i18n:check":{flags:["--ci"],positional:0,usage:"vitnode i18n:check [--ci]"},"i18n:create":{flags:[],positional:"any",usage:'vitnode i18n:create <code> "<name>"'},"i18n:delete":{flags:[],positional:1,usage:"vitnode i18n:delete <code>"},"i18n:update":{flags:[],positional:0,usage:"vitnode i18n:update"},"i18n:update:ai":{flags:["--concurrency","--model"],positional:"any",usage:"vitnode i18n:update:ai [code...] [--model <id>] [--concurrency <n>]",valueFlags:["--concurrency","--model"]},migrate:{flags:["--generate"],positional:0,usage:"vitnode migrate [--generate]"}},Sn=()=>Object.keys(be).sort(),In=e=>e!==void 0&&Object.hasOwn(be,e),Tn=e=>e.map(n=>`"${n}"`).join(", "),Rn=e=>{let n=e.indexOf("=");return n===-1?[e,void 0]:[e.slice(0,n),e.slice(n+1)]},Ln=e=>e.flags.length===0?"It accepts no flags.":`Allowed: ${[...e.flags].sort().join(", ")}.`,En=(e,n,o)=>{let t=`for command "${e}"`,r=`Usage: ${n.usage}`;if(n.flags.length===0&&n.positional===0)return o.length===0?null:`Command "${e}" accepts no arguments, but got ${Tn(o)}. ${r}`;let s=n.valueFlags??[],i=new Set,l=0;for(let d=0;d<o.length;d+=1){let m=o[d];if(!m.startsWith("-")){l+=1;continue}let[y,C]=Rn(m);if(!n.flags.includes(y))return`Invalid argument "${m}" ${t}. ${Ln(n)} ${r}`;if(i.has(y))return`Argument "${y}" is repeated ${t}. ${r}`;if(i.add(y),!s.includes(y)){if(C!==void 0)return`Argument "${y}" ${t} takes no value. ${r}`;continue}if(C!==void 0){if(C==="")return`Argument "${y}" ${t} needs a value. ${r}`;continue}let $=o[d+1];if($===void 0||$.startsWith("-"))return`Argument "${y}" ${t} needs a value. ${r}`;d+=1}return n.positional!=="any"&&l>n.positional?n.positional===0?`Command "${e}" accepts no positional arguments, but got ${String(l)}. ${r}`:`Command "${e}" accepts at most ${String(n.positional)} argument, but got ${String(l)}. ${r}`:null},qe=e=>{let[n,...o]=e,t=`Available commands: ${Sn().join(", ")}.`;if(n===void 0||n==="")return{message:`No command given. ${t}`,ok:!1};if(!In(n))return{message:`Command not found: "${n}". ${t}`,ok:!1};let r=En(n,be[n],o);return r===null?{args:o,command:n,ok:!0}:{message:r,ok:!1}};import{spawn as Pn}from"child_process";var we=(e,n)=>{let o=Pn(e,n,{stdio:"inherit",shell:process.platform==="win32",env:process.env});return o.on("error",t=>{console.error(`\x1B[31m${e} failed:\x1B[0m`,t)}),o.on("exit",t=>{t!==null&&t!==0&&console.error(`\x1B[31m${e} exited with code ${t}\x1B[0m`)}),o},Ue=({initMessage:e})=>{let n=[we("tsc",["-w","-p","tsconfig.build.json","--preserveWatchOutput"]),we("swc",["src","-d","dist","--config-file",".swcrc","--copy-files","-w"]),we("tsc-alias",["-w","-p","tsconfig.build.json"])],o=()=>{n.forEach(t=>t.kill()),process.exit(0)};process.on("SIGINT",o),process.on("SIGTERM",o),console.log(`${e} \x1B[34mWatching plugin sources...\x1B[0m`)};import{existsSync as Ze,readdirSync as Gn,readFileSync as Bn}from"fs";import{join as He,relative as Jn}from"path";import{createJiti as jn}from"jiti";import{existsSync as Dn,readdirSync as Mn,statSync as On}from"fs";import{join as Ke}from"path";var xe=(e,n,o=4)=>{let t=(r,s)=>{if(s>o)return null;try{let i=Ke(r,"src",n);if(Dn(i))return i;let l=Mn(r);for(let d of l){if(d==="node_modules"||d.startsWith(".")||d==="dist"||d==="build"||d==="out")continue;let m=Ke(r,d);try{if(On(m).isDirectory()){let y=t(m,s+1);if(y)return y}}catch{}}}catch{}return null};return t(e,0)};async function I({baseDir:e,type:n="config",optional:o=!1}={}){let t=e??process.cwd(),r=`vitnode.${n}.ts`,s=xe(t,r);if(!s){if(o)return null;console.error(`Config file not found: ${r}`),console.error(`Searched recursively in ${t} (excluding node_modules, .*, dist, build, out)`),process.exit(1)}try{let i=n==="config"?"vitNodeConfig":"vitNodeApiConfig",m=(await jn(import.meta.url,{interopDefault:!0}).import(s))[i];if(!m){if(o)return null;console.error(`Export "${i}" not found in ${s}`),process.exit(1)}return m}catch(i){if(o)return null;console.error("Failed to load config:",i),process.exit(1)}}import{existsSync as de,readdirSync as Be,readFileSync as Je}from"fs";import{join as W}from"path";import{stdin as Fn,stdout as qn}from"process";import{createInterface as Un}from"readline/promises";var Ve=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),le=(e,n)=>{let o={...e};for(let t of Object.keys(n)){if(t==="__proto__")continue;let r=n[t],s=o[t];o[t]=Ve(s)&&Ve(r)?le(s,r):r}return o};import{existsSync as $e}from"fs";import{join as ce,resolve as We}from"path";function G(e){let n=e;for(;n!==We(n,"..");){let t=ce(n,"turbo.json");if($e(t))return n;n=We(n,"..")}let o=ce(e,"package.json");if($e(o))return e;throw new Error("\u274C Could not locate project root")}function Ge(e,n){let o=process.cwd();return[ce(o,"node_modules",e),...n===o?[]:[ce(n,"node_modules",e)]].find(r=>$e(r))??null}var ze="@vitnode/core",B=({api:e,web:n})=>n||e?{api:e,web:n}:{api:!0,web:!0},ge=(e,n,{repoRoot:o,scope:t})=>{let r=Ge(e,o);if(!r)return[];let s=W(r,"src","locales"),i=[];return t.web&&i.push(W(s,`${n}.json`)),t.api&&i.push(W(s,"api",`${n}.json`)),i},H=e=>{if(!de(e))return{};try{let n=JSON.parse(Je(e,"utf-8"));return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:{}}catch{return{}}},ue=(e,n="")=>typeof e!="object"||e===null||Array.isArray(e)?n?[n]:[]:Object.entries(e).flatMap(([o,t])=>ue(t,n?`${n}.${o}`:o)),Kn=(e,{locale:n,repoRoot:o,scope:t})=>ge(e,n,{repoRoot:o,scope:t}).map(H).reduce((r,s)=>le(r,s),{}),Vn=(e,n,o)=>H(W(e,"src","locales",n,`${o}.json`)),X=(e,{appDir:n,defaultLocale:o,repoRoot:t,scope:r})=>le(Kn(e,{locale:o,repoRoot:t,scope:r}),Vn(n,e,o)),w=e=>`\x1B[90m${e}\x1B[0m`,D=e=>`\x1B[31m${e}\x1B[0m`,T=e=>`\x1B[32m${e}\x1B[0m`,q=e=>`\x1B[36m${e}\x1B[0m`,J=e=>`\x1B[33m${e}\x1B[0m`,E="\x1B[34m[VitNode]\x1B[0m",pe=()=>Un({input:Fn,output:qn}),Wn=async(e,n,o)=>{for(;;){let t=(await e.question(n)).trim(),r=o(t);if(r){console.log(D(` ${r}`));continue}return t}},Ye=async(e,n)=>{let o=(await e.question(n)).trim().toLowerCase();return o==="y"||o==="yes"},se=async({missingMessage:e,provided:n,question:o,rl:t,validate:r})=>{if(n!==void 0){let s=r(n);return s&&(console.error(D(s)),process.exit(1)),n}return t||(console.error(D(e)),process.exit(1)),Wn(t,o,r)},fe=e=>{let n=W(e,"src"),o=W(n,"i18n.ts");if(de(o))return o;let t=new Set(["build","dist","node_modules","out"]),r=(s,i)=>{if(i>4||!de(s))return null;for(let l of Be(s,{withFileTypes:!0})){if(l.name.startsWith(".")||t.has(l.name))continue;let d=W(s,l.name);if(l.isDirectory()){let m=r(d,i+1);if(m)return m}else if(l.name.endsWith(".ts")){let m=Je(d,"utf-8");if(m.includes("defaultLocale")&&/locales\s*:\s*\[/.test(m))return d}}return null};return r(n,0)},Q=e=>{let n=W(e,"src","locales"),o=[];if(!de(n))return o;let t=(r,s)=>{for(let i of Be(r,{withFileTypes:!0})){let l=W(r,i.name);i.isDirectory()?t(l,[...s,i.name]):i.name.endsWith(".json")&&s.length>0&&o.push({locale:i.name.replace(/\.json$/,""),path:l,pluginId:s.join("/")})}};return t(n,[]),o};var zn="@vitnode/core",Z=8,Y=e=>`\x1B[90m${e}\x1B[0m`,ee=e=>`\x1B[31m${e}\x1B[0m`,_e=e=>`\x1B[33m${e}\x1B[0m`,Xe=e=>`\x1B[32m${e}\x1B[0m`,en=(e,n="")=>typeof e!="object"||e===null||Array.isArray(e)?n?[n]:[]:Object.entries(e).flatMap(([o,t])=>en(t,n?`${n}.${o}`:o)),Qe=e=>{if(!Ze(e))return null;try{return en(JSON.parse(Bn(e,"utf-8")))}catch(n){return console.error(ee(` Could not parse ${e}: ${String(n)}`)),[]}},Yn=e=>{let n=He(e,"src","locales"),o=[];if(!Ze(n))return o;let t=(r,s)=>{for(let i of Gn(r,{withFileTypes:!0})){let l=He(r,i.name);i.isDirectory()?t(l,[...s,i.name]):i.name.endsWith(".json")&&s.length>0&&o.push({locale:i.name.replace(/\.json$/,""),path:l,pluginId:s.join("/")})}};return t(n,[]),o},nn=async e=>{let n=e==="--ci",o=process.cwd(),t=G(o),r=await I({optional:!0}),s=await I({optional:!0,type:"api.config"}),i=r??s;i||(console.error(ee("No vitnode.config.ts or vitnode.api.config.ts found.")),process.exit(1));let l=B({api:s!==null,web:r!==null}),d=i.i18n?.defaultLocale??"en",m=(i.i18n?.locales??[]).map(c=>c.code),y=i.i18n?.messages??{},C=[...new Set([zn,...[r,s].flatMap(c=>(c?.plugins??[]).map(b=>b.pluginId))])],$=Yn(o),h=[...new Set([...m,...$.map(c=>c.locale)])].filter(c=>c!==d);console.log(`\x1B[34m[VitNode]\x1B[0m Checking ${C.length} package(s) against ${h.length||"no"} extra locale(s), default ${Y(d)}.`);let v=0,x=0,R=0,p=new Set(m),f=(c,b)=>{let _=ge(c,b,{repoRoot:t,scope:l}).map(Qe).filter(O=>O!==null),N=$.find(O=>O.pluginId===c&&O.locale===b),M=N?Qe(N.path):null;return _.length===0&&!M?null:[...new Set([..._.flat(),...M??[]])]};for(let c of C){let b=f(c,d);if(!b){ge(c,d,{repoRoot:t,scope:l}).length>0?console.log(Y(` ${c}: no strings for this app - nothing to translate`)):(console.log(_e(` ${c}: no "${d}" messages found - is the package installed?`)),x+=1);continue}for(let _ of h){let N=f(c,_);if(!N){p.has(_)?(R+=1,x+=1,console.log(ee(` ${c} \xB7 ${_}: no locale file - create src/locales/${c}/${_}.json`))):console.log(Y(` ${c} \xB7 ${_}: not translated, falls back to ${d}`));continue}let M=new Set(b),O=new Set(N),S=b.filter(u=>!O.has(u)),P=N.filter(u=>!M.has(u));if(S.length===0&&P.length===0){console.log(Xe(` ${c} \xB7 ${_}: complete`));continue}if(S.length>0){v+=S.length,x+=1,console.log(_e(` ${c} \xB7 ${_}: ${S.length} key(s) missing, falling back to ${d}`));for(let u of S.slice(0,Z))console.log(Y(` ${u}`));S.length>Z&&console.log(Y(` ... and ${S.length-Z} more`))}if(P.length>0){x+=1,console.log(_e(` ${c} \xB7 ${_}: ${P.length} key(s) unknown to ${d} - typo or leftover?`));for(let u of P.slice(0,Z))console.log(Y(` ${u}`));P.length>Z&&console.log(Y(` ... and ${P.length-Z} more`))}}}for(let c of $){let b=y[c.locale]?.[c.pluginId],_=Jn(o,c.path);b?m.length>0&&!m.includes(c.locale)&&(R+=1,x+=1,console.log(ee(` ${_} uses a locale that is not in \`i18n.locales\`.`))):(R+=1,x+=1,console.log(ee(` ${_} is never loaded - add \`"${c.pluginId}": () => import("./locales/${c.pluginId}/${c.locale}.json")\` under \`i18n.messages.${c.locale}\`.`)))}x===0&&(console.log(Xe(" Everything is translated. Nice.")),process.exit(0)),console.log(`\x1B[34m[VitNode]\x1B[0m ${x} issue(s)`+(R>0?ee(`, ${R} error(s)`):"")+`, ${v} untranslated key(s).`),process.exit(R>0||n?1:0)};import{existsSync as Hn,mkdirSync as Xn,readFileSync as Qn,writeFileSync as ve}from"fs";import{dirname as Zn,join as tn,relative as ie}from"path";var et=/^[a-z]{2,3}(-[A-Za-z]{2,4})?$/,Ne=(e,n,o)=>`${e}"${n}": () => import("./locales/${n}/${o}.json"),`,ne=e=>JSON.stringify(e),on=(e,n)=>/^[^\S\n]*\n/.test(e.slice(n)),rn=e=>{let n=/\bi18n\s*[:=]\s*\{/.exec(e);if(n?.index===void 0)return null;let o=n.index+n[0].length-1,t=0;for(let r=o;r<e.length;r+=1)if(e[r]==="{")t+=1;else if(e[r]==="}"&&(t-=1,t===0))return{end:r,start:o};return null},ke=(e,n,o,t)=>{e.lastIndex=o;let r=e.exec(n);return r&&r.index<t?r:null},nt=(e,{code:n,name:o})=>{let t=rn(e);if(!t)return null;let r=ke(/^([^\S\n]*)locales\s*:\s*\[/gm,e,t.start,t.end);if(!r)return null;let s=`${r[1]} `,i=r.index+r[0].length,l=`{ code: ${ne(n)}, name: ${ne(o)} },`,d=on(e,i)?`
|
|
5
|
+
import{config as po}from"dotenv";import{spawn as Tn}from"child_process";var z=async(e,n=[])=>await new Promise((o,t)=>{let r=Tn(e,n,{stdio:"inherit",shell:!0,env:process.env});r.on("error",s=>{t(s)}),r.on("close",s=>{s!==0?t(new Error(`Command failed with exit code ${s}`)):o(!0)})});var Ke=async()=>{await z("tsc",["-p","tsconfig.build.json"]),await z("swc",["src","-d","dist","--config-file",".swcrc","--copy-files"]),await z("tsc-alias",["-p","tsconfig.build.json"])};var $e={build:{flags:[],positional:0,usage:"vitnode build"},"db:prepare":{flags:[],positional:0,usage:"vitnode db:prepare"},dev:{flags:[],positional:0,usage:"vitnode dev"},"i18n:check":{flags:["--ci"],positional:0,usage:"vitnode i18n:check [--ci]"},"i18n:create":{flags:[],positional:"any",usage:'vitnode i18n:create <code> "<name>"'},"i18n:delete":{flags:[],positional:1,usage:"vitnode i18n:delete <code>"},"i18n:update":{flags:[],positional:0,usage:"vitnode i18n:update"},"i18n:update:ai":{flags:["--concurrency","--model"],positional:"any",usage:"vitnode i18n:update:ai [code...] [--model <id>] [--concurrency <n>]",valueFlags:["--concurrency","--model"]},migrate:{flags:["--generate"],positional:0,usage:"vitnode migrate [--generate]"}},Rn=()=>Object.keys($e).sort(),Ln=e=>e!==void 0&&Object.hasOwn($e,e),En=e=>e.map(n=>`"${n}"`).join(", "),Pn=e=>{let n=e.indexOf("=");return n===-1?[e,void 0]:[e.slice(0,n),e.slice(n+1)]},jn=e=>e.flags.length===0?"It accepts no flags.":`Allowed: ${[...e.flags].sort().join(", ")}.`,Mn=(e,n,o)=>{let t=`for command "${e}"`,r=`Usage: ${n.usage}`;if(n.flags.length===0&&n.positional===0)return o.length===0?null:`Command "${e}" accepts no arguments, but got ${En(o)}. ${r}`;let s=n.valueFlags??[],a=new Set,l=0;for(let u=0;u<o.length;u+=1){let p=o[u];if(!p.startsWith("-")){l+=1;continue}let[m,S]=Pn(p);if(!n.flags.includes(m))return`Invalid argument "${p}" ${t}. ${jn(n)} ${r}`;if(a.has(m))return`Argument "${m}" is repeated ${t}. ${r}`;if(a.add(m),!s.includes(m)){if(S!==void 0)return`Argument "${m}" ${t} takes no value. ${r}`;continue}if(S!==void 0){if(S==="")return`Argument "${m}" ${t} needs a value. ${r}`;continue}let x=o[u+1];if(x===void 0||x.startsWith("-"))return`Argument "${m}" ${t} needs a value. ${r}`;u+=1}return n.positional!=="any"&&l>n.positional?n.positional===0?`Command "${e}" accepts no positional arguments, but got ${String(l)}. ${r}`:`Command "${e}" accepts at most ${String(n.positional)} argument, but got ${String(l)}. ${r}`:null},Ve=e=>{let[n,...o]=e,t=`Available commands: ${Rn().join(", ")}.`;if(n===void 0||n==="")return{message:`No command given. ${t}`,ok:!1};if(!Ln(n))return{message:`Command not found: "${n}". ${t}`,ok:!1};let r=Mn(n,$e[n],o);return r===null?{args:o,command:n,ok:!0}:{message:r,ok:!1}};import{spawn as Dn}from"child_process";var _e=(e,n)=>{let o=Dn(e,n,{stdio:"inherit",shell:process.platform==="win32",env:process.env});return o.on("error",t=>{console.error(`\x1B[31m${e} failed:\x1B[0m`,t)}),o.on("exit",t=>{t!==null&&t!==0&&console.error(`\x1B[31m${e} exited with code ${t}\x1B[0m`)}),o},Ge=({initMessage:e})=>{let n=[_e("tsc",["-w","-p","tsconfig.build.json","--preserveWatchOutput"]),_e("swc",["src","-d","dist","--config-file",".swcrc","--copy-files","-w"]),_e("tsc-alias",["-w","-p","tsconfig.build.json"])],o=()=>{n.forEach(t=>t.kill()),process.exit(0)};process.on("SIGINT",o),process.on("SIGTERM",o),console.log(`${e} \x1B[34mWatching plugin sources...\x1B[0m`)};import{existsSync as tn,readdirSync as Yn,readFileSync as Hn}from"fs";import{join as Ze,relative as Xn}from"path";import{createJiti as On}from"jiti";import{existsSync as Fn,readdirSync as qn,statSync as Un}from"fs";import{join as We}from"path";var Kn={"api.config":"vitNodeApiConfig",config:"vitNodeConfig","server.config":"vitNodeServerConfig"},ve=(e,n,o=4)=>{let t=(r,s)=>{if(s>o)return null;try{let a=We(r,"src",n);if(Fn(a))return a;let l=qn(r);for(let u of l){if(u==="node_modules"||u.startsWith(".")||u==="dist"||u==="build"||u==="out")continue;let p=We(r,u);try{if(Un(p).isDirectory()){let m=t(p,s+1);if(m)return m}}catch{}}}catch{}return null};return t(e,0)};async function I({baseDir:e,type:n="config",optional:o=!1}={}){let t=e??process.cwd(),r=`vitnode.${n}.ts`,s=ve(t,r);if(!s){if(o)return null;console.error(`Config file not found: ${r}`),console.error(`Searched recursively in ${t} (excluding node_modules, .*, dist, build, out)`),process.exit(1)}try{let a=Kn[n],p=(await On(import.meta.url,{interopDefault:!0}).import(s))[a];if(!p){if(o)return null;console.error(`Export "${a}" not found in ${s}`),process.exit(1)}return p}catch(a){if(o)return null;console.error("Failed to load config:",a),process.exit(1)}}import{existsSync as de,readdirSync as Ye,readFileSync as He}from"fs";import{join as G}from"path";import{stdin as Vn,stdout as Gn}from"process";import{createInterface as Wn}from"readline/promises";var Be=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),le=(e,n)=>{let o={...e};for(let t of Object.keys(n)){if(t==="__proto__")continue;let r=n[t],s=o[t];o[t]=Be(s)&&Be(r)?le(s,r):r}return o};import{existsSync as Ne}from"fs";import{join as ce,resolve as Je}from"path";function W(e){let n=e;for(;n!==Je(n,"..");){let t=ce(n,"turbo.json");if(Ne(t))return n;n=Je(n,"..")}let o=ce(e,"package.json");if(Ne(o))return e;throw new Error("\u274C Could not locate project root")}function ze(e,n){let o=process.cwd();return[ce(o,"node_modules",e),...n===o?[]:[ce(n,"node_modules",e)]].find(r=>Ne(r))??null}var Xe="@vitnode/core",B=({api:e,web:n})=>n||e?{api:e,web:n}:{api:!0,web:!0},ge=(e,n,{repoRoot:o,scope:t})=>{let r=ze(e,o);if(!r)return[];let s=G(r,"src","locales"),a=[];return t.web&&a.push(G(s,`${n}.json`)),t.api&&a.push(G(s,"api",`${n}.json`)),a},H=e=>{if(!de(e))return{};try{let n=JSON.parse(He(e,"utf-8"));return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:{}}catch{return{}}},ue=(e,n="")=>typeof e!="object"||e===null||Array.isArray(e)?n?[n]:[]:Object.entries(e).flatMap(([o,t])=>ue(t,n?`${n}.${o}`:o)),Bn=(e,{locale:n,repoRoot:o,scope:t})=>ge(e,n,{repoRoot:o,scope:t}).map(H).reduce((r,s)=>le(r,s),{}),Jn=(e,n,o)=>H(G(e,"src","locales",n,`${o}.json`)),X=(e,{appDir:n,defaultLocale:o,repoRoot:t,scope:r})=>le(Bn(e,{locale:o,repoRoot:t,scope:r}),Jn(n,e,o)),b=e=>`\x1B[90m${e}\x1B[0m`,P=e=>`\x1B[31m${e}\x1B[0m`,T=e=>`\x1B[32m${e}\x1B[0m`,q=e=>`\x1B[36m${e}\x1B[0m`,J=e=>`\x1B[33m${e}\x1B[0m`,L="\x1B[34m[VitNode]\x1B[0m",pe=()=>Wn({input:Vn,output:Gn}),zn=async(e,n,o)=>{for(;;){let t=(await e.question(n)).trim(),r=o(t);if(r){console.log(P(` ${r}`));continue}return t}},Qe=async(e,n)=>{let o=(await e.question(n)).trim().toLowerCase();return o==="y"||o==="yes"},se=async({missingMessage:e,provided:n,question:o,rl:t,validate:r})=>{if(n!==void 0){let s=r(n);return s&&(console.error(P(s)),process.exit(1)),n}return t||(console.error(P(e)),process.exit(1)),zn(t,o,r)},fe=e=>{let n=G(e,"src"),o=G(n,"i18n.ts");if(de(o))return o;let t=new Set(["build","dist","node_modules","out"]),r=(s,a)=>{if(a>4||!de(s))return null;for(let l of Ye(s,{withFileTypes:!0})){if(l.name.startsWith(".")||t.has(l.name))continue;let u=G(s,l.name);if(l.isDirectory()){let p=r(u,a+1);if(p)return p}else if(l.name.endsWith(".ts")){let p=He(u,"utf-8");if(p.includes("defaultLocale")&&/locales\s*:\s*\[/.test(p))return u}}return null};return r(n,0)},Q=e=>{let n=G(e,"src","locales"),o=[];if(!de(n))return o;let t=(r,s)=>{for(let a of Ye(r,{withFileTypes:!0})){let l=G(r,a.name);a.isDirectory()?t(l,[...s,a.name]):a.name.endsWith(".json")&&s.length>0&&o.push({locale:a.name.replace(/\.json$/,""),path:l,pluginId:s.join("/")})}};return t(n,[]),o};var Qn="@vitnode/core",Z=8,Y=e=>`\x1B[90m${e}\x1B[0m`,ee=e=>`\x1B[31m${e}\x1B[0m`,Ce=e=>`\x1B[33m${e}\x1B[0m`,en=e=>`\x1B[32m${e}\x1B[0m`,on=(e,n="")=>typeof e!="object"||e===null||Array.isArray(e)?n?[n]:[]:Object.entries(e).flatMap(([o,t])=>on(t,n?`${n}.${o}`:o)),nn=e=>{if(!tn(e))return null;try{return on(JSON.parse(Hn(e,"utf-8")))}catch(n){return console.error(ee(` Could not parse ${e}: ${String(n)}`)),[]}},Zn=e=>{let n=Ze(e,"src","locales"),o=[];if(!tn(n))return o;let t=(r,s)=>{for(let a of Yn(r,{withFileTypes:!0})){let l=Ze(r,a.name);a.isDirectory()?t(l,[...s,a.name]):a.name.endsWith(".json")&&s.length>0&&o.push({locale:a.name.replace(/\.json$/,""),path:l,pluginId:s.join("/")})}};return t(n,[]),o},rn=async e=>{let n=e==="--ci",o=process.cwd(),t=W(o),r=await I({optional:!0}),s=await I({optional:!0,type:"api.config"}),a=await I({optional:!0,type:"server.config"}),l=r??s;l||(console.error(ee("No vitnode.config.ts or vitnode.api.config.ts found.")),process.exit(1));let u=B({api:s!==null,web:r!==null}),p=l.i18n?.defaultLocale??"en",m=(l.i18n?.locales??[]).map(d=>d.code),S=a?.messages??l.i18n?.messages??{},x=[...new Set([Qn,...[r,s].flatMap(d=>(d?.plugins??[]).map(R=>R.pluginId))])],y=Zn(o),v=[...new Set([...m,...y.map(d=>d.locale)])].filter(d=>d!==p);console.log(`\x1B[34m[VitNode]\x1B[0m Checking ${x.length} package(s) against ${v.length||"no"} extra locale(s), default ${Y(p)}.`);let N=0,A=0,g=0,h=new Set(m),f=(d,R)=>{let w=ge(d,R,{repoRoot:t,scope:u}).map(nn).filter(C=>C!==null),E=y.find(C=>C.pluginId===d&&C.locale===R),F=E?nn(E.path):null;return w.length===0&&!F?null:[...new Set([...w.flat(),...F??[]])]};for(let d of x){let R=f(d,p);if(!R){ge(d,p,{repoRoot:t,scope:u}).length>0?console.log(Y(` ${d}: no strings for this app - nothing to translate`)):(console.log(Ce(` ${d}: no "${p}" messages found - is the package installed?`)),A+=1);continue}for(let w of v){let E=f(d,w);if(!E){h.has(w)?(g+=1,A+=1,console.log(ee(` ${d} \xB7 ${w}: no locale file - create src/locales/${d}/${w}.json`))):console.log(Y(` ${d} \xB7 ${w}: not translated, falls back to ${p}`));continue}let F=new Set(R),C=new Set(E),j=R.filter(M=>!C.has(M)),D=E.filter(M=>!F.has(M));if(j.length===0&&D.length===0){console.log(en(` ${d} \xB7 ${w}: complete`));continue}if(j.length>0){N+=j.length,A+=1,console.log(Ce(` ${d} \xB7 ${w}: ${j.length} key(s) missing, falling back to ${p}`));for(let M of j.slice(0,Z))console.log(Y(` ${M}`));j.length>Z&&console.log(Y(` ... and ${j.length-Z} more`))}if(D.length>0){A+=1,console.log(Ce(` ${d} \xB7 ${w}: ${D.length} key(s) unknown to ${p} - typo or leftover?`));for(let M of D.slice(0,Z))console.log(Y(` ${M}`));D.length>Z&&console.log(Y(` ... and ${D.length-Z} more`))}}}for(let d of y){let R=S[d.locale]?.[d.pluginId],w=Xn(o,d.path);R?m.length>0&&!m.includes(d.locale)&&(g+=1,A+=1,console.log(ee(` ${w} uses a locale that is not in \`i18n.locales\`.`))):(g+=1,A+=1,console.log(ee(` ${w} is never loaded - add \`"${d.pluginId}": () => import("./${d.pluginId}/${d.locale}.json")\` under \`"${d.locale}"\` in \`src/locales/app.ts\`.`)))}A===0&&(console.log(en(" Everything is translated. Nice.")),process.exit(0)),console.log(`\x1B[34m[VitNode]\x1B[0m ${A} issue(s)`+(g>0?ee(`, ${g} error(s)`):"")+`, ${N} untranslated key(s).`),process.exit(g>0||n?1:0)};import{existsSync as sn,mkdirSync as et,readFileSync as an,writeFileSync as me}from"fs";import{dirname as nt,join as he,relative as ie}from"path";var tt=/^[a-z]{2,3}(-[A-Za-z]{2,4})?$/,ye=(e,n,o,t="./locales")=>`${e}"${n}": () => import("${t}/${n}/${o}.json"),`,ne=e=>JSON.stringify(e),Ae=(e,n)=>/^[^\S\n]*\n/.test(e.slice(n)),ke=he("src","locales","app.ts"),ot=(e,{code:n,pluginIds:o})=>{let t=/\bappMessages\s*(?::[^=]*)?=\s*\{/.exec(e);if(t?.index===void 0)return null;let r=t.index+t[0].length,s=o.map(l=>ye(" ",l,n,".")).join(`
|
|
6
|
+
`),a=`
|
|
7
|
+
"${n}": {
|
|
8
|
+
${s}
|
|
9
|
+
},`;return e.slice(0,r)+(Ae(e,r)?a:`${a}
|
|
10
|
+
`)+e.slice(r)},ln=e=>{let n=/\bi18n\s*[:=]\s*\{/.exec(e);if(n?.index===void 0)return null;let o=n.index+n[0].length-1,t=0;for(let r=o;r<e.length;r+=1)if(e[r]==="{")t+=1;else if(e[r]==="}"&&(t-=1,t===0))return{end:r,start:o};return null},Se=(e,n,o,t)=>{e.lastIndex=o;let r=e.exec(n);return r&&r.index<t?r:null},rt=(e,{code:n,name:o})=>{let t=ln(e);if(!t)return null;let r=Se(/^([^\S\n]*)locales\s*:\s*\[/gm,e,t.start,t.end);if(!r)return null;let s=`${r[1]} `,a=r.index+r[0].length,l=`{ code: ${ne(n)}, name: ${ne(o)} },`,u=Ae(e,a)?`
|
|
6
11
|
${s}${l}`:`
|
|
7
12
|
${s}${l}
|
|
8
|
-
${s}`;return e.slice(0,
|
|
9
|
-
`),
|
|
10
|
-
${
|
|
11
|
-
${
|
|
12
|
-
${
|
|
13
|
-
${
|
|
14
|
-
`)
|
|
15
|
-
${
|
|
16
|
-
${
|
|
17
|
-
${
|
|
18
|
-
${
|
|
19
|
-
${
|
|
20
|
-
`),
|
|
13
|
+
${s}`;return e.slice(0,a)+u+e.slice(a)},st=(e,n)=>{let o=0;for(let t=n;t<e.length;t+=1)if(e[t]==="[")o+=1;else if(e[t]==="]"&&(o-=1,o===0))return t;return-1},it=(e,{code:n,pluginIds:o})=>{let t=ln(e);if(!t)return null;let r=Se(/^([^\S\n]*)messages\s*:\s*\{/gm,e,t.start,t.end);if(r){let N=r[1],A=`${N} `,g=`${A} `,h=o.map(w=>ye(g,w,n)).join(`
|
|
14
|
+
`),f=r.index+r[0].length,d=`
|
|
15
|
+
${A}"${n}": {
|
|
16
|
+
${h}
|
|
17
|
+
${A}},`,R=Ae(e,f)?d:`${d}
|
|
18
|
+
${N}`;return e.slice(0,f)+R+e.slice(f)}let s=Se(/^([^\S\n]*)locales\s*:\s*\[/gm,e,t.start,t.end);if(!s)return null;let a=e.indexOf("[",s.index),l=st(e,a);if(l===-1)return null;let u=s[1],p=`${u} `,m=`${p} `,S=o.map(N=>ye(m,N,n)).join(`
|
|
19
|
+
`),x=l+1,y=",";e[x]===","&&(x+=1,y="");let v=`${y}
|
|
20
|
+
${u}messages: {
|
|
21
|
+
${p}"${n}": {
|
|
22
|
+
${S}
|
|
23
|
+
${p}},
|
|
24
|
+
${u}},`;return e.slice(0,x)+v+e.slice(x)},at=({code:e,defaultLocale:n,locales:o,name:t,pluginIds:r})=>{let s=[...o,{code:e,name:t}].map(l=>` { code: ${ne(l.code)}, name: ${ne(l.name)} },`).join(`
|
|
25
|
+
`),a=r.map(l=>ye(" ",l,e)).join(`
|
|
21
26
|
`);return`import type { VitNodeI18nConfig } from "@vitnode/core/lib/i18n/types";
|
|
22
27
|
|
|
23
28
|
/**
|
|
@@ -32,41 +37,40 @@ ${s}
|
|
|
32
37
|
],
|
|
33
38
|
messages: {
|
|
34
39
|
"${e}": {
|
|
35
|
-
${
|
|
40
|
+
${a}
|
|
36
41
|
},
|
|
37
42
|
},
|
|
38
43
|
} satisfies VitNodeI18nConfig;
|
|
39
|
-
`},
|
|
40
|
-
`);let
|
|
41
|
-
`),
|
|
44
|
+
`},cn=async()=>{let e=process.cwd(),n=await I({optional:!0}),o=await I({optional:!0,type:"api.config"}),t=n??o;t||(console.error(P("No vitnode.config.ts or vitnode.api.config.ts found.")),process.exit(1));let r=B({api:o!==null,web:n!==null}),s=n===null,a=t.i18n?.defaultLocale??"en",l=(t.i18n?.locales??[]).map(i=>({code:i.code,name:i.name})),u=new Set([a,...l.map(i=>i.code)]),p=[...new Set([Xe,...[n,o].flatMap(i=>(i?.plugins??[]).map(c=>c.pluginId))])].sort((i,c)=>i.localeCompare(c)),m=i=>i?tt.test(i)?u.has(i)?`"${i}" already exists in this app.`:null:"Use an ISO code like `pl`, `de`, or `pt-BR`.":"A locale code is required.",S=i=>i?null:"A language name is required.",[x,...y]=process.argv.slice(3),v=y.join(" ").trim()||void 0,g=(process.stdin.isTTY??!1)&&(x===void 0||v===void 0)?pe():null,h='Run: vitnode i18n:create <code> "<name>"';g&&console.log(`${L} Add a language. Press Ctrl+C to abort.
|
|
45
|
+
`);let f,d;try{f=await se({missingMessage:`Missing locale code. ${h}`,provided:x,question:q("? Locale code (e.g. pl, de, pt-BR): "),rl:g,validate:m}),d=await se({missingMessage:`Missing language name. ${h}`,provided:v,question:q("? Language name (e.g. Polski, Deutsch): "),rl:g,validate:S})}finally{g?.close()}console.log();let R=e;try{R=W(e)}catch{}let w=[],E=[],F=[],C=[];for(let i of p){let c=he(e,"src","locales",i,`${f}.json`);if(sn(c)){E.push(ie(e,c)),C.push(i);continue}let $=X(i,{appDir:e,defaultLocale:a,repoRoot:R,scope:r});if(Object.keys($).length===0){F.push(i);continue}et(nt(c),{recursive:!0}),me(c,`${JSON.stringify($,null,2)}
|
|
46
|
+
`),w.push(ie(e,c)),C.push(i)}for(let i of w)console.log(T(` created ${i}`));for(let i of E)console.log(b(` exists ${i}`));for(let i of F)console.log(b(` skipped ${i} (no strings for this app)`));let j=he(e,ke),D=!1;if(sn(j)&&C.length>0){let i=ot(an(j,"utf-8"),{code:f,pluginIds:C});i&&(me(j,i),console.log(T(` updated ${ke}`)),D=!0)}let M=fe(e);if(M){let i=an(M,"utf-8"),c=rt(i,{code:f,name:d}),$=c&&!D&&C.length>0?it(c,{code:f,pluginIds:C}):c;if($?(me(M,$),console.log(T(` updated ${ie(e,M)}`))):console.log(`
|
|
47
|
+
${L} Couldn't edit ${ie(e,M)} automatically. Add:
|
|
48
|
+
`+b(` locales: [{ code: ${ne(f)}, name: ${ne(d)} }, /* ... */]`)),!D&&C.length>0){let _=C.map(k=>` "${k}": () => import("./${k}/${f}.json"),`).join(`
|
|
42
49
|
`);console.log(`
|
|
43
|
-
${
|
|
44
|
-
`+
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
${
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
${
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
${
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
${
|
|
60
|
-
`),
|
|
61
|
-
|
|
62
|
-
${E} Translating with ${T(c.name)} ${w(`(${gn(c.model)})`)} into: ${f.map(a=>q(a)).join(", ")}
|
|
63
|
-
`);let b=new Map,_=a=>{let g=b.get(a);if(g)return g;let A=X(a,{appDir:e,defaultLocale:i,repoRoot:d,scope:s});return b.set(a,A),A},N=[];for(let a of f)for(let g of y.get(a)??[]){let A=Nt(e,g.path),k=_(g.pluginId);if(Object.keys(k).length===0){console.log(w(` skipped ${A} - no "${i}" source strings`));continue}let L=H(g.path),K=Se(k,L);N.push({current:L,file:g,locale:a,location:A,reconciled:K,untranslated:It(k,K)})}let M=[];for(let a of f){let g=N.filter(L=>L.locale===a).flatMap(L=>L.untranslated),A=Lt(g);if(A.length===0)continue;let k=l.get(a)??a;for(let L of Rt(A,Ct))M.push({languageName:k,locale:a,sources:L});console.log(` ${q(a)} ${g.length} string(s)${g.length===A.length?"":w(` (${A.length} unique)`)}`)}let O=new Map,S=[];if(M.length>0){let a=M.reduce((k,L)=>k+L.sources.length,0);console.log(w(` ${a} unique string(s) in ${M.length} batch(es), up to ${Math.min(R,M.length)} in parallel
|
|
64
|
-
`));let g=0,A=await Et(M,R,async k=>{let L=new Map,K;try{L=await Pt(async()=>jt({code:k.locale,languageName:k.languageName,model:c.model,sources:k.sources}))}catch(ye){K=ye}return g+=1,process.stdout.write(`\r ${w(`translated ${g}/${M.length} batch(es)`)}`),{error:K,locale:k.locale,translations:L}});process.stdout.write(`
|
|
50
|
+
${L} And register the files in ${ke}:
|
|
51
|
+
`+b(` "${f}": {
|
|
52
|
+
${_}
|
|
53
|
+
},`))}}else{let i=he(e,"src","i18n.ts");me(i,at({code:f,defaultLocale:a,locales:l,name:d,pluginIds:C})),console.log(T(` created ${ie(e,i)}`));let c=s?"buildApiConfig":"buildConfig";console.log(`
|
|
54
|
+
${L} Import it into your config so the app picks it up:
|
|
55
|
+
`+b(` import { i18n } from "./i18n";
|
|
56
|
+
`)+b(` ${c}({ i18n, /* ... */ });`))}console.log(`
|
|
57
|
+
${L} ${T(d)} (${f}) added. Translate the files above, then run ${q("vitnode i18n:check")}.`),process.exit(0)};import{existsSync as lt,readdirSync as ct,readFileSync as dt,rmdirSync as gt,unlinkSync as ut,writeFileSync as pt}from"fs";import{dirname as dn,join as ft,relative as we}from"path";var gn=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),mt=(e,n)=>{let o=0;for(let t=n;t<e.length;t+=1)if(e[t]==="[")o+=1;else if(e[t]==="]"&&(o-=1,o===0))return t;return-1},ht=(e,n)=>{let o=/locales\s*:\s*\[/.exec(e);if(o?.index===void 0)return e;let t=e.indexOf("[",o.index),r=mt(e,t);if(r===-1)return e;let s=new RegExp(`[^\\S\\n]*\\{[^{}]*\\bcode\\s*:\\s*["']${gn(n)}["'][^{}]*\\}[^\\S\\n]*,?\\n?`),a=e.slice(t,r+1),l=a.replace(s,"");return l===a?e:e.slice(0,t)+l+e.slice(r+1)},yt=(e,n)=>{let o=gn(n),t=new RegExp(`[^\\S\\n]*["']?${o}["']?\\s*:\\s*\\{[^{}]*\\}[^\\S\\n]*,?\\n?`);return e.replace(t,"")},un=async()=>{let e=process.cwd(),o=await I({optional:!0})??await I({optional:!0,type:"api.config"});o||(console.error(P("No vitnode.config.ts or vitnode.api.config.ts found.")),process.exit(1));let t=o.i18n?.defaultLocale??"en",r=(o.i18n?.locales??[]).map(g=>({code:g.code,name:g.name})),s=Q(e),a=new Set([...r.map(g=>g.code),...s.map(g=>g.locale)]),l=g=>g?g==="en"?"English is the built-in fallback and can't be removed.":g===t?`"${t}" is the default locale - change \`defaultLocale\` before removing it.`:a.has(g)?null:`No language "${g}" found in this app.`:"A locale code is required.",u=process.argv[3],m=process.stdin.isTTY??!1?pe():null,S=fe(e),x=g=>{let h=r.find(f=>f.code===g)?.name;return h?`${h} (${g})`:g},y="",v=!0;try{if(y=await se({missingMessage:"Missing locale code. Run: vitnode i18n:delete <code>",provided:u,question:q("? Locale code to remove: "),rl:m,validate:l}),m){console.log(`
|
|
58
|
+
${L} About to remove ${J(x(y))}:`);for(let g of s.filter(h=>h.locale===y))console.log(b(` delete ${we(e,g.path)}`));S&&console.log(b(` update ${we(e,S)}`)),v=await Qe(m,q(`
|
|
59
|
+
? Remove it? [y/N] `))}}finally{m?.close()}v||(console.log(b(`
|
|
60
|
+
Aborted, nothing was removed.`)),process.exit(0)),console.log();let N=ft(e,"src","locales"),A=g=>{let h=g;for(;h.startsWith(N)&&h!==N&&(lt(h)&&ct(h).length===0);)gt(h),h=dn(h)};for(let g of s.filter(h=>h.locale===y))ut(g.path),console.log(T(` deleted ${we(e,g.path)}`)),A(dn(g.path));if(S){let g=dt(S,"utf-8"),h=yt(ht(g,y),y);h!==g&&(pt(S,h),console.log(T(` updated ${we(e,S)}`)))}console.log(`
|
|
61
|
+
${L} ${T(x(y))} removed.`),process.exit(0)};import{checkbox as xt,select as $t}from"@inquirer/prompts";import{generateText as _t,Output as vt}from"ai";import{config as Nt}from"dotenv";import{writeFileSync as Ct}from"fs";import{dirname as Le,join as kt,relative as St}from"path";import{z as At}from"zod";import{writeFileSync as wt}from"fs";import{relative as bt}from"path";var Ie=8,Te=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),Re=(e,n)=>{let o=(t,r)=>{if(Te(t)){let s=Te(r)?r:{};return Object.fromEntries(Object.entries(t).map(([a,l])=>[a,o(l,s[a])]))}return r!==void 0&&!Te(r)?r:t};return o(e,n)},pn=async()=>{let e=process.cwd(),n=await I({optional:!0}),o=await I({optional:!0,type:"api.config"}),t=n??o;t||(console.error(P("No vitnode.config.ts or vitnode.api.config.ts found.")),process.exit(1));let r=B({api:o!==null,web:n!==null}),s=t.i18n?.defaultLocale??"en",a=e;try{a=W(e)}catch{}let l=Q(e).filter(y=>y.locale!==s);l.length===0&&(console.log(`${L} No translation files to update.`),process.exit(0));let u=new Map,p=y=>{let v=u.get(y);if(v)return v;let N=X(y,{appDir:e,defaultLocale:s,repoRoot:a,scope:r});return u.set(y,N),N};console.log(`${L} Syncing ${l.length} translation file(s) against ${b(s)}.`);let m=0,S=0,x=0;for(let y of l){let v=bt(e,y.path),N=p(y.pluginId);if(Object.keys(N).length===0){console.log(b(` skipped ${v} - no "${s}" source strings`));continue}let A=H(y.path),g=new Set(ue(N)),h=new Set(ue(A)),f=[...g].filter(w=>!h.has(w)),d=[...h].filter(w=>!g.has(w));if(f.length===0&&d.length===0){console.log(b(` ok ${v}`));continue}wt(y.path,`${JSON.stringify(Re(N,A),null,2)}
|
|
62
|
+
`),x+=1,m+=f.length,S+=d.length,console.log(`${T(` updated ${v}`)} ${b(`+${f.length} -${d.length}`)}`);for(let w of f.slice(0,Ie))console.log(T(` + ${w}`));for(let w of d.slice(0,Ie-f.length))console.log(P(` - ${w}`));let R=Math.min(f.length,Ie)+d.length;f.length+d.length>R&&console.log(b(` ... and ${f.length+d.length-R} more`))}x===0&&(console.log(T(" Every translation is already in sync.")),process.exit(0)),console.log(`
|
|
63
|
+
${L} ${T(`${x} file(s) updated`)}: ${J(`+${m}`)} added, ${J(`-${S}`)} removed. Translate the added keys, then run vitnode i18n:check.`),process.exit(0)};var It=40,Tt=6,Ee=3,Pe=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),fn=e=>typeof e=="string"?e:e.modelId,Rt=e=>{let n=e.replace(/\{[a-zA-Z0-9_]+\}/g,"").replace(/<[^>]+>/g,"");return/\p{L}/u.test(n)},Lt=(e,n)=>{let o=[],t=(r,s,a)=>{if(Pe(r)){let l=Pe(s)?s:{};for(let[u,p]of Object.entries(r))t(p,l[u],[...a,u]);return}typeof r=="string"&&s===r&&Rt(r)&&o.push({path:a,source:r})};return t(e,n,[]),o},Et=(e,n)=>{let o=structuredClone(e);for(let{path:t,value:r}of n){if(t.length===0)continue;let s=o,a=!0;for(let l=0;l<t.length-1;l+=1){let u=s[t[l]];if(!Pe(u)){a=!1;break}s=u}a&&(s[t[t.length-1]]=r)}return o},Pt=(e,n)=>{let o=[];for(let t=0;t<e.length;t+=n)o.push(e.slice(t,t+n));return o},jt=e=>{let n=new Set,o=[];for(let t of e)n.has(t.source)||(n.add(t.source),o.push(t.source));return o},Mt=async(e,n,o)=>{let t=new Array(e.length),r=0,s=async()=>{for(;;){let l=r;if(r+=1,l>=e.length)return;t[l]=await o(e[l],l)}},a=Math.max(1,Math.min(n,e.length));return await Promise.all(Array.from({length:a},async()=>s())),t},Dt=async e=>{let n;for(let o=0;o<Ee;o+=1)try{return await e()}catch(t){n=t,o<Ee-1&&await new Promise(r=>setTimeout(r,500*2**o))}throw n},Ot=async({code:e,languageName:n,model:o,sources:t})=>{let{output:r}=await _t({model:o,output:vt.array({element:At.string()}),temperature:0,system:["You are a professional software localization translator.",`Translate each string from English into ${n} (${e}).`,"Input is a JSON array of strings. Return a JSON array of the same length, in the same order - one translation per input string, and nothing else.","Preserve placeholders verbatim: {name}, {count}, ICU plurals such as {count, plural, one {#} other {#}}, and tags such as <b></b>. Never rename or reorder them.","Keep the original whitespace and punctuation. Don't translate brand names, code, URLs, or identifiers. Write natural, concise UI copy."].join(`
|
|
64
|
+
`),prompt:JSON.stringify(t)});if(r.length!==t.length)throw new Error(`expected ${t.length} translations, got ${r.length}`);let s=new Map;return t.forEach((a,l)=>{s.set(a,r[l])}),s},mn=async()=>{let e=process.cwd(),n=await I({optional:!0}),o=await I({optional:!0,type:"api.config"}),t=n??o;t||(console.error(P("No vitnode.config.ts or vitnode.api.config.ts found.")),process.exit(1));let r=o?.ai?.models??[];if(r.length===0){let i=Le(e),c=i!==e?ve(i,"vitnode.api.config.ts"):null;if(c&&(r=(await I({baseDir:i,optional:!0,type:"api.config"}))?.ai?.models??[],r.length>0)){let _=Le(Le(c));Nt({path:kt(_,".env"),quiet:!0})}}r.length===0&&(console.error(P("No AI models configured. Add an `ai.models` entry to vitnode.api.config.ts (searched this app and one level up).")),process.exit(1));let s=B({api:o!==null,web:n!==null}),a=t.i18n?.defaultLocale??"en",l=new Map((t.i18n?.locales??[]).map(i=>[i.code,i.name])),u=e;try{u=W(e)}catch{}let p=Q(e).filter(i=>i.locale!==a);p.length===0&&(console.log(`${L} No translation files to translate. Run ${q("vitnode i18n:create")} first.`),process.exit(0));let m=new Map;for(let i of p){let c=m.get(i.locale)??[];c.push(i),m.set(i.locale,c)}let S=[...m.keys()].sort((i,c)=>i.localeCompare(c)),x=process.argv.slice(3),y,v,N=[];for(let i=0;i<x.length;i+=1){let c=x[i];c==="--model"?(y=x[i+1],i+=1):c.startsWith("--model=")?y=c.slice(8):c==="--concurrency"?(v=Number(x[i+1]),i+=1):c.startsWith("--concurrency=")?v=Number(c.slice(14)):N.push(...c.split(/[\s,]+/).filter(Boolean))}let A=v&&Number.isInteger(v)&&v>0?v:Tt,g=process.stdin.isTTY??!1,h,f;try{if(N.length>0){let i=N.filter(c=>!m.has(c));i.length>0&&(console.error(P(`No translation files for: ${i.join(", ")}.`)),process.exit(1)),h=[...new Set(N)]}else g?h=await xt({choices:S.map(i=>({checked:!0,name:`${l.get(i)??i} ${b(`(${i})`)}`,value:i})),message:"Which languages should be translated from English?",required:!0}):(console.error(P("Missing languages. Run: vitnode i18n:update:ai <code...> [--model <id>]")),process.exit(1));if(y!==void 0){let i=r.find(c=>c.id===y);i||(console.error(P(`AI model "${y}" is not defined in vitnode.api.config.ts.`)),process.exit(1)),f=i}else if(g){let i=await $t({choices:r.map(c=>({name:`${c.name} ${b(fn(c.model))}`,value:c.id})),default:r[0].id,message:"Which AI model should translate? (from vitnode.api.config.ts)"});f=r.find(c=>c.id===i)??r[0]}else f=r[0]}catch(i){throw i instanceof Error&&i.name==="ExitPromptError"&&(console.log(b(`
|
|
65
|
+
Cancelled.`)),process.exit(0)),i}h.length===0&&(console.log(`${L} No languages selected.`),process.exit(0)),console.log(`
|
|
66
|
+
${L} Translating with ${T(f.name)} ${b(`(${fn(f.model)})`)} into: ${h.map(i=>q(i)).join(", ")}
|
|
67
|
+
`);let d=new Map,R=i=>{let c=d.get(i);if(c)return c;let $=X(i,{appDir:e,defaultLocale:a,repoRoot:u,scope:s});return d.set(i,$),$},w=[];for(let i of h)for(let c of m.get(i)??[]){let $=St(e,c.path),_=R(c.pluginId);if(Object.keys(_).length===0){console.log(b(` skipped ${$} - no "${a}" source strings`));continue}let k=H(c.path),K=Re(_,k);w.push({current:k,file:c,locale:i,location:$,reconciled:K,untranslated:Lt(_,K)})}let E=[];for(let i of h){let c=w.filter(k=>k.locale===i).flatMap(k=>k.untranslated),$=jt(c);if($.length===0)continue;let _=l.get(i)??i;for(let k of Pt($,It))E.push({languageName:_,locale:i,sources:k});console.log(` ${q(i)} ${c.length} string(s)${c.length===$.length?"":b(` (${$.length} unique)`)}`)}let F=new Map,C=[];if(E.length>0){let i=E.reduce((_,k)=>_+k.sources.length,0);console.log(b(` ${i} unique string(s) in ${E.length} batch(es), up to ${Math.min(A,E.length)} in parallel
|
|
68
|
+
`));let c=0,$=await Mt(E,A,async _=>{let k=new Map,K;try{k=await Dt(async()=>Ot({code:_.locale,languageName:_.languageName,model:f.model,sources:_.sources}))}catch(xe){K=xe}return c+=1,process.stdout.write(`\r ${b(`translated ${c}/${E.length} batch(es)`)}`),{error:K,locale:_.locale,translations:k}});process.stdout.write(`
|
|
65
69
|
|
|
66
|
-
`);for(let
|
|
67
|
-
`),
|
|
68
|
-
${
|
|
69
|
-
Everything is already translated.`)),process.exit(0)),
|
|
70
|
-
${E} ${T(`${P} file(s) updated`)}, ${J(String(u))} string(s) translated.`),process.exit(S.length>0?1:0)};import{count as Wt,sql as vn}from"drizzle-orm";import{migrate as Gt}from"drizzle-orm/postgres-js/migrator";import{createJiti as Bt}from"jiti";import{existsSync as Jt}from"fs";import{join as zt}from"path";import Yt from"postgres";import{camelCase as yn,index as he}from"drizzle-orm/pg-core";import{camelCase as Dt}from"drizzle-orm/pg-core";var U=Dt.table.withRLS("core_roles",e=>({id:e.serial().primaryKey(),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().$onUpdate(()=>new Date),protected:e.boolean().notNull().default(!1),default:e.boolean().notNull().default(!1),root:e.boolean().notNull().default(!1),guest:e.boolean().notNull().default(!1),color:e.varchar({length:50}),allowUploadFiles:e.boolean().notNull().default(!1),totalMaxStorage:e.integer(),maxStorageForSubmit:e.integer()}));import{camelCase as mn,index as hn}from"drizzle-orm/pg-core";import{camelCase as ae,index as oe,primaryKey as Mt}from"drizzle-orm/pg-core";import{camelCase as pn,index as Le}from"drizzle-orm/pg-core";var te=pn.table.withRLS("core_languages",e=>({id:e.serial().primaryKey(),code:e.varchar({length:32}).notNull().unique(),name:e.varchar({length:255}).notNull(),timezone:e.varchar({length:255}).notNull().default("UTC"),protected:e.boolean().notNull().default(!1),default:e.boolean().notNull().default(!1),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().defaultNow().$onUpdate(()=>new Date),time24:e.boolean().notNull().default(!1)}),e=>[Le("core_languages_code_idx").on(e.code),Le("core_languages_name_idx").on(e.name)]),fn=pn.table.withRLS("core_languages_words",e=>({id:e.serial().primaryKey(),languageCode:e.varchar().notNull().references(()=>te.code,{onDelete:"cascade"}),pluginCode:e.varchar({length:50}).notNull(),itemId:e.integer().notNull(),value:e.text().notNull(),tableName:e.varchar({length:255}).notNull(),variable:e.varchar({length:255}).notNull()}),e=>[Le("core_languages_words_lang_code_idx").on(e.languageCode)]);var F=ae.table.withRLS("core_users",e=>({id:e.serial().primaryKey(),nameCode:e.varchar({length:255}).notNull().unique(),name:e.varchar({length:255}).notNull().unique(),email:e.varchar({length:255}).notNull().unique(),password:e.varchar(),createdAt:e.timestamp().notNull().defaultNow(),newsletter:e.boolean().notNull().default(!1),avatarColor:e.varchar({length:6}).notNull(),emailVerified:e.boolean().notNull().default(!1),roleId:e.integer().references(()=>U.id).notNull(),birthday:e.timestamp(),ipAddress:e.varchar({length:40}).notNull(),language:e.varchar({length:32}).notNull().default("en").references(()=>te.code,{onDelete:"set default"})}),e=>[oe("core_users_name_code_idx").on(e.nameCode),oe("core_users_name_idx").on(e.name),oe("core_users_email_idx").on(e.email)]),$r=ae.table.withRLS("core_users_secondary_roles",e=>({userId:e.integer().references(()=>F.id,{onDelete:"cascade"}).notNull(),roleId:e.integer().references(()=>U.id,{onDelete:"cascade"}).notNull(),createdAt:e.timestamp().notNull().defaultNow()}),e=>[Mt({columns:[e.userId,e.roleId]}),oe("core_users_secondary_roles_user_id_idx").on(e.userId),oe("core_users_secondary_roles_role_id_idx").on(e.roleId)]),_r=ae.table.withRLS("core_users_sso",e=>({userId:e.integer().references(()=>F.id,{onDelete:"cascade"}).notNull(),providerId:e.varchar({length:255}).notNull(),providerAccountId:e.varchar({length:255}).notNull(),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().defaultNow().$onUpdate(()=>new Date)}),e=>[oe("core_users_sso_user_id_idx").on(e.userId)]),vr=ae.table.withRLS("core_users_confirm_emails",e=>({id:e.serial().primaryKey(),userId:e.integer().references(()=>F.id,{onDelete:"cascade"}).notNull(),token:e.varchar({length:100}).notNull().unique(),createdAt:e.timestamp().notNull().defaultNow(),expiresAt:e.timestamp().notNull(),ipAddress:e.varchar({length:40}).notNull()})),Nr=ae.table.withRLS("core_users_forgot_password",e=>({id:e.serial().primaryKey(),userId:e.integer().references(()=>F.id,{onDelete:"cascade"}).notNull().unique(),token:e.varchar({length:100}).notNull().unique(),ipAddress:e.varchar({length:40}).notNull(),createdAt:e.timestamp().notNull().defaultNow(),expiresAt:e.timestamp().notNull()}));var Sr=mn.table.withRLS("core_sessions",e=>({id:e.serial().primaryKey(),token:e.varchar({length:255}).notNull().unique(),userId:e.integer().notNull().references(()=>F.id,{onDelete:"cascade"}),createdAt:e.timestamp().notNull().defaultNow(),expiresAt:e.timestamp().notNull(),deviceId:e.integer().references(()=>Ee.id,{onDelete:"cascade"}).notNull()}),e=>[hn("core_sessions_user_id_idx").on(e.userId)]),Ee=mn.table.withRLS("core_sessions_known_devices",e=>({id:e.serial().primaryKey(),publicId:e.varchar({length:32}).notNull().unique(),ipAddress:e.varchar({length:40}).notNull(),userAgent:e.text().notNull(),lastSeen:e.timestamp().notNull().defaultNow()}),e=>[hn("core_sessions_known_devices_ip_address_idx").on(e.ipAddress)]);var bn=yn.table.withRLS("core_admin_permissions",e=>({id:e.serial().primaryKey(),roleId:e.integer().references(()=>U.id,{onDelete:"cascade"}),userId:e.integer().references(()=>F.id,{onDelete:"cascade"}),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().defaultNow().$onUpdate(()=>new Date),protected:e.boolean().notNull().default(!1),unrestricted:e.boolean().notNull().default(!1),permissions:e.jsonb().$type().notNull().default([])}),e=>[he("core_admin_permissions_role_id_idx").on(e.roleId),he("core_admin_permissions_user_id_idx").on(e.userId)]),Pr=yn.table.withRLS("core_admin_sessions",e=>({id:e.serial().primaryKey(),token:e.varchar({length:255}).notNull().unique(),userId:e.integer().notNull().references(()=>F.id,{onDelete:"cascade"}),createdAt:e.timestamp().notNull().defaultNow(),lastSeen:e.timestamp().notNull().defaultNow(),expiresAt:e.timestamp().notNull(),deviceId:e.integer().references(()=>Ee.id,{onDelete:"cascade"}).notNull()}),e=>[he("core_admin_sessions_token_idx").on(e.token),he("core_admin_sessions_user_id_idx").on(e.userId)]);import{camelCase as Ot,index as wn}from"drizzle-orm/pg-core";var xn=Ot.table.withRLS("core_moderators_permissions",e=>({id:e.serial().primaryKey(),roleId:e.integer().references(()=>U.id,{onDelete:"cascade"}),userId:e.integer().references(()=>F.id,{onDelete:"cascade"}),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().defaultNow().$onUpdate(()=>new Date),protected:e.boolean().notNull().default(!1),unrestricted:e.boolean().notNull().default(!1),permissions:e.jsonb().$type().notNull().default([])}),e=>[wn("core_moderators_permissions_role_id_idx").on(e.roleId),wn("core_moderators_permissions_user_id_idx").on(e.userId)]);import{sql as Pe}from"drizzle-orm";import{camelCase as Ft,customType as qt,index as re,unique as Ut}from"drizzle-orm/pg-core";var Kt=qt({dataType(){return"tsvector"}}),je={da:"danish",de:"german",en:"english",es:"spanish",fi:"finnish",fr:"french",hu:"hungarian",it:"italian",nl:"dutch",no:"norwegian",pl:"polish",pt:"portuguese",ro:"romanian",ru:"russian",sv:"swedish",tr:"turkish"},Vt="simple";var $n=`CASE lower(split_part("core_search_index"."languageCode", '-', 1)) ${Object.entries(je).map(([e,n])=>`WHEN '${e}' THEN '${n}'::regconfig`).join(" ")} ELSE '${Vt}'::regconfig END`,_n=Ft.table.withRLS("core_search_index",e=>({id:e.serial().primaryKey(),pluginId:e.varchar({length:255}).notNull(),itemType:e.varchar({length:100}).notNull(),itemId:e.integer().notNull(),languageCode:e.varchar({length:32}).notNull().default(""),authorId:e.integer().references(()=>F.id,{onDelete:"set null",onUpdate:"cascade"}),title:e.text().notNull().default(""),content:e.text().notNull().default(""),searchVector:Kt("search_vector").notNull().generatedAlwaysAs(()=>Pe`setweight(to_tsvector(${Pe.raw($n)}, coalesce(${_n.title}, '')), 'A') || setweight(to_tsvector(${Pe.raw($n)}, coalesce(${_n.content}, '')), 'B')`),containerType:e.varchar({length:100}),containerId:e.integer(),url:e.text(),isPublic:e.boolean().notNull().default(!0),metadata:e.jsonb().$type().notNull().default({}),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp(),indexedAt:e.timestamp().notNull().defaultNow()}),e=>[Ut("core_search_index_item_unique").on(e.itemType,e.itemId,e.languageCode),re("core_search_index_search_vector_idx").using("gin",e.searchVector),re("core_search_index_created_at_idx").on(e.createdAt),re("core_search_index_author_id_idx").on(e.authorId),re("core_search_index_item_type_idx").on(e.itemType),re("core_search_index_language_code_idx").on(e.languageCode),re("core_search_index_is_public_idx").on(e.isPublic)]);var De=async()=>{try{await z("npm",["run","drizzle-kit","up"]),await z("npm",["run","drizzle-kit","generate"])}catch(e){console.error("\x1B[31m%s\x1B[0m",e),process.exit(1)}},Ht=async()=>{let e=zt(process.cwd(),"drizzle.config.ts");if(Jt(e))try{let o=await Bt(import.meta.url,{interopDefault:!0}).import(e),t=o.default?.out??o.out;if(typeof t=="string"&&t.length>0)return t}catch{}return"./migrations"},Xt=e=>{let n=new Set(["23505","42710"]);for(let o=e,t=0;o!=null&&t<5;t++){let{code:r}=o;if(typeof r=="string"&&n.has(r))return!0;o=o.cause}return!1},Qt=async e=>{let n=[...new Set(Object.values(je))];if(n.length===0)return;let o=await e.execute(vn`SELECT cfgname FROM pg_ts_config`),t=new Set(o.map(s=>s.cfgname)),r=n.filter(s=>!t.has(s));if(r.length!==0){console.log(`\x1B[33m[VitNode]\x1B[0m No dictionary installed for text-search config(s) [${r.join(", ")}] - registering a "COPY = simple" fallback (search works, stemming is skipped).`);for(let s of r)try{await e.execute(vn.raw(`CREATE TEXT SEARCH CONFIGURATION "${s}" (COPY = simple)`))}catch(i){if(!Xt(i))throw i}}},Zt=async()=>{let e=await I({type:"api.config"});await Qt(e.dbProvider);let n=await Ht();try{await Gt(e.dbProvider,{migrationsFolder:n})}catch(o){let t=o;console.error("\x1B[31m[VitNode] Database migration failed.\x1B[0m"),t.severity&&console.error(`\x1B[31mSeverity:\x1B[0m ${t.severity}`),t.code&&console.error(`\x1B[31mSQLSTATE:\x1B[0m ${t.code}`),console.error(`\x1B[31mMessage:\x1B[0m ${t.message??String(o)}`),t.detail&&console.error(`\x1B[31mDetail:\x1B[0m ${t.detail}`),t.hint&&console.error(`\x1B[31mHint:\x1B[0m ${t.hint}`),t.where&&console.error(`\x1B[31mWhere:\x1B[0m ${t.where}`),t.position&&console.error(`\x1B[31mPosition:\x1B[0m ${t.position}`),t.query&&console.error(`\x1B[31mFailing SQL:\x1B[0m
|
|
70
|
+
`);for(let _ of $){let k=F.get(_.locale)??new Map;for(let[K,xe]of _.translations)k.set(K,xe);F.set(_.locale,k),_.error&&C.push(_.error)}}let j=0,D=0,M=0;for(let i of w){let c=F.get(i.locale),$=i.untranslated.flatMap(k=>{let K=c?.get(k.source);return K===void 0?[]:[{path:k.path,value:K}]}),_=Et(i.reconciled,$);JSON.stringify(i.current)!==JSON.stringify(_)?(Ct(i.file.path,`${JSON.stringify(_,null,2)}
|
|
71
|
+
`),j+=1,D+=$.length,console.log($.length===0?`${T(` synced ${i.location}`)} ${b("(structure only)")}`:`${T(` updated ${i.location}`)} ${b(`\u2192 ${i.locale} +${$.length}`)}`)):console.log(b(` ok ${i.location}`)),M+=i.untranslated.length-$.length}if(C.length>0){let i=C[0];console.log(`
|
|
72
|
+
${L} ${J(`${C.length} batch(es) failed`)} after ${Ee} attempts - ${M} string(s) left in English.`),console.log(P(` ${i instanceof Error?i.message:String(i)}`)),console.log(b(" Check your AI provider credentials (e.g. AI_GATEWAY_API_KEY) or rate limits, then re-run to fill the rest."))}j===0&&C.length===0&&(console.log(T(`
|
|
73
|
+
Everything is already translated.`)),process.exit(0)),j>0&&console.log(`
|
|
74
|
+
${L} ${T(`${j} file(s) updated`)}, ${J(String(D))} string(s) translated.`),process.exit(C.length>0?1:0)};import{count as Jt,sql as kn}from"drizzle-orm";import{migrate as zt}from"drizzle-orm/postgres-js/migrator";import{createJiti as Yt}from"jiti";import{existsSync as Ht}from"fs";import{join as Xt}from"path";import Qt from"postgres";import{camelCase as xn,index as be}from"drizzle-orm/pg-core";import{camelCase as Ft}from"drizzle-orm/pg-core";var U=Ft.table.withRLS("core_roles",e=>({id:e.serial().primaryKey(),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().$onUpdate(()=>new Date),protected:e.boolean().notNull().default(!1),default:e.boolean().notNull().default(!1),root:e.boolean().notNull().default(!1),guest:e.boolean().notNull().default(!1),color:e.varchar({length:50}),allowUploadFiles:e.boolean().notNull().default(!1),totalMaxStorage:e.integer(),maxStorageForSubmit:e.integer()}));import{camelCase as wn,index as bn}from"drizzle-orm/pg-core";import{camelCase as ae,index as oe,primaryKey as qt}from"drizzle-orm/pg-core";import{camelCase as hn,index as je}from"drizzle-orm/pg-core";var te=hn.table.withRLS("core_languages",e=>({id:e.serial().primaryKey(),code:e.varchar({length:32}).notNull().unique(),name:e.varchar({length:255}).notNull(),timezone:e.varchar({length:255}).notNull().default("UTC"),protected:e.boolean().notNull().default(!1),default:e.boolean().notNull().default(!1),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().defaultNow().$onUpdate(()=>new Date),time24:e.boolean().notNull().default(!1)}),e=>[je("core_languages_code_idx").on(e.code),je("core_languages_name_idx").on(e.name)]),yn=hn.table.withRLS("core_languages_words",e=>({id:e.serial().primaryKey(),languageCode:e.varchar().notNull().references(()=>te.code,{onDelete:"cascade"}),pluginCode:e.varchar({length:50}).notNull(),itemId:e.integer().notNull(),value:e.text().notNull(),tableName:e.varchar({length:255}).notNull(),variable:e.varchar({length:255}).notNull()}),e=>[je("core_languages_words_lang_code_idx").on(e.languageCode)]);var O=ae.table.withRLS("core_users",e=>({id:e.serial().primaryKey(),nameCode:e.varchar({length:255}).notNull().unique(),name:e.varchar({length:255}).notNull().unique(),email:e.varchar({length:255}).notNull().unique(),password:e.varchar(),createdAt:e.timestamp().notNull().defaultNow(),newsletter:e.boolean().notNull().default(!1),avatarColor:e.varchar({length:6}).notNull(),emailVerified:e.boolean().notNull().default(!1),roleId:e.integer().references(()=>U.id).notNull(),birthday:e.timestamp(),ipAddress:e.varchar({length:40}).notNull(),language:e.varchar({length:32}).notNull().default("en").references(()=>te.code,{onDelete:"set default"})}),e=>[oe("core_users_name_code_idx").on(e.nameCode),oe("core_users_name_idx").on(e.name),oe("core_users_email_idx").on(e.email)]),Nr=ae.table.withRLS("core_users_secondary_roles",e=>({userId:e.integer().references(()=>O.id,{onDelete:"cascade"}).notNull(),roleId:e.integer().references(()=>U.id,{onDelete:"cascade"}).notNull(),createdAt:e.timestamp().notNull().defaultNow()}),e=>[qt({columns:[e.userId,e.roleId]}),oe("core_users_secondary_roles_user_id_idx").on(e.userId),oe("core_users_secondary_roles_role_id_idx").on(e.roleId)]),Cr=ae.table.withRLS("core_users_sso",e=>({userId:e.integer().references(()=>O.id,{onDelete:"cascade"}).notNull(),providerId:e.varchar({length:255}).notNull(),providerAccountId:e.varchar({length:255}).notNull(),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().defaultNow().$onUpdate(()=>new Date)}),e=>[oe("core_users_sso_user_id_idx").on(e.userId)]),kr=ae.table.withRLS("core_users_confirm_emails",e=>({id:e.serial().primaryKey(),userId:e.integer().references(()=>O.id,{onDelete:"cascade"}).notNull(),token:e.varchar({length:100}).notNull().unique(),createdAt:e.timestamp().notNull().defaultNow(),expiresAt:e.timestamp().notNull(),ipAddress:e.varchar({length:40}).notNull()})),Sr=ae.table.withRLS("core_users_forgot_password",e=>({id:e.serial().primaryKey(),userId:e.integer().references(()=>O.id,{onDelete:"cascade"}).notNull().unique(),token:e.varchar({length:100}).notNull().unique(),ipAddress:e.varchar({length:40}).notNull(),createdAt:e.timestamp().notNull().defaultNow(),expiresAt:e.timestamp().notNull()}));var Rr=wn.table.withRLS("core_sessions",e=>({id:e.serial().primaryKey(),token:e.varchar({length:255}).notNull().unique(),userId:e.integer().notNull().references(()=>O.id,{onDelete:"cascade"}),createdAt:e.timestamp().notNull().defaultNow(),expiresAt:e.timestamp().notNull(),deviceId:e.integer().references(()=>Me.id,{onDelete:"cascade"}).notNull()}),e=>[bn("core_sessions_user_id_idx").on(e.userId)]),Me=wn.table.withRLS("core_sessions_known_devices",e=>({id:e.serial().primaryKey(),publicId:e.varchar({length:32}).notNull().unique(),ipAddress:e.varchar({length:40}).notNull(),userAgent:e.text().notNull(),lastSeen:e.timestamp().notNull().defaultNow()}),e=>[bn("core_sessions_known_devices_ip_address_idx").on(e.ipAddress)]);var $n=xn.table.withRLS("core_admin_permissions",e=>({id:e.serial().primaryKey(),roleId:e.integer().references(()=>U.id,{onDelete:"cascade"}),userId:e.integer().references(()=>O.id,{onDelete:"cascade"}),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().defaultNow().$onUpdate(()=>new Date),protected:e.boolean().notNull().default(!1),unrestricted:e.boolean().notNull().default(!1),permissions:e.jsonb().$type().notNull().default([])}),e=>[be("core_admin_permissions_role_id_idx").on(e.roleId),be("core_admin_permissions_user_id_idx").on(e.userId)]),Dr=xn.table.withRLS("core_admin_sessions",e=>({id:e.serial().primaryKey(),token:e.varchar({length:255}).notNull().unique(),userId:e.integer().notNull().references(()=>O.id,{onDelete:"cascade"}),createdAt:e.timestamp().notNull().defaultNow(),lastSeen:e.timestamp().notNull().defaultNow(),expiresAt:e.timestamp().notNull(),deviceId:e.integer().references(()=>Me.id,{onDelete:"cascade"}).notNull()}),e=>[be("core_admin_sessions_token_idx").on(e.token),be("core_admin_sessions_user_id_idx").on(e.userId)]);import{camelCase as Ut,index as _n}from"drizzle-orm/pg-core";var vn=Ut.table.withRLS("core_moderators_permissions",e=>({id:e.serial().primaryKey(),roleId:e.integer().references(()=>U.id,{onDelete:"cascade"}),userId:e.integer().references(()=>O.id,{onDelete:"cascade"}),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp().notNull().defaultNow().$onUpdate(()=>new Date),protected:e.boolean().notNull().default(!1),unrestricted:e.boolean().notNull().default(!1),permissions:e.jsonb().$type().notNull().default([])}),e=>[_n("core_moderators_permissions_role_id_idx").on(e.roleId),_n("core_moderators_permissions_user_id_idx").on(e.userId)]);import{sql as De}from"drizzle-orm";import{camelCase as Kt,customType as Vt,index as re,unique as Gt}from"drizzle-orm/pg-core";var Wt=Vt({dataType(){return"tsvector"}}),Oe={da:"danish",de:"german",en:"english",es:"spanish",fi:"finnish",fr:"french",hu:"hungarian",it:"italian",nl:"dutch",no:"norwegian",pl:"polish",pt:"portuguese",ro:"romanian",ru:"russian",sv:"swedish",tr:"turkish"},Bt="simple";var Nn=`CASE lower(split_part("core_search_index"."languageCode", '-', 1)) ${Object.entries(Oe).map(([e,n])=>`WHEN '${e}' THEN '${n}'::regconfig`).join(" ")} ELSE '${Bt}'::regconfig END`,Cn=Kt.table.withRLS("core_search_index",e=>({id:e.serial().primaryKey(),pluginId:e.varchar({length:255}).notNull(),itemType:e.varchar({length:100}).notNull(),itemId:e.integer().notNull(),languageCode:e.varchar({length:32}).notNull().default(""),authorId:e.integer().references(()=>O.id,{onDelete:"set null",onUpdate:"cascade"}),title:e.text().notNull().default(""),content:e.text().notNull().default(""),searchVector:Wt("search_vector").notNull().generatedAlwaysAs(()=>De`setweight(to_tsvector(${De.raw(Nn)}, coalesce(${Cn.title}, '')), 'A') || setweight(to_tsvector(${De.raw(Nn)}, coalesce(${Cn.content}, '')), 'B')`),containerType:e.varchar({length:100}),containerId:e.integer(),url:e.text(),isPublic:e.boolean().notNull().default(!0),metadata:e.jsonb().$type().notNull().default({}),createdAt:e.timestamp().notNull().defaultNow(),updatedAt:e.timestamp(),indexedAt:e.timestamp().notNull().defaultNow()}),e=>[Gt("core_search_index_item_unique").on(e.itemType,e.itemId,e.languageCode),re("core_search_index_search_vector_idx").using("gin",e.searchVector),re("core_search_index_created_at_idx").on(e.createdAt),re("core_search_index_author_id_idx").on(e.authorId),re("core_search_index_item_type_idx").on(e.itemType),re("core_search_index_language_code_idx").on(e.languageCode),re("core_search_index_is_public_idx").on(e.isPublic)]);var Fe=async()=>{try{await z("npm",["run","drizzle-kit","up"]),await z("npm",["run","drizzle-kit","generate"])}catch(e){console.error("\x1B[31m%s\x1B[0m",e),process.exit(1)}},Zt=async()=>{let e=Xt(process.cwd(),"drizzle.config.ts");if(Ht(e))try{let o=await Yt(import.meta.url,{interopDefault:!0}).import(e),t=o.default?.out??o.out;if(typeof t=="string"&&t.length>0)return t}catch{}return"./migrations"},eo=e=>{let n=new Set(["23505","42710"]);for(let o=e,t=0;o!=null&&t<5;t++){let{code:r}=o;if(typeof r=="string"&&n.has(r))return!0;o=o.cause}return!1},no=async e=>{let n=[...new Set(Object.values(Oe))];if(n.length===0)return;let o=await e.execute(kn`SELECT cfgname FROM pg_ts_config`),t=new Set(o.map(s=>s.cfgname)),r=n.filter(s=>!t.has(s));if(r.length!==0){console.log(`\x1B[33m[VitNode]\x1B[0m No dictionary installed for text-search config(s) [${r.join(", ")}] - registering a "COPY = simple" fallback (search works, stemming is skipped).`);for(let s of r)try{await e.execute(kn.raw(`CREATE TEXT SEARCH CONFIGURATION "${s}" (COPY = simple)`))}catch(a){if(!eo(a))throw a}}},to=async()=>{let e=await I({type:"api.config"});await no(e.dbProvider);let n=await Zt();try{await zt(e.dbProvider,{migrationsFolder:n})}catch(o){let t=o;console.error("\x1B[31m[VitNode] Database migration failed.\x1B[0m"),t.severity&&console.error(`\x1B[31mSeverity:\x1B[0m ${t.severity}`),t.code&&console.error(`\x1B[31mSQLSTATE:\x1B[0m ${t.code}`),console.error(`\x1B[31mMessage:\x1B[0m ${t.message??String(o)}`),t.detail&&console.error(`\x1B[31mDetail:\x1B[0m ${t.detail}`),t.hint&&console.error(`\x1B[31mHint:\x1B[0m ${t.hint}`),t.where&&console.error(`\x1B[31mWhere:\x1B[0m ${t.where}`),t.position&&console.error(`\x1B[31mPosition:\x1B[0m ${t.position}`),t.query&&console.error(`\x1B[31mFailing SQL:\x1B[0m
|
|
71
75
|
${t.query}`),o instanceof Error&&o.stack&&console.error(`
|
|
72
|
-
\x1B[90m${o.stack}\x1B[0m`),process.exit(1)}},
|
|
76
|
+
\x1B[90m${o.stack}\x1B[0m`),process.exit(1)}},Sn=4675309,An=12e4,oo=250,ro="vitnode-migration-lock",so=e=>{let n=e.$client.options;if(typeof n!="object"||n===null||!("shared"in n))return null;let o=Qt({...n,connection:{...n.connection,application_name:ro},idle_timeout:null,max:1,parameters:{},shared:{retries:0,typeArrayMap:{}}});return{close:async()=>{await o.end({timeout:5})},tryLock:async()=>{let[t]=await o`SELECT pg_try_advisory_lock(${Sn}) AS locked`;return t.locked===!0},unlock:async()=>{await o`SELECT pg_advisory_unlock(${Sn})`}}},io=async({initMessage:e,lock:n,run:o,sleep:t=async r=>{await new Promise(s=>setTimeout(s,r))}})=>{if(n===null){await o();return}let r=Date.now()+An,s=!1,a=!1;try{for(;!s&&(s=await n.tryLock(),!s);){if(Date.now()>r)throw new Error(`Timed out after ${String(An/1e3)}s waiting for another process to finish preparing this database. If nothing else is running, a previous run was killed mid-migration - reconnect and retry, or check for a stuck session with "SELECT * FROM pg_locks WHERE locktype = 'advisory'".`);a||(console.log(`${e} Another process is preparing this database - waiting for it to finish...`),a=!0),await t(oo)}await o()}finally{if(s)try{await n.unlock()}catch{}try{await n.close()}catch{}}},ao=async(e,n,o)=>{await io({initMessage:n,lock:so(e),run:o})},lo=[{code:"en",default:!0,name:"English (USA)",protected:!0,timezone:"America/New_York"}],co=e=>{let n=(e?.locales??[]).filter(s=>s.enabled!==!1);if(n.length===0)return lo;let o=e?.defaultLocale??"en",t=n.some(s=>s.code===o)?o:n[0].code,r=e?.timeZone??"UTC";return n.map(s=>({code:s.code,default:s.code===t,name:s.name,protected:s.code===t,timezone:r}))},go=async()=>{let e=await I({type:"api.config"}),n=e.dbProvider,[o]=await n.select({count:Jt()}).from(U).limit(1),t=co(e.i18n);if(await n.insert(te).values(t).onConflictDoNothing({target:te.code}),o.count===0){let r=await n.insert(U).values([{protected:!0,guest:!0},{protected:!0,default:!0},{protected:!0,color:"hsl(122, 80%, 45%)",allowUploadFiles:!0},{protected:!0,root:!0,color:"hsl(0, 100%, 50%)",allowUploadFiles:!0}]).returning({id:U.id}),{code:s}=t.find(a=>a.default)??t[0];await n.insert(yn).values([{role:r[0].id,value:"Guest"},{role:r[1].id,value:"Member"},{role:r[2].id,value:"Moderator"},{role:r[3].id,value:"Administrator"}].map(({role:a,value:l})=>({itemId:a,languageCode:s,pluginCode:"core",tableName:"core_roles",value:l,variable:"name"}))),await n.insert(vn).values([{roleId:r[2].id,protected:!0,unrestricted:!0},{roleId:r[3].id,protected:!0,unrestricted:!0}]),await n.insert($n).values({roleId:r[3].id,protected:!0,unrestricted:!0})}},uo=({generate:e})=>[...e?[{action:Fe,label:"Generate migrations..."}]:[],{action:to,label:"Apply pending migrations..."},{action:go,label:"Ensure initial data..."}],qe=async({generate:e=!0,initMessage:n})=>{let o=await I({type:"api.config"}),t=uo({generate:e});await ao(o.dbProvider,n,async()=>{for(let[r,s]of t.entries())console.log(`${n} [${r+1}/${t.length}] ${s.label}`),await s.action()})};po({quiet:!0});var V="\x1B[34m[VitNode]\x1B[0m",Ue=Ve(process.argv.slice(2));Ue.ok||(console.error(`${V} \x1B[31m${Ue.message}\x1B[0m`),process.exit(1));var{args:In,command:fo}=Ue;switch(fo){case"build":try{await Ke(),console.log(`${V} \x1B[32mBuild completed successfully.\x1B[0m`),process.exit(0)}catch{process.exit(1)}break;case"db:prepare":try{await qe({initMessage:V}),console.log(`${V} \x1B[32mDatabase ready.\x1B[0m`),process.exit(0)}catch(e){console.error(`${V} \x1B[31mDatabase bootstrap failed - not starting anything.\x1B[0m`),console.error(e instanceof Error?e.stack??e.message:String(e)),process.exit(1)}break;case"dev":Ge({initMessage:V});break;case"i18n:check":await rn(In.includes("--ci")?"--ci":void 0);break;case"i18n:create":await cn();break;case"i18n:delete":await un();break;case"i18n:update":await pn();break;case"i18n:update:ai":await mn();break;case"migrate":try{In.includes("--generate")&&(await Fe(),console.log(`${V} \x1B[32mDatabase migrations generated successfully.\x1B[0m`),process.exit(0)),await qe({initMessage:V}),console.log(`${V} \x1B[32mDatabase migrated successfully.\x1B[0m`),process.exit(0)}catch(e){console.error(`${V} \x1B[31mDatabase migration failed.\x1B[0m`),console.error(e instanceof Error?e.stack??e.message:String(e)),process.exit(1)}break}
|
package/dist/src/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const CONFIG_PLUGIN={pluginId:"@vitnode/core",version:"2.0.0-canary.
|
|
1
|
+
export const CONFIG_PLUGIN={pluginId:"@vitnode/core",version:"2.0.0-canary.3"};
|
|
@@ -3,4 +3,6 @@ export { vitNodeEnv } from "./env";
|
|
|
3
3
|
export { vitNodeOptimizeDeps } from "./optimize-deps";
|
|
4
4
|
export type { VitNodePluginRoutesOptions } from "./plugin-routes";
|
|
5
5
|
export { vitNodePluginRoutes } from "./plugin-routes";
|
|
6
|
+
export type { VitNodeViteOptions } from "./vitnode";
|
|
7
|
+
export { vitnode } from "./vitnode";
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/framework/vite/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/framework/vite/index.ts"],"names":[],"mappings":"AAmCA,YAAY,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{vitNodeEnv}from"./env.js";export{vitNodeOptimizeDeps}from"./optimize-deps.js";export{vitNodePluginRoutes}from"./plugin-routes.js";
|
|
1
|
+
export{vitNodeEnv}from"./env.js";export{vitNodeOptimizeDeps}from"./optimize-deps.js";export{vitNodePluginRoutes}from"./plugin-routes.js";export{vitnode}from"./vitnode.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Plugin } from "vite";
|
|
2
|
-
export declare const VITNODE_CLIENT_DEPENDENCIES: readonly ["@base-ui/react", "@base-ui/react/accordion", "@base-ui/react/alert-dialog", "@base-ui/react/avatar", "@base-ui/react/button", "@base-ui/react/checkbox", "@base-ui/react/collapsible", "@base-ui/react/context-menu", "@base-ui/react/dialog", "@base-ui/react/direction-provider", "@base-ui/react/input", "@base-ui/react/menu", "@base-ui/react/menubar", "@base-ui/react/merge-props", "@base-ui/react/navigation-menu", "@base-ui/react/popover", "@base-ui/react/preview-card", "@base-ui/react/progress", "@base-ui/react/radio", "@base-ui/react/radio-group", "@base-ui/react/scroll-area", "@base-ui/react/select", "@base-ui/react/separator", "@base-ui/react/slider", "@base-ui/react/switch", "@base-ui/react/tabs", "@base-ui/react/toggle", "@base-ui/react/toggle-group", "@base-ui/react/tooltip", "@base-ui/react/use-render", "@dnd-kit/core", "@dnd-kit/modifiers", "@dnd-kit/sortable", "@dnd-kit/utilities", "@hookform/resolvers/zod", "@tiptap/extension-text-align", "@tiptap/react", "@tiptap/starter-kit", "class-variance-authority", "clsx", "cmdk", "embla-carousel-react", "input-otp", "lucide-react", "motion/react", "react-colorful", "react-hook-form", "react-resizable-panels", "react-scan", "recharts", "sonner", "tailwind-merge", "use-debounce", "use-intl", "vaul", "zod"];
|
|
2
|
+
export declare const VITNODE_CLIENT_DEPENDENCIES: readonly ["@base-ui/react", "@base-ui/react/accordion", "@base-ui/react/alert-dialog", "@base-ui/react/avatar", "@base-ui/react/button", "@base-ui/react/checkbox", "@base-ui/react/collapsible", "@base-ui/react/context-menu", "@base-ui/react/dialog", "@base-ui/react/direction-provider", "@base-ui/react/input", "@base-ui/react/menu", "@base-ui/react/menubar", "@base-ui/react/merge-props", "@base-ui/react/navigation-menu", "@base-ui/react/popover", "@base-ui/react/preview-card", "@base-ui/react/progress", "@base-ui/react/radio", "@base-ui/react/radio-group", "@base-ui/react/scroll-area", "@base-ui/react/select", "@base-ui/react/separator", "@base-ui/react/slider", "@base-ui/react/switch", "@base-ui/react/tabs", "@base-ui/react/toggle", "@base-ui/react/toggle-group", "@base-ui/react/tooltip", "@base-ui/react/use-render", "@dnd-kit/core", "@dnd-kit/modifiers", "@dnd-kit/sortable", "@dnd-kit/utilities", "@hookform/resolvers/zod", "@tanstack/react-query", "@tiptap/extension-text-align", "@tiptap/react", "@tiptap/starter-kit", "class-variance-authority", "clsx", "cmdk", "embla-carousel-react", "input-otp", "lucide-react", "motion/react", "react-colorful", "react-hook-form", "react-resizable-panels", "react-scan", "recharts", "sonner", "tailwind-merge", "use-debounce", "use-intl", "vaul", "zod"];
|
|
3
3
|
export declare const vitNodeClientDepsInclude: (root: string) => string[];
|
|
4
4
|
export declare const vitNodeOptimizeDeps: () => Plugin;
|
|
5
5
|
//# sourceMappingURL=optimize-deps.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimize-deps.d.ts","sourceRoot":"","sources":["../../../../src/framework/vite/optimize-deps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,eAAO,MAAM,2BAA2B,
|
|
1
|
+
{"version":3,"file":"optimize-deps.d.ts","sourceRoot":"","sources":["../../../../src/framework/vite/optimize-deps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,eAAO,MAAM,2BAA2B,6xCA0D9B,CAAC;AAiBX,eAAO,MAAM,wBAAwB,GAAI,MAAM,MAAM,KAAG,MAAM,EAK3D,CAAC;AAEJ,eAAO,MAAM,mBAAmB,QAAO,MAQrC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync}from"node:fs";import{dirname,join}from"node:path";const PACKAGE_NAME="@vitnode/core";export const VITNODE_CLIENT_DEPENDENCIES=["@base-ui/react","@base-ui/react/accordion","@base-ui/react/alert-dialog","@base-ui/react/avatar","@base-ui/react/button","@base-ui/react/checkbox","@base-ui/react/collapsible","@base-ui/react/context-menu","@base-ui/react/dialog","@base-ui/react/direction-provider","@base-ui/react/input","@base-ui/react/menu","@base-ui/react/menubar","@base-ui/react/merge-props","@base-ui/react/navigation-menu","@base-ui/react/popover","@base-ui/react/preview-card","@base-ui/react/progress","@base-ui/react/radio","@base-ui/react/radio-group","@base-ui/react/scroll-area","@base-ui/react/select","@base-ui/react/separator","@base-ui/react/slider","@base-ui/react/switch","@base-ui/react/tabs","@base-ui/react/toggle","@base-ui/react/toggle-group","@base-ui/react/tooltip","@base-ui/react/use-render","@dnd-kit/core","@dnd-kit/modifiers","@dnd-kit/sortable","@dnd-kit/utilities","@hookform/resolvers/zod","@tiptap/extension-text-align","@tiptap/react","@tiptap/starter-kit","class-variance-authority","clsx","cmdk","embla-carousel-react","input-otp","lucide-react","motion/react","react-colorful","react-hook-form","react-resizable-panels","react-scan","recharts","sonner","tailwind-merge","use-debounce","use-intl","vaul","zod"];const packageNameOf=specifier=>{const segments=specifier.split("/");return specifier.startsWith("@")?segments.slice(0,2).join("/"):segments[0]};const isReachableFrom=(root,packageName)=>{for(let directory=root;;directory=dirname(directory)){if(existsSync(join(directory,"node_modules",packageName)))return true;if(dirname(directory)===directory)return false}};export const vitNodeClientDepsInclude=root=>VITNODE_CLIENT_DEPENDENCIES.map(specifier=>isReachableFrom(root,packageNameOf(specifier))?specifier:`${PACKAGE_NAME} > ${specifier}`);export const vitNodeOptimizeDeps=()=>({apply:"serve",config:userConfig=>({optimizeDeps:{include:vitNodeClientDepsInclude(userConfig.root??process.cwd())}}),name:"vitnode:optimize-deps"});
|
|
1
|
+
import{existsSync}from"node:fs";import{dirname,join}from"node:path";const PACKAGE_NAME="@vitnode/core";export const VITNODE_CLIENT_DEPENDENCIES=["@base-ui/react","@base-ui/react/accordion","@base-ui/react/alert-dialog","@base-ui/react/avatar","@base-ui/react/button","@base-ui/react/checkbox","@base-ui/react/collapsible","@base-ui/react/context-menu","@base-ui/react/dialog","@base-ui/react/direction-provider","@base-ui/react/input","@base-ui/react/menu","@base-ui/react/menubar","@base-ui/react/merge-props","@base-ui/react/navigation-menu","@base-ui/react/popover","@base-ui/react/preview-card","@base-ui/react/progress","@base-ui/react/radio","@base-ui/react/radio-group","@base-ui/react/scroll-area","@base-ui/react/select","@base-ui/react/separator","@base-ui/react/slider","@base-ui/react/switch","@base-ui/react/tabs","@base-ui/react/toggle","@base-ui/react/toggle-group","@base-ui/react/tooltip","@base-ui/react/use-render","@dnd-kit/core","@dnd-kit/modifiers","@dnd-kit/sortable","@dnd-kit/utilities","@hookform/resolvers/zod","@tanstack/react-query","@tiptap/extension-text-align","@tiptap/react","@tiptap/starter-kit","class-variance-authority","clsx","cmdk","embla-carousel-react","input-otp","lucide-react","motion/react","react-colorful","react-hook-form","react-resizable-panels","react-scan","recharts","sonner","tailwind-merge","use-debounce","use-intl","vaul","zod"];const packageNameOf=specifier=>{const segments=specifier.split("/");return specifier.startsWith("@")?segments.slice(0,2).join("/"):segments[0]};const isReachableFrom=(root,packageName)=>{for(let directory=root;;directory=dirname(directory)){if(existsSync(join(directory,"node_modules",packageName)))return true;if(dirname(directory)===directory)return false}};export const vitNodeClientDepsInclude=root=>VITNODE_CLIENT_DEPENDENCIES.map(specifier=>isReachableFrom(root,packageNameOf(specifier))?specifier:`${PACKAGE_NAME} > ${specifier}`);export const vitNodeOptimizeDeps=()=>({apply:"serve",config:userConfig=>({optimizeDeps:{include:vitNodeClientDepsInclude(userConfig.root??process.cwd())}}),name:"vitnode:optimize-deps"});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import type { VitNodeEnvOptions } from "./env";
|
|
3
|
+
import type { VitNodePluginRoutesOptions } from "./plugin-routes";
|
|
4
|
+
export interface VitNodeViteOptions extends VitNodeEnvOptions, VitNodePluginRoutesOptions {
|
|
5
|
+
}
|
|
6
|
+
export declare const vitnode: ({ appRoot, clientEnv, hostRoutesDir, }: VitNodeViteOptions) => Plugin[];
|
|
7
|
+
//# sourceMappingURL=vitnode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitnode.d.ts","sourceRoot":"","sources":["../../../../src/framework/vite/vitnode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAMlE,MAAM,WAAW,kBACf,SAAQ,iBAAiB,EAAE,0BAA0B;CAAG;AAuB1D,eAAO,MAAM,OAAO,GAAI,wCAIrB,kBAAkB,KAAG,MAAM,EAI7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{vitNodeEnv}from"./env.js";import{vitNodeOptimizeDeps}from"./optimize-deps.js";import{vitNodePluginRoutes}from"./plugin-routes.js";export const vitnode=({appRoot,clientEnv,hostRoutesDir})=>[vitNodeEnv({clientEnv}),vitNodeOptimizeDeps(),vitNodePluginRoutes({appRoot,hostRoutesDir})];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "@tanstack/react-start/server-only";
|
|
2
2
|
import type { AppMessagesMap, LocaleMessagesMap, MessagesSource } from "../../lib/i18n/types";
|
|
3
|
+
import type { VitNodeServerConfig } from "../../vitnode.config";
|
|
3
4
|
import type { IntlMessages } from "./runtime";
|
|
4
5
|
export interface BundledMessagesOptions {
|
|
5
6
|
appMessages?: AppMessagesMap;
|
|
@@ -12,8 +13,9 @@ export declare const buildBundledMessagesSources: ({ appMessages, packageMessage
|
|
|
12
13
|
export interface IntlMessagesLoaderOptions extends BundledMessagesOptions {
|
|
13
14
|
defaultLocale: string;
|
|
14
15
|
}
|
|
15
|
-
export
|
|
16
|
+
export type IntlMessagesLoader = (args: {
|
|
16
17
|
locale: string;
|
|
17
18
|
namespaces: readonly string[];
|
|
18
19
|
}) => Promise<IntlMessages>;
|
|
20
|
+
export declare function createIntlMessagesLoader(options: IntlMessagesLoaderOptions | VitNodeServerConfig): IntlMessagesLoader;
|
|
19
21
|
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/i18n/messages.ts"],"names":[],"mappings":"AAAA,OAAO,mCAAmC,CAAC;AAG3C,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/i18n/messages.ts"],"names":[],"mappings":"AAAA,OAAO,mCAAmC,CAAC;AAG3C,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAO5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAW9C,MAAM,WAAW,sBAAsB;IAErC,WAAW,CAAC,EAAE,cAAc,CAAC;IAc7B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC,CAAC;IAE/D,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjC;AAWD,eAAO,MAAM,2BAA2B,GAAI,4CAIzC,sBAAsB,KAAG,cAAc,EAWU,CAAC;AAErD,MAAM,WAAW,yBAA0B,SAAQ,sBAAsB;IACvE,aAAa,EAAE,MAAM,CAAC;CACvB;AAGD,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AA6C5B,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GAAG,mBAAmB,GACvD,kBAAkB,CAqBpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@tanstack/react-start/server-only";import{CONFIG_PLUGIN}from"../../config.js";import{loadMessages}from"../../lib/i18n/load-messages.js";import{pickMessages}from"../../lib/i18n/pick-messages.js";import{buildAppMessagesSources}from"../../lib/i18n/sources.js";const WEB_SCOPE="web";export const buildBundledMessagesSources=({appMessages,packageMessages,plugins})=>[{id:CONFIG_PLUGIN.pluginId,messages:packageMessages[CONFIG_PLUGIN.pluginId]},...plugins.map(({pluginId})=>({id:pluginId,messages:packageMessages[pluginId]})),...buildAppMessagesSources(appMessages,WEB_SCOPE)].map(source=>({...source,scope:WEB_SCOPE}));
|
|
1
|
+
import"@tanstack/react-start/server-only";import{CONFIG_PLUGIN}from"../../config.js";import{loadMessages}from"../../lib/i18n/load-messages.js";import{pickMessages}from"../../lib/i18n/pick-messages.js";import{buildAppMessagesSources}from"../../lib/i18n/sources.js";const WEB_SCOPE="web";export const buildBundledMessagesSources=({appMessages,packageMessages,plugins})=>[{id:CONFIG_PLUGIN.pluginId,messages:packageMessages[CONFIG_PLUGIN.pluginId]},...plugins.map(({pluginId})=>({id:pluginId,messages:packageMessages[pluginId]})),...buildAppMessagesSources(appMessages,WEB_SCOPE)].map(source=>({...source,scope:WEB_SCOPE}));const isServerConfig=options=>"config"in options;const loaderOptionsFrom=options=>isServerConfig(options)?{appMessages:options.messages,defaultLocale:options.config.i18n.defaultLocale,packageMessages:options.packageMessages??{},plugins:options.config.plugins}:options;export function createIntlMessagesLoader(options){const{defaultLocale,...sourceOptions}=loaderOptionsFrom(options);const sources=buildBundledMessagesSources(sourceOptions);return async({locale,namespaces})=>{const merged=await loadMessages({defaultLocale,locale,sources});return{locale,messages:pickMessages(merged,namespaces)}}}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "@tanstack/react-start/server-only";
|
|
2
|
-
export type { BundledMessagesOptions, IntlMessagesLoaderOptions, } from "./messages";
|
|
2
|
+
export type { BundledMessagesOptions, IntlMessagesLoader, IntlMessagesLoaderOptions, } from "./messages";
|
|
3
3
|
export { buildBundledMessagesSources, createIntlMessagesLoader, } from "./messages";
|
|
4
4
|
export type { LocaleRequestPlan } from "./request";
|
|
5
5
|
export { handleLocaleRequest } from "./request";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/i18n/server.ts"],"names":[],"mappings":"AAAA,OAAO,mCAAmC,CAAC;AAW3C,YAAY,EACV,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/i18n/server.ts"],"names":[],"mappings":"AAAA,OAAO,mCAAmC,CAAC;AAW3C,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AnyRequestMiddleware } from "@tanstack/react-start";
|
|
2
|
+
import type { LocaleConfig } from "../../lib/i18n/types";
|
|
3
|
+
import type { VitNodeConfig } from "../../vitnode.config";
|
|
4
|
+
export interface VitNodeStartOptions<AppLocales extends LocaleConfig[] = LocaleConfig[]> {
|
|
5
|
+
config: VitNodeConfig<AppLocales>;
|
|
6
|
+
requestMiddleware?: readonly AnyRequestMiddleware[];
|
|
7
|
+
}
|
|
8
|
+
export declare const createVitNodeStart: <AppLocales extends LocaleConfig[]>({ config, requestMiddleware, }: VitNodeStartOptions<AppLocales>) => import("@tanstack/react-start").StartInstance<[], import("@tanstack/router-core").SSROption, readonly [import("@tanstack/react-start").RequestMiddlewareAfterServer<{}, undefined, undefined>, import("@tanstack/react-start").RequestMiddlewareAfterServer<{}, undefined, undefined>, ...AnyRequestMiddleware[]], []>;
|
|
9
|
+
//# sourceMappingURL=create-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-start.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/start/create-start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAIlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMtD,MAAM,WAAW,mBAAmB,CAClC,UAAU,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE;IAWlD,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAQlC,iBAAiB,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACrD;AA6BD,eAAO,MAAM,kBAAkB,GAAI,UAAU,SAAS,YAAY,EAAE,EAAE,gCAGnE,mBAAmB,CAAC,UAAU,CAAC,2TAUjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createCsrfMiddleware,createStart}from"@tanstack/react-start";import{localeRoutingFromConfig}from"../../lib/i18n/locale-routing.js";import{createLocaleRequestMiddleware}from"./locale-middleware.js";export const createVitNodeStart=({config,requestMiddleware=[]})=>{const localeRouting=localeRoutingFromConfig(config.i18n);return createStart(()=>({requestMiddleware:[createCsrfMiddleware({filter:ctx=>ctx.handlerType==="serverFn"}),createLocaleRequestMiddleware(localeRouting),...requestMiddleware]}))};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const DOCUMENT_CACHE_CONTROL = "private, no-store";
|
|
2
|
+
export declare const applyDocumentCacheControl: (response: Response) => void;
|
|
3
|
+
export declare const applyRedirectCacheControl: (response: Response) => void;
|
|
4
|
+
//# sourceMappingURL=document-headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-headers.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/start/document-headers.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAkC1D,eAAO,MAAM,yBAAyB,GAAI,UAAU,QAAQ,KAAG,IAI9D,CAAC;AAgBF,eAAO,MAAM,yBAAyB,GAAI,UAAU,QAAQ,KAAG,IAI9D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DOCUMENT_CACHE_CONTROL="private, no-store";const isRenderedDocument=headers=>(headers.get("content-type")??"").toLowerCase().startsWith("text/html");export const applyDocumentCacheControl=response=>{if(!isRenderedDocument(response.headers))return;response.headers.set("cache-control",DOCUMENT_CACHE_CONTROL)};export const applyRedirectCacheControl=response=>{if(!response.headers.has("set-cookie"))return;response.headers.set("cache-control",DOCUMENT_CACHE_CONTROL)};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/start/index.ts"],"names":[],"mappings":"AA2BA,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{createVitNodeStart}from"./create-start.js";export{applyDocumentCacheControl,applyRedirectCacheControl,DOCUMENT_CACHE_CONTROL}from"./document-headers.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { LocaleRouting } from "../../lib/i18n/locale-routing";
|
|
2
|
+
export declare const createLocaleRequestMiddleware: (localeRouting: LocaleRouting) => import("@tanstack/react-start").RequestMiddlewareAfterServer<{}, undefined, undefined>;
|
|
3
|
+
//# sourceMappingURL=locale-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale-middleware.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/start/locale-middleware.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAI/D,eAAO,MAAM,6BAA6B,GAAI,eAAe,aAAa,2FAGvE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createMiddleware}from"@tanstack/react-start";import{runLocaleRequest}from"./locale-request.js";export const createLocaleRequestMiddleware=localeRouting=>createMiddleware().server(async ctx=>await runLocaleRequest(ctx,localeRouting));
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RequestServerOptions } from "@tanstack/react-start";
|
|
2
|
+
import type { LocaleRouting } from "../../lib/i18n/locale-routing";
|
|
3
|
+
type LocaleRequestContext = Pick<RequestServerOptions<unknown, unknown>, "handlerType" | "next" | "request">;
|
|
4
|
+
export declare const runLocaleRequest: ({ handlerType, next, request }: LocaleRequestContext, localeRouting: LocaleRouting) => Promise<Response | import("@tanstack/react-start").RequestServerResult<unknown, unknown, undefined>>;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=locale-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale-request.d.ts","sourceRoot":"","sources":["../../../../src/tanstack/start/locale-request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,KAAK,oBAAoB,GAAG,IAAI,CAC9B,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,EACtC,aAAa,GAAG,MAAM,GAAG,SAAS,CACnC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,gCAAgC,oBAAoB,EACpD,eAAe,aAAa,yGAgB7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{handleLocaleRequest}from"../i18n/request.js";import{applyDocumentCacheControl,applyRedirectCacheControl}from"./document-headers.js";export const runLocaleRequest=async({handlerType,next,request},localeRouting)=>{if(handlerType!=="router")return await next();const{redirect,setCookie}=handleLocaleRequest(request,localeRouting);if(redirect){applyRedirectCacheControl(redirect);return redirect}const result=await next();if(setCookie)result.response.headers.append("set-cookie",setCookie);applyDocumentCacheControl(result.response);return result};
|