@playdrop/playdrop-cli 0.3.1-build.1 → 0.3.4-build.1

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.
Files changed (268) hide show
  1. package/README.md +1 -0
  2. package/config/client-meta.json +5 -5
  3. package/dist/apps/build.js +90 -114
  4. package/dist/apps/upload.js +30 -8
  5. package/dist/apps/validate.js +61 -0
  6. package/dist/assets/model-artifacts.d.ts +8 -0
  7. package/dist/assets/model-artifacts.js +375 -0
  8. package/dist/assets/model-worker.d.ts +22 -0
  9. package/dist/assets/model-worker.js +123 -0
  10. package/dist/catalogue.d.ts +4 -4
  11. package/dist/catalogue.js +234 -44
  12. package/dist/commands/build.js +15 -2
  13. package/dist/commands/dev.js +2 -0
  14. package/dist/commands/devServer.js +88 -9
  15. package/dist/commands/generation.js +130 -6
  16. package/dist/commands/migrateCatalogueV2.js +4 -4
  17. package/dist/commands/upload.js +63 -18
  18. package/dist/index.js +6 -5
  19. package/dist/playwright.js +9 -1
  20. package/node_modules/@playdrop/ai-client/dist/index.d.ts +1 -1
  21. package/node_modules/@playdrop/ai-client/dist/index.d.ts.map +1 -1
  22. package/node_modules/@playdrop/api-client/dist/client.d.ts +39 -17
  23. package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
  24. package/node_modules/@playdrop/api-client/dist/client.js +236 -42
  25. package/node_modules/@playdrop/api-client/dist/index.d.ts +27 -5
  26. package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
  27. package/node_modules/@playdrop/api-client/dist/index.js +39 -9
  28. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/entity-cleaner.d.ts +3 -3
  29. package/node_modules/@playdrop/boxel-core/dist/src/entity-cleaner.js.map +1 -0
  30. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/entity-utils.d.ts +8 -8
  31. package/node_modules/@playdrop/boxel-core/dist/src/entity-utils.js.map +1 -0
  32. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/common.d.ts +2 -2
  33. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/common.js.map +1 -1
  34. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/textured-builder.d.ts +2 -2
  35. package/node_modules/@playdrop/boxel-core/dist/src/humanoid/r15/textured-builder.js.map +1 -0
  36. package/node_modules/@playdrop/boxel-core/dist/src/humanoid/r15/types.d.ts +6 -0
  37. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/voxel-builder.d.ts +2 -2
  38. package/node_modules/@playdrop/boxel-core/dist/src/humanoid/r15/voxel-builder.js.map +1 -0
  39. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/builder.d.ts +3 -3
  40. package/node_modules/@playdrop/boxel-core/dist/src/humanoid/r6/builder.js.map +1 -0
  41. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/templates/index.d.ts +4 -4
  42. package/node_modules/@playdrop/boxel-core/dist/src/humanoid/templates/index.js.map +1 -0
  43. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/palette_tools.d.ts +4 -4
  44. package/node_modules/@playdrop/boxel-core/dist/src/palette_tools.js.map +1 -0
  45. package/node_modules/@playdrop/boxel-core/dist/src/serialization.d.ts +4 -0
  46. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/serialization.js +10 -10
  47. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/serialization.js.map +1 -1
  48. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/textures.d.ts +5 -5
  49. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/textures.js.map +1 -1
  50. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/textured-boxes/infer-face.d.ts +2 -2
  51. package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/infer-face.js.map +1 -0
  52. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/textured-boxes/layer-mode.d.ts +2 -2
  53. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/textured-boxes/layer-mode.js +1 -1
  54. package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/layer-mode.js.map +1 -0
  55. package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/merge-overlay.d.ts +2 -0
  56. package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/merge-overlay.js.map +1 -0
  57. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/textured-boxes/slice.d.ts +2 -2
  58. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/textured-boxes/slice.js +1 -1
  59. package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/slice.js.map +1 -0
  60. package/node_modules/@playdrop/boxel-core/dist/src/transforms/upscale.d.ts +3 -0
  61. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/upscale.js +1 -1
  62. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/upscale.js.map +1 -1
  63. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/voxels/slice.d.ts +2 -2
  64. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/voxels/slice.js.map +1 -1
  65. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/types.d.ts +3 -3
  66. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/validation.d.ts +10 -10
  67. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/validation.js +36 -36
  68. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/validation.js.map +1 -1
  69. package/node_modules/@playdrop/boxel-core/dist/test/entity-utils.test.js.map +1 -0
  70. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/index.test.js +2 -2
  71. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/index.test.js.map +1 -1
  72. package/node_modules/@playdrop/boxel-core/dist/test/layer-mode.test.js.map +1 -0
  73. package/node_modules/@playdrop/boxel-core/dist/test/palette-tools.test.js.map +1 -0
  74. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/serialization.test.js +6 -6
  75. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/serialization.test.js.map +1 -1
  76. package/node_modules/@playdrop/boxel-core/dist/test/textures.test.js.map +1 -0
  77. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/types.test.js +1 -1
  78. package/node_modules/@playdrop/boxel-core/dist/test/types.test.js.map +1 -0
  79. package/node_modules/@playdrop/boxel-core/dist/test/upscale.test.js.map +1 -0
  80. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/validation.test.js +11 -11
  81. package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/validation.test.js.map +1 -1
  82. package/node_modules/@playdrop/{entity-core → boxel-core}/package.json +2 -2
  83. package/node_modules/@playdrop/boxel-three/dist/src/animations.d.ts +4 -0
  84. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/animations.js +1 -1
  85. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/builders.d.ts +1 -1
  86. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/builders.js +3 -3
  87. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/context.d.ts +3 -3
  88. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/exporters/glb.d.ts +9 -9
  89. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/exporters/glb.js +4 -4
  90. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/exporters/image.d.ts +4 -4
  91. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/exporters/image.js +5 -5
  92. package/node_modules/@playdrop/boxel-three/dist/src/index.d.ts +17 -0
  93. package/node_modules/@playdrop/boxel-three/dist/src/index.js +15 -0
  94. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/instantiate.d.ts +4 -4
  95. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/instantiate.js +4 -4
  96. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/nodes.d.ts +1 -1
  97. package/node_modules/@playdrop/boxel-three/dist/src/overlays.d.ts +7 -0
  98. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/overlays.js +1 -1
  99. package/node_modules/@playdrop/boxel-three/dist/src/scene.d.ts +3 -0
  100. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/scene.js +6 -6
  101. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/skinned-mesh.d.ts +2 -2
  102. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/textures.d.ts +1 -1
  103. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/textures.js +2 -2
  104. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/types.d.ts +15 -15
  105. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/voxels/faces.d.ts +1 -1
  106. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/voxels/mesher.d.ts +1 -1
  107. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/voxels/mesher.js +1 -1
  108. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/export-image.playwright.test.js +4 -4
  109. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/fixtures/render-worker.d.ts +3 -3
  110. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/fixtures/render-worker.js +10 -10
  111. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/glb-skinned.test.js +5 -5
  112. package/node_modules/@playdrop/boxel-three/dist/test/index.test.js +8 -0
  113. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/instantiate.test.js +2 -2
  114. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/overlays.test.js +3 -3
  115. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/scene-filter.test.js +5 -5
  116. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/scene-smoke.test.js +3 -3
  117. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/skinned-mesh.test.js +2 -2
  118. package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/textured-overlay.test.js +3 -3
  119. package/node_modules/@playdrop/{entity-three → boxel-three}/package.json +3 -3
  120. package/node_modules/@playdrop/config/client-meta.json +5 -5
  121. package/node_modules/@playdrop/config/dist/tsconfig.tsbuildinfo +1 -1
  122. package/node_modules/@playdrop/types/dist/api.d.ts +155 -52
  123. package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
  124. package/node_modules/@playdrop/types/dist/api.js +27 -0
  125. package/node_modules/@playdrop/types/dist/asset-pack.d.ts +1 -0
  126. package/node_modules/@playdrop/types/dist/asset-pack.d.ts.map +1 -1
  127. package/node_modules/@playdrop/types/dist/asset.d.ts +20 -4
  128. package/node_modules/@playdrop/types/dist/asset.d.ts.map +1 -1
  129. package/node_modules/@playdrop/types/dist/asset.js +43 -37
  130. package/node_modules/@playdrop/types/dist/entity.d.ts +2 -2
  131. package/node_modules/@playdrop/types/dist/entity.d.ts.map +1 -1
  132. package/node_modules/@playdrop/types/dist/entity.js +2 -2
  133. package/node_modules/@playdrop/types/dist/realtime.d.ts +1 -0
  134. package/node_modules/@playdrop/types/dist/realtime.d.ts.map +1 -1
  135. package/package.json +10 -7
  136. package/node_modules/@playdrop/entity-core/dist/src/entity-cleaner.js.map +0 -1
  137. package/node_modules/@playdrop/entity-core/dist/src/entity-utils.js.map +0 -1
  138. package/node_modules/@playdrop/entity-core/dist/src/humanoid/r15/textured-builder.js.map +0 -1
  139. package/node_modules/@playdrop/entity-core/dist/src/humanoid/r15/types.d.ts +0 -6
  140. package/node_modules/@playdrop/entity-core/dist/src/humanoid/r15/voxel-builder.js.map +0 -1
  141. package/node_modules/@playdrop/entity-core/dist/src/humanoid/r6/builder.js.map +0 -1
  142. package/node_modules/@playdrop/entity-core/dist/src/humanoid/templates/index.js.map +0 -1
  143. package/node_modules/@playdrop/entity-core/dist/src/palette_tools.js.map +0 -1
  144. package/node_modules/@playdrop/entity-core/dist/src/serialization.d.ts +0 -4
  145. package/node_modules/@playdrop/entity-core/dist/src/transforms/textured-boxes/infer-face.js.map +0 -1
  146. package/node_modules/@playdrop/entity-core/dist/src/transforms/textured-boxes/layer-mode.js.map +0 -1
  147. package/node_modules/@playdrop/entity-core/dist/src/transforms/textured-boxes/merge-overlay.d.ts +0 -2
  148. package/node_modules/@playdrop/entity-core/dist/src/transforms/textured-boxes/merge-overlay.js.map +0 -1
  149. package/node_modules/@playdrop/entity-core/dist/src/transforms/textured-boxes/slice.js.map +0 -1
  150. package/node_modules/@playdrop/entity-core/dist/src/transforms/upscale.d.ts +0 -3
  151. package/node_modules/@playdrop/entity-core/dist/test/entity-utils.test.js.map +0 -1
  152. package/node_modules/@playdrop/entity-core/dist/test/layer-mode.test.js.map +0 -1
  153. package/node_modules/@playdrop/entity-core/dist/test/palette-tools.test.js.map +0 -1
  154. package/node_modules/@playdrop/entity-core/dist/test/textures.test.js.map +0 -1
  155. package/node_modules/@playdrop/entity-core/dist/test/types.test.js.map +0 -1
  156. package/node_modules/@playdrop/entity-core/dist/test/upscale.test.js.map +0 -1
  157. package/node_modules/@playdrop/entity-three/dist/src/animations.d.ts +0 -4
  158. package/node_modules/@playdrop/entity-three/dist/src/index.d.ts +0 -17
  159. package/node_modules/@playdrop/entity-three/dist/src/index.js +0 -15
  160. package/node_modules/@playdrop/entity-three/dist/src/overlays.d.ts +0 -7
  161. package/node_modules/@playdrop/entity-three/dist/src/scene.d.ts +0 -3
  162. package/node_modules/@playdrop/entity-three/dist/test/index.test.js +0 -8
  163. package/node_modules/@playdrop/types/dist/profile-asset-semantics.d.ts +0 -22
  164. package/node_modules/@playdrop/types/dist/profile-asset-semantics.d.ts.map +0 -1
  165. package/node_modules/@playdrop/types/dist/profile-asset-semantics.js +0 -105
  166. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/entity-cleaner.js +0 -0
  167. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/entity-utils.js +0 -0
  168. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/format-utils.d.ts +0 -0
  169. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/format-utils.js +0 -0
  170. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/format-utils.js.map +0 -0
  171. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/geometry.d.ts +0 -0
  172. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/geometry.js +0 -0
  173. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/geometry.js.map +0 -0
  174. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/index.d.ts +0 -0
  175. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/index.js +0 -0
  176. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/index.js.map +0 -0
  177. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/common.js +0 -0
  178. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/index.d.ts +0 -0
  179. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/index.js +0 -0
  180. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/index.js.map +0 -0
  181. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/textured-builder.js +0 -0
  182. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/types.js +0 -0
  183. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/types.js.map +0 -0
  184. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r15/voxel-builder.js +0 -0
  185. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/builder.js +0 -0
  186. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/index.d.ts +0 -0
  187. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/index.js +0 -0
  188. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/index.js.map +0 -0
  189. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/scanner.d.ts +0 -0
  190. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/scanner.js +0 -0
  191. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/scanner.js.map +0 -0
  192. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/textures/artifacts.d.ts +0 -0
  193. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/textures/artifacts.js +0 -0
  194. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/textures/artifacts.js.map +0 -0
  195. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/textures/face-map.d.ts +0 -0
  196. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/textures/face-map.js +0 -0
  197. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/r6/textures/face-map.js.map +0 -0
  198. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/templates/humanoid_r15.json +0 -0
  199. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/templates/humanoid_r6.json +0 -0
  200. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/humanoid/templates/index.js +0 -0
  201. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/index.d.ts +0 -0
  202. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/index.js +0 -0
  203. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/index.js.map +0 -0
  204. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/materials.d.ts +0 -0
  205. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/materials.js +0 -0
  206. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/materials.js.map +0 -0
  207. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/palette_tools.js +0 -0
  208. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/textures.js +0 -0
  209. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/textured-boxes/infer-face.js +0 -0
  210. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/textured-boxes/merge-overlay.js +0 -0
  211. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/voxels/slice.js +0 -0
  212. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/voxels/textured-to-voxel.d.ts +0 -0
  213. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/voxels/textured-to-voxel.js +0 -0
  214. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/transforms/voxels/textured-to-voxel.js.map +0 -0
  215. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/types.js +0 -0
  216. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/types.js.map +0 -0
  217. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/voxels/greedy-mesher.d.ts +0 -0
  218. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/voxels/greedy-mesher.js +0 -0
  219. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/voxels/greedy-mesher.js.map +0 -0
  220. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/voxels.d.ts +0 -0
  221. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/voxels.js +0 -0
  222. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/src/voxels.js.map +0 -0
  223. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/entity-utils.test.d.ts +0 -0
  224. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/entity-utils.test.js +0 -0
  225. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/greedy-mesher.test.d.ts +0 -0
  226. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/greedy-mesher.test.js +0 -0
  227. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/greedy-mesher.test.js.map +0 -0
  228. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/humanoid/humanoid-builders.test.d.ts +0 -0
  229. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/humanoid/humanoid-builders.test.js +0 -0
  230. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/humanoid/humanoid-builders.test.js.map +0 -0
  231. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/index.test.d.ts +0 -0
  232. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/layer-mode.test.d.ts +0 -0
  233. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/layer-mode.test.js +0 -0
  234. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/materials.test.d.ts +0 -0
  235. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/materials.test.js +0 -0
  236. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/materials.test.js.map +0 -0
  237. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/palette-tools.test.d.ts +0 -0
  238. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/palette-tools.test.js +0 -0
  239. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/serialization.test.d.ts +0 -0
  240. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/textures.test.d.ts +0 -0
  241. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/textures.test.js +0 -0
  242. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/types.test.d.ts +0 -0
  243. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/upscale.test.d.ts +0 -0
  244. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/upscale.test.js +0 -0
  245. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/validation.test.d.ts +0 -0
  246. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/voxels.test.d.ts +0 -0
  247. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/voxels.test.js +0 -0
  248. /package/node_modules/@playdrop/{entity-core → boxel-core}/dist/test/voxels.test.js.map +0 -0
  249. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/context.js +0 -0
  250. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/nodes.js +0 -0
  251. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/primitives.d.ts +0 -0
  252. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/primitives.js +0 -0
  253. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/skinned-mesh.js +0 -0
  254. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/texture-atlas.d.ts +0 -0
  255. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/texture-atlas.js +0 -0
  256. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/types.js +0 -0
  257. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/src/voxels/faces.js +0 -0
  258. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/export-image.playwright.test.d.ts +0 -0
  259. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/glb-skinned.test.d.ts +0 -0
  260. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/index.test.d.ts +0 -0
  261. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/instantiate.test.d.ts +0 -0
  262. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/overlays.test.d.ts +0 -0
  263. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/scene-filter.test.d.ts +0 -0
  264. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/scene-smoke.test.d.ts +0 -0
  265. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/skinned-mesh.test.d.ts +0 -0
  266. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/textured-overlay.test.d.ts +0 -0
  267. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/voxels.test.d.ts +0 -0
  268. /package/node_modules/@playdrop/{entity-three → boxel-three}/dist/test/voxels.test.js +0 -0
