@auraindustry/aurajs 0.0.6 → 0.1.0
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/README.md +103 -7
- package/benchmarks/perf-thresholds.json +54 -0
- package/package.json +4 -7
- package/src/asset-pack.mjs +5 -1
- package/src/authored-project.mjs +1449 -0
- package/src/authored-runtime.mjs +2016 -0
- package/src/authoring/avatar-animation-graph.mjs +648 -0
- package/src/bin-integrity.mjs +272 -0
- package/src/build-contract/assets.mjs +130 -0
- package/src/build-contract/capabilities.mjs +116 -0
- package/src/build-contract/constants.mjs +6 -0
- package/src/build-contract/helpers.mjs +44 -0
- package/src/build-contract/web-templates.mjs +5993 -0
- package/src/build-contract.mjs +27 -2910
- package/src/bundler.mjs +188 -55
- package/src/cli.mjs +4825 -1512
- package/src/commands/project-authoring.mjs +434 -0
- package/src/config.mjs +27 -0
- package/src/conformance/cases/app-and-ui-runtime-cases.mjs +3309 -0
- package/src/conformance/cases/core-runtime-cases.mjs +1431 -0
- package/src/conformance/cases/index.mjs +11 -0
- package/src/conformance/cases/scene3d-and-media-cases.mjs +2094 -0
- package/src/conformance/cases/systems-and-gameplay-cases.mjs +1776 -0
- package/src/conformance/shared.mjs +27 -0
- package/src/conformance-runner.mjs +25 -13
- package/src/conformance.mjs +619 -4020
- package/src/cutscene.mjs +362 -5
- package/src/dev-cli-action.mjs +249 -0
- package/src/dev-cli-inspect.mjs +92 -0
- package/src/dev-cli-state.mjs +80 -0
- package/src/external-asset-cache.mjs +587 -0
- package/src/external-asset-policy.mjs +217 -0
- package/src/external-package-surface.mjs +206 -0
- package/src/game-action-runtime.mjs +869 -0
- package/src/game-state-runtime.mjs +206 -6
- package/src/headless-action.mjs +186 -0
- package/src/headless-test/runtime-animation.mjs +1173 -0
- package/src/headless-test/runtime-coordinator.mjs +1514 -0
- package/src/headless-test/runtime-primitives.mjs +320 -0
- package/src/headless-test/runtime-world.mjs +2253 -0
- package/src/headless-test.mjs +392 -4298
- package/src/host-binary.mjs +342 -14
- package/src/icon-discovery.mjs +64 -0
- package/src/make-catalog.mjs +109 -0
- package/src/make.mjs +197 -0
- package/src/package-integrity.mjs +586 -0
- package/src/perf-benchmark.mjs +353 -0
- package/src/postinstall.mjs +5 -5
- package/src/prefabs/index.mjs +34 -0
- package/src/prefabs/scene-serialization.mjs +184 -0
- package/src/project-importer.mjs +620 -0
- package/src/project-registry.mjs +24 -0
- package/src/publish-command.mjs +195 -0
- package/src/publish-env-example.mjs +83 -0
- package/src/publish-validation.mjs +708 -0
- package/src/retro/assets/compile.mjs +232 -0
- package/src/retro/backend-gba/authoring.mjs +1029 -0
- package/src/retro/backend-gba/rom.mjs +363 -0
- package/src/retro/backend-gbc/rom.mjs +85 -0
- package/src/retro/build.mjs +278 -0
- package/src/retro/cli/commands.mjs +292 -0
- package/src/retro/cli/templates.mjs +84 -0
- package/src/retro/diagnostics/catalog.mjs +110 -0
- package/src/retro/diagnostics/emit.mjs +72 -0
- package/src/retro/emulator/case-overlay.mjs +64 -0
- package/src/retro/emulator/discovery.mjs +158 -0
- package/src/retro/emulator/macos-case-overlay.swift +220 -0
- package/src/retro/emulator/profiles.mjs +146 -0
- package/src/retro/emulator/runner.mjs +289 -0
- package/src/retro/frontend/load-project.mjs +98 -0
- package/src/retro/index.mjs +30 -0
- package/src/retro/ir/build-ir.mjs +108 -0
- package/src/retro/runtime-gba/contract.mjs +151 -0
- package/src/retro/runtime-gbc/contract.mjs +117 -0
- package/src/retro/shared/span.mjs +26 -0
- package/src/retro/shared/targets.mjs +64 -0
- package/src/retro/validator/check-project.mjs +114 -0
- package/src/runtime-hotspot-audit.mjs +707 -0
- package/src/scaffold/config.mjs +1000 -0
- package/src/scaffold/fs.mjs +56 -0
- package/src/scaffold/layout.mjs +318 -0
- package/src/scaffold/project-docs.mjs +438 -0
- package/src/scaffold.mjs +93 -596
- package/src/scene-composition/index.mjs +326 -0
- package/src/scene-composition/runtime.mjs +751 -0
- package/src/self-hosted-assets.mjs +604 -0
- package/src/session-client.mjs +750 -0
- package/src/session-native-launcher.mjs +74 -0
- package/src/session-protocol.mjs +75 -0
- package/src/session-runtime.mjs +321 -0
- package/src/session-server.mjs +360 -0
- package/src/shader-kits/index.mjs +773 -0
- package/src/starter-content-registry.mjs +292 -0
- package/src/state-artifacts.mjs +662 -24
- package/src/state-dev-reload.mjs +99 -2
- package/src/terminal-ui.mjs +245 -0
- package/src/web-conformance.mjs +219 -0
- package/templates/create/2d/config/gameplay/shooter.config.js +26 -0
- package/templates/create/2d/content/gameplay/waves.json +26 -0
- package/templates/create/2d/content/registries/.gitkeep +1 -0
- package/templates/create/2d/docs/design/.gitkeep +1 -0
- package/templates/create/2d/docs/design/loop.md +5 -0
- package/templates/create/2d/prefabs/enemies.prefab.js +90 -0
- package/templates/create/2d/prefabs/enemy-basic.prefab.js +18 -0
- package/templates/create/2d/prefabs/player.prefab.js +36 -0
- package/templates/create/2d/prefabs/projectiles.prefab.js +35 -0
- package/templates/create/2d/scenes/boot.scene.js +12 -0
- package/templates/create/2d/scenes/gameplay.scene.js +230 -0
- package/templates/create/2d/scenes/menu.scene.js +9 -0
- package/templates/create/2d/src/main.js +6 -185
- package/templates/create/2d/src/runtime/app.js +49 -0
- package/templates/create/2d/src/runtime/capabilities.js +35 -0
- package/templates/create/2d/ui/hud.screen.js +40 -0
- package/templates/create/2d/ui/pause.screen.js +149 -0
- package/templates/create/2d/ui/settings.screen.js +347 -0
- package/templates/create/2d/ui/title.screen.js +13 -0
- package/templates/create/2d-adventure/aura.config.json +28 -0
- package/templates/create/2d-adventure/config/gameplay/adventure.config.js +14 -0
- package/templates/create/2d-adventure/content/gameplay/world.js +46 -0
- package/templates/create/2d-adventure/content/registries/.gitkeep +1 -0
- package/templates/create/2d-adventure/docs/design/loop.md +5 -0
- package/templates/create/2d-adventure/prefabs/player.prefab.js +54 -0
- package/templates/create/2d-adventure/prefabs/relic.prefab.js +38 -0
- package/templates/create/2d-adventure/prefabs/world.prefab.js +125 -0
- package/templates/create/2d-adventure/scenes/gameplay.scene.js +256 -0
- package/templates/create/2d-adventure/src/runtime/capabilities.js +34 -0
- package/templates/create/2d-adventure/ui/hud.screen.js +60 -0
- package/templates/create/2d-survivor/config/gameplay/survivor.config.js +33 -0
- package/templates/create/2d-survivor/content/gameplay/spawn-zones.json +29 -0
- package/templates/create/2d-survivor/content/registries/.gitkeep +1 -0
- package/templates/create/2d-survivor/docs/design/.gitkeep +1 -0
- package/templates/create/2d-survivor/docs/design/loop.md +5 -0
- package/templates/create/2d-survivor/prefabs/enemies.prefab.js +178 -0
- package/templates/create/2d-survivor/prefabs/enemy-swarm.prefab.js +18 -0
- package/templates/create/2d-survivor/prefabs/player.prefab.js +42 -0
- package/templates/create/2d-survivor/prefabs/projectiles.prefab.js +56 -0
- package/templates/create/2d-survivor/scenes/boot.scene.js +12 -0
- package/templates/create/2d-survivor/scenes/gameplay.scene.js +314 -0
- package/templates/create/2d-survivor/scenes/menu.scene.js +9 -0
- package/templates/create/2d-survivor/src/main.js +5 -332
- package/templates/create/2d-survivor/src/runtime/app.js +49 -0
- package/templates/create/2d-survivor/src/runtime/capabilities.js +35 -0
- package/templates/create/2d-survivor/ui/hud.screen.js +45 -0
- package/templates/create/2d-survivor/ui/title.screen.js +13 -0
- package/templates/create/3d/assets/models/starter-avatar.gltf +184 -0
- package/templates/create/3d/config/gameplay/.gitkeep +1 -0
- package/templates/create/3d/content/gameplay/checkpoints.json +33 -0
- package/templates/create/3d/content/gameplay/course.js +40 -0
- package/templates/create/3d/content/registries/.gitkeep +1 -0
- package/templates/create/3d/docs/design/.gitkeep +1 -0
- package/templates/create/3d/docs/design/loop.md +5 -0
- package/templates/create/3d/prefabs/checkpoint.prefab.js +15 -0
- package/templates/create/3d/prefabs/player.prefab.js +204 -0
- package/templates/create/3d/prefabs/world.prefab.js +112 -0
- package/templates/create/3d/scenes/boot.scene.js +12 -0
- package/templates/create/3d/scenes/checkpoint.scene.js +9 -0
- package/templates/create/3d/scenes/gameplay.scene.js +292 -0
- package/templates/create/3d/src/main.js +6 -295
- package/templates/create/3d/src/runtime/app.js +49 -0
- package/templates/create/3d/src/runtime/capabilities.js +53 -0
- package/templates/create/3d/src/runtime/materials.js +34 -0
- package/templates/create/3d/src/runtime/state.js +39 -0
- package/templates/create/3d/ui/hud.screen.js +75 -0
- package/templates/create/3d/ui/pause.screen.js +166 -0
- package/templates/create/3d/ui/settings.screen.js +387 -0
- package/templates/create/3d-adventure/assets/models/starter-avatar.gltf +184 -0
- package/templates/create/3d-adventure/aura.config.json +28 -0
- package/templates/create/3d-adventure/config/gameplay/adventure.config.js +9 -0
- package/templates/create/3d-adventure/content/gameplay/course.js +62 -0
- package/templates/create/3d-adventure/content/registries/.gitkeep +1 -0
- package/templates/create/3d-adventure/docs/design/loop.md +5 -0
- package/templates/create/3d-adventure/prefabs/player.prefab.js +168 -0
- package/templates/create/3d-adventure/prefabs/relic.prefab.js +35 -0
- package/templates/create/3d-adventure/prefabs/world.prefab.js +119 -0
- package/templates/create/3d-adventure/scenes/gameplay.scene.js +358 -0
- package/templates/create/3d-adventure/src/runtime/capabilities.js +56 -0
- package/templates/create/3d-adventure/src/runtime/materials.js +39 -0
- package/templates/create/3d-adventure/src/runtime/state.js +31 -0
- package/templates/create/3d-adventure/ui/hud.screen.js +70 -0
- package/templates/create/3d-adventure/ui/pause.screen.js +437 -0
- package/templates/create/3d-collectathon/assets/models/starter-avatar.gltf +184 -0
- package/templates/create/3d-collectathon/config/gameplay/.gitkeep +1 -0
- package/templates/create/3d-collectathon/content/gameplay/collectibles.json +26 -0
- package/templates/create/3d-collectathon/content/gameplay/course.js +46 -0
- package/templates/create/3d-collectathon/content/registries/.gitkeep +1 -0
- package/templates/create/3d-collectathon/docs/design/.gitkeep +1 -0
- package/templates/create/3d-collectathon/docs/design/loop.md +5 -0
- package/templates/create/3d-collectathon/prefabs/collectible.prefab.js +15 -0
- package/templates/create/3d-collectathon/prefabs/player.prefab.js +207 -0
- package/templates/create/3d-collectathon/prefabs/world.prefab.js +112 -0
- package/templates/create/3d-collectathon/scenes/boot.scene.js +12 -0
- package/templates/create/3d-collectathon/scenes/checkpoint.scene.js +9 -0
- package/templates/create/3d-collectathon/scenes/gameplay.scene.js +200 -0
- package/templates/create/3d-collectathon/src/main.js +5 -355
- package/templates/create/3d-collectathon/src/runtime/app.js +49 -0
- package/templates/create/3d-collectathon/src/runtime/capabilities.js +53 -0
- package/templates/create/3d-collectathon/src/runtime/materials.js +34 -0
- package/templates/create/3d-collectathon/src/runtime/state.js +27 -0
- package/templates/create/3d-collectathon/ui/hud.screen.js +66 -0
- package/templates/create/3d-collectathon/ui/pause.screen.js +13 -0
- package/templates/create/blank/config/gameplay/.gitkeep +1 -0
- package/templates/create/blank/content/gameplay/.gitkeep +1 -0
- package/templates/create/blank/content/registries/.gitkeep +1 -0
- package/templates/create/blank/docs/design/.gitkeep +1 -0
- package/templates/create/blank/docs/design/loop.md +5 -0
- package/templates/create/blank/prefabs/.gitkeep +1 -0
- package/templates/create/blank/scenes/.gitkeep +1 -0
- package/templates/create/blank/src/runtime/.gitkeep +1 -0
- package/templates/create/blank/ui/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/assets/audio/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/assets/fonts/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/assets/sprites/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/assets/starter/README.md +11 -0
- package/templates/create/deckbuilder-2d/assets/ui/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/aura.config.json +28 -0
- package/templates/create/deckbuilder-2d/config/gameplay/deckbuilder.config.js +26 -0
- package/templates/create/deckbuilder-2d/content/cards/guard.card.js +19 -0
- package/templates/create/deckbuilder-2d/content/cards/spark.card.js +20 -0
- package/templates/create/deckbuilder-2d/content/cards/starter.deck.js +69 -0
- package/templates/create/deckbuilder-2d/content/cards/strike.card.js +19 -0
- package/templates/create/deckbuilder-2d/content/cards/survey.card.js +20 -0
- package/templates/create/deckbuilder-2d/content/encounters/training-battle.encounter.js +14 -0
- package/templates/create/deckbuilder-2d/content/encounters/training-battle.js +65 -0
- package/templates/create/deckbuilder-2d/content/enemies/training-automaton.enemy.js +48 -0
- package/templates/create/deckbuilder-2d/content/gameplay/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/content/registries/cards.registry.js +26 -0
- package/templates/create/deckbuilder-2d/content/registries/encounters.registry.js +20 -0
- package/templates/create/deckbuilder-2d/content/registries/enemies.registry.js +20 -0
- package/templates/create/deckbuilder-2d/content/registries/relics.registry.js +20 -0
- package/templates/create/deckbuilder-2d/content/relics/ember-charm.relic.js +18 -0
- package/templates/create/deckbuilder-2d/docs/design/loop.md +12 -0
- package/templates/create/deckbuilder-2d/prefabs/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/scenes/boot.scene.js +84 -0
- package/templates/create/deckbuilder-2d/scenes/gameplay.scene.js +641 -0
- package/templates/create/deckbuilder-2d/src/components/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/src/main.js +17 -0
- package/templates/create/deckbuilder-2d/src/runtime/capabilities.js +22 -0
- package/templates/create/deckbuilder-2d/src/shared/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/src/systems/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/tests/smoke/.gitkeep +1 -0
- package/templates/create/deckbuilder-2d/ui/hud.screen.js +80 -0
- package/templates/create/deckbuilder-2d/ui/pause.screen.js +146 -0
- package/templates/create/deckbuilder-2d/ui/settings.screen.js +342 -0
- package/templates/create/local-multiplayer/aura.config.json +40 -0
- package/templates/create/local-multiplayer/config/gameplay/local-multiplayer.config.js +26 -0
- package/templates/create/local-multiplayer/content/gameplay/room-layout.js +13 -0
- package/templates/create/local-multiplayer/content/registries/.gitkeep +1 -0
- package/templates/create/local-multiplayer/docs/design/loop.md +14 -0
- package/templates/create/local-multiplayer/prefabs/player.prefab.js +99 -0
- package/templates/create/local-multiplayer/scenes/boot.scene.js +12 -0
- package/templates/create/local-multiplayer/scenes/gameplay.scene.js +443 -0
- package/templates/create/local-multiplayer/src/main.js +17 -0
- package/templates/create/local-multiplayer/src/runtime/capabilities.js +28 -0
- package/templates/create/local-multiplayer/ui/hud.screen.js +60 -0
- package/templates/create/shared/src/runtime/project-inspector.js +105 -0
- package/templates/create/shared/src/runtime/scene-flow.js +290 -0
- package/templates/create/shared/src/runtime/screen-shell.js +222 -0
- package/templates/create/shared/src/runtime/ui-forms.js +209 -0
- package/templates/create/shared/src/runtime/ui-settings.js +237 -0
- package/templates/create/shared/src/runtime/ui-theme.js +352 -0
- package/templates/create/shared/src/starter-utils/adventure-objectives.js +102 -0
- package/templates/create/shared/src/starter-utils/animation-2d.js +337 -0
- package/templates/create/shared/src/starter-utils/avatar-3d.js +404 -0
- package/templates/create/shared/src/starter-utils/combat-feedback-2d.js +320 -0
- package/templates/create/shared/src/starter-utils/core.js +39 -3
- package/templates/create/shared/src/starter-utils/index.js +8 -2
- package/templates/create/shared/src/starter-utils/platformer-3d.js +34 -3
- package/templates/create/shared/src/starter-utils/triggers.js +662 -0
- package/templates/create/shared/src/starter-utils/tween-2d.js +615 -0
- package/templates/create/video-cutscene/assets/video/.gitkeep +0 -0
- package/templates/create/video-cutscene/aura.config.json +28 -0
- package/templates/create/video-cutscene/config/gameplay/.gitkeep +0 -0
- package/templates/create/video-cutscene/content/gameplay/.gitkeep +0 -0
- package/templates/create/video-cutscene/content/registries/.gitkeep +0 -0
- package/templates/create/video-cutscene/docs/design/loop.md +22 -0
- package/templates/create/video-cutscene/prefabs/.gitkeep +0 -0
- package/templates/create/video-cutscene/scenes/boot.scene.js +11 -0
- package/templates/create/video-cutscene/scenes/cutscene.scene.js +113 -0
- package/templates/create/video-cutscene/scenes/gameplay.scene.js +50 -0
- package/templates/create/video-cutscene/src/main.js +17 -0
- package/templates/create/video-cutscene/src/runtime/app.js +52 -0
- package/templates/create/video-cutscene/src/runtime/capabilities.js +35 -0
- package/templates/create/video-cutscene/src/runtime/state.js +13 -0
- package/templates/create/video-cutscene/ui/.gitkeep +0 -0
- package/templates/create-bin/play.js +1187 -0
- package/templates/make/README.md +46 -0
- package/templates/make/catalog.json +51 -0
- package/templates/make/component/files/{{MAKE_NAME}}.component.js +20 -0
- package/templates/make/component/manifest.json +9 -0
- package/templates/make/data/files/{{MAKE_NAME}}.json +14 -0
- package/templates/make/data/manifest.json +9 -0
- package/templates/make/material/files/{{MAKE_NAME}}.material.json +17 -0
- package/templates/make/material/manifest.json +9 -0
- package/templates/make/prefab/files/{{MAKE_NAME}}.prefab.js +20 -0
- package/templates/make/prefab/manifest.json +9 -0
- package/templates/make/scene/files/{{MAKE_NAME}}.scene.js +31 -0
- package/templates/make/scene/manifest.json +9 -0
- package/templates/make/shader/files/{{MAKE_NAME}}.shader.js +23 -0
- package/templates/make/shader/manifest.json +9 -0
- package/templates/make/system/files/{{MAKE_NAME}}.system.js +15 -0
- package/templates/make/system/manifest.json +9 -0
- package/templates/make/ui-screen/files/{{MAKE_NAME}}.screen.js +16 -0
- package/templates/make/ui-screen/files/{{MAKE_NAME}}.screen.json +23 -0
- package/templates/make/ui-screen/manifest.json +10 -0
- package/templates/make-starters/deckbuilder-2d/card/files/{{MAKE_NAME}}.card.js +22 -0
- package/templates/make-starters/deckbuilder-2d/card/manifest.json +9 -0
- package/templates/make-starters/deckbuilder-2d/catalog.json +34 -0
- package/templates/make-starters/deckbuilder-2d/encounter/files/{{MAKE_NAME}}.encounter.js +18 -0
- package/templates/make-starters/deckbuilder-2d/encounter/manifest.json +9 -0
- package/templates/make-starters/deckbuilder-2d/enemy/files/{{MAKE_NAME}}.enemy.js +28 -0
- package/templates/make-starters/deckbuilder-2d/enemy/manifest.json +9 -0
- package/templates/make-starters/deckbuilder-2d/relic/files/{{MAKE_NAME}}.relic.js +23 -0
- package/templates/make-starters/deckbuilder-2d/relic/manifest.json +9 -0
- package/templates/retro/platformer/README.md +10 -0
- package/templates/retro/platformer/assets/retro/assets.json +91 -0
- package/templates/retro/platformer/aura.config.json +7 -0
- package/templates/retro/platformer/package.json +5 -0
- package/templates/retro/platformer/src/main.js +40 -0
- package/templates/retro/puzzle-grid/README.md +10 -0
- package/templates/retro/puzzle-grid/assets/retro/assets.json +90 -0
- package/templates/retro/puzzle-grid/aura.config.json +7 -0
- package/templates/retro/puzzle-grid/package.json +5 -0
- package/templates/retro/puzzle-grid/src/main.js +29 -0
- package/templates/retro/tactics-grid/README.md +10 -0
- package/templates/retro/tactics-grid/assets/retro/assets.json +90 -0
- package/templates/retro/tactics-grid/aura.config.json +7 -0
- package/templates/retro/tactics-grid/package.json +5 -0
- package/templates/retro/tactics-grid/src/main.js +35 -0
- package/templates/retro/topdown-adventure/README.md +10 -0
- package/templates/retro/topdown-adventure/assets/retro/assets.json +95 -0
- package/templates/retro/topdown-adventure/aura.config.json +7 -0
- package/templates/retro/topdown-adventure/package.json +5 -0
- package/templates/retro/topdown-adventure/src/main.js +29 -0
- package/templates/skills/aurajs/SKILL.md +61 -5
package/src/host-binary.mjs
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { basename, dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
3
4
|
import {
|
|
4
5
|
accessSync,
|
|
5
6
|
existsSync,
|
|
6
7
|
readFileSync,
|
|
7
8
|
mkdirSync,
|
|
8
9
|
copyFileSync,
|
|
10
|
+
chmodSync,
|
|
9
11
|
statSync,
|
|
10
12
|
writeFileSync,
|
|
11
13
|
unlinkSync,
|
|
14
|
+
renameSync,
|
|
12
15
|
constants as fsConstants,
|
|
13
16
|
} from 'node:fs';
|
|
14
17
|
import { createHash } from 'node:crypto';
|
|
15
18
|
import { homedir } from 'node:os';
|
|
16
19
|
|
|
17
20
|
const requireFromHere = createRequire(import.meta.url);
|
|
21
|
+
const CLI_PACKAGE_JSON_URL = new URL('../package.json', import.meta.url);
|
|
18
22
|
|
|
19
23
|
const HOST_PACKAGE_SPECS = Object.freeze([
|
|
20
24
|
Object.freeze({
|
|
@@ -51,6 +55,14 @@ function readJsonFile(path) {
|
|
|
51
55
|
return JSON.parse(readFileSync(path, 'utf8'));
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
function defaultCliPackageVersion() {
|
|
59
|
+
try {
|
|
60
|
+
return readJsonFile(CLI_PACKAGE_JSON_URL).version || null;
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
54
66
|
function findPackageRootFromResolvedFile(resolvedFile, packageName, readPackageJson) {
|
|
55
67
|
let cursor = dirname(resolvedFile);
|
|
56
68
|
while (true) {
|
|
@@ -84,6 +96,10 @@ function defaultCacheRoot() {
|
|
|
84
96
|
return process.env.AURAJS_HOST_CACHE_DIR || join(homedir(), '.cache', 'aurajs', 'host-binaries');
|
|
85
97
|
}
|
|
86
98
|
|
|
99
|
+
function defaultReleaseBaseUrl() {
|
|
100
|
+
return process.env.AURAJS_HOST_RELEASE_BASE_URL || 'https://raw.githubusercontent.com/Aura-Industry';
|
|
101
|
+
}
|
|
102
|
+
|
|
87
103
|
function resolveOverrideHostBinaryPath({
|
|
88
104
|
platform = process.platform,
|
|
89
105
|
arch = process.arch,
|
|
@@ -119,15 +135,21 @@ function safeUnlink(path) {
|
|
|
119
135
|
} catch {}
|
|
120
136
|
}
|
|
121
137
|
|
|
122
|
-
function
|
|
123
|
-
const binaryStats = statSync(binaryPath);
|
|
138
|
+
function resolveCachePaths(spec, packageVersion, cacheRoot, binaryRelativePath = spec.binaryRelativePath) {
|
|
124
139
|
const cacheDir = resolve(cacheRoot, spec.target, packageVersion || 'unknown');
|
|
125
|
-
const cachedBinaryPath = resolve(cacheDir, basename(
|
|
140
|
+
const cachedBinaryPath = resolve(cacheDir, basename(binaryRelativePath));
|
|
126
141
|
const manifestPath = resolve(cacheDir, 'manifest.json');
|
|
127
142
|
return {
|
|
128
143
|
cacheDir,
|
|
129
144
|
cachedBinaryPath,
|
|
130
145
|
manifestPath,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function resolveCacheInfo(spec, binaryPath, packageRoot, packageVersion, cacheRoot) {
|
|
150
|
+
const binaryStats = statSync(binaryPath);
|
|
151
|
+
return {
|
|
152
|
+
...resolveCachePaths(spec, packageVersion, cacheRoot, binaryPath),
|
|
131
153
|
sourceStat: {
|
|
132
154
|
size: binaryStats.size,
|
|
133
155
|
mtimeMs: binaryStats.mtimeMs,
|
|
@@ -138,6 +160,83 @@ function resolveCacheInfo(spec, binaryPath, packageRoot, packageVersion, cacheRo
|
|
|
138
160
|
};
|
|
139
161
|
}
|
|
140
162
|
|
|
163
|
+
function readValidCachedBinary({ spec, packageVersion, cacheRoot }) {
|
|
164
|
+
const cache = resolveCachePaths(spec, packageVersion, cacheRoot);
|
|
165
|
+
if (!existsSync(cache.cachedBinaryPath) || !existsSync(cache.manifestPath)) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
const manifest = readJsonFile(cache.manifestPath);
|
|
171
|
+
const cachedStats = statSync(cache.cachedBinaryPath);
|
|
172
|
+
const cachedHash = hashFile(cache.cachedBinaryPath);
|
|
173
|
+
const versionMatches = manifest?.packageVersion == null || manifest.packageVersion === (packageVersion || 'unknown');
|
|
174
|
+
if (
|
|
175
|
+
manifest?.packageName !== spec.packageName
|
|
176
|
+
|| manifest?.target !== spec.target
|
|
177
|
+
|| manifest?.sha256 !== cachedHash
|
|
178
|
+
|| manifest?.size !== cachedStats.size
|
|
179
|
+
|| !versionMatches
|
|
180
|
+
) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
...cache,
|
|
186
|
+
manifest,
|
|
187
|
+
cachedStats,
|
|
188
|
+
cachedHash,
|
|
189
|
+
};
|
|
190
|
+
} catch {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function ensureCachedBinaryExecutable(path, platform) {
|
|
196
|
+
if (platform === 'win32') return;
|
|
197
|
+
try {
|
|
198
|
+
chmodSync(path, 0o755);
|
|
199
|
+
} catch {}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function formatReleaseRepo(spec) {
|
|
203
|
+
return `Aura-Industry/aurajs-${spec.target}`;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function buildReleaseSource(spec, packageVersion) {
|
|
207
|
+
const tag = `v${packageVersion}`;
|
|
208
|
+
const baseUrl = defaultReleaseBaseUrl().replace(/\/+$/, '');
|
|
209
|
+
const repo = formatReleaseRepo(spec);
|
|
210
|
+
const rootUrl = `${baseUrl}/aurajs-${spec.target}/${tag}`;
|
|
211
|
+
return {
|
|
212
|
+
repo,
|
|
213
|
+
tag,
|
|
214
|
+
rootUrl,
|
|
215
|
+
packageJsonUrl: `${rootUrl}/package.json`,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async function fetchText(url, fetchImpl) {
|
|
220
|
+
const response = await fetchImpl(url);
|
|
221
|
+
if (!response?.ok) {
|
|
222
|
+
throw new Error(`HTTP ${response?.status ?? 'ERR'} for ${url}`);
|
|
223
|
+
}
|
|
224
|
+
return response.text();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function fetchBytes(url, fetchImpl) {
|
|
228
|
+
const response = await fetchImpl(url);
|
|
229
|
+
if (!response?.ok) {
|
|
230
|
+
throw new Error(`HTTP ${response?.status ?? 'ERR'} for ${url}`);
|
|
231
|
+
}
|
|
232
|
+
const buffer = await response.arrayBuffer();
|
|
233
|
+
return Buffer.from(buffer);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function writeCachedBinaryManifest(manifestPath, manifest) {
|
|
237
|
+
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
238
|
+
}
|
|
239
|
+
|
|
141
240
|
export class HostBinaryResolutionError extends Error {
|
|
142
241
|
constructor(message, { code = 'AURA_HOST_BINARY_ERROR', platform, arch, packageName, cause } = {}) {
|
|
143
242
|
super(message, cause ? { cause } : undefined);
|
|
@@ -202,22 +301,43 @@ export function resolveAndCacheHostBinary({
|
|
|
202
301
|
platform = process.platform,
|
|
203
302
|
arch = process.arch,
|
|
204
303
|
cacheRoot = defaultCacheRoot(),
|
|
205
|
-
packageJsonVersion,
|
|
304
|
+
packageJsonVersion = defaultCliPackageVersion(),
|
|
206
305
|
resolvePackageRoot,
|
|
207
306
|
} = {}) {
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
if (resolved.override) {
|
|
307
|
+
const override = resolveOverrideHostBinaryPath({ platform, arch });
|
|
308
|
+
if (override) {
|
|
211
309
|
return {
|
|
212
|
-
...
|
|
213
|
-
cacheDir: dirname(
|
|
214
|
-
cachedBinaryPath:
|
|
310
|
+
...override,
|
|
311
|
+
cacheDir: dirname(override.binaryPath),
|
|
312
|
+
cachedBinaryPath: override.binaryPath,
|
|
215
313
|
manifestPath: null,
|
|
216
314
|
cacheStatus: 'override',
|
|
217
315
|
diagnostics: ['Using AURAJS_HOST_BINARY_PATH override; cache step skipped.'],
|
|
218
316
|
};
|
|
219
317
|
}
|
|
220
318
|
|
|
319
|
+
const spec = getHostPackageSpec({ platform, arch });
|
|
320
|
+
const versionedCacheHit = packageJsonVersion
|
|
321
|
+
? readValidCachedBinary({ spec, packageVersion: packageJsonVersion, cacheRoot })
|
|
322
|
+
: null;
|
|
323
|
+
if (versionedCacheHit) {
|
|
324
|
+
ensureCachedBinaryExecutable(versionedCacheHit.cachedBinaryPath, platform);
|
|
325
|
+
return {
|
|
326
|
+
...spec,
|
|
327
|
+
packageRoot: versionedCacheHit.manifest?.packageRoot || null,
|
|
328
|
+
cacheDir: versionedCacheHit.cacheDir,
|
|
329
|
+
cachedBinaryPath: versionedCacheHit.cachedBinaryPath,
|
|
330
|
+
manifestPath: versionedCacheHit.manifestPath,
|
|
331
|
+
cacheStatus: 'hit',
|
|
332
|
+
binaryPath: versionedCacheHit.cachedBinaryPath,
|
|
333
|
+
diagnostics: [],
|
|
334
|
+
packageVersion: versionedCacheHit.manifest?.packageVersion || packageJsonVersion || null,
|
|
335
|
+
release: versionedCacheHit.manifest?.release || null,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const resolved = resolveHostBinaryPath({ platform, arch, resolvePackageRoot });
|
|
340
|
+
|
|
221
341
|
let packageVersion = packageJsonVersion;
|
|
222
342
|
try {
|
|
223
343
|
const packageJson = readJsonFile(resolve(resolved.packageRoot, 'package.json'));
|
|
@@ -237,6 +357,7 @@ export function resolveAndCacheHostBinary({
|
|
|
237
357
|
const sourceHash = hashFile(cache.sourceBinaryPath);
|
|
238
358
|
const manifest = {
|
|
239
359
|
packageName: resolved.packageName,
|
|
360
|
+
packageVersion: packageVersion || 'unknown',
|
|
240
361
|
target: resolved.target,
|
|
241
362
|
sourceBinaryPath: cache.sourceBinaryPath,
|
|
242
363
|
packageRoot: cache.packageRoot,
|
|
@@ -266,7 +387,8 @@ export function resolveAndCacheHostBinary({
|
|
|
266
387
|
if (!cacheHit) {
|
|
267
388
|
safeUnlink(cache.cachedBinaryPath);
|
|
268
389
|
copyFileSync(cache.sourceBinaryPath, cache.cachedBinaryPath);
|
|
269
|
-
|
|
390
|
+
ensureCachedBinaryExecutable(cache.cachedBinaryPath, platform);
|
|
391
|
+
writeCachedBinaryManifest(cache.manifestPath, manifest);
|
|
270
392
|
}
|
|
271
393
|
|
|
272
394
|
return {
|
|
@@ -276,10 +398,181 @@ export function resolveAndCacheHostBinary({
|
|
|
276
398
|
manifestPath: cache.manifestPath,
|
|
277
399
|
cacheStatus: cacheHit ? 'hit' : 'refreshed',
|
|
278
400
|
binaryPath: cache.cachedBinaryPath,
|
|
401
|
+
packageVersion,
|
|
279
402
|
diagnostics: cacheHit
|
|
280
403
|
? []
|
|
281
|
-
: ['Host binary cache was missing/stale/corrupt and has been refreshed from
|
|
404
|
+
: ['Host binary cache was missing/stale/corrupt and has been refreshed from a packaged host binary.'],
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export async function downloadAndCacheHostBinary({
|
|
409
|
+
platform = process.platform,
|
|
410
|
+
arch = process.arch,
|
|
411
|
+
cacheRoot = defaultCacheRoot(),
|
|
412
|
+
packageJsonVersion = defaultCliPackageVersion(),
|
|
413
|
+
fetchImpl = globalThis.fetch,
|
|
414
|
+
} = {}) {
|
|
415
|
+
if (!packageJsonVersion) {
|
|
416
|
+
throw new HostBinaryResolutionError(
|
|
417
|
+
'Host binary download requires an explicit CLI package version.',
|
|
418
|
+
{ code: 'AURA_HOST_VERSION_REQUIRED', platform, arch },
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (typeof fetchImpl !== 'function') {
|
|
423
|
+
throw new HostBinaryResolutionError(
|
|
424
|
+
'Global fetch is unavailable; cannot download the host binary.',
|
|
425
|
+
{ code: 'AURA_HOST_DOWNLOAD_UNAVAILABLE', platform, arch },
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const override = resolveOverrideHostBinaryPath({ platform, arch });
|
|
430
|
+
if (override) {
|
|
431
|
+
return {
|
|
432
|
+
...override,
|
|
433
|
+
cacheDir: dirname(override.binaryPath),
|
|
434
|
+
cachedBinaryPath: override.binaryPath,
|
|
435
|
+
manifestPath: null,
|
|
436
|
+
cacheStatus: 'override',
|
|
437
|
+
diagnostics: ['Using AURAJS_HOST_BINARY_PATH override; cache step skipped.'],
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const spec = getHostPackageSpec({ platform, arch });
|
|
442
|
+
const source = buildReleaseSource(spec, packageJsonVersion);
|
|
443
|
+
let remotePackage;
|
|
444
|
+
|
|
445
|
+
try {
|
|
446
|
+
remotePackage = JSON.parse(await fetchText(source.packageJsonUrl, fetchImpl));
|
|
447
|
+
} catch (cause) {
|
|
448
|
+
throw new HostBinaryResolutionError(
|
|
449
|
+
`Failed to load host package metadata for ${spec.packageName}@${packageJsonVersion} from ${source.repo} (${source.tag}).`,
|
|
450
|
+
{ code: 'AURA_HOST_DOWNLOAD_METADATA_FAILED', platform, arch, packageName: spec.packageName, cause },
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (remotePackage?.name !== spec.packageName) {
|
|
455
|
+
throw new HostBinaryResolutionError(
|
|
456
|
+
`Downloaded host package metadata does not match expected package "${spec.packageName}".`,
|
|
457
|
+
{ code: 'AURA_HOST_DOWNLOAD_METADATA_INVALID', platform, arch, packageName: spec.packageName },
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
if (remotePackage?.version !== packageJsonVersion) {
|
|
461
|
+
throw new HostBinaryResolutionError(
|
|
462
|
+
`Downloaded host package version mismatch for "${spec.packageName}": expected ${packageJsonVersion}, received ${remotePackage?.version || 'unknown'}.`,
|
|
463
|
+
{ code: 'AURA_HOST_VERSION_MISMATCH', platform, arch, packageName: spec.packageName },
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const remoteBinaryPath = remotePackage?.aurajsHost?.binaryPath;
|
|
468
|
+
const checksumAlgorithm = remotePackage?.aurajsHost?.checksumAlgorithm;
|
|
469
|
+
const checksum = remotePackage?.aurajsHost?.checksum;
|
|
470
|
+
if (typeof remoteBinaryPath !== 'string' || remoteBinaryPath.length === 0) {
|
|
471
|
+
throw new HostBinaryResolutionError(
|
|
472
|
+
`Downloaded host package metadata for "${spec.packageName}" is missing aurajsHost.binaryPath.`,
|
|
473
|
+
{ code: 'AURA_HOST_DOWNLOAD_METADATA_INVALID', platform, arch, packageName: spec.packageName },
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
if (checksumAlgorithm !== 'sha256' || typeof checksum !== 'string' || checksum.length === 0) {
|
|
477
|
+
throw new HostBinaryResolutionError(
|
|
478
|
+
`Downloaded host package metadata for "${spec.packageName}" is missing a valid SHA256 checksum.`,
|
|
479
|
+
{ code: 'AURA_HOST_DOWNLOAD_METADATA_INVALID', platform, arch, packageName: spec.packageName },
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const binaryUrl = `${source.rootUrl}/${remoteBinaryPath}`;
|
|
484
|
+
let binaryBuffer;
|
|
485
|
+
try {
|
|
486
|
+
binaryBuffer = await fetchBytes(binaryUrl, fetchImpl);
|
|
487
|
+
} catch (cause) {
|
|
488
|
+
throw new HostBinaryResolutionError(
|
|
489
|
+
`Failed to download host binary for ${spec.packageName}@${packageJsonVersion} from ${source.repo} (${source.tag}).`,
|
|
490
|
+
{ code: 'AURA_HOST_DOWNLOAD_BINARY_FAILED', platform, arch, packageName: spec.packageName, cause },
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const binaryHash = createHash('sha256').update(binaryBuffer).digest('hex');
|
|
495
|
+
if (binaryHash !== checksum) {
|
|
496
|
+
throw new HostBinaryResolutionError(
|
|
497
|
+
`Downloaded host binary checksum mismatch for ${spec.packageName}@${packageJsonVersion}.`,
|
|
498
|
+
{ code: 'AURA_HOST_CHECKSUM_MISMATCH', platform, arch, packageName: spec.packageName },
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const cache = resolveCachePaths(spec, packageJsonVersion, cacheRoot, remoteBinaryPath);
|
|
503
|
+
mkdirSync(cache.cacheDir, { recursive: true });
|
|
504
|
+
|
|
505
|
+
const tempBinaryPath = `${cache.cachedBinaryPath}.download-${process.pid}-${Date.now()}`;
|
|
506
|
+
safeUnlink(tempBinaryPath);
|
|
507
|
+
safeUnlink(cache.cachedBinaryPath);
|
|
508
|
+
|
|
509
|
+
try {
|
|
510
|
+
writeFileSync(tempBinaryPath, binaryBuffer);
|
|
511
|
+
ensureCachedBinaryExecutable(tempBinaryPath, platform);
|
|
512
|
+
renameSync(tempBinaryPath, cache.cachedBinaryPath);
|
|
513
|
+
} finally {
|
|
514
|
+
safeUnlink(tempBinaryPath);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const manifest = {
|
|
518
|
+
packageName: spec.packageName,
|
|
519
|
+
packageVersion: packageJsonVersion,
|
|
520
|
+
target: spec.target,
|
|
521
|
+
sourceBinaryPath: binaryUrl,
|
|
522
|
+
packageRoot: null,
|
|
523
|
+
size: binaryBuffer.length,
|
|
524
|
+
mtimeMs: Date.now(),
|
|
525
|
+
mode: platform === 'win32' ? null : 0o755,
|
|
526
|
+
sha256: binaryHash,
|
|
527
|
+
release: {
|
|
528
|
+
repo: source.repo,
|
|
529
|
+
tag: source.tag,
|
|
530
|
+
packageJsonUrl: source.packageJsonUrl,
|
|
531
|
+
binaryUrl,
|
|
532
|
+
},
|
|
282
533
|
};
|
|
534
|
+
writeCachedBinaryManifest(cache.manifestPath, manifest);
|
|
535
|
+
|
|
536
|
+
return {
|
|
537
|
+
...spec,
|
|
538
|
+
packageRoot: null,
|
|
539
|
+
binaryPath: cache.cachedBinaryPath,
|
|
540
|
+
cacheDir: cache.cacheDir,
|
|
541
|
+
cachedBinaryPath: cache.cachedBinaryPath,
|
|
542
|
+
manifestPath: cache.manifestPath,
|
|
543
|
+
cacheStatus: 'downloaded',
|
|
544
|
+
packageVersion: packageJsonVersion,
|
|
545
|
+
diagnostics: [`Downloaded host binary from ${source.repo}@${source.tag}.`],
|
|
546
|
+
release: manifest.release,
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
export async function ensureHostBinaryAvailable(options = {}) {
|
|
551
|
+
try {
|
|
552
|
+
const defaultSearchFrom = dirname(fileURLToPath(CLI_PACKAGE_JSON_URL));
|
|
553
|
+
return resolveGateHostBinary({
|
|
554
|
+
platform: options.platform,
|
|
555
|
+
arch: options.arch,
|
|
556
|
+
searchFrom: options.searchFrom || defaultSearchFrom,
|
|
557
|
+
cacheRoot: options.cacheRoot,
|
|
558
|
+
resolveCachedBinary: (cachedOptions) => resolveAndCacheHostBinary({
|
|
559
|
+
...options,
|
|
560
|
+
...cachedOptions,
|
|
561
|
+
}),
|
|
562
|
+
resolvePackagedBinary: (packagedOptions) => resolveHostBinaryPath({
|
|
563
|
+
...options,
|
|
564
|
+
...packagedOptions,
|
|
565
|
+
}),
|
|
566
|
+
});
|
|
567
|
+
} catch (error) {
|
|
568
|
+
if (!(error instanceof HostBinaryResolutionError)) {
|
|
569
|
+
throw error;
|
|
570
|
+
}
|
|
571
|
+
if (!options?.packageJsonVersion) {
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
return downloadAndCacheHostBinary(options);
|
|
575
|
+
}
|
|
283
576
|
}
|
|
284
577
|
|
|
285
578
|
function findInstalledPackageRoot(packageName, { requireResolve, readPackageJson }) {
|
|
@@ -295,7 +588,7 @@ function findInstalledPackageRoot(packageName, { requireResolve, readPackageJson
|
|
|
295
588
|
resolvedEntrypoint = requireResolve(packageName);
|
|
296
589
|
} catch (cause) {
|
|
297
590
|
throw new HostBinaryResolutionError(
|
|
298
|
-
`Missing host
|
|
591
|
+
`Missing packaged host binary "${packageName}". Run "npm install" to restore packaged binaries, or let AuraJS download the host on first run.`,
|
|
299
592
|
{ code: 'AURA_HOST_PACKAGE_MISSING', packageName, cause },
|
|
300
593
|
);
|
|
301
594
|
}
|
|
@@ -365,6 +658,23 @@ export function resolveGateHostBinary({
|
|
|
365
658
|
const repoRoot = findRepoRootWithRustHost(searchFrom);
|
|
366
659
|
const localCandidates = repoRoot ? resolveLocalHostBinaryCandidates(repoRoot, binaryName) : [];
|
|
367
660
|
const checkedCandidates = localCandidates.map((candidate) => candidate.path);
|
|
661
|
+
const override = resolveOverrideHostBinaryPath({ platform, arch });
|
|
662
|
+
|
|
663
|
+
if (override) {
|
|
664
|
+
return {
|
|
665
|
+
...override,
|
|
666
|
+
source: 'override',
|
|
667
|
+
reasonCode: 'host_binary_override_selected',
|
|
668
|
+
diagnostics: ['Using AURAJS_HOST_BINARY_PATH override; local build/package resolution skipped.'],
|
|
669
|
+
localBuild: {
|
|
670
|
+
repoRoot,
|
|
671
|
+
checked: checkedCandidates,
|
|
672
|
+
},
|
|
673
|
+
resolvedAt: new Date().toISOString(),
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const availableLocalCandidates = [];
|
|
368
678
|
|
|
369
679
|
for (const candidate of localCandidates) {
|
|
370
680
|
if (!existsSync(candidate.path)) continue;
|
|
@@ -372,9 +682,27 @@ export function resolveGateHostBinary({
|
|
|
372
682
|
diagnostics.push(`[host_binary_local_non_executable] Detected local ${candidate.kind} host binary but it is not executable: ${candidate.path}`);
|
|
373
683
|
continue;
|
|
374
684
|
}
|
|
685
|
+
availableLocalCandidates.push({
|
|
686
|
+
...candidate,
|
|
687
|
+
mtimeMs: statSync(candidate.path).mtimeMs,
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
if (availableLocalCandidates.length > 0) {
|
|
692
|
+
availableLocalCandidates.sort((a, b) => {
|
|
693
|
+
if (a.kind !== b.kind) {
|
|
694
|
+
return a.kind === 'release' ? -1 : 1;
|
|
695
|
+
}
|
|
696
|
+
if (b.mtimeMs !== a.mtimeMs) {
|
|
697
|
+
return b.mtimeMs - a.mtimeMs;
|
|
698
|
+
}
|
|
699
|
+
return 0;
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
const candidate = availableLocalCandidates[0];
|
|
375
703
|
if (candidate.kind === 'debug') {
|
|
376
704
|
diagnostics.push(
|
|
377
|
-
`[host_binary_local_debug_fallback] Selected local debug host
|
|
705
|
+
`[host_binary_local_debug_fallback] Selected newer local debug host: ${candidate.path}`,
|
|
378
706
|
);
|
|
379
707
|
}
|
|
380
708
|
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { basename, extname, join, relative, resolve } from 'node:path';
|
|
3
|
+
|
|
4
|
+
export const SUPPORTED_BUILD_ICON_EXTENSIONS = Object.freeze(['.png', '.jpg', '.jpeg', '.ico', '.icns']);
|
|
5
|
+
|
|
6
|
+
function compareCandidates(a, b) {
|
|
7
|
+
if (a.exactBaseName !== b.exactBaseName) {
|
|
8
|
+
return a.exactBaseName ? -1 : 1;
|
|
9
|
+
}
|
|
10
|
+
if (a.extensionRank !== b.extensionRank) {
|
|
11
|
+
return a.extensionRank - b.extensionRank;
|
|
12
|
+
}
|
|
13
|
+
if (a.depth !== b.depth) {
|
|
14
|
+
return a.depth - b.depth;
|
|
15
|
+
}
|
|
16
|
+
return a.relativePath.localeCompare(b.relativePath);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function walk(dirPath, visit) {
|
|
20
|
+
for (const entry of readdirSync(dirPath, { withFileTypes: true })) {
|
|
21
|
+
const fullPath = join(dirPath, entry.name);
|
|
22
|
+
if (entry.isDirectory()) {
|
|
23
|
+
walk(fullPath, visit);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (entry.isFile()) {
|
|
27
|
+
visit(fullPath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function discoverProjectIconPath({ projectRoot, assetDir = 'assets' } = {}) {
|
|
33
|
+
const normalizedAssetDir = String(assetDir || 'assets').trim() || 'assets';
|
|
34
|
+
const assetRoot = resolve(projectRoot, normalizedAssetDir);
|
|
35
|
+
if (!existsSync(assetRoot)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const candidates = [];
|
|
40
|
+
walk(assetRoot, (fullPath) => {
|
|
41
|
+
const extension = extname(fullPath).toLowerCase();
|
|
42
|
+
const extensionRank = SUPPORTED_BUILD_ICON_EXTENSIONS.indexOf(extension);
|
|
43
|
+
if (extensionRank === -1) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const fileBaseName = basename(fullPath, extension).toLowerCase();
|
|
47
|
+
if (!fileBaseName.startsWith('logo')) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const relativePath = relative(projectRoot, fullPath).split('\\').join('/');
|
|
51
|
+
candidates.push({
|
|
52
|
+
relativePath,
|
|
53
|
+
exactBaseName: fileBaseName === 'logo',
|
|
54
|
+
extensionRank,
|
|
55
|
+
depth: relativePath.split('/').length,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (candidates.length === 0) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
candidates.sort(compareCandidates);
|
|
63
|
+
return candidates[0].relativePath;
|
|
64
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
const CLI_SRC_DIR = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const CORE_MAKE_TEMPLATE_DIR = resolve(CLI_SRC_DIR, '../templates/make');
|
|
7
|
+
const CORE_MAKE_CATALOG_PATH = resolve(CORE_MAKE_TEMPLATE_DIR, 'catalog.json');
|
|
8
|
+
const STARTER_MAKE_TEMPLATE_DIR = resolve(CLI_SRC_DIR, '../templates/make-starters');
|
|
9
|
+
|
|
10
|
+
function readJsonFile(path) {
|
|
11
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function normalizeCatalogRows(source, { owner, scope, manifestDir }) {
|
|
15
|
+
const kinds = Array.isArray(source?.kinds) ? source.kinds : [];
|
|
16
|
+
return kinds.map((entry) => {
|
|
17
|
+
const id = String(entry?.id || '').trim();
|
|
18
|
+
const manifest = String(entry?.manifest || '').trim();
|
|
19
|
+
if (!id || !manifest) {
|
|
20
|
+
throw new Error(`Invalid make catalog entry for owner "${owner}".`);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
id,
|
|
24
|
+
owner,
|
|
25
|
+
scope,
|
|
26
|
+
manifestPath: resolve(manifestDir, manifest),
|
|
27
|
+
outputRoot: typeof entry?.outputRoot === 'string' && entry.outputRoot.trim().length > 0
|
|
28
|
+
? entry.outputRoot.trim()
|
|
29
|
+
: null,
|
|
30
|
+
registerAs: typeof entry?.registerAs === 'string' && entry.registerAs.trim().length > 0
|
|
31
|
+
? entry.registerAs.trim()
|
|
32
|
+
: null,
|
|
33
|
+
defaultRole: typeof entry?.defaultRole === 'string' && entry.defaultRole.trim().length > 0
|
|
34
|
+
? entry.defaultRole.trim()
|
|
35
|
+
: null,
|
|
36
|
+
starterContentFamily: typeof entry?.starterContentFamily === 'string' && entry.starterContentFamily.trim().length > 0
|
|
37
|
+
? entry.starterContentFamily.trim()
|
|
38
|
+
: null,
|
|
39
|
+
starterContentRegistry: typeof entry?.starterContentRegistry === 'string' && entry.starterContentRegistry.trim().length > 0
|
|
40
|
+
? entry.starterContentRegistry.trim()
|
|
41
|
+
: null,
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function loadProjectTemplate(projectRoot) {
|
|
47
|
+
if (!projectRoot) return 'blank';
|
|
48
|
+
const capabilitiesPath = resolve(projectRoot, 'aura.capabilities.json');
|
|
49
|
+
if (!existsSync(capabilitiesPath)) return 'blank';
|
|
50
|
+
try {
|
|
51
|
+
const capabilities = readJsonFile(capabilitiesPath);
|
|
52
|
+
if (typeof capabilities?.template === 'string' && capabilities.template.trim().length > 0) {
|
|
53
|
+
return capabilities.template.trim();
|
|
54
|
+
}
|
|
55
|
+
} catch {}
|
|
56
|
+
return 'blank';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function loadCoreMakeCatalog() {
|
|
60
|
+
const catalog = readJsonFile(CORE_MAKE_CATALOG_PATH);
|
|
61
|
+
return normalizeCatalogRows(catalog, {
|
|
62
|
+
owner: 'core',
|
|
63
|
+
scope: 'core',
|
|
64
|
+
manifestDir: CORE_MAKE_TEMPLATE_DIR,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function loadStarterMakeCatalog(template, options = {}) {
|
|
69
|
+
const normalizedTemplate = String(template || '').trim() || 'blank';
|
|
70
|
+
const starterCatalogRoot = resolve(options.catalogRoot || STARTER_MAKE_TEMPLATE_DIR);
|
|
71
|
+
const catalogPath = resolve(starterCatalogRoot, normalizedTemplate, 'catalog.json');
|
|
72
|
+
if (!existsSync(catalogPath)) return [];
|
|
73
|
+
const catalog = readJsonFile(catalogPath);
|
|
74
|
+
return normalizeCatalogRows(catalog, {
|
|
75
|
+
owner: `starter:${normalizedTemplate}`,
|
|
76
|
+
scope: normalizedTemplate,
|
|
77
|
+
manifestDir: dirname(catalogPath),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function loadMakeCatalog(options = {}) {
|
|
82
|
+
const projectRoot = options.projectRoot ? resolve(options.projectRoot) : null;
|
|
83
|
+
const template = options.template || loadProjectTemplate(projectRoot);
|
|
84
|
+
const coreEntries = loadCoreMakeCatalog();
|
|
85
|
+
const starterEntries = loadStarterMakeCatalog(template, options);
|
|
86
|
+
const merged = new Map();
|
|
87
|
+
|
|
88
|
+
for (const entry of [...coreEntries, ...starterEntries]) {
|
|
89
|
+
if (merged.has(entry.id)) {
|
|
90
|
+
throw new Error(`Duplicate make kind "${entry.id}" in merged make catalog.`);
|
|
91
|
+
}
|
|
92
|
+
merged.set(entry.id, entry);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return [...merged.values()];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function listMakeKinds(options = {}) {
|
|
99
|
+
return loadMakeCatalog(options).map((entry) => entry.id);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function listCoreMakeKinds() {
|
|
103
|
+
return loadCoreMakeCatalog().map((entry) => entry.id);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function resolveMakeKind(kind, options = {}) {
|
|
107
|
+
const normalizedKind = String(kind || '').trim();
|
|
108
|
+
return loadMakeCatalog(options).find((entry) => entry.id === normalizedKind) || null;
|
|
109
|
+
}
|