@66rpg/lumimaker 0.1.47 → 0.1.48
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
CHANGED
|
@@ -21,7 +21,7 @@ ${o.join(`
|
|
|
21
21
|
`+s("common","page_info_pattern",{page:String(e.page||1),count:String(e.count||r.length),total:String(e.total)})):"";return i+a}function Be(e,t){let n=f.versions,o=[{key:"version",header:n.col_version.text,minWidth:10},{key:"status",header:n.col_status.text,minWidth:8},{key:"changelog",header:n.col_changelog.text,minWidth:12},{key:"published_at",header:n.col_published_at.text,minWidth:18},{key:"post",header:n.col_post.text,minWidth:14}],r=t.map(i=>{let c=!!i.post_id||i.post_status!=null?Number(i.post_status)===4?n.post_public.text:n.post_draft.text:"-";return{version:i.version_name||i.version||i.version_no||"-",status:ss(i.status??i.audit_status),changelog:i.changelog||"-",published_at:is(i.published_at),post:c}});return ae(o,r,{emptyText:n.empty_versions.text,title:A.bold(e)})}function Ao(e,t){let n=f.templates,o=[{key:"data_id",header:n.col_data_id.text,minWidth:14},{key:"data_ver",header:n.col_data_ver.text,minWidth:10},{key:"summary",header:n.col_data_summary.text,minWidth:12}],r=t.map(i=>({data_id:A.cyan(i.data_id||"-"),data_ver:i.data_ver||"-",summary:i.summary||"-"}));return ae(o,r,{emptyText:n.empty_data.text,title:A.bold(e)})}function U(e){if(e==null||typeof e=="object")return;let t=String(e).trim();return t||void 0}function ls(e){let t=U(e);if(!(!t||t==="0"))return t}function ms(e){if(e==null||e==="")return;let t=typeof e=="number"?e:Number(e);if(!(!Number.isFinite(t)||t===0))return t===2?s("fmt","val_demo"):t===3?f.games.val_derived.text:t===1?s("fmt","val_official"):s("fmt","val_unknown")}function us(e,t){let n=t==="template"?["template_id","id"]:t==="project"?["project_id","id"]:["game_id","id"];for(let o of n){let r=ls(e[o]);if(r)return t==="game"?{label:(typeof e.variant=="number"?e.variant:Number(e.variant))===2?s("fmt","label_game_demo_id"):s("fmt","label_game_official_id"),id:r}:t==="template"?{label:s("fmt","label_template_id"),id:r}:{label:s("fmt","label_project_id"),id:r}}}function Ge(e,t,n="game"){let o=[],r=U(t.name)??U(t.template_name)??U(t.project_name);r&&o.push({label:s("fmt","label_name"),value:r,highlight:!0});let i=us(t,n);i&&o.push({label:i.label,value:i.id});let a=ms(t.variant);a&&o.push({label:s("fmt","label_type"),value:a});let c=U(t.parent_game_id);c&&o.push({label:s("fmt","label_parent"),value:c});let m=U(t.summary);m&&o.push({label:s("fmt","label_summary"),value:m});let l=U(t.latest_version_name)??(t.latest_version_no!=null&&t.latest_version_no!==""?s("fmt","version_no",{n:t.latest_version_no}):void 0);l&&o.push({label:s("fmt","label_version"),value:l}),t.status!=null&&t.status!==""&&o.push({label:s("fmt","label_shelf"),value:bo(t.status)});let u=U(t.demo_scope);u&&o.push({label:s("fmt","label_demo_scope"),value:u});let _=U(t.play_duration);if(_&&o.push({label:s("fmt","label_play_duration"),value:_}),t.post_status!=null&&t.post_status!==""){let y=Number(t.post_status)===4;o.push({label:s("fmt","label_post_status"),value:y?f.versions.post_public.text:f.versions.post_draft.text})}return Ae(D(e,o,{status:"info"}),t)}function Eo(e={}){let t=U(e.message)??s("fmt","logout_done");return A.green(`\u2714 ${t}`)}function We(e,t){let n=f.shelf,o=s("fmt",`type_${e}`),r=e==="template"?"template_id":e==="game"?"game_id":"project_id",i=e==="template"?"template_name":e==="game"?"name":"project_name",a=[{label:s("fmt","shelf_id",{type:o}),value:t[r]||"-",highlight:!0}];return t[i]&&a.push({label:s("fmt","shelf_name",{type:o}),value:t[i]}),t.shelf_status&&a.push({label:n.label_shelf.text,value:bo(t.shelf_status)}),t.changelog&&a.push({label:n.label_changelog.text,value:t.changelog}),Ae(D(`${o}${n.card_title_shelf_updated.text}`,a,{status:"success"}),t)}function Ro(e){let t=f.skill,n=s("fmt","list_sep"),o=Array.isArray(e.copied)?e.copied.join(n):"-",r=Array.isArray(e.targets)?e.targets.join(n):"-";return D(t.card_title.text,[{label:t.label_kit.text,value:e.kit||"-"},{label:t.label_copied.text,value:o},{label:t.label_targets.text,value:r,highlight:!0}],{status:"success"})}function Ut(e){return rs(e.replace(/https?:\/\/\S*test-lumi\.66rpg\.com\S*/gi,"").replace(/https?:\/\/\S*lumi\.66rpg\.com\/api\S*/gi,"").replace(/\b(?:test-lumi\.66rpg\.com|lumi\.66rpg\.com\/api|base_lumi_api)\b/gi,""))}function Po(e){let t=f.error,n=f.error_codes,o=Ut(Je(e.message||t.default_message.text)),r=e.hint?Ut(Je(e.hint)):e.hint,i=e.server_msg?Ut(Je(e.server_msg)):"";if(!r){let a=e.code!=null?String(e.code):"";a==="2001"||o.includes("\u672A\u767B\u5F55")?r=n[2001].text:a==="2003"||o.includes("\u51ED\u8BC1\u5DF2\u8FC7\u671F")?r=n[2003].text:o.includes("\u6821\u9A8C\u5931\u8D25")||o.includes("\u54C8\u5E0C")||o.includes("MD5")||o.includes("SHA-256")||o.includes("checksum")?r=Y(n["1003_checksum"].text):o.includes("dist")||o.includes("index.html")?r=n["1001_missing_dist"].text:o.includes("scripts.")||/scripts\s/.test(o)?r=n["1001_missing_script"].text:o.includes("\u6682\u65E0\u5DF2\u901A\u8FC7\u5BA1\u6838")||o.includes("\u5C1A\u672A\u901A\u8FC7\u5BA1\u6838")||o.includes("\u8FD8\u5728\u5BA1\u6838\u4E2D")?r=n["1001_no_approved"].text:a==="2002"||a==="8004"||o.includes("\u6743\u9650")||o.includes("\u7B7E\u7EA6")?r=n[8004].text:n[a]&&(r=n[a].text)}return r&&(r=Y(r)),fo(o,{code:e.code,hint:r,serverCode:e.server_code,serverMsg:i||void 0})}var Co=new Set(["login","logout","skill"]);function No(e){let t=e.code!=null?String(e.code):"";if(t==="2001"||t==="2003")return!0;let n=e.message||"";return n.includes("\u672A\u767B\u5F55")||n.includes("\u51ED\u8BC1\u5DF2\u8FC7\u671F")||n.includes("\u767B\u5F55\u51ED\u8BC1\u5DF2\u8FC7\u671F")||n.includes("\u767B\u5F55\u5DF2\u5931\u6548")||n.includes("refresh_token \u5DF2\u5931\u6548")}function To(e,t){if(e!=="whoami"||!t||typeof t!="object")return!1;let n=t;return n.offline?!1:n.logged_in===!1||n.expired===!0}function Do(e,t={stdinTty:!!process.stdin.isTTY,stdoutTty:!!process.stdout.isTTY}){return e.skipLoginPrompt||e.command&&Co.has(e.command)||e.isAgent||e.isJson||e.isInteractive===!1?!1:!!(t.stdinTty&&t.stdoutTty)}function Lo(e){return!(!e.isAgent||e.skipLoginPrompt||e.command&&Co.has(e.command))}import le from"node:fs";import Ke from"node:os";import ds from"node:path";var ps="analytics-identity.json";function qt(e){return ds.join(P(e),ps)}function Mo(e){if(typeof e=="number"&&Number.isFinite(e)&&e>0)return String(Math.trunc(e));if(typeof e=="string"){let t=e.trim();if(/^[1-9][0-9]{0,18}$/.test(t))return t}}function Jt(e,t=Ke.homedir()){let n=Mo(e);if(n){try{let o=P(t);le.mkdirSync(o,{recursive:!0}),le.writeFileSync(qt(t),`${JSON.stringify({uid:n})}
|
|
22
22
|
`)}catch{}return n}}function Qe(e=Ke.homedir()){try{let t=qt(e);le.existsSync(t)&&le.unlinkSync(t)}catch{}}function Ee(e=Ke.homedir()){try{let t=qt(e);if(!le.existsSync(t))return;let n=JSON.parse(le.readFileSync(t,"utf8"));return Mo(n?.uid)}catch{return}}function Oo(e=Ke.homedir()){let t=Ee(e);return t?{uid:t,logged_in:!0}:{logged_in:!1}}function Bt(e){return!!(e.isJson&&!e.isAgent)}function $o(e){let t=Se(e).trim();if(!t)return"";let n=t.match(/^(?:\d{4}-\d{2}-\d{2}T[\d:.]+Z\s+)?(INFO|DEBUG|WARN|ERROR)\s+(.*)$/);if(n){let o=n[1],r=n[2];if(o==="INFO")return`${w.brandTag} ${w.badgeInfo} ${r}`;if(o==="DEBUG")return`${w.brandTag} ${w.badgeDebug} ${me.gray(r)}`;if(o==="WARN")return`${w.brandTag} ${w.badgeWarn} ${me.yellow(r)}`;if(o==="ERROR")return`${w.brandTag} ${w.badgeError} ${me.red(r)}`}return t.startsWith("[lumimaker]")?e:`${w.brandTag} ${e}`}function Vo(e){return{...process.env,...e,LUMIMAKER_FROM_KIT:"1",LUMIMAKER_TOOL:"npm"}}var J=!1;function Wt(){return J}function Gt(e,t){return J=!1,new Promise(n=>{let o=Uo(e,t,{stdio:"inherit",env:Vo()}),r=!1;o.on("spawn",()=>{r=!0,J=!0}),o.on("exit",i=>{J=r,n(i??0)}),o.on("error",i=>{J=!1,console.error(me.red(s("kit","run_failed",{e:q(i)}))),n(1)})})}function _s(e,t,n){J=!1;let o=t.includes("--json")?[...t]:[...t,"--json"];return new Promise(r=>{let i="",a="",c=!1,m=Uo(e,o,{stdio:["inherit","pipe","pipe"],env:Vo(n?{LUMIMAKER_TTY:"1"}:void 0)});m.on("spawn",()=>{c=!0,J=!0}),m.stdout.on("data",l=>{i+=l.toString("utf8")}),m.stderr.on("data",l=>{let _=(a+l.toString("utf8")).split(/\r?\n/);a=_.pop()??"";for(let y of _)y.trim()&&process.stderr.write($o(y)+`
|
|
23
23
|
`)}),m.on("exit",l=>{J=c,a.trim()&&process.stderr.write($o(a)+`
|
|
24
|
-
`);let u=i.trim();try{let _=JSON.parse(u);r({code:l??0,envelope:_,rawStdout:i})}catch{r({code:l??0,envelope:null,rawStdout:i})}}),m.on("error",l=>{J=!1,console.error(me.red(s("kit","cli_failed",{e:q(l)}))),r({code:1,envelope:null,rawStdout:""})})})}async function Fo(e){return Lo(e)?(Nn(s("kit","login_required_agent")),12):gs(e)}async function gs(e){if(!Do(e))return null;if(!await ro())return b.warn(f.common.login_cancelled.text),null;let n=await Gt(e.binPath,["login"]);return n!==0?(b.error(f.common.login_failed.text),n||1):(b.success(f.common.login_retrying.text),Re({...e,skipLoginPrompt:!0}))}function hs(e,t){if(!e)return null;let n=e,o=n.command;return o!=="need-input"&&o!=="update-available"&&o!=="login-required"?null:typeof n.code=="number"&&n.code>0?n.code:t>0?t:11}function bs(e,t,n){try{if(e==="logout"&&(n===0||t?.success===!0)){Qe();return}let o=t?.data;o&&typeof o=="object"&&o!==null&&"uid"in o&&Jt(o.uid)}catch{}}function xs(e){if(!e)return null;let t=e;if(t.command!=="need-input")return null;let n=t.data?.questions;return Array.isArray(n)&&n.length?n:null}async function vs(e,t){if(!e.isInteractive||e.isAgent||e.skipNeedInputPrompt)return null;let n=xs(t);if(!n)return null;let o=await Qn(n);return Object.keys(o).length?Re({...e,args:Kn(e.args,o),skipNeedInputPrompt:!0}):null}async function Re(e){Mn(e.binPath);let t=ce(),{binPath:n,args:o,isJson:r,command:i,subcommand:a,isAgent:c}=e,m=o.includes("--help")||o.includes("-h")||o.includes("--version")||o.includes("-V");if(i==="login"||m)return Gt(n,o);if(Bt(e)){let u=o.includes("--json")?o:[...o,"--json"],_=await Gt(n,u);if(i==="logout"&&_===0)try{Qe()}catch{}return _}let l=await _s(n,o,e.isInteractive);if(bs(i,l.envelope,l.code),await t,!l.envelope)return l.rawStdout&&process.stdout.write(l.rawStdout),l.code;if(l.envelope.success===!0){let u=l.envelope.data??{};if(To(i,u)){let _=await Fo(e);if(_!=null)return _}return Bt(e)?(l.rawStdout&&process.stdout.write(l.rawStdout),0):(ys(i,a,o,u),0)}if(l.envelope.success===!1){let u=hs(l.envelope,l.code);if(c&&u!=null)return l.rawStdout&&process.stdout.write(l.rawStdout),u;let _=await vs(e,l.envelope);if(_!=null)return _;let y=l.envelope.error??{message:s("kit","op_failed")};if(No(y)){let x=await Fo(e);if(x!=null)return x}return Bt(e)?(l.rawStdout&&process.stdout.write(l.rawStdout),l.code||2):(console.error(Po(y)),l.code||2)}return l.rawStdout&&process.stdout.write(l.rawStdout),l.code}function ys(e,t,n,o){if(e==="whoami"){console.log(vo(o));return}if(e==="publish"){console.log(yo(o));return}if(e==="publish-template"||e==="publish-template-data"){console.log(ko(o,e));return}if(e==="publish-project"){console.log(wo(o));return}if(e==="games"){if(t==="update"){console.log(We("game",o));return}if(n.includes("--query")){console.log(Ge(f.games.query_card_title.text,o,"game"));return}if(n.includes("--versions")){console.log(Be(f.games.versions_title.text,Array.isArray(o)?o:[]));return}console.log(Io(o));return}if(e==="templates"){if(t==="update"){console.log(We("template",o));return}if(n.includes("--query")){console.log(Ge(f.templates.query_card_title.text,o,"template"));return}if(n.includes("--versions")){console.log(Be(f.templates.versions_title.text,Array.isArray(o)?o:[]));return}if(n.includes("--data")){console.log(Ao(f.templates.data_packages_title.text,o.items||[]));return}console.log(So(o));return}if(e==="projects"){if(t==="update"){console.log(We("project",o));return}if(n.includes("--query")){console.log(Ge(f.projects.query_card_title.text,o,"project"));return}if(n.includes("--versions")){console.log(Be(f.projects.versions_title.text,Array.isArray(o)?o:[]));return}console.log(jo(o));return}if(e==="skill"){console.log(Ro(o));return}if(e==="logout"){console.log(Eo(o));return}console.log(me.green(`\u2714 ${f.common.success_default.text}`))}import ws from"node:fs";import Qt from"node:path";import{fileURLToPath as Ss}from"node:url";var Kt={name:"@66rpg/lumimaker",version:"0.1.
|
|
24
|
+
`);let u=i.trim();try{let _=JSON.parse(u);r({code:l??0,envelope:_,rawStdout:i})}catch{r({code:l??0,envelope:null,rawStdout:i})}}),m.on("error",l=>{J=!1,console.error(me.red(s("kit","cli_failed",{e:q(l)}))),r({code:1,envelope:null,rawStdout:""})})})}async function Fo(e){return Lo(e)?(Nn(s("kit","login_required_agent")),12):gs(e)}async function gs(e){if(!Do(e))return null;if(!await ro())return b.warn(f.common.login_cancelled.text),null;let n=await Gt(e.binPath,["login"]);return n!==0?(b.error(f.common.login_failed.text),n||1):(b.success(f.common.login_retrying.text),Re({...e,skipLoginPrompt:!0}))}function hs(e,t){if(!e)return null;let n=e,o=n.command;return o!=="need-input"&&o!=="update-available"&&o!=="login-required"?null:typeof n.code=="number"&&n.code>0?n.code:t>0?t:11}function bs(e,t,n){try{if(e==="logout"&&(n===0||t?.success===!0)){Qe();return}let o=t?.data;o&&typeof o=="object"&&o!==null&&"uid"in o&&Jt(o.uid)}catch{}}function xs(e){if(!e)return null;let t=e;if(t.command!=="need-input")return null;let n=t.data?.questions;return Array.isArray(n)&&n.length?n:null}async function vs(e,t){if(!e.isInteractive||e.isAgent||e.skipNeedInputPrompt)return null;let n=xs(t);if(!n)return null;let o=await Qn(n);return Object.keys(o).length?Re({...e,args:Kn(e.args,o),skipNeedInputPrompt:!0}):null}async function Re(e){Mn(e.binPath);let t=ce(),{binPath:n,args:o,isJson:r,command:i,subcommand:a,isAgent:c}=e,m=o.includes("--help")||o.includes("-h")||o.includes("--version")||o.includes("-V");if(i==="login"||m)return Gt(n,o);if(Bt(e)){let u=o.includes("--json")?o:[...o,"--json"],_=await Gt(n,u);if(i==="logout"&&_===0)try{Qe()}catch{}return _}let l=await _s(n,o,e.isInteractive);if(bs(i,l.envelope,l.code),await t,!l.envelope)return l.rawStdout&&process.stdout.write(l.rawStdout),l.code;if(l.envelope.success===!0){let u=l.envelope.data??{};if(To(i,u)){let _=await Fo(e);if(_!=null)return _}return Bt(e)?(l.rawStdout&&process.stdout.write(l.rawStdout),0):(ys(i,a,o,u),0)}if(l.envelope.success===!1){let u=hs(l.envelope,l.code);if(c&&u!=null)return l.rawStdout&&process.stdout.write(l.rawStdout),u;let _=await vs(e,l.envelope);if(_!=null)return _;let y=l.envelope.error??{message:s("kit","op_failed")};if(No(y)){let x=await Fo(e);if(x!=null)return x}return Bt(e)?(l.rawStdout&&process.stdout.write(l.rawStdout),l.code||2):(console.error(Po(y)),l.code||2)}return l.rawStdout&&process.stdout.write(l.rawStdout),l.code}function ys(e,t,n,o){if(e==="whoami"){console.log(vo(o));return}if(e==="publish"){console.log(yo(o));return}if(e==="publish-template"||e==="publish-template-data"){console.log(ko(o,e));return}if(e==="publish-project"){console.log(wo(o));return}if(e==="games"){if(t==="update"){console.log(We("game",o));return}if(n.includes("--query")){console.log(Ge(f.games.query_card_title.text,o,"game"));return}if(n.includes("--versions")){console.log(Be(f.games.versions_title.text,Array.isArray(o)?o:[]));return}console.log(Io(o));return}if(e==="templates"){if(t==="update"){console.log(We("template",o));return}if(n.includes("--query")){console.log(Ge(f.templates.query_card_title.text,o,"template"));return}if(n.includes("--versions")){console.log(Be(f.templates.versions_title.text,Array.isArray(o)?o:[]));return}if(n.includes("--data")){console.log(Ao(f.templates.data_packages_title.text,o.items||[]));return}console.log(So(o));return}if(e==="projects"){if(t==="update"){console.log(We("project",o));return}if(n.includes("--query")){console.log(Ge(f.projects.query_card_title.text,o,"project"));return}if(n.includes("--versions")){console.log(Be(f.projects.versions_title.text,Array.isArray(o)?o:[]));return}console.log(jo(o));return}if(e==="skill"){console.log(Ro(o));return}if(e==="logout"){console.log(Eo(o));return}console.log(me.green(`\u2714 ${f.common.success_default.text}`))}import ws from"node:fs";import Qt from"node:path";import{fileURLToPath as Ss}from"node:url";var Kt={name:"@66rpg/lumimaker",version:"0.1.48",description:"\u5E7B\u5149\u6587\u6E38\u5236\u4F5C\u5668\uFF1A\u767B\u5F55\u3001\u6821\u9A8C\u5E76\u53D1\u5E03\u5230\u5E7B\u5149\u6587\u6E38\u793E\u533A\uFF1Bvalidate-template\uFF08TS\uFF09\uFF1Blogin / publish \u7B49\u8F6C\u53D1 lumimaker",type:"module",bin:{lumimaker:"./bin/lumimaker.js"},files:["dist","bin","skill","skill-targets.json","share/*.mjs","share/internal-registry.md"],scripts:{build:"tsc --noEmit -p tsconfig.json && node ../../scripts/bundle.mjs",test:'node --import tsx --test "src/**/*.test.ts"',prepack:"node ../../scripts/minify-share.mjs inject",postpack:"node ../../scripts/minify-share.mjs restore",prepublishOnly:"npm run build && node ../../scripts/check-versions.mjs"},publishConfig:{access:"public"},engines:{node:">=20"},dependencies:{"@clack/prompts":"^1.8.0",ajv:"^8.17.1",picocolors:"^1.1.1"},optionalDependencies:{"@66rpg/lumimaker-win32-x64":"0.1.48","@66rpg/lumimaker-darwin-arm64":"0.1.48","@66rpg/lumimaker-darwin-x64":"0.1.48"},devDependencies:{"@types/node":"^22.15.0",typescript:"^5.8.3"}};function qo(e){let t=e.trim();return t?t.startsWith("V")||t.startsWith("v")?`v${t.slice(1)}`:`v${t}`:""}function Is(){let e=typeof Kt.version=="string"?Kt.version.trim():"";if(e)return qo(e);let t=Qt.dirname(Ss(import.meta.url)),n=[Qt.resolve(t,"../package.json"),Qt.resolve(t,"../../package.json")];for(let o of n)try{let i=JSON.parse(ws.readFileSync(o,"utf8")).version?.trim();if(i)return qo(i)}catch{}}function Jo(){return"v0.1.48"}var He={CliCommandResult:"CliCommandResult",LumiMakerCommand:"LumiMakerCommand"},js=new Set(["publish","publish-template","publish-template-data","publish-project","login","logout","whoami","games","templates","projects","validate-template","validate","skill","init","help","version","other"]),As=new Set(["update","list","versions","query","data"]),Es=new Set(["bin_missing","usage","version_invalid","unexpected_positional","validate_fail","need_input","update","login_required","fail","publish_aborted","publish_confirm_required","internal_command","cancelled","help"]),Rs=new Set(["publish_aborted","cancelled"]);function Ht(e){return!!(e&&Rs.has(e))}function Bo(e,t){let n=Ht(t.reason),o=t.command==="login"&&e===0&&t.loggedInAfter===!1;return e===0&&(t.outcome==null||t.outcome==="ok")&&!n&&!o}function Go(e){if(e==="publish")return"game";if(e==="publish-template")return"template";if(e==="publish-template-data")return"template_data";if(e==="publish-project")return"project"}function Wo(e){if(e)return js.has(e)?e:"other"}function Ko(e){if(e)return As.has(e)?e:void 0}function Qo(e){if(e)return Es.has(e)?e:void 0}function Yt(e){return e===0?"ok":e===10?"update":e===11?"need_input":e===12?"login_required":e===2?"usage":"fail"}import ue from"node:fs";import Us from"node:os";import Vs from"node:path";import Zt from"node:fs";import Ps from"node:os";import Ho from"node:path";var ze="huanguang",Yo="lumimaker_npm",zo="lumimaker_cli",Cs=`https://fx-it.66rpg.com:8206/sa?project=${ze}`;function zt(e,t=ze){try{let n=new URL(e);return n.protocol==="https:"&&n.hostname==="fx-it.66rpg.com"&&n.port==="8206"&&n.pathname==="/sa"&&n.searchParams.get("project")===t&&!n.username&&!n.password}catch{return!1}}function Ye(e,t){return String(e[t]??"").trim().toLowerCase()}function Ns(e){let t=Ye(e,"LUMIMAKER_NO_ANALYTICS");if(t==="1"||t==="true")return!0;let n=Ye(e,"LUMIMAKER_ANALYTICS");if(n==="0"||n==="false")return!0;let o=Ye(e,"CI");return!!(o==="true"||o==="1"||e.NODE_TEST_CONTEXT)}function Ts(){try{let e=JSON.parse(Zt.readFileSync(Ho.join(G(),"package.json"),"utf8"));return typeof e.version=="string"?e.version:""}catch{return""}}function Ds(e){try{let t=Ho.join(P(e),"config.json");if(!Zt.existsSync(t))return;let n=JSON.parse(Zt.readFileSync(t,"utf8"));return n&&typeof n=="object"?n:void 0}catch{return}}function Ls(e){let t=e?.web_config,n=typeof t?.type=="string"?t.type:"",o=typeof t?.base_cg=="string"?t.base_cg:"",r=`${n} ${o}`.toLowerCase();return r.includes("debug-lumi")?"debug":n&&n!=="1"||r.includes("test")?"test":"release"}function Ms(e){let t=e?.env??process.env,n=e?.homeDir??Ps.homedir(),o=e?.fileConfig??(e?.skipFile?void 0:Ds(n)),r=Ls(o),i=o?.sensorsAnalytics,a=!0;typeof i?.enabled=="boolean"&&(a=i.enabled),Ns(t)&&(a=!1);let c=Cs,m=typeof i?.serverUrl=="string"?i.serverUrl.trim():"";m&&zt(m)&&(c=m);let l=typeof t.LUMIMAKER_SENSORS_URL=="string"?t.LUMIMAKER_SENSORS_URL.trim():"";l&&zt(l)&&(c=l),zt(c)||(a=!1);let u=Ye(t,"LUMIMAKER_ANALYTICS_LOG"),_=r!=="release"&&(i?.showLog===!0||u==="1"||u==="true");return{enabled:a,serverUrl:c,showLog:_,deployEnv:r,releaseId:e?.releaseId??Ts()}}var Xt;function Pe(){return Xt||(Xt=Ms()),Xt}var Os=/^\$?[A-Za-z][A-Za-z0-9_]{0,99}$/,$s=new Set(["access_token","token","cookie","authorization","phone","mobile","wechat","qq","content","body","draft_title","search","query","error","message","stack","order_no","password","refresh_token","nick_name","nickname","username","lumi_username","dest","dest_dir","cwd","argv","from_dir","path","filepath"]);function Fs(e){if(e!=null){if(typeof e=="string")return e.slice(0,256);if(typeof e=="number")return Number.isFinite(e)?e:void 0;if(typeof e=="boolean"||e instanceof Date)return e;if(Array.isArray(e))return e.slice(0,20).map(t=>t.slice(0,256))}}function Xo(e){let t={};for(let[n,o]of Object.entries(e)){if(!Os.test(n)||$s.has(n.toLowerCase()))continue;let r=Fs(o);r!==void 0&&(t[n]=r)}return t}var qs=100,Js=600,Bs=700,Gs="analytics-device-id",Xe=[],Ze=new Set,z,en=!1;function Zo(e){try{return`${e}-${crypto.randomUUID()}`}catch{return`${e}-${Date.now()}-${Math.random().toString(36).slice(2,12)}`}}function er(e=Us.homedir()){if(z)return z;let t=P(e),n=Vs.join(t,Gs);try{if(ue.existsSync(n)){let r=ue.readFileSync(n,"utf8").trim();if(r)return z=r,r}let o=Zo("cli");return ue.mkdirSync(t,{recursive:!0}),ue.writeFileSync(n,`${o}
|
|
25
25
|
`,{encoding:"utf8",flag:"wx"}),z=o,o}catch{try{if(ue.existsSync(n)){let o=ue.readFileSync(n,"utf8").trim();if(o)return z=o,o}}catch{}return z=Zo("session"),z}}function Ws(){let e=Number.parseInt(process.versions.node,10);return Number.isFinite(e)?e:void 0}function Ks(){return Ee()??er()}function Qs(){let e=Pe(),t=Oo();return{product:Yo,app_id:zo,deploy_env:e.deployEnv,env:e.deployEnv==="release"?"production":"development",release_id:e.releaseId,surface:"cli",device_type:"desktop",device_code:er(),tool:"npm",event_schema_version:2,os_platform:process.platform,os_arch:process.arch,node_major:Ws(),logged_in:t.logged_in,uid:t.uid,$is_login_id:!!t.uid}}function Hs(e){Ze.add(e),e.finally(()=>Ze.delete(e))}async function Ys(e,t){let n=Pe();if(!n.enabled)return;let o={distinct_id:Ks(),time:Date.now(),type:"track",event:e,project:ze,properties:{$lib:"Node",$lib_version:n.releaseId||"0",$lib_method:"code",...Xo({...Qs(),...t})}};n.showLog&&console.error(`[lumimaker analytics] ${e}`);let r=Buffer.from(JSON.stringify(o),"utf8").toString("base64"),i=`data=${encodeURIComponent(r)}&gzip=0`,a=await fetch(n.serverUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i,redirect:"error",signal:AbortSignal.timeout(Js)});n.showLog&&console.error(`[lumimaker analytics] ${e} ${a.status}`)}function tr(){if(en)return;en=!0;let e=Xe.splice(0);for(let t of e)Hs(Ys(t.name,t.properties).catch(()=>{}));en=!1}function tn(e,t={}){try{if(!Pe().enabled)return;Xe.length>=qs&&Xe.shift(),Xe.push({name:e,properties:t}),tr()}catch{}}async function nr(e=Bs){try{if(tr(),Ze.size===0)return;await Promise.race([Promise.allSettled([...Ze]),new Promise(t=>{setTimeout(t,e).unref?.()})])}catch{}}function or(e,t){let n=Wo(t.command)??"other",o=t.outcome??Yt(e),r=Ht(t.reason),i=n==="login"&&e===0&&t.loggedInAfter===!1,a=Bo(e,{...t,command:n}),c=Go(t.command);return{command:n,subcommand:Ko(t.subcommand),success:a,outcome:r||i?"fail":o,agent:!!t.agent,interactive:!!t.interactive,json:!!t.json,package:"lumimaker",tool:"npm",reason:Qo(t.reason)??(a?void 0:r?t.reason:o),publish_kind:c,variant:c==="game"?t.variant:void 0}}function rr(e,t){tn(He.CliCommandResult,or(e,t))}function zs(e,t){tn(He.LumiMakerCommand,{...or(e,t),event_schema_version:1})}async function nn(e,t={}){try{t.skip||(rr(e,t),t.rustRan||zs(e,t)),await nr()}catch{}process.exit(e)}function O(e,t,n=22){return` ${K.cyan(e.padEnd(n))}${s("help",t)}`}function sr(e,t,n=22){return` ${K.gray(e.padEnd(n))}${s("help",t)}`}function Zs(e){return typeof e.version=="string"&&e.version.trim()?e.version.trim():(M()?.version??"").trim()}function ea(e){let t=Zs(e);return!t||L(t)?!0:(b.error(s("prompt","version_invalid_log",{version:t})),b.warn(s("prompt","version_invalid_hint")),!1)}function ar(){b.error(s("kit","bin_missing",{pkg:ie()??"@66rpg/lumimaker"}))}function cr(){let e=s("help","tagline").trim()||"lumimaker",t=Jo(),n=t?`${e} ${t}`:e;return`${K.bold(K.cyan(n))}
|
|
26
26
|
|
|
27
27
|
${K.bold(s("help","usage_heading"))}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@66rpg/lumimaker",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.48",
|
|
4
4
|
"description": "幻光文游制作器:登录、校验并发布到幻光文游社区;validate-template(TS);login / publish 等转发 lumimaker",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"picocolors": "^1.1.1"
|
|
34
34
|
},
|
|
35
35
|
"optionalDependencies": {
|
|
36
|
-
"@66rpg/lumimaker-win32-x64": "0.1.
|
|
37
|
-
"@66rpg/lumimaker-darwin-arm64": "0.1.
|
|
38
|
-
"@66rpg/lumimaker-darwin-x64": "0.1.
|
|
36
|
+
"@66rpg/lumimaker-win32-x64": "0.1.48",
|
|
37
|
+
"@66rpg/lumimaker-darwin-arm64": "0.1.48",
|
|
38
|
+
"@66rpg/lumimaker-darwin-x64": "0.1.48"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^22.15.0",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lumimaker-play-sdk
|
|
3
|
-
description: 幻光文游社区播放页 SDK(window.LumiMakerSdk
|
|
3
|
+
description: 幻光文游社区播放页 SDK(window.LumiMakerSdk)接入指引。在作品内实现用户登录、展示昵称头像、查询游玩/购买权限(章节锁)、安全返回社区、进入全屏、响应播放页静音,或写多页 HTML 链接时使用。平台自动注入 SDK 脚本,严禁手动引入或打包 SDK 文件。当前无云存档、无内购接口。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# 播放页 SDK(LumiMakerSdk)
|
|
7
7
|
|
|
8
|
-
作品发布后,在幻光文游社区的**播放页**(宿主)里通过 iframe 运行。平台会在玩法 HTML 里注入脚本,全局对象是 **`window.LumiMakerSdk`**(当前脚本版本 `0.1.
|
|
8
|
+
作品发布后,在幻光文游社区的**播放页**(宿主)里通过 iframe 运行。平台会在玩法 HTML 里注入脚本,全局对象是 **`window.LumiMakerSdk`**(当前脚本版本 `0.1.13`)。作品用它做登录、读用户、查作品权限、安全跳转、全屏。播放页静音由脚本自动处理本页 `audio` / `video` / `AudioContext`,不必先调 API。社区 iframe 里,包根另一个 `.html` 的链接会由脚本拦住并请播放页另签;业务查询串和 `#` 会在新页补回。
|
|
9
9
|
|
|
10
10
|
> **核心原则**:
|
|
11
11
|
> 1. **严禁在工程中引入 SDK 文件**:发布时平台注入。**切勿**下载 `lumimaker-game.js`、**切勿**拷进 `dist/` 或源码、**切勿**手写 `<script src="...lumimaker-game.js">`。
|
|
@@ -22,6 +22,7 @@ description: 幻光文游社区播放页 SDK(window.LumiMakerSdk)接入指
|
|
|
22
22
|
- **用户信息与登录**:唤起社区登录、展示昵称/头像。未登录的试玩仍可玩离线内容。
|
|
23
23
|
- **权限与章节锁**:读 `queryGame()` 的 `can_play` / `purchased`,画作品**自己的**关卡锁或试玩结束提示。正式版未获权时播放页会盖购买遮罩,**根本不会加载**作品 iframe。
|
|
24
24
|
- **安全跳转与全屏**:回社区首页、作者页、上一页;进入/退出播放器全屏壳。公开 API **没有** `toggleFullscreen()`。
|
|
25
|
+
- **多页 HTML**:包根之间的页面跳转由注入脚本自动处理,一般不必调 `openPlayHtml`。子目录页面、目录地址打不开。
|
|
25
26
|
- **播放页静音**:宿主拨静音后脚本已自动静音本页媒体。可选 `isMuted()` / `onMuteChange()`。
|
|
26
27
|
|
|
27
28
|
不要用本 skill 讲发版命令;发版看 `lumimaker`。
|
|
@@ -102,6 +103,7 @@ declare global {
|
|
|
102
103
|
navigateHome(): void
|
|
103
104
|
navigateAuthorPage(): void
|
|
104
105
|
navigateBack(): void
|
|
106
|
+
openPlayHtml(html: string): Promise<void>
|
|
105
107
|
requestFullscreen(): Promise<void>
|
|
106
108
|
exitFullscreen(): Promise<void>
|
|
107
109
|
}
|
|
@@ -144,10 +146,11 @@ declare global {
|
|
|
144
146
|
|
|
145
147
|
1. **不要把 SDK 打进工程**:不要放 `lumimaker-game.js`,不要手写 script 标签。发版会注入玩法 HTML(`index.html`;若已有语言/方向页也会注入那些页)。
|
|
146
148
|
2. **通信边界**:不要 `window.parent.postMessage`,不要读、打印、改 token。不要自己调社区登录、签发 token、下单、支付。
|
|
147
|
-
3.
|
|
148
|
-
4.
|
|
149
|
-
5.
|
|
150
|
-
6.
|
|
149
|
+
3. **跳转回社区**:只用 `navigateHome()` / `navigateAuthorPage()` / `navigateBack()`,不要传 URL,不要 `window.top.location`。不要用 `queryGame()` 的 `play_url` 跳转。对玩家只展示帖子链接(若发版卡片有),不要念播放页地址、作品 ID、关联帖 ID。
|
|
150
|
+
4. **玩法页之间**:只使用 `dist/` **根目录**的 `.html`(与 `index.html` 同级)。不要把玩法页放进子目录,不要用 `jubenba/`、`/`、`.` 这种目录地址,也不要写 `./#id`、`/#id`(会当成打开目录)。页内滚动写 `#id`。根目录页可以带查询串和 `#`;**查询**和 **`#` 各自最长 2048 个字符,超出的部分会被截掉**。查询里**不能**使用 `auth_key`、`signature`、`expires`、`OSSAccessKeyId` 这些签名参数名(大小写不限)。链接上若已 `preventDefault`,脚本不会再换页。已发布入口不必调 `openPlayHtml`。
|
|
151
|
+
5. **购买**:正式版未获权时播放页遮罩,iframe 不会开。作品内只处理「已经进来之后」的自制锁,不要复刻社区购买墙。
|
|
152
|
+
6. **本地预览**:无宿主时 `ready()` 失败正常。不要伪造登录。图音字体继续用工程本地文件。
|
|
153
|
+
7. **没有这些能力**:云存档、内购、查权买断、游戏自己切静音宿主(宿主推静音;作品只可选监听);目录 URL 不会自动变成该目录的 `index.html`。
|
|
151
154
|
|
|
152
155
|
---
|
|
153
156
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# LumiMakerSdk 接口规范细则
|
|
2
2
|
|
|
3
|
-
全局对象为 **`window.LumiMakerSdk`**。发布到幻光文游社区后,在社区播放页的 iframe(或官方 App 打开的受信壳)里运行时,平台注入该对象。脚本版本见 `version`(当前 `0.1.
|
|
3
|
+
全局对象为 **`window.LumiMakerSdk`**。发布到幻光文游社区后,在社区播放页的 iframe(或官方 App 打开的受信壳)里运行时,平台注入该对象。脚本版本见 `version`(当前 `0.1.13`)。
|
|
4
4
|
|
|
5
5
|
失败时抛出的错误对象名为 **`LumiMakerError`**,带 `code` 字符串。
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
| 方法 / 属性 | 返回类型 | 说明 |
|
|
14
14
|
|---|---|---|
|
|
15
|
-
| `version` | string | 脚本版本,如 `"0.1.
|
|
15
|
+
| `version` | string | 脚本版本,如 `"0.1.13"`。 |
|
|
16
16
|
| `ready()` | `Promise<{ ready: boolean; context: LumiMakerContext \| null; error?: string }>` | 与播放页握手。约 5 秒超时。**超时不 throw**,返回 `ready: false`。受信壳超时 `error` 为「等待主站数据超时」(本地预览正常)。未受信容器立刻失败,`error` 为「请在幻光社区或官方 App 中打开」,并跳到社区作品帖。 |
|
|
17
17
|
| `isReady()` | boolean | 是否已拿到 context。 |
|
|
18
18
|
| `getError()` | string | 最近一次握手失败文案;无失败时为空字符串。不是所有通道错误都会写入。 |
|
|
@@ -88,11 +88,30 @@
|
|
|
88
88
|
| `navigateHome()` | void | 播放页回社区首页。 |
|
|
89
89
|
| `navigateAuthorPage()` | void | 打开作者页。 |
|
|
90
90
|
| `navigateBack()` | void | 有历史则后退,否则回作品帖。 |
|
|
91
|
+
| `openPlayHtml(html)` | `Promise<void>` | 换到 **包根** 另一个玩法 HTML,只传文件名(如 `staff.html`)。不要传目录、不要把查询串写进这个参数给签名接口。社区 iframe 会自动拦 `<a>` / `assign` / `replace`(Chromium 还能拦 `location.href =`),已发布入口一般不必调。查出非法文件名 → `FAILED`。官方 App 直开无宿主时会失败。 |
|
|
91
92
|
| `requestFullscreen()` | `Promise<void>` | 全屏**播放器外壳**,不是游戏改 `top`。须在真实点击等手势里调用。 |
|
|
92
93
|
| `exitFullscreen()` | `Promise<void>` | 退出播放器全屏。 |
|
|
93
94
|
|
|
94
95
|
浏览器拒绝全屏 → `FULLSCREEN_DENIED`。
|
|
95
96
|
|
|
97
|
+
### 4.1 包内 HTML 跳转(注入脚本自动拦)
|
|
98
|
+
|
|
99
|
+
社区播放页 iframe 里,脚本会在真正跳走前拦住包根 `.html`,请播放页另签后再换页。作者一般继续写相对链接即可,不必自己调 `openPlayHtml`。
|
|
100
|
+
|
|
101
|
+
查询(`?` 起)和锚点(`#` 起)**各自最长 2048 个字符**,超出的部分会被截掉。查询里**不能**使用 `auth_key`、`signature`、`expires`、`OSSAccessKeyId` 这些签名参数名(大小写不限);写进去会被当成平台已签名地址,业务查询可能补不回。
|
|
102
|
+
|
|
103
|
+
| 写法 | 播放页里 |
|
|
104
|
+
|---|---|
|
|
105
|
+
| 包根 `staff.html`、`search.html?q=`、`snapshot.html#u=…` | 能打开。查询串和 `#` 在新页补回,不要指望它们出现在签名请求里。查询和 `#` **各自最长 2048 个字符**,超出截掉。查询里不要用 `auth_key`、`signature`、`expires`、`OSSAccessKeyId`(大小写不限),这些是平台签名参数名 |
|
|
106
|
+
| 当前页 `#id` | 只滚动,不换页 |
|
|
107
|
+
| `./#id`、`/#id`、`.`、`/`、`jubenba/` | **不要写**。会当成打开目录,请求失败;脚本会拦住,但也不会改成该目录的 `index.html` |
|
|
108
|
+
| 子目录 `jubenba/search.html` | 打不开。玩法 HTML 放在 `dist/` 根目录 |
|
|
109
|
+
| 链接上已 `preventDefault` | 脚本不再换页,让页面自己的点击处理先完成 |
|
|
110
|
+
|
|
111
|
+
带平台签名参数的地址不要改路径。Firefox 里若仍用 `location.href =`,可能拦不住。官方 App 直开入口、没有社区播放页时,这套拦截不装。
|
|
112
|
+
|
|
113
|
+
本地 `npm run dev` 没有这套拦截,相对链接按普通静态站工作。
|
|
114
|
+
|
|
96
115
|
---
|
|
97
116
|
|
|
98
117
|
## 5. 错误码
|
|
@@ -38,7 +38,7 @@ npx lumimaker validate-template
|
|
|
38
38
|
|
|
39
39
|
- 涉及文件或目录缺失:对照协议第 1 节(目录结构)补齐必要项。
|
|
40
40
|
- 涉及配置或脚本问题:对照协议第 2 节(package.json)核对字段格式与脚本要求。
|
|
41
|
-
- 涉及构建输出问题:对照协议第 3
|
|
41
|
+
- 涉及构建输出问题:对照协议第 3 节(构建产物)检查产物目录与入口。社区播放页能打开的玩法 HTML 须在 `dist/` 根目录,见该节第 5 条。
|
|
42
42
|
|
|
43
43
|
> **原则**:仅针对报错项和协议明确约定的内容做修改;协议未约定的文件和配置保持原样,切勿随意变动。
|
|
44
44
|
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
2. **入口文件**:`dist/` 根目录下**必须**产出 `index.html` 入口文件。可以仅产出纯 `index.html`,无需任何其他静态资源文件。
|
|
104
104
|
3. **静态资源(建议)**:若构建产物包含 JavaScript、CSS、图片等静态资源,建议放置于与 `index.html` 同级的 `dist/assets/` 目录下。
|
|
105
105
|
4. **其他产物**:除 `dist/index.html` 外,产物目录内的其他文件组织形式本协议不作强制限制。
|
|
106
|
+
5. **社区播放页能打开的玩法 HTML**:须与 `index.html` 同在 `dist/` 根目录。子目录里的 `.html`、目录地址(如 `jubenba/`)在播放页打不开,也不会自动改成该目录的 `index.html`。页内锚点写 `#id`,不要写 `./#id`。链接写法见 `lumimaker-play-sdk`。
|
|
106
107
|
|
|
107
108
|
---
|
|
108
109
|
|
|
@@ -111,3 +112,4 @@
|
|
|
111
112
|
| 文档版本 | 修订日期 | 变更说明 |
|
|
112
113
|
|---|---|---|
|
|
113
114
|
| 1.0 | 2026-09-22 | 初始版本。明确工程目录结构、`package.json` 配置字段与脚本规范,以及 `dist/` 构建产物约定(assets 为可选,支持纯 index.html)。 |
|
|
115
|
+
| 1.1 | 2026-10-05 | 补充:社区播放页只签 `dist/` 根目录的玩法 HTML;目录地址不会回落为该目录的 `index.html`。 |
|