vite-plugin-ai-auto-i18n 0.4.1 → 0.4.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/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,f as r,h as i,i as a,l as o,m as s,n as c,o as l,p as u,r as d,s as f,u as p}from"./registry-Cj5gJsxW.js";import{n as m,t as h}from"./resolve-ELDMKdoA.js";import g
|
|
1
|
+
import{a as e,c as t,d as n,f as r,h as i,i as a,l as o,m as s,n as c,o as l,p as u,r as d,s as f,u as p}from"./registry-Cj5gJsxW.js";import{n as m,t as h}from"./resolve-ELDMKdoA.js";import{glob as g}from"tinyglobby";import{readFile as _,rm as v}from"node:fs/promises";import y from"node:path";import{createHash as b}from"node:crypto";import{parse as x}from"@babel/parser";import S from"@babel/traverse";import*as C from"@babel/types";import w from"@babel/generator";async function T(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}const E=`\\{([^{}]+)\\}`,D=RegExp(E,`g`);function O(e){return[...e.matchAll(D)].map(e=>e[1])}function k(e,t){let n=new Set(e),r=new Set(t);return n.size===r.size&&[...n].every(e=>r.has(e))}function A(e,t){return e.trim()!==``&&k(O(e),t)}var j=class extends Error{partial;failed;constructor(e,t,n){super(e),this.partial=t,this.failed=n,this.name=`PartialTranslationError`}};async function M(e){let{provider:n,sourceLocale:r,locale:a,requests:o,previous:s,debug:c}=e,l=new Set(o.map(e=>e.id)),u=t(s.messages,l).catalog,d=t(s.sources,l).catalog,f=o.filter(e=>u[e.id]===void 0||d[e.id]!==e.source),p={},m=0,h;if(f.length&&n){if(c)for(let e of f)i(`sent ${r} -> ${a} ${e.id}: ${JSON.stringify(e.source)} (context: ${e.context})`);try{p=await n.translate({sourceLocale:r,targetLocale:a,messages:f})}catch(e){if(!(e instanceof j))throw e;p=e.partial,m=e.failed,h=e.message}if(c)for(let e of f){let t=p[e.id];i(`received ${r} -> ${a} ${e.id}: ${typeof t==`string`?JSON.stringify(t):`(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`&&!A(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 N(e){let t=structuredClone(e.registry),{ambiguous:n,messages:r}=a(t,e.files.flatMap(e=>e.messages)),i=d(t,e.orphanRetentionMinutes),o={};for(let e of r)o[e.id]=e.source;let s=r.map(e=>({id:e.id,source:e.source,context:`${e.component} > ${e.context}`,kind:e.kind,placeholders:e.placeholders})),c=await T(e.locales,e.localeConcurrency,t=>M({provider:e.provider,sourceLocale:e.sourceLocale,locale:t,requests:s,previous:e.previous.get(t)??l(),debug:e.debug})),u=/* @__PURE__ */ new Map,f=/* @__PURE__ */ new Map;return c.forEach((t,n)=>{let r=e.locales[n];t.status===`fulfilled`?u.set(r,t.value):f.set(r,t.reason)}),{registry:t,ambiguous:n,pruned:i,messages:r,sourceFile:{messages:o,sources:{}},locales:u,failures:f}}function P(e){return e.replace(/\s+/g,` `).trim()}function F(e){let t=[P(e.source),e.kind,e.tag.toLowerCase(),e.attribute??``,e.context].join(``);return b(`sha256`).update(t).digest(`hex`).slice(0,24)}const I=S.default??S,ee=/^[A-Z]/,L=/* @__PURE__ */ new Set([`script`,`style`,`code`,`pre`]),R=/* @__PURE__ */ new Set([`alt`,`title`,`placeholder`,`label`,`summary`,`aria-label`,`aria-description`,`aria-placeholder`,`aria-roledescription`,`aria-valuetext`]);function z(e){return e.attributes.some(e=>C.isJSXAttribute(e)&&C.isJSXIdentifier(e.name,{name:`translate`})&&C.isStringLiteral(e.value,{value:`no`}))}function B(e){return C.isJSXIdentifier(e)&&!ee.test(e.name)&&!L.has(e.name)}function V(e){if(C.isIdentifier(e))return e.name;if(C.isMemberExpression(e)&&!e.computed&&C.isIdentifier(e.property)){let t=V(e.object);return t?`${t}.${e.property.name}`:void 0}}function H(e,t){let n=x(e,{sourceType:`unambiguous`,sourceFilename:t,plugins:[`jsx`,`typescript`,`decorators-legacy`]}),r=[];function i(e){let t=e.findParent(e=>e.isFunctionDeclaration()||e.isFunctionExpression()||e.isArrowFunctionExpression());if(!t)return`<module>`;let n=t.parentPath;return n?.isVariableDeclarator()&&C.isIdentifier(n.node.id)?n.node.id.name:t.isFunctionDeclaration()&&t.node.id?t.node.id.name:`<anonymous>`}function a(e,t,n){let r=C.isJSXElement(e)?e.openingElement:e,i=r.attributes.filter(e=>C.isJSXAttribute(e)&&C.isJSXIdentifier(e.name)&&[`aria-label`,`title`,`name`,`type`,`role`].includes(e.name.name)).map(e=>`${e.name.name}=${C.isStringLiteral(e.value)?e.value.value:`{expr}`}`).sort().join(`;`),a=r.attributes.filter(e=>C.isJSXAttribute(e)&&C.isJSXIdentifier(e.name)&&/^on[A-Z]/.test(e.name.name)).map(e=>{let t=C.isJSXExpressionContainer(e.value)?e.value.expression:null,n=t&&C.isIdentifier(t)?t.name:t?.type??`handler`;return`${e.name.name}=${n}`}).sort().join(`,`);return[t,n??``,i,a].filter(Boolean).join(` | `)}function o(e){for(let t=e;t;t=t.parentPath){let e=t.isJSXOpeningElement()?t.node:t.isJSXElement()?t.node.openingElement:void 0;if(e&&z(e))return!0}return!1}return I(n,{JSXElement(e){if(o(e))return;let n=e.node.children,s=n.filter(e=>C.isJSXExpressionContainer(e));if(!s.length||n.some(e=>!C.isJSXText(e)&&!C.isJSXExpressionContainer(e))||!s.every(e=>V(e.expression)!==void 0)||!n.some(e=>C.isJSXText(e)&&/[A-Za-z]/.test(e.value)))return;let c=e.node.openingElement.name;if(!B(c))return;let l=[];for(let e of s){let t=V(e.expression),n=t;for(let e=2;l.includes(n);e++)n=`${t}_${e}`;l.push(n)}let u=``,d=0;for(let e of n)u+=C.isJSXText(e)?e.value:`{${l[d++]}}`;let f=P(u);if(!f)return;let p=c.name,m={source:f,prefix:u.match(/^\s*/)?.[0]??``,suffix:u.match(/\s*$/)?.[0]??``,kind:`mixed`,placeholders:l,file:t,start:e.node.start??0,end:e.node.end??0,tag:p,component:i(e),context:a(e.node,p),fingerprint:``};m.fingerprint=F(m),r.push(m)},JSXText(e){if(o(e))return;let n=e.node.value,s=P(n);if(!s)return;let c=e.findParent(e=>e.isJSXElement());if(!c?.isJSXElement()||c.node.children.some(e=>C.isJSXExpressionContainer(e)))return;let l=c.node.openingElement.name;if(!B(l))return;let u=l.name,d=i(c),f=a(c.node,u),p={source:s,prefix:n.match(/^\s*/)?.[0]??``,suffix:n.match(/\s*$/)?.[0]??``,kind:`text`,file:t,start:e.node.start??0,end:e.node.end??0,tag:u,component:d,context:f,fingerprint:``};p.fingerprint=F(p),r.push(p)},JSXAttribute(e){let n=e.node;if(!C.isJSXIdentifier(n.name)||!R.has(n.name.name)||o(e)||!C.isStringLiteral(n.value))return;let s=P(n.value.value);if(!s||!/[A-Za-z]/.test(s))return;let c=e.parentPath;if(!c.isJSXOpeningElement()||!B(c.node.name))return;let l=c.node.name.name,u=e.findParent(e=>e.isJSXElement());if(!u?.isJSXElement())return;let d=i(u),f=a(u.node,l,n.name.name),p={source:s,kind:`attribute`,file:t,start:n.value.start??0,end:n.value.end??0,tag:l,component:d,attribute:n.name.name,context:f,fingerprint:``};p.fingerprint=F(p),r.push(p)},StringLiteral(e){if(e.parentPath.isJSXAttribute()||!e.node.leadingComments?.some(e=>e.type===`CommentBlock`&&e.value.trim()===`i18n`))return;let n=P(e.node.value);if(!n||!/[A-Za-z]/.test(n))return;let a={source:n,kind:`string`,file:t,start:e.node.start??0,end:e.node.end??0,tag:``,component:i(e),context:``,fingerprint:``};a.fingerprint=F(a),r.push(a)}}),r.sort((e,t)=>e.start-t.start)}const U=S.default??S,W=w.default??w,G=`virtual:autoi18n`,K=`__autoI18nT`,q=`__autoI18nFormat`;function J(e,t,n,r,i,a=!1,o=`en`){let s=x(e,{sourceType:`unambiguous`,sourceFilename:t,plugins:[`jsx`,`typescript`,`decorators-legacy`]}),c=new Map(n.map(e=>[e.start,e])),l=!1,u=!1,d=e=>r===o?e.source:i[e.id]??e.source,f=e=>a?(l=!0,C.callExpression(C.identifier(K),[C.stringLiteral(e.id),C.stringLiteral(e.source)])):C.stringLiteral(d(e));U(s,{JSXElement(e){let t=c.get(e.node.start??-1);if(t?.kind!==`mixed`)return;let n=t.placeholders??[],r=e.node.children.filter(e=>C.isJSXExpressionContainer(e)).map(e=>e.expression),i=t.prefix??``,o=t.suffix??``;if(a){u=!0;let a=C.objectExpression(n.map((e,t)=>C.objectProperty(C.stringLiteral(e),C.cloneNode(r[t])))),s=[i&&C.stringLiteral(i),f(t),o&&C.stringLiteral(o)].filter(Boolean).reduce((e,t)=>C.binaryExpression(`+`,e,t));e.node.children=[C.jsxExpressionContainer(C.callExpression(C.identifier(q),[s,a]))];return}let s=d(t),l=A(s,n)?s:t.source,p=[],m=0,h=e=>{e&&p.push(C.jsxExpressionContainer(C.stringLiteral(e)))};h(i);for(let e of l.matchAll(D))h(l.slice(m,e.index)),p.push(C.jsxExpressionContainer(C.cloneNode(r[n.indexOf(e[1])]))),m=e.index+e[0].length;h(l.slice(m)+o),e.node.children=p},JSXText(e){let t=c.get(e.node.start??-1);if(!t)return;let n=[];a?(t.prefix&&n.push(C.stringLiteral(t.prefix)),n.push(f(t)),t.suffix&&n.push(C.stringLiteral(t.suffix))):n.push(C.stringLiteral(`${t.prefix??``}${d(t)}${t.suffix??``}`));let r=n.reduce((e,t)=>C.binaryExpression(`+`,e,t));e.replaceWith(C.jsxExpressionContainer(r))},JSXAttribute(e){let t=e.node.value;if(!C.isStringLiteral(t))return;let n=c.get(t.start??-1);n&&(e.node.value=a?C.jsxExpressionContainer(f(n)):f(n))},StringLiteral(e){let t=c.get(e.node.start??-1);t?.kind===`string`&&e.replaceWith(f(t))}});let p=[...l?[C.importSpecifier(C.identifier(K),C.identifier(`t`))]:[],...u?[C.importSpecifier(C.identifier(q),C.identifier(`format`))]:[]];p.length&&s.program.body.unshift(C.importDeclaration(p,C.stringLiteral(G)));let m=W(s,{sourceMaps:!0,sourceFileName:t},e);return{code:m.code,map:m.map}}function te(e,t,n){let r=[],i=0;for(let a of e.matchAll(n)){if(!Object.hasOwn(t,a[1]))continue;let n=a.index??0;n>i&&r.push(e.slice(i,n)),r.push(t[a[1]]),i=n+a[0].length}return i<e.length&&r.push(e.slice(i)),r}function ne(e,t){return[`const loaders = {\n${Object.entries(e).map(([e,t])=>` ${JSON.stringify(e)}: () => import(${JSON.stringify(t)}).then(m => (m.default ?? m).messages)`).join(`,
|
|
2
2
|
`)}\n};`,`const sourceLocale = ${JSON.stringify(t)};`,`const resolveLocale = ${h.toString()};`,`const createLocaleLoader = ${m.toString()};`,`const formatPlaceholders = ${te.toString()};`,`const PLACEHOLDER = new RegExp(${JSON.stringify(E)}, "g");`,`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) {`,` if (selected === sourceLocale) throw error;`,` console.warn('autoi18n: could not load "' + selected + '", falling back to "' + sourceLocale + '".', error);`,` selected = sourceLocale;`,` catalog = await loadLocale(selected);`,` }`,` // 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; }`,`export function format(text, values) { return formatPlaceholders(text, values, PLACEHOLDER); }`,`// Dev server pushes fresh catalogues 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]) messages = data.catalogs[currentLocale];`,` notify();`,` });`,`}`].join(`
|
|
3
3
|
`)+`
|
|
4
4
|
`}const Y=6e4;var X=class extends Error{retryable;retryAfterMs;constructor(e,t,n){super(e),this.retryable=t,this.retryAfterMs=n}};function re(e,t=Date.now()){if(!e)return;let n=Number(e);if(Number.isFinite(n))return Math.min(Math.max(n,0)*1e3,Y);let r=Date.parse(e);if(!Number.isNaN(r))return Math.min(Math.max(r-t,0),Y)}const ie=e=>new Promise(t=>setTimeout(t,e));var ae=class{options;constructor(e){this.options=e}async translate(e){let t=Math.max(1,this.options.batchSize??40),n=[];for(let r=0;r<e.messages.length;r+=t)n.push(e.messages.slice(r,r+t));let r=await T(n,this.options.concurrency??4,t=>this.translateBatch({...e,messages:t})),i={},a=[],o=0,s=0;if(r.forEach((e,t)=>{e.status===`fulfilled`?(s++,Object.assign(i,e.value)):(a.push(e.reason),o+=n[t].length)}),!a.length)return i;throw s?new j(`${o} messages failed to translate: ${a[0].message}`,i,o):a[0]}async translateBatch(e){let t=this.options.maxRetries??2,n=this.options.retryDelayMs??500;for(let r=0;;r++)try{return await this.request(e)}catch(e){if(e instanceof X&&!e.retryable||r>=t)throw e;let i=e instanceof X?e.retryAfterMs:void 0;await ie(i??n*2**r*(.5+Math.random()/2))}}async request(e){let t=await fetch(`${this.options.baseURL??`https://api.openai.com/v1`}/chat/completions`,{method:`POST`,signal:AbortSignal.timeout(this.options.timeoutMs??6e4),headers:{Authorization:`Bearer ${this.options.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:this.options.model,temperature:0,response_format:{type:`json_object`},messages:[{role:`system`,content:`You are a professional software localization engine. Translate UI messages from ${e.sourceLocale} to ${e.targetLocale}. Preserve placeholders exactly. Respect context and UI conventions. Return ONLY a JSON object mapping message IDs to translated strings. Do not translate product names or code.`},{role:`user`,content:JSON.stringify(e.messages.map(e=>({id:e.id,text:e.source,context:e.context,kind:e.kind})))}]})});if(!t.ok){let e=t.status===408||t.status===409||t.status===429||t.status>=500;throw new X(`Translation API failed (${t.status}): ${await t.text()}`,e,re(t.headers.get(`retry-after`)))}let r=n.safeParse(await t.json()),i=r.success?r.data.choices[0].message.content:void 0;if(!i)throw new X(`Translation provider returned no content`,!0);let a;try{a=JSON.parse(i)}catch{throw new X(`Translation provider returned invalid JSON`,!0)}let o=u.safeParse(a);if(!o.success)throw new X(`Translation provider returned a non-object`,!0);let s=new Set(e.messages.map(e=>e.id)),c={};for(let[e,t]of Object.entries(o.data))s.has(e)&&typeof t==`string`&&t.trim()&&(c[e]=t);return c}};const Z=[`src/**/*.{tsx,jsx,ts,js}`],Q=[`**/*.test.*`,`**/node_modules/**`];function oe(e){let t=r.safeParse(e);if(t.success)return;let n=t.error.issues.map(e=>`${e.path.join(`.`)||`options`}: ${e.message}`).join(`; `);throw Error(`autoi18n: invalid options (${n}).`)}const $=e=>({info:t=>e.info(t),warn:t=>e.warn(t),error:t=>e.error(t)});async function se(e,t){await Promise.all(t.map(t=>v(y.join(e,`${t}.sources.json`),{force:!0})))}function ce(t){oe(t);let n=t.sourceLocale??`en`,r=t.directory??`.autoi18n`,a=t.delivery??`build`,l=t.debug??!1,u=t.orphanRetentionMinutes??43200,d,m=``,h={},v=/* @__PURE__ */ new Map,b=/* @__PURE__ */ new Map,x=/* @__PURE__ */ new Map,S=/* @__PURE__ */ new Map,C=/* @__PURE__ */ new Set,w,T=Promise.resolve(),E,D=()=>t.locale??process.env.AUTOI18N_LOCALE??n;function O(){let e=t.locales.filter(e=>e!==n),r=t.locale??process.env.AUTOI18N_LOCALE;return a===`build`&&r&&d.command!==`serve`?e.filter(e=>e===r):e}async function k(a){let C=await g(t.include??Z,{cwd:d.root,ignore:t.exclude??Q,absolute:!0}),w=/* @__PURE__ */ new Map,T=[];for(let e of C){let t=await _(e,`utf8`),n=s(t),r=v.get(e),i=r?.hash===n?r:{hash:n,messages:H(t,e)};w.set(e,i),T.push({file:e,messages:i.messages})}let E=y.resolve(d.root,r,`locales`),D=O(),k=/* @__PURE__ */ new Map;for(let e of D)k.set(e,await o(f(E,e),a.warn));let A=await N({files:T,registry:await c(m,a.warn),orphanRetentionMinutes:u,sourceLocale:n,locales:D,localeConcurrency:Math.max(1,Math.floor(t.localeConcurrency??2)),previous:k,provider:t.provider,debug:l});if(l)for(let e of A.pruned)i(`removed ${e.id} ${JSON.stringify(e.source)} (last seen ${e.lastSeen})`);if(A.pruned.length&&a.info(`autoi18n: removed ${A.pruned.length} registry entries no longer in the source.`),await e(m,A.registry),A.ambiguous.length){let e=`autoi18n: ${A.ambiguous.length} duplicated texts changed occurrence count, so their IDs may have moved (e.g. "${A.ambiguous[0]}").`;t.onAmbiguous===`error`?a.error(e):a.warn(e)}await p(f(E,n),A.sourceFile),await se(E,[n,...t.locales]);let j=/* @__PURE__ */ new Map([[n,A.sourceFile.messages]]);for(let[e,t]of A.locales)await p(f(E,e),t.file),j.set(e,t.file.messages);for(let e of A.failures.keys())j.set(e,k.get(e)?.messages??{});let M=0;b=/* @__PURE__ */ new Map;for(let{file:e,messages:t}of T)b.set(e,A.messages.slice(M,M+t.length)),M+=t.length;x=new Map([...w].map(([e,t])=>[e,t.hash])),v=w,S=j,h=Object.fromEntries(t.locales.map(e=>[e,f(E,e)]));for(let[e,n]of A.locales)n.requested&&!t.provider&&t.failOnMissingProvider&&a.error(`Missing ${n.requested} ${e} translations and no provider is configured.`),n.rejected&&a.info(`autoi18n: rejected ${n.rejected} ${e} translations with changed placeholders.`),n.untranslated&&(t.provider?a.warn:a.info)(`autoi18n: ${n.untranslated} ${e} messages have no translation and fall back to the source text.`),n.failed&&a.warn(`autoi18n: ${n.failed} ${e} translation batches failed (${n.failure}); they will be requested again on the next build.`);A.messages.length&&a.info(`autoi18n: indexed ${A.messages.length} messages across ${C.length} files.`);let P=[...A.failures];for(let[e,t]of P.slice(1))a.warn(`autoi18n: ${e} translation failed: ${t.message}`);if(P.length)throw P[0][1]}function A(e){let t=T.then(()=>k(e));return T=t.catch(()=>void 0),t}function j(){w?.ws.send({type:`custom`,event:`autoi18n:update`,data:{catalogs:Object.fromEntries(S)}})}async function M(){try{await A($(d.logger)),j()}catch(e){d.logger.error(`autoi18n: re-translation failed: ${e.message}`)}}function P(){clearTimeout(E),E=setTimeout(()=>void M(),150)}function F(e){if(!/\.[jt]sx?$/.test(e))return!1;let n=y.relative(d.root,e).split(y.sep).join(`/`);return(t.include??Z).some(e=>y.matchesGlob(n,e))&&!(t.exclude??Q).some(e=>y.matchesGlob(n,e))}return{name:`vite-plugin-autoi18n`,enforce:`pre`,configResolved(e){d=e,m=y.resolve(d.root,r,`registry.json`);let i=D();if(i!==n&&!t.locales.includes(i))throw Error(`autoi18n: locale "${i}" is not one of the configured locales (${t.locales.join(`, `)}).`)},resolveId(e){if(e===`virtual:autoi18n`)return`\0${G}`},load(e){if(e===`\0virtual:autoi18n`)return ne(h,n)},configureServer(e){w=e,e.watcher.on(`add`,e=>{F(e)&&P()}),e.watcher.on(`unlink`,e=>{b.has(e)&&P()})},closeBundle(){clearTimeout(E)},async buildStart(){await k({info:e=>this.info(e),warn:e=>this.warn(e),error:e=>this.error(e)})},async transform(e,t){let r=t.split(`?`)[0];if(!b.has(r))return null;s(e)!==x.get(r)&&await A($(d.logger));let i=b.get(r);if(!i||s(e)!==x.get(r))return C.has(r)||(C.add(r),this.warn(`autoi18n: ${r} changed while it was being indexed; its messages are left untranslated.`)),null;let o=d.command===`serve`?n:D(),c=J(e,r,i,o,S.get(o)??{},a===`runtime`,n);return{code:c.code,map:c.map}},async handleHotUpdate({file:e}){if(e.startsWith(y.resolve(d.root,r,`locales`)+y.sep))return[];b.has(e)&&await M()}}}export{ae as OpenAICompatibleProvider,j as PartialTranslationError,ce as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-ai-auto-i18n",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Implicit, build-time AI localization for JSX applications",
|
|
6
6
|
"license": "ISC",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@babel/parser": "^8.1.0",
|
|
44
44
|
"@babel/traverse": "^8.1.0",
|
|
45
45
|
"@babel/types": "^8.1.0",
|
|
46
|
-
"
|
|
46
|
+
"tinyglobby": "^0.2.17",
|
|
47
47
|
"zod": "^4.6.7"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|