ms-vite-plugin 1.4.53 → 1.4.56

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/build.js CHANGED
@@ -1 +1 @@
1
- "use strict";var L=Object.create;var D=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,z=Object.prototype.hasOwnProperty;var N=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of J(e))!z.call(t,i)&&i!==n&&D(t,i,{get:()=>e[i],enumerable:!(s=x(e,i))||s.enumerable});return t};var q=(t,e,n)=>(n=t!=null?L($(t)):{},N(e||!t||!t.__esModule?D(n,"default",{value:t,enumerable:!0}):n,t));var C=exports&&exports.__createBinding||(Object.create?(function(t,e,n,s){s===void 0&&(s=n);var i=Object.getOwnPropertyDescriptor(e,n);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,s,i)}):(function(t,e,n,s){s===void 0&&(s=n),t[s]=e[n]})),W=exports&&exports.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),O=exports&&exports.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var s=[];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(s[s.length]=i);return s},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var s=t(e),i=0;i<s.length;i++)s[i]!=="default"&&C(n,e,s[i]);return W(n,e),n}})(),E=exports&&exports.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildAll=void 0;const A=E(require("archiver")),S=require("child_process"),r=O(require("fs-extra")),M=O(require("os")),o=O(require("path")),K=require("./stopGuardPlugin"),T=E(require("vite-plugin-bundle-obfuscator"));async function G(t,e){const n=(0,A.default)("zip",{zlib:{level:9}}),s=r.createWriteStream(e);return new Promise((i,c)=>{n.directory(t,!1).on("error",a=>c(a)).pipe(s),s.on("close",()=>i()),n.finalize()})}async function B(t,e){const n=[];async function s(i){const c=await r.readdir(i,{withFileTypes:!0});for(const a of c){const f=o.resolve(i,a.name);a.isDirectory()?await s(f):a.isFile()&&(/^main\.(js|ts)$/.test(a.name)||/_thread\.(js|ts)$/.test(a.name))&&n.push(o.relative(e,f))}}return await s(t),n}function R(){const t=[{cmd:o.join(M.homedir(),".KuaiJSDevloper","python","python.exe"),args:["--version"]},{cmd:o.join(M.homedir(),".KuaiJSDevloper","python","bin","python"),args:["--version"]},{cmd:"python",args:["--version"]},{cmd:"python3",args:["--version"]},{cmd:"python3.14",args:["--version"]}];for(const e of t)try{const n=(0,S.spawnSync)(e.cmd,e.args,{encoding:"utf8"}),s=(n.stdout||n.stderr||"").trim();if(s&&/Python\s+3\.14(\.\d+)?/i.test(s))return{ok:!0,path:e.cmd,version:s}}catch{}return{ok:!1}}async function H(t){async function e(n){const s=await r.readdir(n,{withFileTypes:!0});for(const i of s){const c=o.join(n,i.name);if(i.isDirectory())if(i.name==="__pycache__"){const a=await r.readdir(c,{withFileTypes:!0});for(const f of a){const _=o.join(c,f.name);if(f.isFile()&&f.name.endsWith(".cpython-314.pyc")){const v=o.dirname(c),m=f.name.replace(/\.cpython-314\.pyc$/,".pyc"),w=o.join(v,m);await r.move(_,w,{overwrite:!0})}}try{await r.remove(c)}catch{}}else await e(c);else if(i.isFile())if(i.name.endsWith(".cpython-314.pyc")){const a=c.replace(".cpython-314.pyc",".pyc");await r.move(c,a,{overwrite:!0})}else i.name.endsWith(".py")&&await r.remove(c)}}await e(t)}const I=["Minify","Weak","Medium","Strong"];async function Q(t){const e=o.join(t,"obfuscator.json");if(!await r.pathExists(e))return{enabled:!0,preset:"Medium"};try{const n=await r.readJSON(e),s=n?.enabled!==!1,i=U(n?.preset);return{enabled:s,preset:i}}catch(n){return console.error("\u274C \u65E0\u6CD5\u8BFB\u53D6 obfuscator.json"),console.error(n instanceof Error?n.message:String(n)),process.exit(1),{enabled:!0,preset:"Medium"}}}function U(t){if(typeof t!="string")return"Medium";const e=I.find(n=>n.toLowerCase()===t.trim().toLowerCase());return e||(console.warn(`\u26A0\uFE0F obfuscator.json \u7684 preset \u65E0\u6548: ${t}\uFF0C\u5DF2\u6539\u7528 Medium`),"Medium")}function V(t){return[o.join(t,"node_modules/@gamely/prometheus-cli/bin/cli.js"),o.join(t,"node_modules/ms-vite-plugin/node_modules/@gamely/prometheus-cli/bin/cli.js"),o.resolve(process.cwd(),"node_modules/@gamely/prometheus-cli/bin/cli.js")].find(n=>r.pathExistsSync(n))}const X=async(t=!0,e)=>{const n=o.join(e,"scripts"),s=await r.pathExists(o.join(n,"main.js"))||await r.pathExists(o.join(n,"main.ts")),i=await r.pathExists(o.join(n,"main.py")),c=await r.pathExists(o.join(n,"main.lua"));if(s){console.log("\u{1F680} \u5F00\u59CB\u6784\u5EFAJavaScript\u9879\u76EE...");const{build:l}=await import("vite"),u=o.join(e,"obfuscator.json");await r.pathExists(u)||(console.error("\u274C \u9519\u8BEF: \u5F53\u524D\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u7684 \u5FEB\u70B9JS \u9879\u76EE"),console.error("\u8BF7\u786E\u4FDD\u76EE\u5F55\u5305\u542B\u4EE5\u4E0B\u6587\u4EF6:"),console.error(" - obfuscator.json"),process.exit(1));const h=await r.readJSON(u),b=o.join(e,t?"dist":"msbundle"),j=await B(n,n);await r.remove(b);for(const d of j)await l({root:e,build:{lib:{entry:{[o.basename(d,o.extname(d))]:`./scripts/${d}`},fileName:()=>d.replace(/\.ts$/,".js"),formats:["iife"],name:"KuaiJS"},outDir:t?"dist/scripts":"msbundle/scripts",emptyOutDir:!1,sourcemap:t,minify:!t,target:"safari15"},plugins:[(0,K.createStopGuardPlugin)(),...t?[]:[h.enabled?(0,T.default)({autoExcludeNodeModules:!0,threadPool:!0,options:{...h,target:"browser",debugProtection:!1,disableConsoleOutput:!1,domainLock:[],selfDefending:!1,renameGlobals:!1,renameProperties:!1}}):[]]]})}if(t)return;const a=o.join(e,"msbundle");if(await r.ensureDir(a),(i||c)&&await r.copy(o.join(e,"scripts"),o.join(a,"scripts")),i){const l=R();if(l.ok){console.log(`\u2705 \u68C0\u6D4B\u5230 ${l.version} (${l.path})`);const u=(0,S.spawnSync)(l.path,["-m","compileall","scripts"],{encoding:"utf8",cwd:a});u.status===0?(console.log("\u2705 \u6210\u529F\u7F16\u8BD1\u6240\u6709 Python \u6587\u4EF6"),await H(o.join(a,"scripts"))):(console.error("\u274C \u7F16\u8BD1 Python \u6587\u4EF6\u5931\u8D25"),console.error(u.stderr),process.exit(1))}else console.warn("\u26A0\uFE0F \u672A\u68C0\u6D4B\u5230 Python 3.14\uFF0C\u8BF7\u786E\u4FDD\u5728\u76EE\u6807\u8FD0\u884C\u73AF\u5883\u5B89\u88C5 Python 3.14")}else if(c){const l=await Q(e);if(!l.enabled)console.log("\u2139\uFE0F \u5DF2\u5173\u95ED Lua \u6DF7\u6DC6\uFF08obfuscator.json enabled=false\uFF09");else{const u=o.join(a,"scripts"),h=[],b=async d=>{const y=await r.readdir(d,{withFileTypes:!0});for(const p of y){const g=o.join(d,p.name);p.isDirectory()?await b(g):p.isFile()&&p.name.endsWith(".lua")&&h.push(g)}};await b(u);const j=V(e);j||(console.error("\u274C \u672A\u627E\u5230 @gamely/prometheus-cli\uFF0C\u65E0\u6CD5\u6DF7\u6DC6 Lua"),process.exit(1));for(const d of h){const y=o.relative(u,d);console.log(`\u{1F6E0}\uFE0F \u6DF7\u6DC6 Lua: ${y} (preset=${l.preset})`);const p=(0,S.spawnSync)(process.execPath,[j,y,"--preset",l.preset],{cwd:u,encoding:"utf8"});p.status!==0&&(console.error("\u274C \u6DF7\u6DC6 Lua \u5931\u8D25:",y),console.error(p.stderr||p.stdout||""),process.exit(1));const g=y.replace(/\.lua$/,".obfuscated.lua"),P=o.join(u,g);await r.pathExists(P)&&(await r.remove(d),await r.move(P,d,{overwrite:!0}))}console.log("\u2705 Lua \u6DF7\u6DC6\u5B8C\u6210")}}await r.copy(o.join(e,"res"),o.join(a,"res")),await r.copy(o.join(e,"ui"),o.join(a,"ui"));for(const l of["logo.jpg","logo.png"]){const u=o.join(e,l);await r.pathExists(u)&&await r.copy(u,o.join(a,l))}const f=o.join(e,"dist"),_=o.join(e,"package.json"),v=o.join(a,"package.json"),m=await r.readJSON(_);delete m.scripts,delete m.devDependencies,delete m.dependencies,await r.writeJSON(v,m,{spaces:2}),await r.emptyDir(f);const w=o.join(f,"ms.zip"),F=o.join(f,"ms.msbundle");await G(a,w),await r.rename(w,F),await r.remove(a)};exports.buildAll=X;
1
+ "use strict";var F=Object.create;var D=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var z=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of J(e))!q.call(t,i)&&i!==n&&D(t,i,{get:()=>e[i],enumerable:!(s=x(e,i))||s.enumerable});return t};var N=(t,e,n)=>(n=t!=null?F($(t)):{},z(e||!t||!t.__esModule?D(n,"default",{value:t,enumerable:!0}):n,t));var C=exports&&exports.__createBinding||(Object.create?(function(t,e,n,s){s===void 0&&(s=n);var i=Object.getOwnPropertyDescriptor(e,n);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,s,i)}):(function(t,e,n,s){s===void 0&&(s=n),t[s]=e[n]})),W=exports&&exports.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),S=exports&&exports.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var s=[];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(s[s.length]=i);return s},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var s=t(e),i=0;i<s.length;i++)s[i]!=="default"&&C(n,e,s[i]);return W(n,e),n}})(),E=exports&&exports.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildAll=void 0;const A=E(require("archiver")),O=require("child_process"),r=S(require("fs-extra")),L=S(require("os")),o=S(require("path")),K=require("./stopGuardPlugin"),T=require("./luaBundle"),B=E(require("vite-plugin-bundle-obfuscator"));async function G(t,e){const n=(0,A.default)("zip",{zlib:{level:9}}),s=r.createWriteStream(e);return new Promise((i,c)=>{n.directory(t,!1).on("error",a=>c(a)).pipe(s),s.on("close",()=>i()),n.finalize()})}async function R(t,e){const n=[];async function s(i){const c=await r.readdir(i,{withFileTypes:!0});for(const a of c){const f=o.resolve(i,a.name);a.isDirectory()?await s(f):a.isFile()&&(/^main\.(js|ts)$/.test(a.name)||/_thread\.(js|ts)$/.test(a.name))&&n.push(o.relative(e,f))}}return await s(t),n}function H(){const t=[{cmd:o.join(L.homedir(),".KuaiJSDevloper","python","python.exe"),args:["--version"]},{cmd:o.join(L.homedir(),".KuaiJSDevloper","python","bin","python"),args:["--version"]},{cmd:"python",args:["--version"]},{cmd:"python3",args:["--version"]},{cmd:"python3.14",args:["--version"]}];for(const e of t)try{const n=(0,O.spawnSync)(e.cmd,e.args,{encoding:"utf8"}),s=(n.stdout||n.stderr||"").trim();if(s&&/Python\s+3\.14(\.\d+)?/i.test(s))return{ok:!0,path:e.cmd,version:s}}catch{}return{ok:!1}}async function I(t){async function e(n){const s=await r.readdir(n,{withFileTypes:!0});for(const i of s){const c=o.join(n,i.name);if(i.isDirectory())if(i.name==="__pycache__"){const a=await r.readdir(c,{withFileTypes:!0});for(const f of a){const _=o.join(c,f.name);if(f.isFile()&&f.name.endsWith(".cpython-314.pyc")){const v=o.dirname(c),m=f.name.replace(/\.cpython-314\.pyc$/,".pyc"),b=o.join(v,m);await r.move(_,b,{overwrite:!0})}}try{await r.remove(c)}catch{}}else await e(c);else if(i.isFile())if(i.name.endsWith(".cpython-314.pyc")){const a=c.replace(".cpython-314.pyc",".pyc");await r.move(c,a,{overwrite:!0})}else i.name.endsWith(".py")&&await r.remove(c)}}await e(t)}const Q=["Minify","Weak","Medium","Strong"];async function U(t){const e=o.join(t,"obfuscator.json");if(!await r.pathExists(e))return{enabled:!0,preset:"Medium",bundle:!0};try{const n=await r.readJSON(e),s=n?.enabled!==!1,i=n?.bundle!==!1,c=V(n?.preset);return{enabled:s,preset:c,bundle:i}}catch(n){return console.error("\u274C \u65E0\u6CD5\u8BFB\u53D6 obfuscator.json"),console.error(n instanceof Error?n.message:String(n)),process.exit(1),{enabled:!0,preset:"Medium",bundle:!0}}}function V(t){if(typeof t!="string")return"Medium";const e=Q.find(n=>n.toLowerCase()===t.trim().toLowerCase());return e||(console.warn(`\u26A0\uFE0F obfuscator.json \u7684 preset \u65E0\u6548: ${t}\uFF0C\u5DF2\u6539\u7528 Medium`),"Medium")}function X(t){return[o.join(t,"node_modules/@gamely/prometheus-cli/bin/cli.js"),o.join(t,"node_modules/ms-vite-plugin/node_modules/@gamely/prometheus-cli/bin/cli.js"),o.resolve(process.cwd(),"node_modules/@gamely/prometheus-cli/bin/cli.js")].find(n=>r.pathExistsSync(n))}const Y=async(t=!0,e)=>{const n=o.join(e,"scripts"),s=await r.pathExists(o.join(n,"main.js"))||await r.pathExists(o.join(n,"main.ts")),i=await r.pathExists(o.join(n,"main.py")),c=await r.pathExists(o.join(n,"main.lua"));if(s){console.log("\u{1F680} \u5F00\u59CB\u6784\u5EFAJavaScript\u9879\u76EE...");const{build:l}=await import("vite"),u=o.join(e,"obfuscator.json");await r.pathExists(u)||(console.error("\u274C \u9519\u8BEF: \u5F53\u524D\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u7684 \u5FEB\u70B9JS \u9879\u76EE"),console.error("\u8BF7\u786E\u4FDD\u76EE\u5F55\u5305\u542B\u4EE5\u4E0B\u6587\u4EF6:"),console.error(" - obfuscator.json"),process.exit(1));const h=await r.readJSON(u),w=o.join(e,t?"dist":"msbundle"),j=await R(n,n);await r.remove(w);for(const d of j)await l({root:e,build:{lib:{entry:{[o.basename(d,o.extname(d))]:`./scripts/${d}`},fileName:()=>d.replace(/\.ts$/,".js"),formats:["iife"],name:"KuaiJS"},outDir:t?"dist/scripts":"msbundle/scripts",emptyOutDir:!1,sourcemap:t,minify:!t,target:"safari15"},plugins:[(0,K.createStopGuardPlugin)(),...t?[]:[h.enabled?(0,B.default)({autoExcludeNodeModules:!0,threadPool:!0,options:{...h,target:"browser",debugProtection:!1,disableConsoleOutput:!1,domainLock:[],selfDefending:!1,renameGlobals:!1,renameProperties:!1}}):[]]]})}if(t)return;const a=o.join(e,"msbundle");if(await r.ensureDir(a),(i||c)&&await r.copy(o.join(e,"scripts"),o.join(a,"scripts")),i){const l=H();if(l.ok){console.log(`\u2705 \u68C0\u6D4B\u5230 ${l.version} (${l.path})`);const u=(0,O.spawnSync)(l.path,["-m","compileall","scripts"],{encoding:"utf8",cwd:a});u.status===0?(console.log("\u2705 \u6210\u529F\u7F16\u8BD1\u6240\u6709 Python \u6587\u4EF6"),await I(o.join(a,"scripts"))):(console.error("\u274C \u7F16\u8BD1 Python \u6587\u4EF6\u5931\u8D25"),console.error(u.stderr),process.exit(1))}else console.warn("\u26A0\uFE0F \u672A\u68C0\u6D4B\u5230 Python 3.14\uFF0C\u8BF7\u786E\u4FDD\u5728\u76EE\u6807\u8FD0\u884C\u73AF\u5883\u5B89\u88C5 Python 3.14")}else if(c){const l=await U(e),u=o.join(a,"scripts");if(l.bundle?await(0,T.bundleLuaScripts)(u):console.log("\u2139\uFE0F \u5DF2\u5173\u95ED Lua \u5355\u6587\u4EF6\u5408\u5E76\uFF08obfuscator.json bundle=false\uFF09"),!l.enabled)console.log("\u2139\uFE0F \u5DF2\u5173\u95ED Lua \u6DF7\u6DC6\uFF08obfuscator.json enabled=false\uFF09");else{const h=[],w=async d=>{const y=await r.readdir(d,{withFileTypes:!0});for(const p of y){const g=o.join(d,p.name);p.isDirectory()?await w(g):p.isFile()&&p.name.endsWith(".lua")&&h.push(g)}};await w(u);const j=X(e);j||(console.error("\u274C \u672A\u627E\u5230 @gamely/prometheus-cli\uFF0C\u65E0\u6CD5\u6DF7\u6DC6 Lua"),process.exit(1));for(const d of h){const y=o.relative(u,d);console.log(`\u{1F6E0}\uFE0F \u6DF7\u6DC6 Lua: ${y} (preset=${l.preset})`);const p=(0,O.spawnSync)(process.execPath,[j,y,"--preset",l.preset],{cwd:u,encoding:"utf8"});p.status!==0&&(console.error("\u274C \u6DF7\u6DC6 Lua \u5931\u8D25:",y),console.error(p.stderr||p.stdout||""),process.exit(1));const g=y.replace(/\.lua$/,".obfuscated.lua"),P=o.join(u,g);await r.pathExists(P)&&(await r.remove(d),await r.move(P,d,{overwrite:!0}))}console.log("\u2705 Lua \u6DF7\u6DC6\u5B8C\u6210")}}await r.copy(o.join(e,"res"),o.join(a,"res")),await r.copy(o.join(e,"ui"),o.join(a,"ui"));for(const l of["logo.jpg","logo.png"]){const u=o.join(e,l);await r.pathExists(u)&&await r.copy(u,o.join(a,l))}const f=o.join(e,"dist"),_=o.join(e,"package.json"),v=o.join(a,"package.json"),m=await r.readJSON(_);delete m.scripts,delete m.devDependencies,delete m.dependencies,await r.writeJSON(v,m,{spaces:2}),await r.emptyDir(f);const b=o.join(f,"ms.zip"),M=o.join(f,"ms.msbundle");await G(a,b),await r.rename(b,M),await r.remove(a)};exports.buildAll=Y;
@@ -0,0 +1 @@
1
+ export declare function bundleLuaScripts(scriptsDir: string): Promise<number>;
@@ -0,0 +1,4 @@
1
+ "use strict";var b=exports&&exports.__createBinding||(Object.create?(function(t,e,i,n){n===void 0&&(n=i);var a=Object.getOwnPropertyDescriptor(e,i);(!a||("get"in a?!e.__esModule:a.writable||a.configurable))&&(a={enumerable:!0,get:function(){return e[i]}}),Object.defineProperty(t,n,a)}):(function(t,e,i,n){n===void 0&&(n=i),t[n]=e[i]})),_=exports&&exports.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),m=exports&&exports.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(i){var n=[];for(var a in i)Object.prototype.hasOwnProperty.call(i,a)&&(n[n.length]=a);return n},t(e)};return function(e){if(e&&e.__esModule)return e;var i={};if(e!=null)for(var n=t(e),a=0;a<n.length;a++)n[a]!=="default"&&b(i,e,n[a]);return _(i,e),i}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.bundleLuaScripts=v;const c=m(require("fs-extra")),d=m(require("path")),w=new Set(["action","appleocr","cloud","config","cryptoUtils","cv","device","dotocr","file","hid","hotupdate","http","image","ime","logger","media","mysql","netcard","node","paddleocr","pip","system","tomatoocr","tts","ui","utils","yolo","yolocls"]),F=new Set(["coroutine","debug","io","math","os","package","string","table","utf8"]);async function v(t){const e=d.join(t,"main.lua");await c.pathExists(e)||(console.error("\u274C \u672A\u627E\u5230 scripts/main.lua\uFF0C\u65E0\u6CD5\u5408\u5E76 Lua"),process.exit(1));const i=await j(t),n=new Map;for(const o of i){const u=p(t,o),l=h(u);if(!l)continue;if(w.has(l)||F.has(l)){const g=w.has(l)?"\u5BBF\u4E3B":"\u6807\u51C6\u5E93";console.warn(`\u26A0\uFE0F \u8DF3\u8FC7 ${u}\uFF1A\u6A21\u5757\u540D ${l} \u4E0E${g} require \u51B2\u7A81\uFF0C\u8FD0\u884C\u65F6\u672C\u6765\u4E5F\u4E0D\u4F1A\u52A0\u8F7D\u8BE5\u6587\u4EF6`);continue}if(n.has(l))continue;let f=await c.readFile(o,"utf8");f=y(f),n.set(l,{rel:u,source:f})}const a=y(await c.readFile(e,"utf8"));if(n.size===0)return console.log("\u2139\uFE0F Lua \u4EC5\u6709 main.lua\uFF0C\u65E0\u9700\u5408\u5E76"),0;const r=[];r.push("-- KuaiJS Lua bundle: package.preload + main.lua");const s=[...n.keys()].sort((o,u)=>o.localeCompare(u));for(const o of s){const u=n.get(o);r.push(`package.preload[${O(o)}] = function(...)`),r.push(u.source.replace(/\s+$/,"")),r.push("end")}r.push(a.replace(/^\uFEFF/,"")),await c.writeFile(e,`${r.join(`
2
+ `)}
3
+ `,"utf8");for(const o of i)p(t,o)!=="main.lua"&&await c.remove(o);return await $(t),console.log(`\u2705 Lua \u5DF2\u5408\u5E76\u4E3A scripts/main.lua\uFF08${n.size} \u4E2A\u6A21\u5757\uFF09`),n.size}async function j(t){const e=[],i=async n=>{const a=await c.readdir(n,{withFileTypes:!0});for(const r of a){const s=d.join(n,r.name);r.isDirectory()?await i(s):r.isFile()&&r.name.endsWith(".lua")&&e.push(s)}};return await i(t),e.sort((n,a)=>{const r=p(t,n),s=p(t,a),o=h(r)??"",u=h(s)??"";if(o===u&&o){const l=r.endsWith("/init.lua")?1:0,f=s.endsWith("/init.lua")?1:0;return l-f}return r.localeCompare(s)}),e}function h(t){const e=t.replace(/\\/g,"/");if(e!=="main.lua"){if(e.endsWith("/init.lua")){const i=e.slice(0,-9);return i?i.replace(/\//g,"."):"init"}if(e.endsWith(".lua"))return e.slice(0,-4).replace(/\//g,".")}}function p(t,e){return d.relative(t,e).split(d.sep).join("/")}function y(t){let e=t.replace(/^\uFEFF/,"");if(e.startsWith("#!")){const i=e.indexOf(`
4
+ `);e=i>=0?e.slice(i+1):""}return e}function O(t){if(!/["\\\n\r]/.test(t))return`"${t}"`;let e="";for(;t.includes(`]${e}]`);)e+="=";return`[${e}[${t}]${e}]`}async function $(t){const e=async i=>{const n=await c.readdir(i,{withFileTypes:!0});let a=!0;for(const r of n){const s=d.join(i,r.name);r.isDirectory()&&await e(s)?await c.remove(s):a=!1}return a};await e(t)}
package/docs/AGENTS.md CHANGED
@@ -12,9 +12,12 @@
12
12
  - Python 项目使用 Python 文档与写法。
13
13
  - Lua 项目使用 Lua 文档与写法。
14
14
  - 不要混用 JavaScript、Python 与 Lua API。
15
+ - Lua 只提供英文方法,没有中文别名。
16
+ - Lua 模块通过 `require("device")` 加载;`Sleep`、`StartThread` 等是裸全局。
15
17
  - 不要把快点JS Python 脚本当成普通 CPython 脚本。
16
18
  - 不要对快点JS Python 脚本运行 `python -m py_compile`、`py_compile` 或类似 CPython 编译校验。
17
19
  - 不要创建、保留或同步 `__pycache__`、`.pyc` 作为项目改动。
20
+ - Lua 用户模块请用 `require("foo")` / `require("lib.bar")`。Release 打包默认会把 `scripts` 下除 `main.lua` 外的用户 `.lua` 合并进单个 `main.lua`;不要用 `dofile` / `loadfile` 按路径加载这些文件。
18
21
  - 文档未确认的能力必须明确说明无法确认,不要凭经验补全。
19
22
 
20
23
  ## 目录职责
package/docs/SKILL.md CHANGED
@@ -19,6 +19,9 @@ description: 快点JS专用开发助手。用于快点JS项目开发、本地 AP
19
19
  - JavaScript 项目使用 JavaScript 文档与写法。
20
20
  - Lua 项目使用 Lua 文档与写法。
21
21
  - 不要混用 JavaScript、Python 与 Lua API。
22
+ - Lua 只提供英文方法,没有中文别名。
23
+ - Lua 模块通过 `require("device")` 加载;`Sleep`、`StartThread` 等是裸全局。
24
+ - Lua 用户模块请用 `require("foo")` / `require("lib.bar")`。Release 打包默认会把 `scripts` 下除 `main.lua` 外的用户 `.lua` 合并进单个 `main.lua`;不要用 `dofile` / `loadfile` 按路径加载这些文件。
22
25
  - 文档未确认的能力必须明确说明无法确认,并给出保守方案。
23
26
  - 快点JS Python 脚本不使用 CPython 编译校验;不要运行 `python -m py_compile`、`py_compile` 或类似命令。
24
27
 
@@ -1,4 +1,4 @@
1
- # 点阵 OCR 模块 (dotOcr)
1
+ # 点阵 OCR 模块 (dotocr)
2
2
 
3
3
  点阵 OCR 模块基于图色工具生成的固定像素点阵字库,提供精确的文字识别与查找功能。字库保存在项目的 `res/fonts` 目录,使用前需先加载字库取得字库 ID,再复用该 ID 进行识别,使用完毕后释放。
4
4
 
@@ -58,11 +58,12 @@ local listPage = node.createNodeSelector({ mode = 2 })
58
58
 
59
59
  | 字段 | 说明 |
60
60
  | --- | --- |
61
- | `id` | 节点 ID(内部定位用,不要改) |
61
+ | `id` | 节点 ID,不要改 |
62
62
  | `identifier` | 控件标识符 |
63
63
  | `label` | 标签文案 |
64
64
  | `type` | 类型,如 `XCUIElementTypeButton` |
65
65
  | `value` | 当前值 |
66
+ | `placeholderValue` | 输入框占位文字 |
66
67
  | `title` | 标题 |
67
68
  | `enabled` | 是否启用 |
68
69
  | `visible` | 是否可见 |
@@ -76,8 +77,16 @@ local listPage = node.createNodeSelector({ mode = 2 })
76
77
 
77
78
  | 方法 | 说明 |
78
79
  | --- | --- |
80
+ | `hittable()` | 当前是否可点击(可见且未被挡住) |
81
+ | `scrollToVisible()` | 仅滚动到可见,不点击;一般不必手动调用 |
82
+ | `tap()` | 单击;不可见时会先自动滚到可见 |
83
+ | `doubleTap()` | 双击;不可见时会先自动滚到可见 |
84
+ | `press(duration?)` | 长按,`duration` 单位毫秒,默认 500;不可见时会先自动滚到可见 |
79
85
  | `clickCenter()` | 点击中心坐标(坐标点击,不会自动滚动) |
80
86
  | `clickRandom()` | 在节点范围内随机点击(坐标点击,不会自动滚动) |
87
+ | `clearInput()` | 清空输入;不可见时会先自动滚到可见 |
88
+ | `input(text)` | 追加输入,不清空原内容;不可见时会先自动滚到可见 |
89
+ | `setValue(text)` | 设置值(见下方;不可见时会先自动滚到可见) |
81
90
  | `parent()` | 父节点 |
82
91
  | `child(index)` | 第 `index` 个子节点 |
83
92
  | `allChildren()` | 全部子节点 |
@@ -93,7 +102,7 @@ local listPage = node.createNodeSelector({ mode = 2 })
93
102
 
94
103
  | 方法 | 说明 |
95
104
  | --- | --- |
96
- | `releaseNode()` | 立刻释放选择器;与 `<close>` 二选一即可,重复调用安全 |
105
+ | `releaseNode()` | 立刻释放选择器;与 `<close>` 二选一即可 |
97
106
  | `loadNode(timeout?)` | 重新加载界面节点,默认超时 5000ms |
98
107
  | `clearSelector()` | 清除已设置的筛选条件 |
99
108
  | `xml(timeout?)` | 获取界面 XML,失败返回 `nil` |
@@ -115,7 +124,7 @@ selector:releaseNode() -- 手动释放
115
124
 
116
125
  ### 筛选条件
117
126
 
118
- 可链式调用,多个条件同时满足(并且关系)。
127
+ 可链式调用,多个条件同时满足(并且关系)。
119
128
  带 `Match` 的为模糊/正则匹配。
120
129
 
121
130
  **文本**
@@ -126,6 +135,7 @@ selector:releaseNode() -- 手动释放
126
135
  | `title` / `titleMatch` | 标题 |
127
136
  | `identifier` / `identifierMatch` | 标识符 |
128
137
  | `value` / `valueMatch` | 值 |
138
+ | `placeholderValue` / `placeholderValueMatch` | 占位文字 |
129
139
 
130
140
  **类型与状态**
131
141
 
@@ -152,6 +162,7 @@ selector:label("确定"):type("XCUIElementTypeButton"):getOneNodeInfo(3000)
152
162
  -- 模糊
153
163
  selector:labelMatch(".*登录.*"):getNodeInfo(3000)
154
164
  selector:identifierMatch("^login_"):getNodeInfo(3000)
165
+ selector:placeholderValue("请输入账号"):getOneNodeInfo(3000)
155
166
  -- 组合
156
167
  selector
157
168
  :type("XCUIElementTypeTextField")
@@ -165,25 +176,76 @@ selector
165
176
 
166
177
  ## 节点操作说明
167
178
 
179
+ ### 是否可点 / 滚到可见
180
+
181
+ `tap` / `doubleTap` / `press` / `setValue` / `clearInput` / `input` 在元素当前不可见时,会**自动**先滚到可见再操作,一般不用手写滚动:
182
+
183
+ ```lua
184
+ -- 推荐:直接操作,不可见时会自动滚到可见
185
+ btn:tap()
186
+ btn:doubleTap()
187
+ btn:press(800)
188
+ btn:setValue("hello")
189
+ ```
190
+
191
+ - `hittable()`:当前能否点到(可见且未被挡住),用于排查“点了没反应”
192
+ - `scrollToVisible()`:只滚到可见、不点击;仅在你想先露出元素、稍后再操作时使用
193
+ - `clickCenter()` / `clickRandom()`:按坐标点击,**不会**自动滚动
194
+
168
195
  ### 点击
169
196
 
170
197
  | 方法 | 说明 |
171
198
  | --- | --- |
199
+ | `tap()` | 推荐,单击;不可见时自动滚到可见 |
200
+ | `doubleTap()` | 双击;不可见时自动滚到可见 |
201
+ | `press(ms?)` | 长按,默认 500ms;不可见时自动滚到可见 |
172
202
  | `clickCenter()` | 点中心坐标,不自动滚动 |
173
203
  | `clickRandom()` | 范围内随机点,不自动滚动 |
174
204
 
175
- 输入请配合 `ime` 或 `action.input`。
176
-
177
205
  ```lua
178
206
  local node = require("node")
179
207
  local selector <close> = node.createNodeSelector()
180
208
  local btn = selector:label("确定"):type("XCUIElementTypeButton"):getOneNodeInfo(3000)
181
209
 
182
210
  if btn then
183
- btn:clickCenter()
211
+ btn:tap()
212
+ btn:doubleTap()
213
+ btn:press(800)
184
214
  end
185
215
  ```
186
216
 
217
+ ### 输入与设值
218
+
219
+ | 方法 | 说明 |
220
+ | --- | --- |
221
+ | `clearInput()` | 清空;不可见时也会自动滚到可见 |
222
+ | `input(text)` | 追加输入,不清空原内容 |
223
+ | `setValue(text)` | 按控件类型设置;不可见时会先自动滚到可见 |
224
+
225
+ **`setValue` 行为**
226
+
227
+ | 控件类型 | 传参 | 效果 |
228
+ | --- | --- | --- |
229
+ | `PickerWheel` | 选项文案,如 `"1小时"` | 滚到该选项(控件本身不可见时也会先自动滚到可见) |
230
+ | 文本框类(TextField 等) | 字符串 | 聚焦后追加输入,不先清空 |
231
+
232
+ 覆盖原内容请先清空:
233
+
234
+ ```lua
235
+ field:clearInput()
236
+ field:setValue("hello")
237
+ -- 或
238
+ field:clearInput()
239
+ field:input("hello")
240
+ ```
241
+
242
+ ```lua
243
+ local wheel = selector:type("XCUIElementTypePickerWheel"):getOneNodeInfo(3000)
244
+ if wheel then
245
+ -- 不可见时会自动滚到可见,再调到目标选项
246
+ wheel:setValue("1小时")
247
+ end
248
+ ```
187
249
 
188
250
  ### 树导航
189
251
 
@@ -191,10 +253,10 @@ end
191
253
  local field = selector:type("XCUIElementTypeTextField"):getOneNodeInfo(3000)
192
254
  if field then
193
255
  local parent = field:parent()
194
- local children = parent:allChildren() or []
256
+ local children = parent and parent:allChildren() or {}
195
257
  local prev = field:previousSiblings()
196
258
  local next = field:nextSiblings()
197
- local second = parent:child(1)
259
+ local second = parent and parent:child(1)
198
260
  end
199
261
  ```
200
262
 
@@ -206,14 +268,12 @@ end
206
268
 
207
269
  ```lua
208
270
  local node = require("node")
209
- local ime = require("ime")
210
271
  local selector <close> = node.createNodeSelector()
211
272
 
212
273
  local user = selector:type("XCUIElementTypeTextField"):getOneNodeInfo(5000)
213
274
  if user then
214
- user:clickCenter()
215
- ime.clearText()
216
- ime.input("demo_user")
275
+ user:clearInput()
276
+ user:setValue("demo_user")
217
277
  end
218
278
 
219
279
  local pass = selector
@@ -221,9 +281,8 @@ local pass = selector
221
281
  :type("XCUIElementTypeSecureTextField")
222
282
  :getOneNodeInfo(3000)
223
283
  if pass then
224
- pass:clickCenter()
225
- ime.clearText()
226
- ime.input("password")
284
+ pass:clearInput()
285
+ pass:setValue("password")
227
286
  end
228
287
 
229
288
  local login = selector
@@ -232,7 +291,7 @@ local login = selector
232
291
  :type("XCUIElementTypeButton")
233
292
  :getOneNodeInfo(3000)
234
293
  if login then
235
- login:clickCenter()
294
+ login:tap()
236
295
  end
237
296
  ```
238
297
 
@@ -243,7 +302,7 @@ local node = require("node")
243
302
  local selector <close> = node.createNodeSelector({ mode = 2 })
244
303
  local item = selector:label("第 30 项"):getOneNodeInfo(5000)
245
304
  if item then
246
- item:clickCenter()
305
+ item:tap() -- 不在可见区域时会自动滚动
247
306
  end
248
307
  ```
249
308
 
@@ -262,14 +321,17 @@ selector:releaseNode()
262
321
 
263
322
  ## 常见问题
264
323
 
265
- **找不到节点**
324
+ **找不到节点**
266
325
  加大超时;减少条件或改用 `*Match`;换 `mode`;用 `xml()` 看实际文案和类型。
267
326
 
268
- **点了没反应**
269
- 确认点到的是目标控件;用 `clickCenter()` / `clickRandom()` 按坐标点击。
327
+ **点了没反应**
328
+ 先看 `hittable()`;确认点到的是目标控件;可对比 `clickCenter()`。
329
+
330
+ **输入叠在旧文字后面**
331
+ `input` / 文本类 `setValue` 是追加,先 `clearInput()`。
270
332
 
271
- **输入叠在旧文字后面**
272
- 节点没有输入方法,请先 `ime.clearText()` `ime.input()`。
333
+ **滚轮设不中**
334
+ `setValue` 要传界面上显示的选项文案;确认类型是 `PickerWheel`;多列时选对那一列。
273
335
 
274
336
  **要不要释放**
275
337
  要。用 `<close>` 自动释放,或用完调 `releaseNode()`,两种都行。
@@ -1,7 +1,7 @@
1
1
  # OpenCV 模块 (cv)
2
2
 
3
3
  提供图像读写、颜色与阈值、滤波、几何变换、绘制、模板/特征匹配、轮廓、形态学、直方图、霍夫、扫码等能力。
4
- 可通过 `require("cv")` 或 `require("opencv")` 获取。无中文别名。方法与常量对齐 JS `cv`。
4
+ 可通过 `require("cv")` 获取。无中文别名。方法与常量对齐 JS `cv`。
5
5
 
6
6
  注意:
7
7
 
@@ -59,7 +59,7 @@ local gray = cv.cvtColor(src, { code = cv.COLOR_BGR2GRAY })
59
59
  local edges = cv.Canny(gray, { threshold1 = 100, threshold2 = 200 })
60
60
  local feat = cv.SIFT(gray, { nfeatures = 500 })
61
61
  if feat then
62
- logi("keypoints=" .. tostring(#feat.keypoints))
62
+ print("keypoints=" .. tostring(#feat.keypoints))
63
63
  cv.release(feat.descriptors)
64
64
  end
65
65
  cv.imwrite(file.getInternalDir("documents") .. "/edges.png", edges)
@@ -143,9 +143,11 @@ function imread(path) end
143
143
 
144
144
  ```lua
145
145
  local cv = require("cv")
146
+ local file = require("file")
147
+ local image = require("image")
146
148
  local a = cv.imread("template.png")
147
149
  local dir = file.getInternalDir("documents")
148
- local b = cv.imread(`${dir}/shot.jpg`)
150
+ local b = cv.imread(dir .. "/shot.jpg")
149
151
  local imageId = image.captureFullScreen()
150
152
  local c = cv.imread(imageId)
151
153
  image.release(imageId)
@@ -205,8 +207,9 @@ function imwrite(path, mat) end
205
207
 
206
208
  ```lua
207
209
  local cv = require("cv")
210
+ local file = require("file")
208
211
  local src = cv.capture()
209
- cv.imwrite(`${file.getInternalDir("documents")}/out.png`, src)
212
+ cv.imwrite(file.getInternalDir("documents") .. "/out.png", src)
210
213
  cv.release(src)
211
214
  ```
212
215
 
@@ -314,7 +317,7 @@ local cv = require("cv")
314
317
  local a = cv.capture()
315
318
  local b = cv.clone(a)
316
319
  cv.release(a)
317
- logi(cv.isRelease(a)); // true
320
+ print(cv.isRelease(a)) -- true
318
321
  cv.release(b)
319
322
  ```
320
323
 
@@ -556,17 +559,17 @@ local cv = require("cv")
556
559
  cv.rectangle(src, {
557
560
  pt1 = { x = 10, y = 10 },
558
561
  pt2 = { x = 100, y = 80 },
559
- color = [0, 0, 255],
562
+ color = { 0, 0, 255 },
560
563
  thickness = 2,
561
564
  })
562
565
  cv.circle(src, { center = { x = 50, y = 50 }, radius = 20, color = "#00FF00", thickness = -1 })
563
- cv.line(src, { pt1 = { x = 0, y = 0 }, pt2 = { x = 100, y = 100 }, color = [255, 0, 0], thickness = 2 })
566
+ cv.line(src, { pt1 = { x = 0, y = 0 }, pt2 = { x = 100, y = 100 }, color = { 255, 0, 0 }, thickness = 2 })
564
567
  cv.putText(src, {
565
568
  text = "hello",
566
569
  org = { x = 20, y = 40 },
567
570
  fontFace = cv.FONT_HERSHEY_SIMPLEX,
568
571
  fontScale = 1,
569
- color = [255, 255, 255],
572
+ color = { 255, 255, 255 },
570
573
  thickness = 2,
571
574
  })
572
575
  ```
@@ -587,9 +590,9 @@ function fillPoly(mat, options) end
587
590
  ```lua
588
591
  local cv = require("cv")
589
592
  cv.polylines(src, {
590
- pts = [[{ x = 0, y = 0 }, { x = 100, y = 0 }, { x = 100, y = 80 }, { x = 0, y = 80 }]],
593
+ pts = { { x = 0, y = 0 }, { x = 100, y = 0 }, { x = 100, y = 80 }, { x = 0, y = 80 } },
591
594
  isClosed = true,
592
- color = [0, 255, 0],
595
+ color = { 0, 255, 0 },
593
596
  thickness = 2,
594
597
  })
595
598
  ```
@@ -621,11 +624,11 @@ function matchTemplate(image, templ, methodOrOptions) end
621
624
  ```lua
622
625
  local cv = require("cv")
623
626
  local loc = cv.matchTemplateLoc(src, templ, { method = cv.TM_CCOEFF_NORMED })
624
- logi(`best=(${loc.x},${loc.y}) max=${loc.maxVal}`)
627
+ print(string.format("best=(%s,%s) max=%s", loc.x, loc.y, loc.maxVal))
625
628
  cv.rectangle(src, {
626
629
  pt1 = { x = loc.x, y = loc.y },
627
630
  pt2 = { x = loc.x + tw, y = loc.y + th },
628
- color = [0, 0, 255],
631
+ color = { 0, 0, 255 },
629
632
  thickness = 2,
630
633
  })
631
634
  ```
@@ -653,8 +656,8 @@ function findContours(mat, options) end
653
656
 
654
657
  ```lua
655
658
  local cv = require("cv")
656
- local { contours, hierarchy } = cv.findContours(bin, { mode = cv.RETR_TREE, method = cv.CHAIN_APPROX_SIMPLE })
657
- logi(`count=${contours.length} h0=${hierarchy[0]}`)
659
+ local ret = cv.findContours(bin, { mode = cv.RETR_TREE, method = cv.CHAIN_APPROX_SIMPLE })
660
+ print("count=" .. tostring(#ret.contours))
658
661
  ```
659
662
 
660
663
  ### boundingRect / minAreaRect / contourArea / arcLength / approxPolyDP
@@ -82,9 +82,9 @@ function load(paramPath, binPath, nc, useGpu) end
82
82
  **示例:**
83
83
 
84
84
  ```lua
85
- local yoloCls = require("yoloCls")
85
+ local yolocls = require("yolocls")
86
86
  -- 模型文件通常放在 res 目录
87
- local modelId = yoloCls.load(
87
+ local modelId = yolocls.load(
88
88
  "yolo11n_cls_ncnn_model/model.ncnn.param",
89
89
  "yolo11n_cls_ncnn_model/model.ncnn.bin",
90
90
  1000, -- ImageNet 分类模型通常为 1000 类
@@ -129,8 +129,8 @@ function classify(modelId, img, targetSize) end
129
129
  **示例:**
130
130
 
131
131
  ```lua
132
- local yoloCls = require("yoloCls")
133
- local modelId = yoloCls.load(
132
+ local yolocls = require("yolocls")
133
+ local modelId = yolocls.load(
134
134
  "yolo11n_cls_ncnn_model/model.ncnn.param",
135
135
  "yolo11n_cls_ncnn_model/model.ncnn.bin",
136
136
  1000,
@@ -142,7 +142,7 @@ if not modelId then
142
142
  return
143
143
  end
144
144
 
145
- local probs = yoloCls.classify(
145
+ local probs = yolocls.classify(
146
146
  modelId,
147
147
  "screen", -- 使用当前屏幕
148
148
  224 -- 分类模型常用输入尺寸
@@ -166,7 +166,7 @@ if #probs.data > classId then
166
166
  print("类别 " .. tostring(classId) .. " 概率: " .. tostring(probs.data[classId].toFixed(4)))
167
167
  end
168
168
 
169
- yoloCls.free(modelId)
169
+ yolocls.free(modelId)
170
170
  ```
171
171
 
172
172
  #### classifyRegion - 对指定区域执行分类
@@ -206,8 +206,8 @@ function classifyRegion(modelId, img, x, y, ex, ey, targetSize) end
206
206
  **示例:**
207
207
 
208
208
  ```lua
209
- local yoloCls = require("yoloCls")
210
- local regionProbs = yoloCls.classifyRegion(
209
+ local yolocls = require("yolocls")
210
+ local regionProbs = yolocls.classifyRegion(
211
211
  modelId,
212
212
  "screen",
213
213
  100,
@@ -244,9 +244,9 @@ function free(modelId) end
244
244
  **示例:**
245
245
 
246
246
  ```lua
247
- local yoloCls = require("yoloCls")
247
+ local yolocls = require("yolocls")
248
248
  if modelId then
249
- yoloCls.free(modelId)
249
+ yolocls.free(modelId)
250
250
  print("YOLO 分类模型 " .. tostring(modelId) .. " 资源已释放")
251
251
  end
252
252
  ```
@@ -262,8 +262,8 @@ function freeAll() end
262
262
  **示例:**
263
263
 
264
264
  ```lua
265
- local yoloCls = require("yoloCls")
266
- yoloCls.freeAll()
265
+ local yolocls = require("yolocls")
266
+ yolocls.freeAll()
267
267
  print("所有 YOLO 分类模型资源已释放")
268
268
  ```
269
269
 
@@ -15,6 +15,7 @@
15
15
  - 不要把快点JS Python 脚本当成普通 CPython 脚本。
16
16
  - 不要对快点JS Python 脚本运行 `python -m py_compile`、`py_compile` 或类似 CPython 编译校验。
17
17
  - 不要创建、保留或同步 `__pycache__`、`.pyc` 作为项目改动。
18
+ - Lua 用户模块请用 `require("foo")` / `require("lib.bar")`。Release 打包默认会把 `scripts` 下除 `main.lua` 外的用户 `.lua` 合并进单个 `main.lua`;不要用 `dofile` / `loadfile` 按路径加载这些文件。
18
19
  - 文档未确认的能力必须明确说明无法确认,不要凭经验补全。
19
20
 
20
21
  ## 允许的执行方式
@@ -37,7 +37,7 @@
37
37
  ├─ .npmrc ← npm 配置文件
38
38
  ├─ .prettierignore ← 代码格式化忽略文件(仅js项目)
39
39
  ├─ .prettierrc.yaml ← 代码格式化配置(需安装 Prettier 插件,仅js项目)
40
- ├─ obfuscator.json ← 代码混淆配置(JS:javascript-obfuscator;Lua:Prometheus,可开关和选档位)
40
+ ├─ obfuscator.json ← 代码混淆配置(JS:javascript-obfuscator;Lua:Prometheus + 单文件合并,可开关和选档位)
41
41
  ├─ package.json ← 项目依赖配置文件
42
42
  └─ tsconfig.json ← TypeScript 配置文件(用于js提示和网页提示)
43
43
  ```
@@ -9,7 +9,9 @@
9
9
 
10
10
  - 打开主脚本 `main.js | main.py | main.lua`,右键编辑器,选择 `快点JS` -> `打包应用`
11
11
  - 输入在开发者后台->网络验证管理->软件列表 中获取的 `AppId` 字段
12
- - JS / Lua 项目可编辑根目录 `obfuscator.json` 决定打包时是否混淆、用哪档强度;Python 打包编译为 `.pyc`,没有该混淆配置
12
+ - JS / Lua 项目可编辑根目录 `obfuscator.json` 决定打包行为;Python 打包编译为 `.pyc`,没有该配置
13
+ - JS:Vite 把入口打成单文件后再按 `enabled` 混淆
14
+ - Lua:Release 默认把 `scripts` 下用户模块合并为单个 `scripts/main.lua`(`bundle`,缺省 `true`),再按 `enabled` / `preset` 用 Prometheus 混淆该文件。`enabled: false` 时仍可合并。宿主 `require("device")` 等不受影响。不要用 `dofile` / `loadfile` 去读会被删掉的其它 `.lua`
13
15
  - 注意:上传到快点JS热更新服务后,可通过开发者后台->网络验证管理->软件列表的软件编号进行分发
14
16
  - 注意:快点JS上可通过软件面板,输入软件编号进行搜索加载应用
15
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ms-vite-plugin",
3
- "version": "1.4.53",
3
+ "version": "1.4.56",
4
4
  "type": "commonjs",
5
5
  "license": "MIT",
6
6
  "publishConfig": {