vite-plugin-ai-auto-i18n 0.9.0 → 0.9.2

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/README.md CHANGED
@@ -569,8 +569,12 @@ Every push to `main` runs [.github/workflows/release.yml](.github/workflows/rele
569
569
  Test coverage in the release pipeline:
570
570
 
571
571
  - The `verify` job runs `npm run test:coverage`, which runs the suite with V8 coverage on `src/**` and writes `coverage/coverage-summary.json`. That summary is uploaded as the `coverage-summary` artifact.
572
- - The GitHub Release notes end with a `## Test coverage` section, generated from that summary by `node .github/scripts/release.mjs coverage`. It lists statements, branches, functions, and lines for the commit being released.
573
- - No coverage threshold is enforced. A drop in coverage does not block a release.
572
+ - The `verify` job also runs `npm pack --dry-run --json` after the build and uploads the report as the `package-pack` artifact.
573
+ - The GitHub Release notes end with three generated sections:
574
+ - `## Test coverage`, from the coverage summary, with statements, branches, functions, and lines for the commit being released.
575
+ - `## Package`, with tarball size, unpacked size, and file count, plus distribution by location and by type.
576
+ - `## Dependencies`, with runtime and peer dependencies from `package.json`. Dependencies are not bundled into `dist/`.
577
+ - No coverage threshold is enforced and no size limit is checked. A drop in coverage or an increase in package size does not block a release.
574
578
  - To check coverage before pushing to `main`, run the command in [Test coverage](#-test-coverage) locally.
575
579
 
576
580
  ## 🧪 Test coverage
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{t as e}from"./debug-DVrC55pP.js";import{A as t,C as n,D as r,E as i,F as a,I as o,L as s,M as c,N as l,O as u,P as d,R as f,S as p,T as m,b as h,c as g,g as _,i as v,j as y,k as b,l as x,m as S,n as C,o as w,p as T,r as E,t as ee,u as te,v as D,w as O,x as ne,y as k}from"./registry-W7usElv-.js";import{n as A,t as j}from"./resolve-ELDMKdoA.js";import{ArkErrors as M}from"arktype";import{glob as re,readFile as ie,rm as N,stat as ae}from"node:fs/promises";import P from"node:path";import{fileURLToPath as oe}from"node:url";import{createHash as se}from"node:crypto";import{IntlMessageFormat as ce}from"intl-messageformat";import{parseSync as le}from"rolldown/utils";import ue from"magic-string";async function de(e,t,n){let r=Array(e.length),i=0;return await Promise.all(Array.from({length:Math.min(Math.max(1,t),e.length)},async()=>{for(;i<e.length;){let t=i++;try{r[t]={status:`fulfilled`,value:await n(e[t])}}catch(e){r[t]={status:`rejected`,reason:e}}}})),r}var fe=class{available;waiters=[];constructor(e){this.available=Math.max(1,Math.floor(e))}async run(e){await this.acquire();try{return await e()}finally{this.release()}}acquire(){return this.available>0?(this.available--,Promise.resolve()):new Promise(e=>this.waiters.push(e))}release(){let e=this.waiters.shift();e?e():this.available++}};const pe=/* @__PURE__ */ new Set([1,2,3,4,5,6]);function me(e){return e.replace(/['{}]/g,e=>e===`'`?`''`:`'${e}'`)}function he(e){return e.replace(/[^\p{L}\p{N}_]/gu,`_`)}function ge(e){let t;try{t=new ce(e,`en`).getAst()}catch{return}let n=/* @__PURE__ */ new Set,r=e=>{for(let t of e)if(pe.has(t.type)&&t.value&&n.add(t.value),t.children&&r(t.children),t.options)for(let e of Object.values(t.options))r(e.value)};return r(t),[...n]}function _e(e,t){let n=new Set(e),r=new Set(t);return n.size===r.size&&[...n].every(e=>r.has(e))}function ve(e,t){if(e.trim()===``)return!1;let n=ge(e);return n!==void 0&&_e(n,t)}var F=class extends Error{partial;failed;constructor(e,t,n){super(e),this.partial=t,this.failed=n,this.name=`PartialTranslationError`}};async function ye(n){let{provider:r,sourceLocale:i,locale:a,requests:o,previous:s,debug:c}=n,l=new Set(o.map(e=>e.id)),{messages:u,sources:d}=t(s,l).file,f=o.filter(e=>u[e.id]===void 0||d[e.id]!==e.source),p={},m=0,h;if(f.length&&r){if(c)for(let t of f)e(`sent ${i} -> ${a} ${t.id}: ${JSON.stringify(t.source)} (context: ${t.context})`);try{p=await r.translate({sourceLocale:i,targetLocale:a,messages:f})}catch(e){if(!(e instanceof F))throw e;p=e.partial,m=e.failed,h=e.message}if(c)for(let t of f){let n=p[t.id];e(`received ${i} -> ${a} ${t.id}: ${typeof n==`string`?JSON.stringify(n):`(no translation)`}`)}}let g={...u},_={...d},v=0;for(let e of f){delete g[e.id],delete _[e.id];let t=p[e.id];typeof t==`string`&&t.trim()&&(e.kind===`mixed`&&!ve(t,e.placeholders??[])?v++:(g[e.id]=t,_[e.id]=e.source))}let y=o.filter(e=>g[e.id]===void 0).length;return{file:{messages:g,sources:_},untranslated:y,rejected:v,requested:f.length,failed:m,failure:h}}async function be(e){let t=structuredClone(e.registry),{ambiguous:n,messages:r}=E(t,e.files.flatMap(e=>e.messages)),i=C(t,e.orphanRetentionMinutes),a={};for(let e of r)a[e.id]=e.source;let o=r.map(e=>({id:e.id,source:e.source,context:`${e.component} > ${e.context}`,kind:e.kind,placeholders:e.placeholders})),s=await de(e.locales,e.localeConcurrency,t=>ye({provider:e.provider,sourceLocale:e.sourceLocale,locale:t,requests:o,previous:e.previous.get(t)??u(),debug:e.debug})),c=/* @__PURE__ */ new Map,l=/* @__PURE__ */ new Map;return s.forEach((t,n)=>{let r=e.locales[n];t.status===`fulfilled`?c.set(r,t.value):l.set(r,t.reason)}),{registry:t,ambiguous:n,pruned:i,messages:r,sourceFile:{messages:a,sources:{}},locales:c,failures:l}}function I(e){return e.replace(/\s+/g,` `).trim()}function xe(e){let t=[I(e.source),e.kind,e.tag.toLowerCase(),e.attribute??``,e.context].join(``);return se(`sha256`).update(t).digest(`hex`).slice(0,24)}function L(e,t){let n=le(t,e,{lang:`tsx`,sourceType:`unambiguous`});if(n.errors.length)throw SyntaxError(`${t}: ${n.errors[0].message}`);return{program:n.program,commentsByEnd:new Map(n.comments.map(e=>[e.end,e]))}}function Se(e,t){let n=[],r=e=>{if(t(e,n)!==!1){n.push(e);for(let t of Object.keys(e)){if(t===`parent`)continue;let n=e[t];Array.isArray(n)?n.forEach(e=>R(e)&&r(e)):R(n)&&r(n)}n.pop()}};r(e)}function R(e){return typeof e==`object`&&!!e&&typeof e.type==`string`}function z(e){return R(e)&&e.type===`Literal`&&typeof e.value==`string`}function Ce(e,t,n,r){let i=n;for(;;){let n=i;for(;n>0&&/\s/.test(e[n-1]);)n--;let a=t.get(n);if(!a)return!1;if(a.type===`Block`&&a.value.trim()===r)return!0;i=a.start}}function B(e){return e.includes(`&`)?e.replace(ne,(e,t,n)=>{if(n!==void 0)return k.get(n)??e;let r=t.startsWith(`x`)?parseInt(t.slice(1),16):parseInt(t,10);return r<=1114111?String.fromCodePoint(r):e}):e}function we(e){return z(e)?B(e.value):void 0}function V(e){return B(e.value)}function Te(e){return{prefix:e.match(/^\s*/)?.[0]??``,suffix:e.match(/\s*$/)?.[0]??``}}const H=e=>/[A-Za-z]/.test(e);function Ee(e){return e.attributes.some(e=>e.type===`JSXAttribute`&&e.name.type===`JSXIdentifier`&&e.name.name===`translate`&&we(e.value)===`no`)}function De(e){return e.type===`JSXIdentifier`&&!g.test(e.name)&&!_.has(e.name)}function U(e){if(e.type===`Identifier`)return e.name;if(e.type===`MemberExpression`&&!e.computed&&e.property.type===`Identifier`){let t=U(e.object);return t?`${t}.${e.property.name}`:void 0}}const Oe=(e,t)=>e.type===`FunctionExpression`?!(t?.type===`MethodDefinition`||t?.type===`Property`&&(t.method||t.kind!==`init`)):e.type===`FunctionDeclaration`||e.type===`ArrowFunctionExpression`;function ke(e,t){for(let n=e.length-1;n>=0;n--)if(t(e[n]))return n;return-1}function Ae(e){let t=ke(e,e=>e.type===`JSXElement`);return t<0?void 0:{index:t,element:e[t]}}function W(e){return e.some(e=>{let t=e.type===`JSXOpeningElement`?e:e.type===`JSXElement`?e.openingElement:void 0;return t!==void 0&&Ee(t)})}function G(e,t,n){let r=e.attributes.filter(e=>e.type===`JSXAttribute`&&e.name.type===`JSXIdentifier`&&[`aria-label`,`title`,`name`,`type`,`role`].includes(e.name.name)).map(e=>`${e.name.name}=${we(e.value)??`{expr}`}`).sort().join(`;`),i=e.attributes.filter(e=>e.type===`JSXAttribute`&&e.name.type===`JSXIdentifier`&&/^on[A-Z]/.test(e.name.name)).map(e=>e.name.name).sort().join(`,`);return[t,n??``,r,i].filter(Boolean).join(` | `)}function je(e,t,n={},r=L(e,t)){let{program:a,commentsByEnd:o}=r,s=[],c=(e,t=e.source)=>{s.push({...e,fingerprint:xe({...e,source:t})})},l=e=>Object.prototype.hasOwnProperty.call(n.componentProps??{},e)?n.componentProps[e]:[],u=e=>{if(e.type!==`JSXIdentifier`)return!1;let t=e.name;return De(e)||g.test(t)&&l(t).includes(`children`)};function d(e){let t=e.length-1;for(;t>=0&&!Oe(e[t],e[t-1]);)t--;if(t<0)return`<module>`;let n=e[t],r=e[t-1];return r?.type===`VariableDeclarator`&&r.id.type===`Identifier`?r.id.name:n.type===`FunctionDeclaration`&&n.id?n.id.name:`<anonymous>`}function f(e,n){if(W([...n,e]))return;let r=e.children,i=r.filter(e=>e.type===`JSXExpressionContainer`);if(!i.length||r.some(e=>e.type!==`JSXText`&&e.type!==`JSXExpressionContainer`)||!i.every(e=>U(e.expression)!==void 0)||!r.some(e=>e.type===`JSXText`&&H(V(e))))return;let a=e.openingElement.name;if(!u(a))return;let o=[];for(let e of i){let t=U(e.expression),n=t;for(let e=2;o.includes(n);e++)n=`${t}_${e}`;o.push(n)}let s=[];for(let e of o){let t=he(e),n=t;for(let e=2;s.includes(n);e++)n=`${t}_${e}`;s.push(n)}let l=``,f=``,p=0;for(let e of r)if(e.type===`JSXText`){let t=V(e);l+=t,f+=me(t)}else l+=`{${o[p]}}`,f+=`{${s[p]}}`,p++;let m=I(f);if(!m)return;let h=a.name;c({source:m,...Te(l),kind:`mixed`,placeholders:s,file:t,start:e.start,end:e.end,tag:h,component:d(n),context:G(e.openingElement,h)},I(l))}function p(e,n){if(W([...n,e]))return;let r=V(e),i=I(r);if(!i)return;let a=Ae(n);if(!a)return;let{index:o,element:s}=a;if(s.children.some(e=>e.type===`JSXExpressionContainer`))return;let l=s.openingElement.name;if(!u(l))return;let f=l.name;c({source:i,...Te(r),kind:`text`,file:t,start:e.start,end:e.end,tag:f,component:d(n.slice(0,o)),context:G(s.openingElement,f)})}function m(e,n){if(e.name.type!==`JSXIdentifier`)return;let r=e.name.name,a=n[n.length-1];if(a?.type!==`JSXOpeningElement`)return;let o=a.name.type===`JSXIdentifier`?a.name.name:``;if(!(De(a.name)?i.has(r):l(o).includes(r))||W([...n,e])||!z(e.value))return;let s=I(B(e.value.value));if(!s||!H(s))return;let u=Ae(n);if(!u)return;let{index:f,element:p}=u;c({source:s,kind:`attribute`,file:t,start:e.value.start,end:e.value.end,tag:o,component:d(n.slice(0,f)),attribute:r,context:G(p.openingElement,o,r)})}function h(r,i){if(!z(r)||i[i.length-1]?.type===`JSXAttribute`||i.some(e=>e.start===r.start)||!Ce(e,o,r.start,n.stringMarker??`i18n`))return;let a=I(r.value);a&&H(a)&&c({source:a,kind:`string`,file:t,start:r.start,end:r.end,tag:``,component:d(i),context:``})}return Se(a,(e,t)=>{switch(e.type){case`JSXElement`:return f(e,t);case`JSXText`:return p(e,t);case`JSXAttribute`:return m(e,t);case`Literal`:return h(e,t)}}),s.sort((e,t)=>e.start-t.start)}function Me(e,t,r,i,a,o=!1,s=`en`,c=L(e,t)){let{program:l}=c,u={mixed:/* @__PURE__ */ new Map,text:/* @__PURE__ */ new Map,attribute:/* @__PURE__ */ new Map,string:/* @__PURE__ */ new Map};for(let e of r)u[e.kind]?.set(e.start,e);let d=r.map(e=>e.start).sort((e,t)=>e-t),f=(e,t)=>{let n=0,r=d.length;for(;n<r;){let t=n+r>>1;d[t]<e?n=t+1:r=t}return n<d.length&&d[n]<t},h=[];Se(l,e=>{if(!f(e.start,e.end))return!1;if(e.type===`JSXElement`){let t=u.mixed.get(e.start);t&&h.push({kind:`mixed`,node:e,message:t})}else if(e.type===`JSXText`){let t=u.text.get(e.start);t&&h.push({kind:`text`,node:e,message:t})}else if(e.type===`JSXAttribute`&&e.value?.type===`Literal`){let t=u.attribute.get(e.value.start);t&&h.push({kind:`attribute`,node:e.value,message:t})}else if(e.type===`Literal`&&typeof e.value==`string`){let t=u.string.get(e.start);t&&h.push({kind:`string`,node:e,message:t})}});let g=new ue(e),_=!1,v=!1,y=!1,b=e=>i===s?e.source:a[e.id]??e.source,x=e=>o?(_=!0,`${O}(${JSON.stringify(e.id)}, ${JSON.stringify(e.source)})`):JSON.stringify(b(e)),C=e=>{let t=e.prefix??``,n=e.suffix??``;return o?[t&&JSON.stringify(t),x(e),n&&JSON.stringify(n)].filter(Boolean).join(` + `):JSON.stringify(`${t}${b(e)}${n}`)};for(let e of h.reverse()){let{message:t}=e;if(e.kind===`mixed`){let r=e.node;if(!r.closingElement)continue;let a=t.placeholders??[],s=r.children.flatMap(e=>e.type===`JSXExpressionContainer`?[e.expression]:[]),c=e=>g.slice(s[e].start,s[e].end),l=r.openingElement.end,u=r.closingElement.start,d=a.map((e,t)=>`${JSON.stringify(e)}: ${c(t)}`).join(`, `);if(v=!0,o){y=!0,g.overwrite(l,u,`{${p}(${C(t)}, {${d}}, ${n}())}`);continue}let f=b(t),m=ve(f,a)?f:t.source,h=JSON.stringify(`${t.prefix??``}${m}${t.suffix??``}`);g.overwrite(l,u,`{${p}(${h}, {${d}}, ${JSON.stringify(i)})}`)}else e.kind===`text`?g.overwrite(e.node.start,e.node.end,`{${C(t)}}`):e.kind===`attribute`?g.overwrite(e.node.start,e.node.end,o?`{${x(t)}}`:x(t)):g.overwrite(e.node.start,e.node.end,x(t))}let w=[..._?[`t as ${O}`]:[],...y?[`getLocale as ${n}`]:[]];return w.length&&g.prepend(`import { ${w.join(`, `)} } from "${m}";\n`),v&&g.prepend(`import { format as ${p} } from "${S}";\n`),{code:g.toString(),map:g.generateMap({source:t,hires:!0,includeContent:!0})}}function Ne(e,t,n,r,i){try{let a=i+`\0`+n,o=t.get(a);return o||(o=new e(n,i),t.set(a,o)),o.formatToParts(r).map(e=>e.value)}catch(e){return console.warn(`autoi18n: could not format `+JSON.stringify(n)+`.`,e),[n]}}function Pe(){return[`import { IntlMessageFormat } from ${JSON.stringify(T)};`,`const formatMessage = ${Ne.toString()};`,`const cache = new Map();`,`export function format(text, values, locale) { return formatMessage(IntlMessageFormat, cache, text, values, locale); }`].join(`
1
+ import{t as e}from"./debug-DVrC55pP.js";import{A as t,C as n,D as r,E as i,F as a,I as o,L as s,M as c,N as l,O as u,P as d,R as f,S as p,T as m,b as h,c as g,g as _,i as v,j as y,k as b,l as x,m as S,n as C,o as w,p as T,r as E,t as ee,u as te,v as D,w as O,x as ne,y as k}from"./registry-W7usElv-.js";import{n as A,t as j}from"./resolve-ELDMKdoA.js";import{ArkErrors as M}from"arktype";import{glob as re,readFile as ie,rm as N,stat as ae}from"node:fs/promises";import P from"node:path";import{fileURLToPath as oe}from"node:url";import{createHash as se}from"node:crypto";import{IntlMessageFormat as ce}from"intl-messageformat";import{parseSync as le}from"rolldown/utils";import ue from"magic-string";async function de(e,t,n){let r=Array(e.length),i=0;return await Promise.all(Array.from({length:Math.min(Math.max(1,t),e.length)},async()=>{for(;i<e.length;){let t=i++;try{r[t]={status:`fulfilled`,value:await n(e[t])}}catch(e){r[t]={status:`rejected`,reason:e}}}})),r}var fe=class{available;waiters=[];constructor(e){this.available=Math.max(1,Math.floor(e))}async run(e){await this.acquire();try{return await e()}finally{this.release()}}acquire(){return this.available>0?(this.available--,Promise.resolve()):new Promise(e=>this.waiters.push(e))}release(){let e=this.waiters.shift();e?e():this.available++}};const pe=/* @__PURE__ */ new Set([1,2,3,4,5,6]);function me(e){return e.replace(/['{}]/g,e=>e===`'`?`''`:`'${e}'`)}function he(e){return e.replace(/[^\p{L}\p{N}_]/gu,`_`)}function ge(e){let t;try{t=new ce(e,`en`).getAst()}catch{return}let n=/* @__PURE__ */ new Set,r=e=>{for(let t of e)if(pe.has(t.type)&&t.value&&n.add(t.value),t.children&&r(t.children),t.options)for(let e of Object.values(t.options))r(e.value)};return r(t),[...n]}function _e(e,t){let n=new Set(e),r=new Set(t);return n.size===r.size&&[...n].every(e=>r.has(e))}function ve(e,t){if(e.trim()===``)return!1;let n=ge(e);return n!==void 0&&_e(n,t)}var F=class extends Error{partial;failed;constructor(e,t,n){super(e),this.partial=t,this.failed=n,this.name=`PartialTranslationError`}};async function ye(n){let{provider:r,sourceLocale:i,locale:a,requests:o,previous:s,debug:c}=n,l=new Set(o.map(e=>e.id)),{messages:u,sources:d}=t(s,l).file,f=o.filter(e=>u[e.id]===void 0||d[e.id]!==e.source),p={},m=0,h;if(f.length&&r){if(c)for(let t of f)e(`sent ${i} -> ${a} ${t.id}: ${JSON.stringify(t.source)} (context: ${t.context})`);try{p=await r.translate({sourceLocale:i,targetLocale:a,messages:f})}catch(e){if(!(e instanceof F))throw e;p=e.partial,m=e.failed,h=e.message}if(c)for(let t of f){let n=p[t.id];e(`received ${i} -> ${a} ${t.id}: ${typeof n==`string`?JSON.stringify(n):`(no translation)`}`)}}let g={...u},_={...d},v=0;for(let e of f){delete g[e.id],delete _[e.id];let t=p[e.id];typeof t==`string`&&t.trim()&&(e.kind===`mixed`&&!ve(t,e.placeholders??[])?v++:(g[e.id]=t,_[e.id]=e.source))}let y=o.filter(e=>g[e.id]===void 0).length;return{file:{messages:g,sources:_},untranslated:y,rejected:v,requested:f.length,failed:m,failure:h}}async function be(e){let t=structuredClone(e.registry),{ambiguous:n,messages:r}=E(t,e.files.flatMap(e=>e.messages)),i=C(t,e.orphanRetentionMinutes),a={};for(let e of r)a[e.id]=e.source;let o=r.map(e=>({id:e.id,source:e.source,context:`${e.component} > ${e.context}`,kind:e.kind,placeholders:e.placeholders})),s=await de(e.locales,e.localeConcurrency,t=>ye({provider:e.provider,sourceLocale:e.sourceLocale,locale:t,requests:o,previous:e.previous.get(t)??u(),debug:e.debug})),c=/* @__PURE__ */ new Map,l=/* @__PURE__ */ new Map;return s.forEach((t,n)=>{let r=e.locales[n];t.status===`fulfilled`?c.set(r,t.value):l.set(r,t.reason)}),{registry:t,ambiguous:n,pruned:i,messages:r,sourceFile:{messages:a,sources:{}},locales:c,failures:l}}function I(e){return e.replace(/\s+/g,` `).trim()}function xe(e){let t=[I(e.source),e.kind,e.tag.toLowerCase(),e.attribute??``,e.context].join(``);return se(`sha256`).update(t).digest(`hex`).slice(0,24)}function L(e,t){let n=le(t,e,{lang:`tsx`,sourceType:`unambiguous`});if(n.errors.length)throw SyntaxError(`${t}: ${n.errors[0].message}`);return{program:n.program,commentsByEnd:new Map(n.comments.map(e=>[e.end,e]))}}function Se(e,t){let n=[],r=e=>{if(t(e,n)!==!1){n.push(e);for(let t of Object.keys(e)){if(t===`parent`)continue;let n=e[t];Array.isArray(n)?n.forEach(e=>R(e)&&r(e)):R(n)&&r(n)}n.pop()}};r(e)}function R(e){return typeof e==`object`&&!!e&&typeof e.type==`string`}function z(e){return R(e)&&e.type===`Literal`&&typeof e.value==`string`}function Ce(e,t,n,r){let i=n;for(;;){let n=i;for(;n>0&&/\s/.test(e[n-1]);)n--;let a=t.get(n);if(!a)return!1;if(a.type===`Block`&&a.value.trim()===r)return!0;i=a.start}}function B(e){return e.includes(`&`)?e.replace(ne,(e,t,n)=>{if(n!==void 0)return k.get(n)??e;let r=t.startsWith(`x`)?parseInt(t.slice(1),16):parseInt(t,10);return r<=1114111?String.fromCodePoint(r):e}):e}function we(e){return z(e)?B(e.value):void 0}function V(e){return B(e.value)}function Te(e){return{prefix:e.match(/^\s*/)?.[0]??``,suffix:e.match(/\s*$/)?.[0]??``}}const H=e=>/[A-Za-z]/.test(e);function Ee(e){return e.attributes.some(e=>e.type===`JSXAttribute`&&e.name.type===`JSXIdentifier`&&e.name.name===`translate`&&we(e.value)===`no`)}function De(e){return e.type===`JSXIdentifier`&&!g.test(e.name)&&!_.has(e.name)}function U(e){if(e.type===`Identifier`)return e.name;if(e.type===`MemberExpression`&&!e.computed&&e.property.type===`Identifier`){let t=U(e.object);return t?`${t}.${e.property.name}`:void 0}}const Oe=(e,t)=>e.type===`FunctionExpression`?!(t?.type===`MethodDefinition`||t?.type===`Property`&&(t.method||t.kind!==`init`)):e.type===`FunctionDeclaration`||e.type===`ArrowFunctionExpression`;function ke(e,t){for(let n=e.length-1;n>=0;n--)if(t(e[n]))return n;return-1}function Ae(e){let t=ke(e,e=>e.type===`JSXElement`);return t<0?void 0:{index:t,element:e[t]}}function W(e){return e.some(e=>{let t=e.type===`JSXOpeningElement`?e:e.type===`JSXElement`?e.openingElement:void 0;return t!==void 0&&Ee(t)})}function G(e,t,n){let r=e.attributes.filter(e=>e.type===`JSXAttribute`&&e.name.type===`JSXIdentifier`&&[`aria-label`,`title`,`name`,`type`,`role`].includes(e.name.name)).map(e=>`${e.name.name}=${we(e.value)??`{expr}`}`).sort().join(`;`),i=e.attributes.filter(e=>e.type===`JSXAttribute`&&e.name.type===`JSXIdentifier`&&/^on[A-Z]/.test(e.name.name)).map(e=>e.name.name).sort().join(`,`);return[t,n??``,r,i].filter(Boolean).join(` | `)}function je(e,t,n={},r=L(e,t)){let{program:a,commentsByEnd:o}=r,s=[],c=(e,t=e.source)=>{s.push({...e,fingerprint:xe({...e,source:t})})},l=e=>Object.prototype.hasOwnProperty.call(n.componentProps??{},e)?n.componentProps[e]:[],u=e=>{if(e.type!==`JSXIdentifier`)return!1;let t=e.name;return De(e)||g.test(t)&&l(t).includes(`children`)};function d(e){let t=e.length-1;for(;t>=0&&!Oe(e[t],e[t-1]);)t--;if(t<0)return`<module>`;let n=e[t],r=e[t-1];return r?.type===`VariableDeclarator`&&r.id.type===`Identifier`?r.id.name:n.type===`FunctionDeclaration`&&n.id?n.id.name:`<anonymous>`}function f(e,n){if(W([...n,e]))return;let r=e.children,i=r.filter(e=>e.type===`JSXExpressionContainer`);if(!i.length||r.some(e=>e.type!==`JSXText`&&e.type!==`JSXExpressionContainer`)||!i.every(e=>U(e.expression)!==void 0)||!r.some(e=>e.type===`JSXText`&&H(V(e))))return;let a=e.openingElement.name;if(!u(a))return;let o=[];for(let e of i){let t=U(e.expression),n=t;for(let e=2;o.includes(n);e++)n=`${t}_${e}`;o.push(n)}let s=[];for(let e of o){let t=he(e),n=t;for(let e=2;s.includes(n);e++)n=`${t}_${e}`;s.push(n)}let l=``,f=``,p=0;for(let e of r)if(e.type===`JSXText`){let t=V(e);l+=t,f+=me(t)}else l+=`{${o[p]}}`,f+=`{${s[p]}}`,p++;let m=I(f);if(!m)return;let h=a.name;c({source:m,...Te(l),kind:`mixed`,placeholders:s,file:t,start:e.start,end:e.end,tag:h,component:d(n),context:G(e.openingElement,h)},I(l))}function p(e,n){if(W([...n,e]))return;let r=V(e),i=I(r);if(!i)return;let a=Ae(n);if(!a)return;let{index:o,element:s}=a;if(s.children.some(e=>e.type===`JSXExpressionContainer`))return;let l=s.openingElement.name;if(!u(l))return;let f=l.name;c({source:i,...Te(r),kind:`text`,file:t,start:e.start,end:e.end,tag:f,component:d(n.slice(0,o)),context:G(s.openingElement,f)})}function m(e,n){if(e.name.type!==`JSXIdentifier`)return;let r=e.name.name,a=n[n.length-1];if(a?.type!==`JSXOpeningElement`)return;let o=a.name.type===`JSXIdentifier`?a.name.name:``;if(!(De(a.name)?i.has(r):l(o).includes(r))||W([...n,e])||!z(e.value))return;let s=I(B(e.value.value));if(!s||!H(s))return;let u=Ae(n);if(!u)return;let{index:f,element:p}=u;c({source:s,kind:`attribute`,file:t,start:e.value.start,end:e.value.end,tag:o,component:d(n.slice(0,f)),attribute:r,context:G(p.openingElement,o,r)})}function h(r,i){if(!z(r)||i[i.length-1]?.type===`JSXAttribute`||i.some(e=>e.start===r.start)||!Ce(e,o,r.start,n.stringMarker??`i18n`))return;let a=I(r.value);a&&H(a)&&c({source:a,kind:`string`,file:t,start:r.start,end:r.end,tag:``,component:d(i),context:``})}return Se(a,(e,t)=>{switch(e.type){case`JSXElement`:return f(e,t);case`JSXText`:return p(e,t);case`JSXAttribute`:return m(e,t);case`Literal`:return h(e,t)}}),s.sort((e,t)=>e.start-t.start)}function Me(e,t,r,i,a,o=!1,s=`en`,c=L(e,t)){let{program:l}=c,u={mixed:/* @__PURE__ */ new Map,text:/* @__PURE__ */ new Map,attribute:/* @__PURE__ */ new Map,string:/* @__PURE__ */ new Map};for(let e of r)u[e.kind]?.set(e.start,e);let d=r.map(e=>e.start).sort((e,t)=>e-t),f=(e,t)=>{let n=0,r=d.length;for(;n<r;){let t=n+r>>1;d[t]<e?n=t+1:r=t}return n<d.length&&d[n]<t},h=[];Se(l,e=>{if(!f(e.start,e.end))return!1;if(e.type===`JSXElement`){let t=u.mixed.get(e.start);t&&h.push({kind:`mixed`,node:e,message:t})}else if(e.type===`JSXText`){let t=u.text.get(e.start);t&&h.push({kind:`text`,node:e,message:t})}else if(e.type===`JSXAttribute`&&e.value?.type===`Literal`){let t=u.attribute.get(e.value.start);t&&h.push({kind:`attribute`,node:e.value,message:t})}else if(e.type===`Literal`&&typeof e.value==`string`){let t=u.string.get(e.start);t&&h.push({kind:`string`,node:e,message:t})}});let g=new ue(e),_=!1,v=!1,y=!1,b=e=>i===s?e.source:a[e.id]??e.source,x=e=>o?(_=!0,`${O}(${JSON.stringify(e.id)}, ${JSON.stringify(e.source)})`):JSON.stringify(b(e)),C=e=>{let t=e.prefix??``,n=e.suffix??``;return o?[t&&JSON.stringify(t),x(e),n&&JSON.stringify(n)].filter(Boolean).join(` + `):JSON.stringify(`${t}${b(e)}${n}`)};for(let e of h.reverse()){let{message:t}=e;if(e.kind===`mixed`){let r=e.node;if(!r.closingElement)continue;let a=t.placeholders??[],s=r.children.flatMap(e=>e.type===`JSXExpressionContainer`?[e.expression]:[]),c=e=>g.slice(s[e].start,s[e].end),l=r.openingElement.end,u=r.closingElement.start,d=a.map((e,t)=>`${JSON.stringify(e)}: ${c(t)}`).join(`, `);if(v=!0,o){y=!0,g.overwrite(l,u,`{${p}(${C(t)}, {${d}}, ${n}())}`);continue}let f=b(t),m=ve(f,a)?f:t.source,h=JSON.stringify(`${t.prefix??``}${m}${t.suffix??``}`);g.overwrite(l,u,`{${p}(${h}, {${d}}, ${JSON.stringify(i)})}`)}else e.kind===`text`?g.overwrite(e.node.start,e.node.end,`{${C(t)}}`):e.kind===`attribute`?g.overwrite(e.node.start,e.node.end,`{${x(t)}}`):g.overwrite(e.node.start,e.node.end,x(t))}let w=[..._?[`t as ${O}`]:[],...y?[`getLocale as ${n}`]:[]];return w.length&&g.prepend(`import { ${w.join(`, `)} } from "${m}";\n`),v&&g.prepend(`import { format as ${p} } from "${S}";\n`),{code:g.toString(),map:g.generateMap({source:t,hires:!0,includeContent:!0})}}function Ne(e,t,n,r,i){try{let a=i+`\0`+n,o=t.get(a);return o||(o=new e(n,i),t.set(a,o)),o.formatToParts(r).map(e=>e.value)}catch(e){return console.warn(`autoi18n: could not format `+JSON.stringify(n)+`.`,e),[n]}}function Pe(){return[`import { IntlMessageFormat } from ${JSON.stringify(T)};`,`const formatMessage = ${Ne.toString()};`,`const cache = new Map();`,`export function format(text, values, locale) { return formatMessage(IntlMessageFormat, cache, text, values, locale); }`].join(`
2
2
  `)+`
3
3
  `}function K(e){return JSON.stringify(e).replace(/[<>&\u2028\u2029]/g,e=>`\\u${e.charCodeAt(0).toString(16).padStart(4,`0`)}`)}function Fe(e,t){return[`const loaders = {\n${Object.entries(e).map(([e,t])=>` ${K(e)}: () => import(${K(t)}).then(m => (m.default ?? m).messages)`).join(`,
4
4
  `)}\n};`,`const sourceLocale = ${K(t)};`,`const resolveLocale = ${j.toString()};`,`const createLocaleLoader = ${A.toString()};`,`const loadLocale = createLocaleLoader(loaders, sourceLocale);`,`const listeners = new Set();`,`let currentLocale = sourceLocale;`,`let messages = {};`,`let version = 0;`,`let latestRequest = 0;`,`export const locales = Object.keys(loaders);`,`export function getLocale() { return currentLocale; }`,`export function getVersion() { return version; }`,`export function resolveSupported(preferred) { return resolveLocale(preferred, locales, sourceLocale); }`,`export async function setLocale(locale) {`,` const request = ++latestRequest;`,` let selected = loaders[locale] ? locale : sourceLocale;`,` let catalog;`,` try {`,` catalog = await loadLocale(selected);`,` } catch (error) {`,` console.warn('autoi18n: could not load "' + selected + '", falling back to "' + sourceLocale + '".', error);`,` selected = sourceLocale;`,` try {`,` catalog = await loadLocale(selected);`,` } catch (fallbackError) {`,` // Keep the current locale and messages so the UI stays consistent. Texts without a catalogue show their source.`,` console.error('autoi18n: could not load the source catalogue "' + sourceLocale + '".', fallbackError);`,` return;`,` }`,` }`,` // A slower earlier request must not overwrite the locale the user picked last.`,` if (request !== latestRequest) return;`,` messages = catalog;`,` currentLocale = selected;`,` notify();`,`}`,`function notify() {`,` version++;`,` listeners.forEach(fn => fn(currentLocale));`,`}`,`export function subscribe(fn) { listeners.add(fn); return () => { listeners.delete(fn); }; }`,`export function t(id, source) { return messages[id] ?? source; }`,`// Dev server pushes the catalogues that changed after a source change; no page reload is needed.`,`if (import.meta.hot) {`,` import.meta.hot.on("autoi18n:update", data => {`,` for (const [locale, catalog] of Object.entries(data.catalogs)) loadLocale.prime(locale, catalog);`,` if (!data.catalogs[currentLocale]) return;`,` messages = data.catalogs[currentLocale];`,` notify();`,` });`,`}`].join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-ai-auto-i18n",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "type": "module",
5
5
  "description": "Implicit, build-time AI localization for JSX applications",
6
6
  "license": "ISC",