@@ -2,6 +2,7 @@ import AssetRegistry from "../../engine/assets/AssetRegistry.js";
22import AssetLoaderSystem from "../../engine/assets/AssetLoaderSystem.js" ;
33import ImageAssetLoader from "../../engine/assets/ImageAssetLoader.js" ;
44import { prepareVectorGeometryRuntimeAsset } from "./vectorGeometryRuntime.js" ;
5+ import { validatePackageManifest , createRegistryDefinition } from "./runtimeAssetValidationUtils.js" ;
56import { ensureArray } from "../../src/shared/utils/arrayUtils.js" ;
67import { cloneJson } from "../../src/shared/utils/jsonUtils.js" ;
78import { trimSafe } from "../../src/shared/utils/stringUtils.js" ;
@@ -25,76 +26,6 @@ function createLoaderState(status, reports, extra = {}) {
2526 } ;
2627}
2728
28- function validatePackageManifest ( manifest ) {
29- const pkg = manifest ?. package ;
30- if ( ! pkg || typeof pkg !== "object" ) {
31- throw new Error ( "Invalid packaged input: missing package root." ) ;
32- }
33- if ( ! Number . isFinite ( pkg . version ) ) {
34- throw new Error ( "Invalid packaged input: package.version must be numeric." ) ;
35- }
36- if ( ! trimSafe ( pkg . projectId ) ) {
37- throw new Error ( "Invalid packaged input: package.projectId is required." ) ;
38- }
39- if ( ! Array . isArray ( pkg . assets ) || pkg . assets . length === 0 ) {
40- throw new Error ( "Invalid packaged input: package.assets must contain at least one asset." ) ;
41- }
42- if ( ! Array . isArray ( pkg . dependencies ) ) {
43- throw new Error ( "Invalid packaged input: package.dependencies must be an array." ) ;
44- }
45- if ( ! Array . isArray ( pkg . roots ) || pkg . roots . length === 0 ) {
46- throw new Error ( "Invalid packaged input: package.roots must contain at least one startup root." ) ;
47- }
48-
49- const seenIds = new Set ( ) ;
50- pkg . assets . forEach ( ( asset , index ) => {
51- const id = trimSafe ( asset ?. id ) ;
52- const type = trimSafe ( asset ?. type ) ;
53- if ( ! id ) {
54- throw new Error ( `Invalid packaged input: asset at index ${ index } is missing id.` ) ;
55- }
56- if ( ! type ) {
57- throw new Error ( `Invalid packaged input: asset ${ id } is missing type.` ) ;
58- }
59- if ( seenIds . has ( id ) ) {
60- throw new Error ( `Invalid packaged input: duplicate packaged asset ${ id } .` ) ;
61- }
62- seenIds . add ( id ) ;
63- } ) ;
64-
65- pkg . roots . forEach ( ( root , index ) => {
66- const id = trimSafe ( root ?. id ) ;
67- if ( ! id || ! seenIds . has ( id ) ) {
68- throw new Error ( `Invalid packaged input: startup root at index ${ index } does not resolve to a packaged asset.` ) ;
69- }
70- } ) ;
71-
72- pkg . dependencies . forEach ( ( dependency , index ) => {
73- const from = trimSafe ( dependency ?. from ) ;
74- const to = trimSafe ( dependency ?. to ) ;
75- const type = trimSafe ( dependency ?. type ) ;
76- if ( ! from || ! to || ! type ) {
77- throw new Error ( `Invalid packaged input: dependency at index ${ index } is incomplete.` ) ;
78- }
79- if ( ! seenIds . has ( from ) || ! seenIds . has ( to ) ) {
80- throw new Error ( `Invalid packaged input: dependency ${ from } -> ${ to } references a missing packaged asset.` ) ;
81- }
82- } ) ;
83-
84- return pkg ;
85- }
86-
87- function createRegistryDefinition ( asset , source ) {
88- const type = trimSafe ( asset ?. type ) ;
89- const sourceType = type === "image" ? "image" : "data" ;
90- return {
91- id : trimSafe ( asset ?. id ) ,
92- type : sourceType ,
93- path : trimSafe ( asset ?. path ) ,
94- source
95- } ;
96- }
97-
9829function toBootstrapData ( packageManifest , loadedAssets ) {
9930 const pkg = packageManifest . package ;
10031 return {
0 commit comments