package/dist/catalogue.js CHANGED
@@ -13,6 +13,12 @@ const catalogue_utils_1 = require("./catalogue-utils");
13
13
  const HEX_COLOR_REGEX = /^#?(?:[0-9a-fA-F]{6})$/;
14
14
  const SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
15
15
  const ASSET_CATEGORY_SET = new Set(types_1.ASSET_CATEGORY_VALUES);
16
+ const LISTING_IMAGE_EXTENSIONS = new Set(['.png']);
17
+ const LISTING_VIDEO_EXTENSIONS = new Set(['.mp4']);
18
+ const BOXEL_GENERATED_FILE_ROLES = new Set(['mesh', 'preview']);
19
+ const BOXEL_REQUIRED_FILE_ROLES = ['primary', 'mesh', 'preview'];
20
+ const VOX_GENERATED_FILE_ROLES = new Set(['boxel', 'mesh', 'preview']);
21
+ const VOX_REQUIRED_FILE_ROLES = ['primary', 'boxel', 'mesh', 'preview'];
16
22
  const ASSET_SUBCATEGORY_SET_BY_CATEGORY = types_1.ASSET_SUBCATEGORY_DEFINITIONS.reduce((acc, definition) => {
17
23
  if (!acc[definition.category]) {
18
24
  acc[definition.category] = new Set();
@@ -20,6 +26,38 @@ const ASSET_SUBCATEGORY_SET_BY_CATEGORY = types_1.ASSET_SUBCATEGORY_DEFINITIONS.
20
26
  acc[definition.category].add(definition.subcategory);
21
27
  return acc;
22
28
  }, {});
29
+ function normalizeFileRole(role) {
30
+ return role.trim().toLowerCase();
31
+ }
32
+ function inferGeneratedModel3DFormat(category, subcategory, format, files) {
33
+ if (category !== 'MODEL_3D' || !(0, types_1.isModel3DAssetSubcategory)('MODEL_3D', subcategory)) {
34
+ return null;
35
+ }
36
+ const normalizedFormat = typeof format === 'string' ? format.trim().toUpperCase() : '';
37
+ if (normalizedFormat === 'PLAYDROP_BOXEL_JSON' || normalizedFormat === 'VOX') {
38
+ return normalizedFormat;
39
+ }
40
+ const primary = typeof files?.primary === 'string' ? files.primary.trim().toLowerCase() : '';
41
+ if (primary.endsWith('.boxel.json')) {
42
+ return 'PLAYDROP_BOXEL_JSON';
43
+ }
44
+ if (primary.endsWith('.vox')) {
45
+ return 'VOX';
46
+ }
47
+ return null;
48
+ }
49
+ function getGeneratedModel3DFileRoles(format) {
50
+ if (format === 'VOX') {
51
+ return {
52
+ generated: VOX_GENERATED_FILE_ROLES,
53
+ required: VOX_REQUIRED_FILE_ROLES,
54
+ };
55
+ }
56
+ return {
57
+ generated: BOXEL_GENERATED_FILE_ROLES,
58
+ required: BOXEL_REQUIRED_FILE_ROLES,
59
+ };
60
+ }
23
61
  /**
24
62
  * Validates a listing asset path:
25
63
  * - Must exist
@@ -57,6 +95,16 @@ function validateListingAssetPath(baseDir, relativePath, fieldName) {
57
95
  }
58
96
  return undefined;
59
97
  }
98
+ function validateListingAssetExtension(relativePath, fieldName, kind) {
99
+ const extension = (0, node_path_1.extname)(relativePath).toLowerCase();
100
+ if (kind === 'image' && !LISTING_IMAGE_EXTENSIONS.has(extension)) {
101
+ return `${fieldName} must use a .png file. Received "${relativePath}".`;
102
+ }
103
+ if (kind === 'video' && !LISTING_VIDEO_EXTENSIONS.has(extension)) {
104
+ return `${fieldName} must use a .mp4 file. Received "${relativePath}".`;
105
+ }
106
+ return undefined;
107
+ }
60
108
  /**
61
109
  * Resolves a listing asset path after validation.
62
110
  */
@@ -592,60 +640,98 @@ function buildAppTasks(rootDir, catalogues, options) {
592
640
  };
593
641
  // Icon
594
642
  if (typeof rawListing.icon === 'string' && rawListing.icon.trim()) {
595
- const validationError = validateListingAssetPath(file.directory, rawListing.icon.trim(), 'listing.icon');
596
- if (validationError) {
597
- errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
643
+ const iconPath = rawListing.icon.trim();
644
+ const extensionError = validateListingAssetExtension(iconPath, 'listing.icon', 'image');
645
+ if (extensionError) {
646
+ errors.push(`[${label}] Skipping ${rawName}: ${extensionError}`);
598
647
  listingValidationFailed = true;
599
648
  }
600
649
  else {
601
- resolvedListing.iconPath = resolveListingAssetPath(file.directory, rawListing.icon.trim());
650
+ const validationError = validateListingAssetPath(file.directory, iconPath, 'listing.icon');
651
+ if (validationError) {
652
+ errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
653
+ listingValidationFailed = true;
654
+ }
655
+ else {
656
+ resolvedListing.iconPath = resolveListingAssetPath(file.directory, iconPath);
657
+ }
602
658
  }
603
659
  }
604
660
  // Hero images
605
661
  if (!listingValidationFailed && typeof rawListing.heroPortrait === 'string' && rawListing.heroPortrait.trim()) {
606
- const validationError = validateListingAssetPath(file.directory, rawListing.heroPortrait.trim(), 'listing.heroPortrait');
607
- if (validationError) {
608
- errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
662
+ const heroPortraitPath = rawListing.heroPortrait.trim();
663
+ const extensionError = validateListingAssetExtension(heroPortraitPath, 'listing.heroPortrait', 'image');
664
+ if (extensionError) {
665
+ errors.push(`[${label}] Skipping ${rawName}: ${extensionError}`);
609
666
  listingValidationFailed = true;
610
667
  }
611
668
  else {
612
- resolvedListing.heroPortraitPath = resolveListingAssetPath(file.directory, rawListing.heroPortrait.trim());
669
+ const validationError = validateListingAssetPath(file.directory, heroPortraitPath, 'listing.heroPortrait');
670
+ if (validationError) {
671
+ errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
672
+ listingValidationFailed = true;
673
+ }
674
+ else {
675
+ resolvedListing.heroPortraitPath = resolveListingAssetPath(file.directory, heroPortraitPath);
676
+ }
613
677
  }
614
678
  }
615
679
  if (!listingValidationFailed && typeof rawListing.heroLandscape === 'string' && rawListing.heroLandscape.trim()) {
616
- const validationError = validateListingAssetPath(file.directory, rawListing.heroLandscape.trim(), 'listing.heroLandscape');
617
- if (validationError) {
618
- errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
680
+ const heroLandscapePath = rawListing.heroLandscape.trim();
681
+ const extensionError = validateListingAssetExtension(heroLandscapePath, 'listing.heroLandscape', 'image');
682
+ if (extensionError) {
683
+ errors.push(`[${label}] Skipping ${rawName}: ${extensionError}`);
619
684
  listingValidationFailed = true;
620
685
  }
621
686
  else {
622
- resolvedListing.heroLandscapePath = resolveListingAssetPath(file.directory, rawListing.heroLandscape.trim());
687
+ const validationError = validateListingAssetPath(file.directory, heroLandscapePath, 'listing.heroLandscape');
688
+ if (validationError) {
689
+ errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
690
+ listingValidationFailed = true;
691
+ }
692
+ else {
693
+ resolvedListing.heroLandscapePath = resolveListingAssetPath(file.directory, heroLandscapePath);
694
+ }
623
695
  }
624
696
  }
625
697
  // Screenshots
626
698
  if (!listingValidationFailed && Array.isArray(rawListing.screenshotsPortrait)) {
627
699
  for (const p of rawListing.screenshotsPortrait) {
628
700
  if (typeof p === 'string' && p.trim()) {
629
- const validationError = validateListingAssetPath(file.directory, p.trim(), 'listing.screenshotsPortrait item');
701
+ const screenshotPath = p.trim();
702
+ const extensionError = validateListingAssetExtension(screenshotPath, 'listing.screenshotsPortrait item', 'image');
703
+ if (extensionError) {
704
+ errors.push(`[${label}] Skipping ${rawName}: ${extensionError}`);
705
+ listingValidationFailed = true;
706
+ break;
707
+ }
708
+ const validationError = validateListingAssetPath(file.directory, screenshotPath, 'listing.screenshotsPortrait item');
630
709
  if (validationError) {
631
710
  errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
632
711
  listingValidationFailed = true;
633
712
  break;
634
713
  }
635
- resolvedListing.screenshotPortraitPaths.push(resolveListingAssetPath(file.directory, p.trim()));
714
+ resolvedListing.screenshotPortraitPaths.push(resolveListingAssetPath(file.directory, screenshotPath));
636
715
  }
637
716
  }
638
717
  }
639
718
  if (!listingValidationFailed && Array.isArray(rawListing.screenshotsLandscape)) {
640
719
  for (const p of rawListing.screenshotsLandscape) {
641
720
  if (typeof p === 'string' && p.trim()) {
642
- const validationError = validateListingAssetPath(file.directory, p.trim(), 'listing.screenshotsLandscape item');
721
+ const screenshotPath = p.trim();
722
+ const extensionError = validateListingAssetExtension(screenshotPath, 'listing.screenshotsLandscape item', 'image');
723
+ if (extensionError) {
724
+ errors.push(`[${label}] Skipping ${rawName}: ${extensionError}`);
725
+ listingValidationFailed = true;
726
+ break;
727
+ }
728
+ const validationError = validateListingAssetPath(file.directory, screenshotPath, 'listing.screenshotsLandscape item');
643
729
  if (validationError) {
644
730
  errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
645
731
  listingValidationFailed = true;
646
732
  break;
647
733
  }
648
- resolvedListing.screenshotLandscapePaths.push(resolveListingAssetPath(file.directory, p.trim()));
734
+ resolvedListing.screenshotLandscapePaths.push(resolveListingAssetPath(file.directory, screenshotPath));
649
735
  }
650
736
  }
651
737
  }
@@ -653,26 +739,40 @@ function buildAppTasks(rootDir, catalogues, options) {
653
739
  if (!listingValidationFailed && Array.isArray(rawListing.videosPortrait)) {
654
740
  for (const p of rawListing.videosPortrait) {
655
741
  if (typeof p === 'string' && p.trim()) {
656
- const validationError = validateListingAssetPath(file.directory, p.trim(), 'listing.videosPortrait item');
742
+ const videoPath = p.trim();
743
+ const extensionError = validateListingAssetExtension(videoPath, 'listing.videosPortrait item', 'video');
744
+ if (extensionError) {
745
+ errors.push(`[${label}] Skipping ${rawName}: ${extensionError}`);
746
+ listingValidationFailed = true;
747
+ break;
748
+ }
749
+ const validationError = validateListingAssetPath(file.directory, videoPath, 'listing.videosPortrait item');
657
750
  if (validationError) {
658
751
  errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
659
752
  listingValidationFailed = true;
660
753
  break;
661
754
  }
662
- resolvedListing.videoPortraitPaths.push(resolveListingAssetPath(file.directory, p.trim()));
755
+ resolvedListing.videoPortraitPaths.push(resolveListingAssetPath(file.directory, videoPath));
663
756
  }
664
757
  }
665
758
  }
666
759
  if (!listingValidationFailed && Array.isArray(rawListing.videosLandscape)) {
667
760
  for (const p of rawListing.videosLandscape) {
668
761
  if (typeof p === 'string' && p.trim()) {
669
- const validationError = validateListingAssetPath(file.directory, p.trim(), 'listing.videosLandscape item');
762
+ const videoPath = p.trim();
763
+ const extensionError = validateListingAssetExtension(videoPath, 'listing.videosLandscape item', 'video');
764
+ if (extensionError) {
765
+ errors.push(`[${label}] Skipping ${rawName}: ${extensionError}`);
766
+ listingValidationFailed = true;
767
+ break;
768
+ }
769
+ const validationError = validateListingAssetPath(file.directory, videoPath, 'listing.videosLandscape item');
670
770
  if (validationError) {
671
771
  errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
672
772
  listingValidationFailed = true;
673
773
  break;
674
774
  }
675
- resolvedListing.videoLandscapePaths.push(resolveListingAssetPath(file.directory, p.trim()));
775
+ resolvedListing.videoLandscapePaths.push(resolveListingAssetPath(file.directory, videoPath));
676
776
  }
677
777
  }
678
778
  }
@@ -724,6 +824,11 @@ function buildAppTasks(rootDir, catalogues, options) {
724
824
  const fileEntries = embedded?.files && typeof embedded.files === 'object' && !Array.isArray(embedded.files)
725
825
  ? embedded.files
726
826
  : null;
827
+ const embeddedFormat = typeof embedded?.format === 'string' && embedded.format.trim().length > 0
828
+ ? embedded.format.trim().toUpperCase()
829
+ : undefined;
830
+ const generatedModel3DFormat = inferGeneratedModel3DFormat(category, subcategory, embeddedFormat, fileEntries);
831
+ const generatedModel3DRoles = generatedModel3DFormat ? getGeneratedModel3DFileRoles(generatedModel3DFormat) : null;
727
832
  if (!fileEntries || Object.keys(fileEntries).length === 0) {
728
833
  errors.push(`[${label}] Skipping ${rawName}: embedded asset "${embeddedName}" must define files.`);
729
834
  continue;
@@ -739,7 +844,14 @@ function buildAppTasks(rootDir, catalogues, options) {
739
844
  }
740
845
  const relativeEmbeddedPath = fileValue.trim();
741
846
  const absoluteEmbeddedPath = (0, node_path_1.resolve)(file.directory, relativeEmbeddedPath);
847
+ const normalizedRole = normalizeFileRole(role);
848
+ const allowMissingGenerated = Boolean(generatedModel3DRoles?.generated.has(normalizedRole));
742
849
  if (!(0, node_fs_1.existsSync)(absoluteEmbeddedPath) || !(0, node_fs_1.statSync)(absoluteEmbeddedPath).isFile()) {
850
+ if (allowMissingGenerated) {
851
+ files[role] = relativeEmbeddedPath.replace(/\\/g, '/');
852
+ filePaths[role] = absoluteEmbeddedPath;
853
+ continue;
854
+ }
743
855
  errors.push(`[${label}] Skipping ${rawName}: embedded asset "${embeddedName}" file not found at ${absoluteEmbeddedPath}.`);
744
856
  embeddedHasError = true;
745
857
  continue;
@@ -750,6 +862,14 @@ function buildAppTasks(rootDir, catalogues, options) {
750
862
  if (embeddedHasError) {
751
863
  continue;
752
864
  }
865
+ if (generatedModel3DRoles) {
866
+ const normalizedRoles = new Set(Object.keys(files).map((role) => normalizeFileRole(role)));
867
+ const missingRoles = generatedModel3DRoles.required.filter((role) => !normalizedRoles.has(role));
868
+ if (missingRoles.length > 0) {
869
+ errors.push(`[${label}] Skipping ${rawName}: embedded asset "${embeddedName}" with subcategory=${subcategory} must define files.${missingRoles.join(' and files.')}.`);
870
+ continue;
871
+ }
872
+ }
753
873
  if (category === 'SPRITESHEET') {
754
874
  const hasAtlas = Object.prototype.hasOwnProperty.call(files, 'atlas');
755
875
  const hasManifest = Object.prototype.hasOwnProperty.call(files, 'manifest');
@@ -772,10 +892,10 @@ function buildAppTasks(rootDir, catalogues, options) {
772
892
  cataloguePath: label,
773
893
  category,
774
894
  subcategory,
775
- format: typeof embedded?.format === 'string' && embedded.format.trim().length > 0 ? embedded.format.trim().toUpperCase() : undefined,
895
+ format: embeddedFormat,
776
896
  visibility: normalizeAssetVisibilityValue(embedded?.visibility, errors, `${label} embedded asset \"${embeddedName}\"`),
777
897
  shopListed: typeof embedded?.shopListed === 'boolean' ? embedded.shopListed : undefined,
778
- shopPriceCoins: Number.isInteger(embedded?.shopPriceCoins) ? Number(embedded.shopPriceCoins) : undefined,
898
+ shopPriceCredits: Number.isInteger(embedded?.shopPriceCredits) ? Number(embedded.shopPriceCredits) : undefined,
779
899
  files,
780
900
  filePaths,
781
901
  });
@@ -863,9 +983,12 @@ function buildAssetTasks(catalogues) {
863
983
  if (!subcategory) {
864
984
  continue;
865
985
  }
986
+ const format = typeof entry.format === 'string' && entry.format.trim().length > 0 ? entry.format.trim().toUpperCase() : undefined;
866
987
  const fileEntries = entry.files && typeof entry.files === 'object' && !Array.isArray(entry.files)
867
988
  ? entry.files
868
989
  : null;
990
+ const generatedModel3DFormat = inferGeneratedModel3DFormat(category, subcategory, format, fileEntries);
991
+ const generatedModel3DRoles = generatedModel3DFormat ? getGeneratedModel3DFileRoles(generatedModel3DFormat) : null;
869
992
  if (!fileEntries || Object.keys(fileEntries).length === 0) {
870
993
  errors.push(`[${label}] Asset "${name}" must define files.`);
871
994
  continue;
@@ -881,7 +1004,14 @@ function buildAssetTasks(catalogues) {
881
1004
  }
882
1005
  const relativePath = value.trim();
883
1006
  const absolutePath = (0, node_path_1.resolve)(file.directory, relativePath);
1007
+ const normalizedRole = normalizeFileRole(role);
1008
+ const allowMissingGenerated = Boolean(generatedModel3DRoles?.generated.has(normalizedRole));
884
1009
  if (!(0, node_fs_1.existsSync)(absolutePath) || !(0, node_fs_1.statSync)(absolutePath).isFile()) {
1010
+ if (allowMissingGenerated) {
1011
+ files[role] = relativePath.replace(/\\/g, '/');
1012
+ filePaths[role] = absolutePath;
1013
+ continue;
1014
+ }
885
1015
  errors.push(`[${label}] Asset "${name}" file not found at ${absolutePath}.`);
886
1016
  hasError = true;
887
1017
  continue;
@@ -892,6 +1022,14 @@ function buildAssetTasks(catalogues) {
892
1022
  if (hasError) {
893
1023
  continue;
894
1024
  }
1025
+ if (generatedModel3DRoles) {
1026
+ const normalizedRoles = new Set(Object.keys(files).map((role) => normalizeFileRole(role)));
1027
+ const missingRoles = generatedModel3DRoles.required.filter((role) => !normalizedRoles.has(role));
1028
+ if (missingRoles.length > 0) {
1029
+ errors.push(`[${label}] Asset "${name}" with subcategory=${subcategory} must define files.${missingRoles.join(' and files.')}.`);
1030
+ continue;
1031
+ }
1032
+ }
895
1033
  if (category === 'SPRITESHEET') {
896
1034
  const hasAtlas = Object.prototype.hasOwnProperty.call(files, 'atlas');
897
1035
  const hasManifest = Object.prototype.hasOwnProperty.call(files, 'manifest');
@@ -927,10 +1065,10 @@ function buildAssetTasks(catalogues) {
927
1065
  category,
928
1066
  subcategory,
929
1067
  username,
930
- format: typeof entry.format === 'string' && entry.format.trim().length > 0 ? entry.format.trim().toUpperCase() : undefined,
1068
+ format,
931
1069
  visibility: normalizeAssetVisibilityValue(entry.visibility, errors, `${label} asset \"${name}\"`),
932
1070
  shopListed: typeof entry.shopListed === 'boolean' ? entry.shopListed : undefined,
933
- shopPriceCoins: Number.isInteger(entry.shopPriceCoins) ? Number(entry.shopPriceCoins) : undefined,
1071
+ shopPriceCredits: Number.isInteger(entry.shopPriceCredits) ? Number(entry.shopPriceCredits) : undefined,
934
1072
  files,
935
1073
  filePaths,
936
1074
  relations,
@@ -1006,84 +1144,136 @@ function buildAssetPackTasks(catalogues) {
1006
1144
  videoLandscapePaths: [],
1007
1145
  };
1008
1146
  if (typeof rawListing.icon === 'string' && rawListing.icon.trim()) {
1009
- const validationError = validateListingAssetPath(file.directory, rawListing.icon.trim(), 'assetPacks.listing.icon');
1010
- if (validationError) {
1011
- errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1147
+ const iconPath = rawListing.icon.trim();
1148
+ const extensionError = validateListingAssetExtension(iconPath, 'assetPacks.listing.icon', 'image');
1149
+ if (extensionError) {
1150
+ errors.push(`[${label}] Skipping asset pack "${name}": ${extensionError}`);
1012
1151
  listingValidationFailed = true;
1013
1152
  }
1014
1153
  else {
1015
- resolvedListing.iconPath = resolveListingAssetPath(file.directory, rawListing.icon.trim());
1154
+ const validationError = validateListingAssetPath(file.directory, iconPath, 'assetPacks.listing.icon');
1155
+ if (validationError) {
1156
+ errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1157
+ listingValidationFailed = true;
1158
+ }
1159
+ else {
1160
+ resolvedListing.iconPath = resolveListingAssetPath(file.directory, iconPath);
1161
+ }
1016
1162
  }
1017
1163
  }
1018
1164
  if (!listingValidationFailed && typeof rawListing.heroPortrait === 'string' && rawListing.heroPortrait.trim()) {
1019
- const validationError = validateListingAssetPath(file.directory, rawListing.heroPortrait.trim(), 'assetPacks.listing.heroPortrait');
1020
- if (validationError) {
1021
- errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1165
+ const heroPortraitPath = rawListing.heroPortrait.trim();
1166
+ const extensionError = validateListingAssetExtension(heroPortraitPath, 'assetPacks.listing.heroPortrait', 'image');
1167
+ if (extensionError) {
1168
+ errors.push(`[${label}] Skipping asset pack "${name}": ${extensionError}`);
1022
1169
  listingValidationFailed = true;
1023
1170
  }
1024
1171
  else {
1025
- resolvedListing.heroPortraitPath = resolveListingAssetPath(file.directory, rawListing.heroPortrait.trim());
1172
+ const validationError = validateListingAssetPath(file.directory, heroPortraitPath, 'assetPacks.listing.heroPortrait');
1173
+ if (validationError) {
1174
+ errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1175
+ listingValidationFailed = true;
1176
+ }
1177
+ else {
1178
+ resolvedListing.heroPortraitPath = resolveListingAssetPath(file.directory, heroPortraitPath);
1179
+ }
1026
1180
  }
1027
1181
  }
1028
1182
  if (!listingValidationFailed && typeof rawListing.heroLandscape === 'string' && rawListing.heroLandscape.trim()) {
1029
- const validationError = validateListingAssetPath(file.directory, rawListing.heroLandscape.trim(), 'assetPacks.listing.heroLandscape');
1030
- if (validationError) {
1031
- errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1183
+ const heroLandscapePath = rawListing.heroLandscape.trim();
1184
+ const extensionError = validateListingAssetExtension(heroLandscapePath, 'assetPacks.listing.heroLandscape', 'image');
1185
+ if (extensionError) {
1186
+ errors.push(`[${label}] Skipping asset pack "${name}": ${extensionError}`);
1032
1187
  listingValidationFailed = true;
1033
1188
  }
1034
1189
  else {
1035
- resolvedListing.heroLandscapePath = resolveListingAssetPath(file.directory, rawListing.heroLandscape.trim());
1190
+ const validationError = validateListingAssetPath(file.directory, heroLandscapePath, 'assetPacks.listing.heroLandscape');
1191
+ if (validationError) {
1192
+ errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1193
+ listingValidationFailed = true;
1194
+ }
1195
+ else {
1196
+ resolvedListing.heroLandscapePath = resolveListingAssetPath(file.directory, heroLandscapePath);
1197
+ }
1036
1198
  }
1037
1199
  }
1038
1200
  if (!listingValidationFailed && Array.isArray(rawListing.screenshotsPortrait)) {
1039
1201
  for (const p of rawListing.screenshotsPortrait) {
1040
1202
  if (typeof p === 'string' && p.trim()) {
1041
- const validationError = validateListingAssetPath(file.directory, p.trim(), 'assetPacks.listing.screenshotsPortrait item');
1203
+ const screenshotPath = p.trim();
1204
+ const extensionError = validateListingAssetExtension(screenshotPath, 'assetPacks.listing.screenshotsPortrait item', 'image');
1205
+ if (extensionError) {
1206
+ errors.push(`[${label}] Skipping asset pack "${name}": ${extensionError}`);
1207
+ listingValidationFailed = true;
1208
+ break;
1209
+ }
1210
+ const validationError = validateListingAssetPath(file.directory, screenshotPath, 'assetPacks.listing.screenshotsPortrait item');
1042
1211
  if (validationError) {
1043
1212
  errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1044
1213
  listingValidationFailed = true;
1045
1214
  break;
1046
1215
  }
1047
- resolvedListing.screenshotPortraitPaths.push(resolveListingAssetPath(file.directory, p.trim()));
1216
+ resolvedListing.screenshotPortraitPaths.push(resolveListingAssetPath(file.directory, screenshotPath));
1048
1217
  }
1049
1218
  }
1050
1219
  }
1051
1220
  if (!listingValidationFailed && Array.isArray(rawListing.screenshotsLandscape)) {
1052
1221
  for (const p of rawListing.screenshotsLandscape) {
1053
1222
  if (typeof p === 'string' && p.trim()) {
1054
- const validationError = validateListingAssetPath(file.directory, p.trim(), 'assetPacks.listing.screenshotsLandscape item');
1223
+ const screenshotPath = p.trim();
1224
+ const extensionError = validateListingAssetExtension(screenshotPath, 'assetPacks.listing.screenshotsLandscape item', 'image');
1225
+ if (extensionError) {
1226
+ errors.push(`[${label}] Skipping asset pack "${name}": ${extensionError}`);
1227
+ listingValidationFailed = true;
1228
+ break;
1229
+ }
1230
+ const validationError = validateListingAssetPath(file.directory, screenshotPath, 'assetPacks.listing.screenshotsLandscape item');
1055
1231
  if (validationError) {
1056
1232
  errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1057
1233
  listingValidationFailed = true;
1058
1234
  break;
1059
1235
  }
1060
- resolvedListing.screenshotLandscapePaths.push(resolveListingAssetPath(file.directory, p.trim()));
1236
+ resolvedListing.screenshotLandscapePaths.push(resolveListingAssetPath(file.directory, screenshotPath));
1061
1237
  }
1062
1238
  }
1063
1239
  }
1064
1240
  if (!listingValidationFailed && Array.isArray(rawListing.videosPortrait)) {
1065
1241
  for (const p of rawListing.videosPortrait) {
1066
1242
  if (typeof p === 'string' && p.trim()) {
1067
- const validationError = validateListingAssetPath(file.directory, p.trim(), 'assetPacks.listing.videosPortrait item');
1243
+ const videoPath = p.trim();
1244
+ const extensionError = validateListingAssetExtension(videoPath, 'assetPacks.listing.videosPortrait item', 'video');
1245
+ if (extensionError) {
1246
+ errors.push(`[${label}] Skipping asset pack "${name}": ${extensionError}`);
1247
+ listingValidationFailed = true;
1248
+ break;
1249
+ }
1250
+ const validationError = validateListingAssetPath(file.directory, videoPath, 'assetPacks.listing.videosPortrait item');
1068
1251
  if (validationError) {
1069
1252
  errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1070
1253
  listingValidationFailed = true;
1071
1254
  break;
1072
1255
  }
1073
- resolvedListing.videoPortraitPaths.push(resolveListingAssetPath(file.directory, p.trim()));
1256
+ resolvedListing.videoPortraitPaths.push(resolveListingAssetPath(file.directory, videoPath));
1074
1257
  }
1075
1258
  }
1076
1259
  }
1077
1260
  if (!listingValidationFailed && Array.isArray(rawListing.videosLandscape)) {
1078
1261
  for (const p of rawListing.videosLandscape) {
1079
1262
  if (typeof p === 'string' && p.trim()) {
1080
- const validationError = validateListingAssetPath(file.directory, p.trim(), 'assetPacks.listing.videosLandscape item');
1263
+ const videoPath = p.trim();
1264
+ const extensionError = validateListingAssetExtension(videoPath, 'assetPacks.listing.videosLandscape item', 'video');
1265
+ if (extensionError) {
1266
+ errors.push(`[${label}] Skipping asset pack "${name}": ${extensionError}`);
1267
+ listingValidationFailed = true;
1268
+ break;
1269
+ }
1270
+ const validationError = validateListingAssetPath(file.directory, videoPath, 'assetPacks.listing.videosLandscape item');
1081
1271
  if (validationError) {
1082
1272
  errors.push(`[${label}] Skipping asset pack "${name}": ${validationError}`);
1083
1273
  listingValidationFailed = true;
1084
1274
  break;
1085
1275
  }
1086
- resolvedListing.videoLandscapePaths.push(resolveListingAssetPath(file.directory, p.trim()));
1276
+ resolvedListing.videoLandscapePaths.push(resolveListingAssetPath(file.directory, videoPath));
1087
1277
  }
1088
1278
  }
1089
1279
  }
@@ -5,6 +5,7 @@ const taskSelection_1 = require("../taskSelection");
5
5
  const taskUtils_1 = require("../taskUtils");
6
6
  const uploadLog_1 = require("../uploadLog");
7
7
  const apps_1 = require("../apps");
8
+ const model_artifacts_1 = require("../assets/model-artifacts");
8
9
  async function build(pathOrName) {
9
10
  const selection = (0, taskSelection_1.selectTasks)(pathOrName);
10
11
  if (selection.errors.length > 0) {
@@ -22,18 +23,30 @@ async function build(pathOrName) {
22
23
  for (const task of (0, taskUtils_1.sortTasks)(tasks)) {
23
24
  const entityId = task.name;
24
25
  try {
26
+ let skipped = false;
27
+ let detail;
25
28
  if (task.kind === 'app') {
26
29
  await (0, apps_1.validateAppTask)(task);
27
30
  await (0, apps_1.buildApp)(task);
28
31
  }
29
- const skipped = task.kind !== 'app';
32
+ else if (task.kind === 'asset' || task.kind === 'embedded-asset') {
33
+ const generated = await (0, model_artifacts_1.prepareModel3DAssetArtifacts)(task);
34
+ if (!generated) {
35
+ skipped = true;
36
+ detail = `no build step for ${task.kind}`;
37
+ }
38
+ }
39
+ else {
40
+ skipped = true;
41
+ detail = `no build step for ${task.kind}`;
42
+ }
30
43
  const entry = {
31
44
  action: 'build',
32
45
  status: skipped ? 'skipped' : 'success',
33
46
  entityType: task.kind,
34
47
  entityId,
35
48
  catalogue: task.cataloguePath,
36
- detail: skipped ? `no build step for ${task.kind}` : undefined,
49
+ detail,
37
50
  };
38
51
  results.push(entry);
39
52
  console.log((0, uploadLog_1.formatTaskLogLine)(entry));
@@ -260,8 +260,10 @@ async function dev(targetArg, _port, appOption) {
260
260
  });
261
261
  const webUrl = envConfig.webBase;
262
262
  const entryLabel = (0, node_path_1.relative)(process.cwd(), filePath) || filePath;
263
+ const runtimeRootLabel = (0, node_path_1.relative)(process.cwd(), (0, node_path_1.dirname)(filePath)) || (0, node_path_1.dirname)(filePath);
263
264
  console.log(`🚀 App dev server running at http://localhost:${portToUse}`);
264
265
  console.log(`Serving ${entryLabel}`);
266
+ console.log(`Static root ${runtimeRootLabel}`);
265
267
  if (projectInfo.projectDir && !devScriptAvailable && projectInfo.packageJsonPath) {
266
268
  const projectLabel = (0, devShared_1.formatProjectLabel)(projectInfo);
267
269
  if (projectLabel) {