@fps-games/editor-deployment 0.2.3-beta.14 → 0.2.3-beta.16
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/bin/fps-editor-prepare.mjs +1 -1
- package/bin/fps-editor-project.mjs +1 -1
- package/licenses/THIRD_PARTY_NOTICES.txt +2 -2
- package/manifest.json +50 -50
- package/npm-shrinkwrap.json +2 -2
- package/package.json +6 -6
- package/public/assets/index-Cv7z0zVA.js +1 -0
- package/public/assets/index-Cv7z0zVA.js.br +0 -0
- package/public/assets/index-Cv7z0zVA.js.gz +0 -0
- package/public/assets/playable-sdk-DO95mXOf.js +4 -0
- package/public/assets/playable-sdk-DO95mXOf.js.br +0 -0
- package/public/assets/playable-sdk-DO95mXOf.js.gz +0 -0
- package/public/assets/playable-standard-project-Do0uyGjy.js +5250 -0
- package/public/assets/playable-standard-project-Do0uyGjy.js.br +0 -0
- package/public/assets/playable-standard-project-Do0uyGjy.js.gz +0 -0
- package/public/index.html +3 -3
- package/public/index.html.br +0 -0
- package/public/index.html.gz +0 -0
- package/runtime/editor-control-plane.mjs +4 -96
- package/worker/editor-service-worker.mjs +16 -16
- package/public/assets/index-CToRH9gy.js +0 -1
- package/public/assets/index-CToRH9gy.js.br +0 -0
- package/public/assets/index-CToRH9gy.js.gz +0 -0
- package/public/assets/playable-sdk-CrrQJDf4.js +0 -4
- package/public/assets/playable-sdk-CrrQJDf4.js.br +0 -0
- package/public/assets/playable-sdk-CrrQJDf4.js.gz +0 -0
- package/public/assets/playable-standard-project-DkUozryX.js +0 -5249
- package/public/assets/playable-standard-project-DkUozryX.js.br +0 -0
- package/public/assets/playable-standard-project-DkUozryX.js.gz +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createHash as ue,randomBytes as yt}from"node:crypto";import{copyFile as ze,lstat as q,mkdir as fe,mkdtemp as $t,readFile as me,readdir as wt,realpath as ee,rename as X,rm as te,stat as xt,writeFile as St}from"node:fs/promises";import{fileURLToPath as It,pathToFileURL as Mt}from"node:url";import a from"node:path";import Ye from"node:path";function $e(e){let t=[],r;for(let n=0;n<e.length;n+=1){let i=e[n];if(i!=="--project-root"&&!i.startsWith("--project-root=")){t.push(i);continue}if(r!==void 0)throw new Error("--project-root may only be provided once.");let o=i==="--project-root"?e[++n]:i.slice(15);if(o===void 0||!o.trim()||o.startsWith("--"))throw new Error("--project-root requires a non-empty path.");r=o}return{argv:t,projectRoot:Ye.resolve(process.cwd(),r??"."),explicit:r!==void 0}}import{readFile as bt,realpath as Le,stat as ht}from"node:fs/promises";import le from"node:path";function we(e){return e==="fps.builtin.pbr"||e==="fps.builtin.standard"?e:void 0}var g={nodeKinds:["group","instance","transform","primitive","image"],primitiveShapes:["cube","sphere","plane","capsule"],transformTypes:["plain","light","camera","groundDecal"],assetTypes:["glb","texture"],materialScopes:["sharedAsset","nodeMaterial"],materialModes:["shared","instance"],materialShaderIds:["fps.builtin.pbr","fps.builtin.standard"],materialAssetSystemPresets:["default-pbr","default-standard"],runtimeV3:{assetFields:["id","guid","type","url","external","warmupCount","singleton","materialMode","defaults","materialSlots"],materialSlotFields:["slotId","label","sourceSurfaces"],materialSlotSourceSurfaceFields:["ownerNodePath","nodeIndex","nodeIndexPath","meshIndex","primitiveIndex","sourceMaterialIndex","sourceMeshName"]},hierarchy:{parentTargets:["root","sceneNode"]},runtimeOnlyTokens:["/@fs","assetUrl","sourceAssetUrl","sourceAssetPath"]},Kt=new Set(g.nodeKinds),Wt=new Set(g.primitiveShapes),Jt=new Set(g.assetTypes),Zt=new Set(g.materialModes),Yt=new Set(g.materialScopes),Xt=new Set(g.materialAssetSystemPresets),Qt=new Set(g.transformTypes),vt=new Set(g.hierarchy.parentTargets),er=g.runtimeOnlyTokens,tr=new Set(g.runtimeV3.assetFields),rr=new Set(g.runtimeV3.materialSlotFields),nr=new Set(g.runtimeV3.materialSlotSourceSurfaceFields);var Xe=/^[a-z0-9]+(?:[._-][a-z0-9]+)+$/;function xe(e){return typeof e=="string"&&!e.startsWith("fps.builtin.")&&Xe.test(e)}var w=(e,t)=>({kind:"number",...e!=null?{min:e}:{},...t!=null?{max:t}:{}}),R={kind:"texture"},Se={kind:"color"},Qe={kind:"enum",values:["lit","unlit"]},ve={kind:"enum",values:["opaque","mask","blend"]},ke={lightingModel:Qe,baseColor:{kind:"object",properties:{color:Se,texture:R,brightness:w(0),saturation:w(0),contrast:w(0),hue:w(-180,180)}},normal:{kind:"object",properties:{texture:R,strength:w(0)}},emission:{kind:"object",properties:{color:Se,intensity:w(0),texture:R,maskTexture:R}},alpha:{kind:"object",properties:{mode:ve,opacity:w(0,1),cutoff:w(0,1),texture:R}}},et={kind:"object",properties:{...ke,metallic:w(0,1),roughness:w(0,1),metallicRoughness:{kind:"object",properties:{texture:R}},occlusion:{kind:"object",properties:{texture:R,strength:w(0)}}}},tt={kind:"object",properties:ke},rt={lightingModel:"lit",baseColor:{color:{r:1,g:1,b:1},brightness:1,saturation:1,contrast:1,hue:0},metallic:0,roughness:1,emission:{color:{r:0,g:0,b:0},intensity:0}},nt={lightingModel:"lit",baseColor:{color:{r:1,g:1,b:1},brightness:1,saturation:1,contrast:1,hue:0},emission:{color:{r:0,g:0,b:0},intensity:0}},Ie=[{id:"surface",title:"Surface",order:40},{id:"geometry",title:"Geometry",order:50},{id:"emission",title:"Emission",order:60},{id:"alpha",title:"Alpha",order:70}],T={path:"properties.lightingModel",operator:"equals",value:"lit",inactiveReasonKey:"litMaterial"},je=[V("properties.lightingModel","surface",1,"enum","assetLightingModel","lightingModel","lit",{options:[{value:"lit",labelKey:"assetLightingModelLit"},{value:"unlit",labelKey:"assetLightingModelUnlit"}],binding:"lightingModel",updateClass:"define"}),V("properties.baseColor.color","surface",2,"color","assetBaseColor","baseColor",{r:1,g:1,b:1},{binding:"baseColor.color"}),z("properties.baseColor.texture.textureAssetId","properties.baseColor.texture","surface",3,"assetBaseTexture","baseTexture","baseColor.texture"),x("properties.baseColor.brightness","surface",4,"assetBrightness","brightness",1,{softMin:0,softMax:4,step:.05,conditions:[L("properties.baseColor.texture.textureAssetId","baseTexture")]}),x("properties.baseColor.saturation","surface",5,"assetSaturation","saturation",1,{softMin:0,softMax:2,step:.05,conditions:[L("properties.baseColor.texture.textureAssetId","baseTexture")]}),x("properties.baseColor.contrast","surface",6,"assetContrast","contrast",1,{softMin:0,softMax:2,step:.05,conditions:[L("properties.baseColor.texture.textureAssetId","baseTexture")]}),x("properties.baseColor.hue","surface",7,"assetHue","hue",0,{step:1,conditions:[L("properties.baseColor.texture.textureAssetId","baseTexture")]}),z("properties.normal.texture.textureAssetId","properties.normal.texture","geometry",10,"assetNormalTexture","normalTexture","normal.texture",[T]),x("properties.normal.strength","geometry",11,"assetNormalStrength","normalStrength",1,{softMin:0,softMax:4,step:.05,conditions:[T,L("properties.normal.texture.textureAssetId","normalTexture")]}),V("properties.emission.color","emission",50,"color","assetEmissionColor","emissionColor",{r:0,g:0,b:0},{binding:"emission.color"}),x("properties.emission.intensity","emission",51,"assetEmissionIntensity","emissionIntensity",0,{softMin:0,softMax:8,step:.05}),z("properties.emission.texture.textureAssetId","properties.emission.texture","emission",52,"assetEmissionTexture","emissionTexture","emission.texture"),V("properties.alpha.mode","alpha",60,"enum","assetAlphaMode","alphaMode","opaque",{options:[{value:"opaque",labelKey:"assetAlphaModeOpaque"},{value:"mask",labelKey:"assetAlphaModeMask"},{value:"blend",labelKey:"assetAlphaModeBlend"}],binding:"alpha.mode",updateClass:"pipeline"}),x("properties.alpha.opacity","alpha",61,"assetAlphaOpacity","alphaOpacity",1,{step:.05,conditions:[{path:"properties.alpha.mode",operator:"equals",value:"blend",inactiveReasonKey:"alphaBlend"}]}),x("properties.alpha.cutoff","alpha",62,"assetAlphaCutoff","alphaCutoff",.5,{step:.01,conditions:[{path:"properties.alpha.mode",operator:"equals",value:"mask",inactiveReasonKey:"alphaMask"}]}),z("properties.alpha.texture.textureAssetId","properties.alpha.texture","alpha",63,"assetAlphaTexture","alphaTexture","alpha.texture",[{path:"properties.alpha.mode",operator:"not-equals",value:"opaque",inactiveReasonKey:"alphaTransparency"}])],it=[...je,x("properties.metallic","geometry",20,"assetMetallic","metallic",0,{step:.05,conditions:[T]}),x("properties.roughness","geometry",21,"assetRoughness","roughness",1,{step:.05,conditions:[T]}),z("properties.metallicRoughness.texture.textureAssetId","properties.metallicRoughness.texture","geometry",22,"assetMetallicRoughnessTexture","metallicRoughnessTexture","metallicRoughness.texture",[T]),z("properties.occlusion.texture.textureAssetId","properties.occlusion.texture","geometry",23,"assetOcclusionTexture","occlusionTexture","occlusion.texture",[T]),x("properties.occlusion.strength","geometry",24,"assetOcclusionStrength","occlusionStrength",1,{softMin:0,softMax:4,step:.05,conditions:[T,L("properties.occlusion.texture.textureAssetId","occlusionTexture")]})],oe=[{shaderId:"fps.builtin.pbr",version:1,runtimeKind:"pbr",displayName:"PBR",propertiesSchema:et,defaultProperties:rt,inspector:{sections:Ie,fields:it}},{shaderId:"fps.builtin.standard",version:1,runtimeKind:"standard",displayName:"Standard",propertiesSchema:tt,defaultProperties:nt,inspector:{sections:Ie,fields:je}}],sr=se(oe);function se(e){let t=new Map;for(let n of e){ot(n,t);let i=st(n);t.set(n.shaderId,Fe(i))}let r=Object.freeze([...t.values()]);return Object.freeze({get(n){return typeof n=="string"?t.get(n)??null:null},list(){return r}})}function V(e,t,r,n,i,o,s,l){return{path:e,sectionId:t,order:r,control:n,labelKey:i,tooltipKey:o,defaultValue:s,updateClass:"uniform",...l}}function x(e,t,r,n,i,o,s={}){return V(e,t,r,"number",n,i,o,{binding:e.replace(/^properties\./,""),step:s.step??.05,displayPrecision:2,precision:2,...s})}function z(e,t,r,n,i,o,s,l){return V(e,r,n,"texture",i,o,"",{schemaPath:t,binding:s,updateClass:"texture",conditions:l})}function L(e,t){return{path:e,operator:"truthy",inactiveReasonKey:t}}function ot(e,t){if(!we(e.shaderId)&&!xe(e.shaderId))throw new Error("Material Shader Definition shaderId must be a supported built-in id or a lowercase namespaced project id.");if(!Number.isInteger(e.version)||e.version<=0)throw new Error(`Material Shader Definition ${e.shaderId} must use a positive integer version.`);if(t.has(e.shaderId))throw new Error(`Duplicate Material Shader Definition: ${e.shaderId}`);if(e.sourceFile!=null&&!ct(e.sourceFile))throw new Error(`Material Shader Definition ${e.shaderId} sourceFile must be a safe project-relative path.`);Ee(e.shaderId,e.propertiesSchema,"properties");let r=[];if(Pe(e.propertiesSchema,e.defaultProperties,"properties",r),r.length>0){let o=r[0];throw new Error(`Material Shader Definition ${e.shaderId} default ${o.path} ${o.message}.`)}let n=new Set;for(let o of e.inspector.sections){if(!o.id.trim()||n.has(o.id))throw new Error(`Material Shader Definition ${e.shaderId} contains an invalid or duplicate section: ${o.id}`);n.add(o.id)}let i=new Set;for(let o of e.inspector.fields){if(!o.path.startsWith("properties.")||i.has(o.path))throw new Error(`Material Shader Definition ${e.shaderId} contains an invalid or duplicate field: ${o.path}`);if(!n.has(o.sectionId))throw new Error(`Material Shader Definition ${e.shaderId} field ${o.path} references an unknown section.`);at(e,o),i.add(o.path)}}function st(e){let t=structuredClone(e);return{...t,inspector:{...t.inspector,fields:t.inspector.fields.map(r=>{if(r.control!=="number")return r;let n=Ae(t.propertiesSchema,r.schemaPath??r.path);return n?.kind!=="number"?r:{...r,...n.min!=null?{min:n.min}:{},...n.max!=null?{max:n.max}:{}}})}}}function at(e,t){let r=[["min",t.min],["max",t.max],["softMin",t.softMin],["softMax",t.softMax]];for(let[i,o]of r)if(o!=null&&!Number.isFinite(o))throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} ${i} must be finite.`);if(t.control!=="number"){if(r.some(([,i])=>i!=null))throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} uses numeric ranges with a non-number control.`);return}let n=Ae(e.propertiesSchema,t.schemaPath??t.path);if(n?.kind!=="number")throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} must reference a number schema.`);for(let[i,o,s]of[["min",t.min,n.min],["max",t.max,n.max]])if(o!=null&&o!==s)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} ${i} must match propertiesSchema.`);if(t.softMin!=null&&t.softMax!=null&&t.softMin>t.softMax)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMin must not exceed softMax.`);if(n.min!=null&&t.softMin!=null&&t.softMin<n.min)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMin must not be below the schema minimum.`);if(n.max!=null&&t.softMax!=null&&t.softMax>n.max)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMax must not exceed the schema maximum.`)}function Ee(e,t,r){if(t.kind==="object"){for(let[n,i]of Object.entries(t.properties))Ee(e,i,`${r}.${n}`);return}if(t.kind==="number"){if(t.min!=null&&!Number.isFinite(t.min))throw new Error(`Material Shader Definition ${e} number field ${r} min must be finite.`);if(t.max!=null&&!Number.isFinite(t.max))throw new Error(`Material Shader Definition ${e} number field ${r} max must be finite.`);if(t.min!=null&&t.max!=null&&t.min>t.max)throw new Error(`Material Shader Definition ${e} number field ${r} min must not exceed max.`);return}if(t.kind==="color"&&t.channels!=null&&t.channels!==3&&t.channels!==4)throw new Error(`Material Shader Definition ${e} color field ${r} channels must be 3 or 4.`)}function ct(e){let t=e.trim();return!t||t.startsWith("/")||t.includes("\\")||t.includes(":")?!1:!t.split("/").includes("..")}function lt(e){let t=e.trim();return t.startsWith("properties.")?t:`properties.${t}`}function Ae(e,t){let r=lt(t).replace(/^properties\./,"").split(".").filter(Boolean);if(r.length===0)return null;let n=e;for(let i of r){if(n.kind!=="object")return null;let o=n.properties[i];if(!o)return null;n=o}return n}function Pe(e,t,r,n){if(e.kind==="object"){if(!ie(t)){n.push({path:r,message:"must be an object"});return}for(let o of Object.keys(t))Object.prototype.hasOwnProperty.call(e.properties,o)||n.push({path:`${r}.${o}`,message:"is not supported by the selected shader"});for(let[o,s]of Object.entries(e.properties))t[o]!==void 0&&Pe(s,t[o],`${r}.${o}`,n);return}if(e.kind==="number"){if(typeof t!="number"||!Number.isFinite(t)){n.push({path:r,message:"must be a finite number"});return}e.min!=null&&t<e.min&&n.push({path:r,message:`must be greater than or equal to ${e.min}`}),e.max!=null&&t>e.max&&n.push({path:r,message:`must be less than or equal to ${e.max}`});return}if(e.kind==="boolean"){typeof t!="boolean"&&n.push({path:r,message:"must be a boolean"});return}if(e.kind==="string"){t!==null&&typeof t!="string"?n.push({path:r,message:"must be a string"}):t===null&&!e.nullable&&n.push({path:r,message:"must not be null"});return}if(e.kind==="enum"){(typeof t!="string"||!e.values.includes(t))&&n.push({path:r,message:`must be one of: ${e.values.join(", ")}`});return}if(e.kind==="color"){let o=e.channels===4?["r","g","b","a"]:["r","g","b"];Me(t,r,o,n,e.channels===4?"an RGBA object":"an RGB object");return}if(e.kind==="vec2"||e.kind==="vec3"){Me(t,r,e.kind==="vec2"?["x","y"]:["x","y","z"],n,`a ${e.kind} object`);return}if(t===null)return;if(!ie(t)){n.push({path:r,message:"must be a texture reference object or null"});return}Object.keys(t).some(o=>o!=="url"&&o!=="textureAssetId")&&n.push({path:r,message:"must contain only url or textureAssetId"});for(let o of["url","textureAssetId"]){let s=t[o];s!==void 0&&(typeof s!="string"||!s.trim())&&n.push({path:`${r}.${o}`,message:"must be a non-empty string"})}}function Me(e,t,r,n,i){if(!ie(e)){n.push({path:t,message:`must be ${i}`});return}Object.keys(e).some(o=>!r.includes(o))&&n.push({path:t,message:`must contain only ${r.join(", ")}`});for(let o of r)(typeof e[o]!="number"||!Number.isFinite(e[o]))&&n.push({path:`${t}.${o}`,message:"must be a finite number"})}function Fe(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))Fe(t)}return e}function ie(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}var ut=Object.freeze([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),ft=Object.freeze([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function O(e){return mt(new TextEncoder().encode(e))}function v(e){return`sha256:${O(JSON.stringify(e))}`}function mt(e){let t=Math.ceil((e.length+9)/64)*64,r=new Uint8Array(t);r.set(e),r[e.length]=128;let n=new DataView(r.buffer);n.setUint32(t-8,Math.floor(e.length/536870912),!1),n.setUint32(t-4,e.length*8>>>0,!1);let i=[...ut],o=new Uint32Array(64);for(let s=0;s<r.length;s+=64){for(let u=0;u<16;u+=1)o[u]=n.getUint32(s+u*4,!1);for(let u=16;u<64;u+=1){let j=o[u-15],E=o[u-2],F=M(j,7)^M(j,18)^j>>>3,J=M(E,17)^M(E,19)^E>>>10;o[u]=o[u-16]+F+o[u-7]+J>>>0}let[l,S,I,D,f,d,c,P]=i;for(let u=0;u<64;u+=1){let j=M(f,6)^M(f,11)^M(f,25),E=f&d^~f&c,F=P+j+E+ft[u]+o[u]>>>0,J=M(l,2)^M(l,13)^M(l,22),_=l&S^l&I^S&I,Z=J+_>>>0;P=c,c=d,d=f,f=D+F>>>0,D=I,I=S,S=l,l=F+Z>>>0}i[0]=i[0]+l>>>0,i[1]=i[1]+S>>>0,i[2]=i[2]+I>>>0,i[3]=i[3]+D>>>0,i[4]=i[4]+f>>>0,i[5]=i[5]+d>>>0,i[6]=i[6]+c>>>0,i[7]=i[7]+P>>>0}return i.map(s=>s.toString(16).padStart(8,"0")).join("")}function M(e,t){return e>>>t|e<<32-t}var B="fps.plugin.materials",ae="@fps-games/plugin-materials";function Re(e){let t=e?.[B];if(t==null)return null;if(!U(t)||t.schemaVersion!==1||typeof t.snapshotId!="string"||!Array.isArray(t.shaders))throw new Error("Materials Plugin snapshot is invalid. Run fps-editor-prepare again.");let r=structuredClone(t);return pt(r),Te(r)}function dt(e){return se([...oe,...e?.shaders.map(t=>t.definition)??[]])}function pt(e){if(!/^sha256:[a-f0-9]{64}$/.test(e.snapshotId)||e.shaders.length===0)throw new Error("Materials Plugin snapshot identity is invalid. Run fps-editor-prepare again.");for(let r of e.shaders)if(!U(r)||!U(r.definition)||!U(r.program))throw new Error("Materials Plugin Shader snapshot is invalid. Run fps-editor-prepare again.");dt(e);for(let r of e.shaders){let{definition:n,program:i}=r;if(i.shaderId!==n.shaderId||i.definitionVersion!==n.version)throw new Error(`Material snapshot Definition identity does not match its program: ${n.shaderId}`);if(i.language!=="glsl"||!Ne(i.vertexSourcePath)||!Ne(i.fragmentSourcePath)||!/^[a-f0-9]{64}$/.test(i.vertexSourceHash)||!/^[a-f0-9]{64}$/.test(i.fragmentSourceHash)||typeof i.vertexSource!="string"||!i.vertexSource.trim()||typeof i.fragmentSource!="string"||!i.fragmentSource.trim())throw new Error(`Material snapshot program is invalid: ${n.shaderId}`);if(O(i.vertexSource)!==i.vertexSourceHash||O(i.fragmentSource)!==i.fragmentSourceHash)throw new Error(`Material snapshot source hash does not match its GLSL content: ${n.shaderId}`);if(!Array.isArray(i.attributes)||i.attributes.length===0||i.attributes.some(o=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(o))||new Set(i.attributes).size!==i.attributes.length)throw new Error(`Material snapshot attributes are invalid: ${n.shaderId}`);if(!["opaque","combine","add"].includes(i.alphaMode)||!U(i.enumUniformValues)||!U(i.frame)||!["on-demand","continuous"].includes(i.frame.mode))throw new Error(`Material snapshot rendering policy is invalid: ${n.shaderId}`)}let t={schemaVersion:e.schemaVersion,shaders:e.shaders};if(v(t)!==e.snapshotId)throw new Error("Materials Plugin snapshot payload does not match its identity. Run fps-editor-prepare again.")}function Ne(e){return typeof e=="string"&&!!e&&!e.startsWith("/")&&!e.includes("\\")&&!e.includes(":")&&e.split("/").every(t=>!!t&&t!=="."&&t!=="..")}function Te(e){if(!e||typeof e!="object"||Object.isFrozen(e))return e;for(let t of Object.values(e))Te(t);return Object.freeze(e)}function U(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}async function Ve(e,t){let r=t.plugins.find(I=>I.pluginId===B&&I.targets.includes("editor"));if(!r)return null;if(r.packageName!==ae)throw new Error(`Materials Plugin package must be ${ae}.`);if(r.config==null)return null;let n=A(r.config,"Materials Plugin config");if(n.schemaVersion!==1||!Array.isArray(n.shaders)||n.shaders.length===0)throw new Error("Materials Plugin config must use schemaVersion 1 and declare shaders.");let i=await Le(e),o=new Set,s=[];for(let I of n.shaders){let D=A(I,"Materials Plugin shader entry"),f=A(D.definition,"Materials Plugin Shader Definition"),d=A(D.program,"Materials Plugin shader program"),c=G(f.shaderId,"Material shaderId");if(o.has(c))throw new Error(`Duplicate Material shaderId: ${c}`);o.add(c);let P=f.version;if(!Number.isSafeInteger(P)||Number(P)<1)throw new Error(`Material Definition version must be a positive integer: ${c}`);if(f.runtimeKind!=="shader-material")throw new Error(`Material runtimeKind must be shader-material: ${c}`);if(d.language!=="glsl")throw new Error(`Material program language must be glsl: ${c}`);let u=Ce(d.vertexSource,`Material vertexSource: ${c}`),j=Ce(d.fragmentSource,`Material fragmentSource: ${c}`),E=await Oe(i,u),F=await Oe(i,j),J=_e(A(f.inspector,"Material Inspector").fields,"Material Inspector fields"),_=new Map;for(let $ of J){let p=A($,"Material Inspector field"),b=G(p.path,"Material Inspector field path");if(_.has(b))throw new Error(`Duplicate Material Inspector field: ${c}:${b}`);if(_.set(b,p),p.updateClass!=="uniform")throw new Error(`Deployment ShaderMaterial only supports uniform fields: ${c}:${b}`);if(!["number","boolean","enum","color","vec2","vec3"].includes(String(p.control)))throw new Error(`Deployment ShaderMaterial does not support control: ${c}:${String(p.control)}`);ce(p.binding,`Material Inspector binding: ${c}:${b}`);let N=De(f.propertiesSchema,typeof p.schemaPath=="string"?p.schemaPath:b);if(!N||N.kind!==p.control)throw new Error(`Material Inspector field control does not match its schema: ${c}:${b}`);let Y=gt(f.defaultProperties,b);if(Y===void 0||JSON.stringify(Y)!==JSON.stringify(p.defaultValue))throw new Error(`Material Inspector field default must match defaultProperties: ${c}:${b}`)}let Z=H(d.enumUniformValues)?d.enumUniformValues:{};for(let[$,p]of Object.entries(Z)){let b=_.get($),N=b?De(f.propertiesSchema,b.schemaPath??$):null,Y=A(p,`Material enum uniform mapping: ${c}:${$}`);if(!b||b.control!=="enum"||N?.kind!=="enum"||!Array.isArray(N.values)||N.values.some(Q=>typeof Q!="string"||!Number.isFinite(Y[Q]))||Object.keys(Y).some(Q=>!N.values.includes(Q)))throw new Error(`Material enum uniform mapping is invalid: ${c}:${$}`)}for(let[$,p]of _)if(p.control==="enum"&&!Object.prototype.hasOwnProperty.call(Z,$))throw new Error(`Material enum uniform mapping is required: ${c}:${$}`);let y=d.frame===void 0?{mode:"on-demand"}:A(d.frame,"Material frame");if(y.mode!=="on-demand"&&y.mode!=="continuous")throw new Error(`Material frame mode is invalid: ${c}`);y.timeUniform!==void 0&&ce(y.timeUniform,`Material timeUniform: ${c}`),y.cameraPositionUniform!==void 0&&ce(y.cameraPositionUniform,`Material cameraPositionUniform: ${c}`);let ye=d.alphaMode??"opaque";if(!["opaque","combine","add"].includes(String(ye)))throw new Error(`Material alphaMode is invalid: ${c}`);s.push(Object.freeze({definition:f,program:Object.freeze({shaderId:c,definitionVersion:P,language:"glsl",vertexSourcePath:u,fragmentSourcePath:j,vertexSourceHash:O(E),fragmentSourceHash:O(F),vertexSource:E,fragmentSource:F,attributes:Object.freeze(d.attributes===void 0?["position","normal"]:_e(d.attributes,"Material attributes").map($=>G($,"Material attribute"))),alphaMode:ye,enumUniformValues:Object.freeze(structuredClone(Z)),frame:Object.freeze({mode:y.mode,...y.timeUniform?{timeUniform:G(y.timeUniform,"Material timeUniform")}:{},...y.cameraPositionUniform?{cameraPositionUniform:G(y.cameraPositionUniform,"Material cameraPositionUniform")}:{}})})}))}let l={schemaVersion:1,shaders:Object.freeze(s)},S=Object.freeze({...l,snapshotId:v(l)});return Re({[B]:S})}async function Oe(e,t){let r=le.resolve(e,t),n=await Le(r).catch(()=>"");if(!n||n!==e&&!n.startsWith(`${e}${le.sep}`))throw new Error(`Material shader source escapes the project root: ${t}`);if(!(await ht(n)).isFile())throw new Error(`Material shader source is not a file: ${t}`);return bt(n,"utf8")}function Ce(e,t){let r=G(e,t);if(le.isAbsolute(r)||r.includes("\\")||r.split("/").some(n=>!n||n==="."||n===".."))throw new Error(`${t} must be a normalized project-relative path.`);return r}function G(e,t){if(typeof e!="string"||!e.trim())throw new Error(`${t} must be a non-empty string.`);return e.trim()}function ce(e,t){if(typeof e!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`${t} must be a GLSL identifier.`)}function De(e,t){let r=H(e)?e:null;if(!r||typeof t!="string")return null;for(let n of t.replace(/^properties\./,"").split(".").filter(Boolean)){if(r.kind!=="object"||!H(r.properties)||!H(r.properties[n]))return null;r=r.properties[n]}return r}function gt(e,t){let r=e;for(let n of t.replace(/^properties\./,"").split(".").filter(Boolean)){if(!H(r))return;r=r[n]}return r}function _e(e,t){if(!Array.isArray(e))throw new Error(`${t} must be an array.`);return e}function A(e,t){if(!H(e))throw new Error(`${t} must be an object.`);return e}function H(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}var kt=a.dirname(It(import.meta.url)),de=a.resolve(kt,".."),pe=$e(process.argv.slice(2)),jt=pe.argv.includes("--reset-test-state"),Ue=pe.argv.filter(e=>e!=="--reset-test-state");if(Ue.length>0)throw new Error(`Unexpected argument: ${Ue[0]}`);var h=await ee(pe.projectRoot),W=a.join(h,".fps-editor"),K=a.join(W,"deployments"),Et=a.join(W,"state"),He=a.join(W,"current.json");Bt();await he(h,W);await he(W,K);await he(W,Et,448);jt&&console.log("[fps-editor-prepare] Browser Draft test state resets with the page lifecycle.");var k=await Ot(),C=JSON.parse(await me(a.join(de,"manifest.json"),"utf8"));Ft(C);var ne=await _t(),Be=await Ve(h,ne),qe=Object.freeze({...Be?{[B]:Be}:{}}),Ke=Lt({projectDefinition:ne,pluginSnapshots:qe});await be(de,C.files);var We=zt(C.files);k&&k.editorDistHash===C.build.distHash&&k.projectSourceHash===Ke&&k.deployment?.packageHash===We&&JSON.stringify(k.deployment?.manifest)===JSON.stringify(C)&&await Nt(k)&&(console.log("[fps-editor-prepare] existing Browser deployment and static Project definition are current."),process.exit(0));var m=await Pt(de,C,We),At=["a","b"].map(e=>({release:e,artifactId:`${m.id}-${e}`,rootPath:a.relative(h,a.join(m.rootPath,"public")),build:{...m.manifest.build,buildId:`${m.manifest.build.buildId}.release-${e}`}})),Je={schemaVersion:4,preparedAt:new Date().toISOString(),editorDistHash:C.build.distHash,projectSourceHash:Ke,projectDefinition:ne,pluginSnapshots:qe,deployment:{id:m.id,rootPath:a.relative(h,m.rootPath),packageHash:m.packageHash,manifest:m.manifest},serverEntry:a.relative(h,a.join(m.rootPath,m.manifest.entrypoints.server)),workerEntry:a.relative(h,a.join(m.rootPath,m.manifest.entrypoints.worker)),browserEntry:a.relative(h,a.join(m.rootPath,m.manifest.entrypoints.browser)),builds:At,staged:k?.deployment?.id&&k.deployment.id!==m.id?{deploymentId:k.deployment.id}:null};await Vt(He,Je);await Ct(Je);console.log([`[fps-editor-prepare] prepared Browser + Project I/O deployment ${m.id}`,`for static Project ${ne.projectId}.`].join(" "));async function Pt(e,t,r){let n=await $t(a.join(K,".install-"));try{for(let l of t.files){let S=a.join(n,l.path);await fe(a.dirname(S),{recursive:!0}),await ze(a.join(e,l.path),S)}await ze(a.join(e,"manifest.json"),a.join(n,"manifest.json"));let i=`${t.version}-${r.slice(0,16)}`,o=a.join(K,i),s=await q(o).catch(()=>null);return s&&await Rt(e,o,t)?await te(n,{recursive:!0,force:!0}):s?await Tt(n,o):await X(n,o),{id:i,rootPath:o,manifest:t,packageHash:r}}finally{await te(n,{recursive:!0,force:!0}).catch(()=>{})}}function Ft(e){if(e?.schemaVersion!==3||e.artifactKind!=="fps-editor-deployment-package"||e.packageName!=="@fps-games/editor-deployment")throw new Error("Editor deployment manifest is invalid.");if(e.node?.range!==">=24 <27"||e.node?.bundled!==!1)throw new Error("Editor deployment Node.js contract is invalid.");if(typeof e.build?.version!="string"||typeof e.build?.distHash!="string"||typeof e.commitSha!="string")throw new Error("Editor deployment build identity is incomplete.");if(e.authority!=="browser")throw new Error("Editor deployment authority must be Browser-owned.");for(let t of["server","worker","browser"])if(typeof e.entrypoints?.[t]!="string")throw new Error(`Editor deployment ${t} entrypoint is missing.`);for(let t of["prepare","server","project"])if(typeof e.binaries?.[t]!="string")throw new Error(`Editor deployment ${t} binary is missing.`);if(e.projectContentBundled!==!1)throw new Error("Editor deployment must not contain project content.")}async function be(e,t){if(!Array.isArray(t)||t.length===0)throw new Error("Editor deployment file manifest is empty.");for(let r of t){if(!Ze(r.path))throw new Error(`Unsafe deployment file path: ${String(r.path)}.`);let n=await re(e,r.path);if(n.byteLength!==r.size||Ut(n)!==r.sha256)throw new Error(`Editor deployment file integrity mismatch: ${r.path}.`)}}async function Nt(e){try{if(!e.deployment||typeof e.deployment.rootPath!="string"||!e.deployment.manifest||!Array.isArray(e.deployment.manifest.files))return!1;let t=a.resolve(h,e.deployment.rootPath);if(!ge(t,K))return!1;let r={serverEntry:a.relative(h,a.join(t,e.deployment.manifest.entrypoints.server)),workerEntry:a.relative(h,a.join(t,e.deployment.manifest.entrypoints.worker)),browserEntry:a.relative(h,a.join(t,e.deployment.manifest.entrypoints.browser))};if(Object.entries(r).some(([s,l])=>e[s]!==l))return!1;let n=Object.values(r);return(await Promise.all(n.map(s=>q(a.join(h,s))))).every(s=>s.isFile()&&!s.isSymbolicLink())?(await be(t,e.deployment.manifest.files),(await re(t,"manifest.json")).equals(Buffer.from(`${JSON.stringify(e.deployment.manifest,null,2)}
|
|
2
|
+
import{createHash as ue,randomBytes as yt}from"node:crypto";import{copyFile as ze,lstat as q,mkdir as fe,mkdtemp as $t,readFile as me,readdir as wt,realpath as ee,rename as X,rm as te,stat as xt,writeFile as St}from"node:fs/promises";import{fileURLToPath as It,pathToFileURL as Mt}from"node:url";import a from"node:path";import Ye from"node:path";function $e(e){let t=[],r;for(let n=0;n<e.length;n+=1){let i=e[n];if(i!=="--project-root"&&!i.startsWith("--project-root=")){t.push(i);continue}if(r!==void 0)throw new Error("--project-root may only be provided once.");let o=i==="--project-root"?e[++n]:i.slice(15);if(o===void 0||!o.trim()||o.startsWith("--"))throw new Error("--project-root requires a non-empty path.");r=o}return{argv:t,projectRoot:Ye.resolve(process.cwd(),r??"."),explicit:r!==void 0}}import{readFile as bt,realpath as Le,stat as ht}from"node:fs/promises";import le from"node:path";function we(e){return e==="fps.builtin.pbr"||e==="fps.builtin.standard"?e:void 0}var g={nodeKinds:["group","instance","transform","primitive","image"],primitiveShapes:["cube","sphere","plane","capsule"],transformTypes:["plain","light","camera","groundDecal"],assetTypes:["glb","texture"],materialScopes:["sharedAsset","nodeMaterial"],materialModes:["shared","instance"],materialShaderIds:["fps.builtin.pbr","fps.builtin.standard"],materialAssetSystemPresets:["default-pbr","default-standard"],runtimeV3:{assetFields:["id","guid","type","url","external","warmupCount","singleton","materialMode","defaults","materialSlots"],materialSlotFields:["slotId","label","sourceSurfaces"],materialSlotSourceSurfaceFields:["ownerNodePath","nodeIndex","nodeIndexPath","meshIndex","primitiveIndex","sourceMaterialIndex","sourceMeshName"]},hierarchy:{parentTargets:["root","sceneNode"]},runtimeOnlyTokens:["/@fs","assetUrl","sourceAssetUrl","sourceAssetPath"]},Kt=new Set(g.nodeKinds),Wt=new Set(g.primitiveShapes),Jt=new Set(g.assetTypes),Zt=new Set(g.materialModes),Yt=new Set(g.materialScopes),Xt=new Set(g.materialAssetSystemPresets),Qt=new Set(g.transformTypes),vt=new Set(g.hierarchy.parentTargets),er=g.runtimeOnlyTokens,tr=new Set(g.runtimeV3.assetFields),rr=new Set(g.runtimeV3.materialSlotFields),nr=new Set(g.runtimeV3.materialSlotSourceSurfaceFields);var Xe=/^[a-z0-9]+(?:[._-][a-z0-9]+)+$/;function xe(e){return typeof e=="string"&&!e.startsWith("fps.builtin.")&&Xe.test(e)}var w=(e,t)=>({kind:"number",...e!=null?{min:e}:{},...t!=null?{max:t}:{}}),R={kind:"texture"},Se={kind:"color"},Qe={kind:"enum",values:["lit","unlit"]},ve={kind:"enum",values:["opaque","mask","blend"]},ke={lightingModel:Qe,baseColor:{kind:"object",properties:{color:Se,texture:R,brightness:w(0),saturation:w(0),contrast:w(0),hue:w(-180,180)}},normal:{kind:"object",properties:{texture:R,strength:w(0)}},emission:{kind:"object",properties:{color:Se,intensity:w(0),texture:R,maskTexture:R}},alpha:{kind:"object",properties:{mode:ve,opacity:w(0,1),cutoff:w(0,1),texture:R}}},et={kind:"object",properties:{...ke,metallic:w(0,1),roughness:w(0,1),metallicRoughness:{kind:"object",properties:{texture:R}},occlusion:{kind:"object",properties:{texture:R,strength:w(0)}}}},tt={kind:"object",properties:ke},rt={lightingModel:"lit",baseColor:{color:{r:1,g:1,b:1},brightness:1,saturation:1,contrast:1,hue:0},metallic:0,roughness:1,emission:{color:{r:0,g:0,b:0},intensity:0}},nt={lightingModel:"lit",baseColor:{color:{r:1,g:1,b:1},brightness:1,saturation:1,contrast:1,hue:0},emission:{color:{r:0,g:0,b:0},intensity:0}},Ie=[{id:"surface",title:"Surface",order:40},{id:"geometry",title:"Geometry",order:50},{id:"emission",title:"Emission",order:60},{id:"alpha",title:"Alpha",order:70}],T={path:"properties.lightingModel",operator:"equals",value:"lit",inactiveReasonKey:"litMaterial"},je=[V("properties.lightingModel","surface",1,"enum","assetLightingModel","lightingModel","lit",{options:[{value:"lit",labelKey:"assetLightingModelLit"},{value:"unlit",labelKey:"assetLightingModelUnlit"}],binding:"lightingModel",updateClass:"define"}),V("properties.baseColor.color","surface",2,"color","assetBaseColor","baseColor",{r:1,g:1,b:1},{binding:"baseColor.color"}),z("properties.baseColor.texture.textureAssetId","properties.baseColor.texture","surface",3,"assetBaseTexture","baseTexture","baseColor.texture"),x("properties.baseColor.brightness","surface",4,"assetBrightness","brightness",1,{softMin:0,softMax:4,step:.05,conditions:[L("properties.baseColor.texture.textureAssetId","baseTexture")]}),x("properties.baseColor.saturation","surface",5,"assetSaturation","saturation",1,{softMin:0,softMax:2,step:.05,conditions:[L("properties.baseColor.texture.textureAssetId","baseTexture")]}),x("properties.baseColor.contrast","surface",6,"assetContrast","contrast",1,{softMin:0,softMax:2,step:.05,conditions:[L("properties.baseColor.texture.textureAssetId","baseTexture")]}),x("properties.baseColor.hue","surface",7,"assetHue","hue",0,{step:1,conditions:[L("properties.baseColor.texture.textureAssetId","baseTexture")]}),z("properties.normal.texture.textureAssetId","properties.normal.texture","geometry",10,"assetNormalTexture","normalTexture","normal.texture",[T]),x("properties.normal.strength","geometry",11,"assetNormalStrength","normalStrength",1,{softMin:0,softMax:4,step:.05,conditions:[T,L("properties.normal.texture.textureAssetId","normalTexture")]}),V("properties.emission.color","emission",50,"color","assetEmissionColor","emissionColor",{r:0,g:0,b:0},{binding:"emission.color"}),x("properties.emission.intensity","emission",51,"assetEmissionIntensity","emissionIntensity",0,{softMin:0,softMax:8,step:.05}),z("properties.emission.texture.textureAssetId","properties.emission.texture","emission",52,"assetEmissionTexture","emissionTexture","emission.texture"),V("properties.alpha.mode","alpha",60,"enum","assetAlphaMode","alphaMode","opaque",{options:[{value:"opaque",labelKey:"assetAlphaModeOpaque"},{value:"mask",labelKey:"assetAlphaModeMask"},{value:"blend",labelKey:"assetAlphaModeBlend"}],binding:"alpha.mode",updateClass:"pipeline"}),x("properties.alpha.opacity","alpha",61,"assetAlphaOpacity","alphaOpacity",1,{step:.05,conditions:[{path:"properties.alpha.mode",operator:"equals",value:"blend",inactiveReasonKey:"alphaBlend"}]}),x("properties.alpha.cutoff","alpha",62,"assetAlphaCutoff","alphaCutoff",.5,{step:.01,conditions:[{path:"properties.alpha.mode",operator:"equals",value:"mask",inactiveReasonKey:"alphaMask"}]}),z("properties.alpha.texture.textureAssetId","properties.alpha.texture","alpha",63,"assetAlphaTexture","alphaTexture","alpha.texture",[{path:"properties.alpha.mode",operator:"not-equals",value:"opaque",inactiveReasonKey:"alphaTransparency"}])],it=[...je,x("properties.metallic","geometry",20,"assetMetallic","metallic",0,{step:.05,conditions:[T]}),x("properties.roughness","geometry",21,"assetRoughness","roughness",1,{step:.05,conditions:[T]}),z("properties.metallicRoughness.texture.textureAssetId","properties.metallicRoughness.texture","geometry",22,"assetMetallicRoughnessTexture","metallicRoughnessTexture","metallicRoughness.texture",[T]),z("properties.occlusion.texture.textureAssetId","properties.occlusion.texture","geometry",23,"assetOcclusionTexture","occlusionTexture","occlusion.texture",[T]),x("properties.occlusion.strength","geometry",24,"assetOcclusionStrength","occlusionStrength",1,{softMin:0,softMax:4,step:.05,conditions:[T,L("properties.occlusion.texture.textureAssetId","occlusionTexture")]})],oe=[{shaderId:"fps.builtin.pbr",version:1,runtimeKind:"pbr",displayName:"PBR",propertiesSchema:et,defaultProperties:rt,inspector:{sections:Ie,fields:it}},{shaderId:"fps.builtin.standard",version:1,runtimeKind:"standard",displayName:"Standard",propertiesSchema:tt,defaultProperties:nt,inspector:{sections:Ie,fields:je}}],sr=se(oe);function se(e){let t=new Map;for(let n of e){ot(n,t);let i=st(n);t.set(n.shaderId,Fe(i))}let r=Object.freeze([...t.values()]);return Object.freeze({get(n){return typeof n=="string"?t.get(n)??null:null},list(){return r}})}function V(e,t,r,n,i,o,s,l){return{path:e,sectionId:t,order:r,control:n,labelKey:i,tooltipKey:o,defaultValue:s,updateClass:"uniform",...l}}function x(e,t,r,n,i,o,s={}){return V(e,t,r,"number",n,i,o,{binding:e.replace(/^properties\./,""),step:s.step??.05,displayPrecision:2,precision:2,...s})}function z(e,t,r,n,i,o,s,l){return V(e,r,n,"texture",i,o,"",{schemaPath:t,binding:s,updateClass:"texture",...l?{conditions:l}:{}})}function L(e,t){return{path:e,operator:"truthy",inactiveReasonKey:t}}function ot(e,t){if(!we(e.shaderId)&&!xe(e.shaderId))throw new Error("Material Shader Definition shaderId must be a supported built-in id or a lowercase namespaced project id.");if(!Number.isInteger(e.version)||e.version<=0)throw new Error(`Material Shader Definition ${e.shaderId} must use a positive integer version.`);if(t.has(e.shaderId))throw new Error(`Duplicate Material Shader Definition: ${e.shaderId}`);if(e.sourceFile!=null&&!ct(e.sourceFile))throw new Error(`Material Shader Definition ${e.shaderId} sourceFile must be a safe project-relative path.`);Ee(e.shaderId,e.propertiesSchema,"properties");let r=[];if(Pe(e.propertiesSchema,e.defaultProperties,"properties",r),r.length>0){let o=r[0];throw new Error(`Material Shader Definition ${e.shaderId} default ${o.path} ${o.message}.`)}let n=new Set;for(let o of e.inspector.sections){if(!o.id.trim()||n.has(o.id))throw new Error(`Material Shader Definition ${e.shaderId} contains an invalid or duplicate section: ${o.id}`);n.add(o.id)}let i=new Set;for(let o of e.inspector.fields){if(!o.path.startsWith("properties.")||i.has(o.path))throw new Error(`Material Shader Definition ${e.shaderId} contains an invalid or duplicate field: ${o.path}`);if(!n.has(o.sectionId))throw new Error(`Material Shader Definition ${e.shaderId} field ${o.path} references an unknown section.`);at(e,o),i.add(o.path)}}function st(e){let t=structuredClone(e);return{...t,inspector:{...t.inspector,fields:t.inspector.fields.map(r=>{if(r.control!=="number")return r;let n=Ae(t.propertiesSchema,r.schemaPath??r.path);return n?.kind!=="number"?r:{...r,...n.min!=null?{min:n.min}:{},...n.max!=null?{max:n.max}:{}}})}}}function at(e,t){let r=[["min",t.min],["max",t.max],["softMin",t.softMin],["softMax",t.softMax]];for(let[i,o]of r)if(o!=null&&!Number.isFinite(o))throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} ${i} must be finite.`);if(t.control!=="number"){if(r.some(([,i])=>i!=null))throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} uses numeric ranges with a non-number control.`);return}let n=Ae(e.propertiesSchema,t.schemaPath??t.path);if(n?.kind!=="number")throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} must reference a number schema.`);for(let[i,o,s]of[["min",t.min,n.min],["max",t.max,n.max]])if(o!=null&&o!==s)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} ${i} must match propertiesSchema.`);if(t.softMin!=null&&t.softMax!=null&&t.softMin>t.softMax)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMin must not exceed softMax.`);if(n.min!=null&&t.softMin!=null&&t.softMin<n.min)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMin must not be below the schema minimum.`);if(n.max!=null&&t.softMax!=null&&t.softMax>n.max)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMax must not exceed the schema maximum.`)}function Ee(e,t,r){if(t.kind==="object"){for(let[n,i]of Object.entries(t.properties))Ee(e,i,`${r}.${n}`);return}if(t.kind==="number"){if(t.min!=null&&!Number.isFinite(t.min))throw new Error(`Material Shader Definition ${e} number field ${r} min must be finite.`);if(t.max!=null&&!Number.isFinite(t.max))throw new Error(`Material Shader Definition ${e} number field ${r} max must be finite.`);if(t.min!=null&&t.max!=null&&t.min>t.max)throw new Error(`Material Shader Definition ${e} number field ${r} min must not exceed max.`);return}if(t.kind==="color"&&t.channels!=null&&t.channels!==3&&t.channels!==4)throw new Error(`Material Shader Definition ${e} color field ${r} channels must be 3 or 4.`)}function ct(e){let t=e.trim();return!t||t.startsWith("/")||t.includes("\\")||t.includes(":")?!1:!t.split("/").includes("..")}function lt(e){let t=e.trim();return t.startsWith("properties.")?t:`properties.${t}`}function Ae(e,t){let r=lt(t).replace(/^properties\./,"").split(".").filter(Boolean);if(r.length===0)return null;let n=e;for(let i of r){if(n.kind!=="object")return null;let o=n.properties[i];if(!o)return null;n=o}return n}function Pe(e,t,r,n){if(e.kind==="object"){if(!ie(t)){n.push({path:r,message:"must be an object"});return}for(let o of Object.keys(t))Object.prototype.hasOwnProperty.call(e.properties,o)||n.push({path:`${r}.${o}`,message:"is not supported by the selected shader"});for(let[o,s]of Object.entries(e.properties))t[o]!==void 0&&Pe(s,t[o],`${r}.${o}`,n);return}if(e.kind==="number"){if(typeof t!="number"||!Number.isFinite(t)){n.push({path:r,message:"must be a finite number"});return}e.min!=null&&t<e.min&&n.push({path:r,message:`must be greater than or equal to ${e.min}`}),e.max!=null&&t>e.max&&n.push({path:r,message:`must be less than or equal to ${e.max}`});return}if(e.kind==="boolean"){typeof t!="boolean"&&n.push({path:r,message:"must be a boolean"});return}if(e.kind==="string"){t!==null&&typeof t!="string"?n.push({path:r,message:"must be a string"}):t===null&&!e.nullable&&n.push({path:r,message:"must not be null"});return}if(e.kind==="enum"){(typeof t!="string"||!e.values.includes(t))&&n.push({path:r,message:`must be one of: ${e.values.join(", ")}`});return}if(e.kind==="color"){let o=e.channels===4?["r","g","b","a"]:["r","g","b"];Me(t,r,o,n,e.channels===4?"an RGBA object":"an RGB object");return}if(e.kind==="vec2"||e.kind==="vec3"){Me(t,r,e.kind==="vec2"?["x","y"]:["x","y","z"],n,`a ${e.kind} object`);return}if(t===null)return;if(!ie(t)){n.push({path:r,message:"must be a texture reference object or null"});return}Object.keys(t).some(o=>o!=="url"&&o!=="textureAssetId")&&n.push({path:r,message:"must contain only url or textureAssetId"});for(let o of["url","textureAssetId"]){let s=t[o];s!==void 0&&(typeof s!="string"||!s.trim())&&n.push({path:`${r}.${o}`,message:"must be a non-empty string"})}}function Me(e,t,r,n,i){if(!ie(e)){n.push({path:t,message:`must be ${i}`});return}Object.keys(e).some(o=>!r.includes(o))&&n.push({path:t,message:`must contain only ${r.join(", ")}`});for(let o of r)(typeof e[o]!="number"||!Number.isFinite(e[o]))&&n.push({path:`${t}.${o}`,message:"must be a finite number"})}function Fe(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))Fe(t)}return e}function ie(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}var ut=Object.freeze([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),ft=Object.freeze([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function O(e){return mt(new TextEncoder().encode(e))}function v(e){return`sha256:${O(JSON.stringify(e))}`}function mt(e){let t=Math.ceil((e.length+9)/64)*64,r=new Uint8Array(t);r.set(e),r[e.length]=128;let n=new DataView(r.buffer);n.setUint32(t-8,Math.floor(e.length/536870912),!1),n.setUint32(t-4,e.length*8>>>0,!1);let i=[...ut],o=new Uint32Array(64);for(let s=0;s<r.length;s+=64){for(let u=0;u<16;u+=1)o[u]=n.getUint32(s+u*4,!1);for(let u=16;u<64;u+=1){let j=o[u-15],E=o[u-2],F=M(j,7)^M(j,18)^j>>>3,J=M(E,17)^M(E,19)^E>>>10;o[u]=o[u-16]+F+o[u-7]+J>>>0}let[l,S,I,D,f,d,c,P]=i;for(let u=0;u<64;u+=1){let j=M(f,6)^M(f,11)^M(f,25),E=f&d^~f&c,F=P+j+E+ft[u]+o[u]>>>0,J=M(l,2)^M(l,13)^M(l,22),_=l&S^l&I^S&I,Z=J+_>>>0;P=c,c=d,d=f,f=D+F>>>0,D=I,I=S,S=l,l=F+Z>>>0}i[0]=i[0]+l>>>0,i[1]=i[1]+S>>>0,i[2]=i[2]+I>>>0,i[3]=i[3]+D>>>0,i[4]=i[4]+f>>>0,i[5]=i[5]+d>>>0,i[6]=i[6]+c>>>0,i[7]=i[7]+P>>>0}return i.map(s=>s.toString(16).padStart(8,"0")).join("")}function M(e,t){return e>>>t|e<<32-t}var B="fps.plugin.materials",ae="@fps-games/plugin-materials";function Re(e){let t=e?.[B];if(t==null)return null;if(!U(t)||t.schemaVersion!==1||typeof t.snapshotId!="string"||!Array.isArray(t.shaders))throw new Error("Materials Plugin snapshot is invalid. Run fps-editor-prepare again.");let r=structuredClone(t);return pt(r),Te(r)}function dt(e){return se([...oe,...e?.shaders.map(t=>t.definition)??[]])}function pt(e){if(!/^sha256:[a-f0-9]{64}$/.test(e.snapshotId)||e.shaders.length===0)throw new Error("Materials Plugin snapshot identity is invalid. Run fps-editor-prepare again.");for(let r of e.shaders)if(!U(r)||!U(r.definition)||!U(r.program))throw new Error("Materials Plugin Shader snapshot is invalid. Run fps-editor-prepare again.");dt(e);for(let r of e.shaders){let{definition:n,program:i}=r;if(i.shaderId!==n.shaderId||i.definitionVersion!==n.version)throw new Error(`Material snapshot Definition identity does not match its program: ${n.shaderId}`);if(i.language!=="glsl"||!Ne(i.vertexSourcePath)||!Ne(i.fragmentSourcePath)||!/^[a-f0-9]{64}$/.test(i.vertexSourceHash)||!/^[a-f0-9]{64}$/.test(i.fragmentSourceHash)||typeof i.vertexSource!="string"||!i.vertexSource.trim()||typeof i.fragmentSource!="string"||!i.fragmentSource.trim())throw new Error(`Material snapshot program is invalid: ${n.shaderId}`);if(O(i.vertexSource)!==i.vertexSourceHash||O(i.fragmentSource)!==i.fragmentSourceHash)throw new Error(`Material snapshot source hash does not match its GLSL content: ${n.shaderId}`);if(!Array.isArray(i.attributes)||i.attributes.length===0||i.attributes.some(o=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(o))||new Set(i.attributes).size!==i.attributes.length)throw new Error(`Material snapshot attributes are invalid: ${n.shaderId}`);if(!["opaque","combine","add"].includes(i.alphaMode)||!U(i.enumUniformValues)||!U(i.frame)||!["on-demand","continuous"].includes(i.frame.mode))throw new Error(`Material snapshot rendering policy is invalid: ${n.shaderId}`)}let t={schemaVersion:e.schemaVersion,shaders:e.shaders};if(v(t)!==e.snapshotId)throw new Error("Materials Plugin snapshot payload does not match its identity. Run fps-editor-prepare again.")}function Ne(e){return typeof e=="string"&&!!e&&!e.startsWith("/")&&!e.includes("\\")&&!e.includes(":")&&e.split("/").every(t=>!!t&&t!=="."&&t!=="..")}function Te(e){if(!e||typeof e!="object"||Object.isFrozen(e))return e;for(let t of Object.values(e))Te(t);return Object.freeze(e)}function U(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}async function Ve(e,t){let r=t.plugins.find(I=>I.pluginId===B&&I.targets.includes("editor"));if(!r)return null;if(r.packageName!==ae)throw new Error(`Materials Plugin package must be ${ae}.`);if(r.config==null)return null;let n=A(r.config,"Materials Plugin config");if(n.schemaVersion!==1||!Array.isArray(n.shaders)||n.shaders.length===0)throw new Error("Materials Plugin config must use schemaVersion 1 and declare shaders.");let i=await Le(e),o=new Set,s=[];for(let I of n.shaders){let D=A(I,"Materials Plugin shader entry"),f=A(D.definition,"Materials Plugin Shader Definition"),d=A(D.program,"Materials Plugin shader program"),c=G(f.shaderId,"Material shaderId");if(o.has(c))throw new Error(`Duplicate Material shaderId: ${c}`);o.add(c);let P=f.version;if(!Number.isSafeInteger(P)||Number(P)<1)throw new Error(`Material Definition version must be a positive integer: ${c}`);if(f.runtimeKind!=="shader-material")throw new Error(`Material runtimeKind must be shader-material: ${c}`);if(d.language!=="glsl")throw new Error(`Material program language must be glsl: ${c}`);let u=Ce(d.vertexSource,`Material vertexSource: ${c}`),j=Ce(d.fragmentSource,`Material fragmentSource: ${c}`),E=await Oe(i,u),F=await Oe(i,j),J=_e(A(f.inspector,"Material Inspector").fields,"Material Inspector fields"),_=new Map;for(let $ of J){let p=A($,"Material Inspector field"),b=G(p.path,"Material Inspector field path");if(_.has(b))throw new Error(`Duplicate Material Inspector field: ${c}:${b}`);if(_.set(b,p),p.updateClass!=="uniform")throw new Error(`Deployment ShaderMaterial only supports uniform fields: ${c}:${b}`);if(!["number","boolean","enum","color","vec2","vec3"].includes(String(p.control)))throw new Error(`Deployment ShaderMaterial does not support control: ${c}:${String(p.control)}`);ce(p.binding,`Material Inspector binding: ${c}:${b}`);let N=De(f.propertiesSchema,typeof p.schemaPath=="string"?p.schemaPath:b);if(!N||N.kind!==p.control)throw new Error(`Material Inspector field control does not match its schema: ${c}:${b}`);let Y=gt(f.defaultProperties,b);if(Y===void 0||JSON.stringify(Y)!==JSON.stringify(p.defaultValue))throw new Error(`Material Inspector field default must match defaultProperties: ${c}:${b}`)}let Z=H(d.enumUniformValues)?d.enumUniformValues:{};for(let[$,p]of Object.entries(Z)){let b=_.get($),N=b?De(f.propertiesSchema,b.schemaPath??$):null,Y=A(p,`Material enum uniform mapping: ${c}:${$}`);if(!b||b.control!=="enum"||N?.kind!=="enum"||!Array.isArray(N.values)||N.values.some(Q=>typeof Q!="string"||!Number.isFinite(Y[Q]))||Object.keys(Y).some(Q=>!N.values.includes(Q)))throw new Error(`Material enum uniform mapping is invalid: ${c}:${$}`)}for(let[$,p]of _)if(p.control==="enum"&&!Object.prototype.hasOwnProperty.call(Z,$))throw new Error(`Material enum uniform mapping is required: ${c}:${$}`);let y=d.frame===void 0?{mode:"on-demand"}:A(d.frame,"Material frame");if(y.mode!=="on-demand"&&y.mode!=="continuous")throw new Error(`Material frame mode is invalid: ${c}`);y.timeUniform!==void 0&&ce(y.timeUniform,`Material timeUniform: ${c}`),y.cameraPositionUniform!==void 0&&ce(y.cameraPositionUniform,`Material cameraPositionUniform: ${c}`);let ye=d.alphaMode??"opaque";if(!["opaque","combine","add"].includes(String(ye)))throw new Error(`Material alphaMode is invalid: ${c}`);s.push(Object.freeze({definition:f,program:Object.freeze({shaderId:c,definitionVersion:P,language:"glsl",vertexSourcePath:u,fragmentSourcePath:j,vertexSourceHash:O(E),fragmentSourceHash:O(F),vertexSource:E,fragmentSource:F,attributes:Object.freeze(d.attributes===void 0?["position","normal"]:_e(d.attributes,"Material attributes").map($=>G($,"Material attribute"))),alphaMode:ye,enumUniformValues:Object.freeze(structuredClone(Z)),frame:Object.freeze({mode:y.mode,...y.timeUniform?{timeUniform:G(y.timeUniform,"Material timeUniform")}:{},...y.cameraPositionUniform?{cameraPositionUniform:G(y.cameraPositionUniform,"Material cameraPositionUniform")}:{}})})}))}let l={schemaVersion:1,shaders:Object.freeze(s)},S=Object.freeze({...l,snapshotId:v(l)});return Re({[B]:S})}async function Oe(e,t){let r=le.resolve(e,t),n=await Le(r).catch(()=>"");if(!n||n!==e&&!n.startsWith(`${e}${le.sep}`))throw new Error(`Material shader source escapes the project root: ${t}`);if(!(await ht(n)).isFile())throw new Error(`Material shader source is not a file: ${t}`);return bt(n,"utf8")}function Ce(e,t){let r=G(e,t);if(le.isAbsolute(r)||r.includes("\\")||r.split("/").some(n=>!n||n==="."||n===".."))throw new Error(`${t} must be a normalized project-relative path.`);return r}function G(e,t){if(typeof e!="string"||!e.trim())throw new Error(`${t} must be a non-empty string.`);return e.trim()}function ce(e,t){if(typeof e!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`${t} must be a GLSL identifier.`)}function De(e,t){let r=H(e)?e:null;if(!r||typeof t!="string")return null;for(let n of t.replace(/^properties\./,"").split(".").filter(Boolean)){if(r.kind!=="object"||!H(r.properties)||!H(r.properties[n]))return null;r=r.properties[n]}return r}function gt(e,t){let r=e;for(let n of t.replace(/^properties\./,"").split(".").filter(Boolean)){if(!H(r))return;r=r[n]}return r}function _e(e,t){if(!Array.isArray(e))throw new Error(`${t} must be an array.`);return e}function A(e,t){if(!H(e))throw new Error(`${t} must be an object.`);return e}function H(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}var kt=a.dirname(It(import.meta.url)),de=a.resolve(kt,".."),pe=$e(process.argv.slice(2)),jt=pe.argv.includes("--reset-test-state"),Ue=pe.argv.filter(e=>e!=="--reset-test-state");if(Ue.length>0)throw new Error(`Unexpected argument: ${Ue[0]}`);var h=await ee(pe.projectRoot),W=a.join(h,".fps-editor"),K=a.join(W,"deployments"),Et=a.join(W,"state"),He=a.join(W,"current.json");Bt();await he(h,W);await he(W,K);await he(W,Et,448);jt&&console.log("[fps-editor-prepare] Browser Draft test state resets with the page lifecycle.");var k=await Ot(),C=JSON.parse(await me(a.join(de,"manifest.json"),"utf8"));Ft(C);var ne=await _t(),Be=await Ve(h,ne),qe=Object.freeze({...Be?{[B]:Be}:{}}),Ke=Lt({projectDefinition:ne,pluginSnapshots:qe});await be(de,C.files);var We=zt(C.files);k&&k.editorDistHash===C.build.distHash&&k.projectSourceHash===Ke&&k.deployment?.packageHash===We&&JSON.stringify(k.deployment?.manifest)===JSON.stringify(C)&&await Nt(k)&&(console.log("[fps-editor-prepare] existing Browser deployment and static Project definition are current."),process.exit(0));var m=await Pt(de,C,We),At=["a","b"].map(e=>({release:e,artifactId:`${m.id}-${e}`,rootPath:a.relative(h,a.join(m.rootPath,"public")),build:{...m.manifest.build,buildId:`${m.manifest.build.buildId}.release-${e}`}})),Je={schemaVersion:4,preparedAt:new Date().toISOString(),editorDistHash:C.build.distHash,projectSourceHash:Ke,projectDefinition:ne,pluginSnapshots:qe,deployment:{id:m.id,rootPath:a.relative(h,m.rootPath),packageHash:m.packageHash,manifest:m.manifest},serverEntry:a.relative(h,a.join(m.rootPath,m.manifest.entrypoints.server)),workerEntry:a.relative(h,a.join(m.rootPath,m.manifest.entrypoints.worker)),browserEntry:a.relative(h,a.join(m.rootPath,m.manifest.entrypoints.browser)),builds:At,staged:k?.deployment?.id&&k.deployment.id!==m.id?{deploymentId:k.deployment.id}:null};await Vt(He,Je);await Ct(Je);console.log([`[fps-editor-prepare] prepared Browser + Project I/O deployment ${m.id}`,`for static Project ${ne.projectId}.`].join(" "));async function Pt(e,t,r){let n=await $t(a.join(K,".install-"));try{for(let l of t.files){let S=a.join(n,l.path);await fe(a.dirname(S),{recursive:!0}),await ze(a.join(e,l.path),S)}await ze(a.join(e,"manifest.json"),a.join(n,"manifest.json"));let i=`${t.version}-${r.slice(0,16)}`,o=a.join(K,i),s=await q(o).catch(()=>null);return s&&await Rt(e,o,t)?await te(n,{recursive:!0,force:!0}):s?await Tt(n,o):await X(n,o),{id:i,rootPath:o,manifest:t,packageHash:r}}finally{await te(n,{recursive:!0,force:!0}).catch(()=>{})}}function Ft(e){if(e?.schemaVersion!==3||e.artifactKind!=="fps-editor-deployment-package"||e.packageName!=="@fps-games/editor-deployment")throw new Error("Editor deployment manifest is invalid.");if(e.node?.range!==">=24 <27"||e.node?.bundled!==!1)throw new Error("Editor deployment Node.js contract is invalid.");if(typeof e.build?.version!="string"||typeof e.build?.distHash!="string"||typeof e.commitSha!="string")throw new Error("Editor deployment build identity is incomplete.");if(e.authority!=="browser")throw new Error("Editor deployment authority must be Browser-owned.");for(let t of["server","worker","browser"])if(typeof e.entrypoints?.[t]!="string")throw new Error(`Editor deployment ${t} entrypoint is missing.`);for(let t of["prepare","server","project"])if(typeof e.binaries?.[t]!="string")throw new Error(`Editor deployment ${t} binary is missing.`);if(e.projectContentBundled!==!1)throw new Error("Editor deployment must not contain project content.")}async function be(e,t){if(!Array.isArray(t)||t.length===0)throw new Error("Editor deployment file manifest is empty.");for(let r of t){if(!Ze(r.path))throw new Error(`Unsafe deployment file path: ${String(r.path)}.`);let n=await re(e,r.path);if(n.byteLength!==r.size||Ut(n)!==r.sha256)throw new Error(`Editor deployment file integrity mismatch: ${r.path}.`)}}async function Nt(e){try{if(!e.deployment||typeof e.deployment.rootPath!="string"||!e.deployment.manifest||!Array.isArray(e.deployment.manifest.files))return!1;let t=a.resolve(h,e.deployment.rootPath);if(!ge(t,K))return!1;let r={serverEntry:a.relative(h,a.join(t,e.deployment.manifest.entrypoints.server)),workerEntry:a.relative(h,a.join(t,e.deployment.manifest.entrypoints.worker)),browserEntry:a.relative(h,a.join(t,e.deployment.manifest.entrypoints.browser))};if(Object.entries(r).some(([s,l])=>e[s]!==l))return!1;let n=Object.values(r);return(await Promise.all(n.map(s=>q(a.join(h,s))))).every(s=>s.isFile()&&!s.isSymbolicLink())?(await be(t,e.deployment.manifest.files),(await re(t,"manifest.json")).equals(Buffer.from(`${JSON.stringify(e.deployment.manifest,null,2)}
|
|
3
3
|
`))):!1}catch{return!1}}async function Rt(e,t,r){try{await be(t,r.files);let[n,i]=await Promise.all([re(e,"manifest.json"),re(t,"manifest.json")]);return n.equals(i)}catch{return!1}}async function re(e,t){if(!Ze(t))throw new Error(`Unsafe deployment file path: ${String(t)}.`);let r=await q(e);if(!r.isDirectory()||r.isSymbolicLink())throw new Error(`Editor deployment root is not a regular directory: ${e}.`);let n=await ee(e),i=a.join(e,t),o=await q(i);if(!o.isFile()||o.isSymbolicLink())throw new Error(`Editor deployment file is not a regular file: ${t}.`);let s=await ee(i),l=a.resolve(n,t);if(s!==l||!ge(s,n))throw new Error(`Editor deployment file escaped its deployment root: ${t}.`);return me(i)}async function he(e,t,r){await q(t).catch(s=>{if(Ge(s)&&s.code==="ENOENT")return null;throw s})||await fe(t,r===void 0?void 0:{mode:r}).catch(s=>{if(!Ge(s)||s.code!=="EEXIST")throw s});let i=await q(t),o=await ee(t);if(!i.isDirectory()||i.isSymbolicLink()||o!==t||!ge(o,e))throw new Error(`Editor deployment directory must be a regular project directory: ${t}.`)}async function Tt(e,t){let r=a.join(K,`.replace-${a.basename(t)}-${process.pid}-${yt(6).toString("hex")}`);await X(t,r);try{await X(e,t)}catch(n){try{await X(r,t)}catch(i){throw new AggregateError([n,i],`Editor deployment replacement and rollback both failed for ${a.basename(t)}.`)}throw n}await te(r,{recursive:!0,force:!0})}async function Ot(){try{let e=JSON.parse(await me(He,"utf8"));return e?.schemaVersion===4?e:null}catch{return null}}async function Ct(e){let t=new Set([e.deployment.id,e.staged?.deploymentId].filter(Boolean));await Dt(K,t)}async function Dt(e,t){for(let r of await wt(e,{withFileTypes:!0}))!r.isDirectory()||r.name.startsWith(".")||t.has(r.name)||await te(a.join(e,r.name),{recursive:!0,force:!0})}async function _t(){let e=a.join(h,"fps.config.ts");if(!(await xt(e).catch(()=>null))?.isFile())throw new Error("fps.config.ts is required.");let r=await import(`${Mt(e).href}?fps-editor-prepare=${Date.now()}`),n=r.default??r.fpsConfig;if(!n||typeof n!="object"||Array.isArray(n)||n.schemaVersion!==1||typeof n.projectId!="string"||!n.authoring||!Array.isArray(n.plugins))throw new Error("fps.config.ts must default-export a valid defineFpsProject() definition.");return n}function Lt(e){return ue("sha256").update(JSON.stringify(e)).digest("hex")}async function Vt(e,t){await fe(a.dirname(e),{recursive:!0});let r=`${e}.${process.pid}.tmp`;await St(r,`${JSON.stringify(t,null,2)}
|
|
4
4
|
`),await X(r,e)}function Ze(e){return typeof e=="string"&&e.length>0&&!e.includes("\\")&&!a.isAbsolute(e)&&!e.split("/").includes("..")}function ge(e,t){if(e===t)return!0;let r=a.relative(t,e);return r.length>0&&r!==".."&&!r.startsWith(`..${a.sep}`)&&!a.isAbsolute(r)}function zt(e){return ue("sha256").update(JSON.stringify(e)).digest("hex")}function Ut(e){return ue("sha256").update(e).digest("hex")}function Ge(e){return e instanceof Error&&"code"in e}function Bt(){let e=Number.parseInt(process.versions.node.split(".")[0]??"",10);if(!Number.isSafeInteger(e)||e<24||e>=27)throw new Error(`prepare:server requires Node.js >=24 <27; current version is ${process.versions.node}.`)}
|