diff --git a/.changeset/config.json b/.changeset/config.json index f8daad62..1c3df7d6 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -8,6 +8,7 @@ "fixed": [ [ "@nx.js/nro", + "@nx.js/nsp", "create-nxjs-app", "nxjs-runtime" ] diff --git a/.changeset/tidy-timers-begin.md b/.changeset/tidy-timers-begin.md new file mode 100644 index 00000000..d7900d4c --- /dev/null +++ b/.changeset/tidy-timers-begin.md @@ -0,0 +1,5 @@ +--- +'@nx.js/nsp': patch +--- + +Add `@nx.js/nsp` package diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aca6863e..913fba8f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,6 +84,9 @@ jobs: - name: Copy `nxjs.nro` to "@nx.js/nro" run: cp -v nxjs.nro packages/nro/dist + - name: Copy files to "@nx.js/nsp" + run: cp -rv build/exefs nxjs.nacp icon.jpg packages/nsp + - name: Create Release Pull Request or Publish to npm id: changesets uses: changesets/action@v1 diff --git a/.gitignore b/.gitignore index a743d55d..bed5cbe1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ node_modules /lib/*/lib /lib/*/debug /lib/*/release +/hacbrewpack_* +/exefs +/control /nxjs.* !/nxjs.jpg diff --git a/Makefile b/Makefile index b8db8adf..c2e8cc17 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ include $(DEVKITPRO)/libnx/switch_rules # SOURCES is a list of directories containing source code # DATA is a list of directories containing data files # INCLUDES is a list of directories containing header files +# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm". # ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional) # # NO_ICON: if set to anything, do not use icon. @@ -28,25 +29,21 @@ include $(DEVKITPRO)/libnx/switch_rules # - .jpg # - icon.jpg # - /default_icon.jpg -# -# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder. -# If not set, it attempts to use one of the following (in this order): -# - .json -# - config.json -# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead -# of a homebrew executable (.nro). This is intended to be used for sysmodules. -# NACP building is skipped as well. #--------------------------------------------------------------------------------- + APP_TITLE := nx.js APP_TITLEID := 016e782e6a730000 # 6e782e6a73 is "nx.js" in hex šŸ˜‰ APP_AUTHOR := TooTallNate APP_VERSION := `jq -r .version < ../packages/runtime/package.json` + TARGET := nxjs BUILD := build SOURCES := source DATA := data INCLUDES := include +EXEFS_SRC := exefs_src ROMFS := romfs +CONFIG_JSON := npdm.json #--------------------------------------------------------------------------------- # options for code generation @@ -58,10 +55,10 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \ CFLAGS += $(INCLUDE) -D__SWITCH__ `freetype-config --cflags` `aarch64-none-elf-pkg-config cairo --cflags` -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions ASFLAGS := -g $(ARCH) -LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) +LDFLAGS = -specs=${DEVKITPRO}/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LIBS := -pthread -lmbedtls -lmbedx509 -lmbedcrypto -lharfbuzz `freetype-config --libs` `aarch64-none-elf-pkg-config cairo --libs` -lturbojpeg -lwebp -lqjs -lm3 -lm @@ -117,18 +114,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -ifeq ($(strip $(CONFIG_JSON)),) - jsons := $(wildcard *.json) - ifneq (,$(findstring $(TARGET).json,$(jsons))) - export APP_JSON := $(TOPDIR)/$(TARGET).json - else - ifneq (,$(findstring config.json,$(jsons))) - export APP_JSON := $(TOPDIR)/config.json - endif - endif -else - export APP_JSON := $(TOPDIR)/$(CONFIG_JSON) -endif +export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC) ifeq ($(strip $(ICON)),) icons := $(wildcard *.jpg) @@ -159,6 +145,19 @@ ifneq ($(ROMFS),) export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS) endif +ifeq ($(strip $(CONFIG_JSON)),) + jsons := $(wildcard *.json) + ifneq (,$(findstring $(TARGET).json,$(jsons))) + export APP_JSON := $(TOPDIR)/$(TARGET).json + else + ifneq (,$(findstring config.json,$(jsons))) + export APP_JSON := $(TOPDIR)/config.json + endif + endif +else + export APP_JSON := $(TOPDIR)/$(CONFIG_JSON) +endif + .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- @@ -171,11 +170,7 @@ $(BUILD): #--------------------------------------------------------------------------------- clean: @echo clean ... -ifeq ($(strip $(APP_JSON)),) - @rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf -else - @rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf -endif + @rm -fr $(BUILD) $(TARGET).pfs0 $(TARGET).nso $(TARGET).nro $(TARGET).nacp $(TARGET).elf $(TARGET).npdm #--------------------------------------------------------------------------------- @@ -187,9 +182,15 @@ DEPENDS := $(OFILES:.o=.d) #--------------------------------------------------------------------------------- # main targets #--------------------------------------------------------------------------------- +all : $(OUTPUT).pfs0 $(OUTPUT).nro + ifeq ($(strip $(APP_JSON)),) +$(OUTPUT).pfs0 : $(OUTPUT).nso +else +$(OUTPUT).pfs0 : $(OUTPUT).nso $(OUTPUT).npdm +endif -all : $(OUTPUT).nro +$(OUTPUT).nso : $(OUTPUT).elf ifeq ($(strip $(NO_NACP)),) $(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp @@ -197,16 +198,6 @@ else $(OUTPUT).nro : $(OUTPUT).elf endif -else - -all : $(OUTPUT).nsp - -$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm - -$(OUTPUT).nso : $(OUTPUT).elf - -endif - $(OUTPUT).elf : $(OFILES) $(OFILES_SRC) : $(HFILES_BIN) diff --git a/apps/2048/.gitignore b/apps/2048/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/2048/.gitignore +++ b/apps/2048/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/2048/package.json b/apps/2048/package.json index 0e0e0797..4327016c 100644 --- a/apps/2048/package.json +++ b/apps/2048/package.json @@ -5,15 +5,17 @@ "description": "nx.js port of the 2048 game", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.js --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "dependencies": { "nxjs-constants": "workspace:*" }, "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/ansi/.gitignore b/apps/ansi/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/ansi/.gitignore +++ b/apps/ansi/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/ansi/package.json b/apps/ansi/package.json index 101c9707..009f19a5 100644 --- a/apps/ansi/package.json +++ b/apps/ansi/package.json @@ -5,12 +5,14 @@ "description": "nx.js app with colors and cursor movement using ANSI escapes", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" }, "dependencies": { diff --git a/apps/app-launch/.gitignore b/apps/app-launch/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/app-launch/.gitignore +++ b/apps/app-launch/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/app-launch/package.json b/apps/app-launch/package.json index 818524bd..49060df4 100644 --- a/apps/app-launch/package.json +++ b/apps/app-launch/package.json @@ -5,12 +5,14 @@ "description": "List and launch installed games", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 --format=esm src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/battery/.gitignore b/apps/battery/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/battery/.gitignore +++ b/apps/battery/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/battery/package.json b/apps/battery/package.json index 1a812f0b..4bcf1e52 100644 --- a/apps/battery/package.json +++ b/apps/battery/package.json @@ -5,12 +5,14 @@ "description": "nx.js app to display the battery charge level", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 --format=esm src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/canvas/.gitignore b/apps/canvas/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/canvas/.gitignore +++ b/apps/canvas/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/canvas/package.json b/apps/canvas/package.json index 34f5b786..6ade8867 100644 --- a/apps/canvas/package.json +++ b/apps/canvas/package.json @@ -5,12 +5,14 @@ "description": "nx.js app using the web `Canvas` API", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/fonts/.gitignore b/apps/fonts/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/fonts/.gitignore +++ b/apps/fonts/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/fonts/package.json b/apps/fonts/package.json index c5f2bfc7..e2d5e5e5 100644 --- a/apps/fonts/package.json +++ b/apps/fonts/package.json @@ -5,12 +5,14 @@ "description": "nx.js app using customs fonts", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/hello-world/.gitignore b/apps/hello-world/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/hello-world/.gitignore +++ b/apps/hello-world/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/hello-world/package.json b/apps/hello-world/package.json index c7473cb5..6a9a96a8 100644 --- a/apps/hello-world/package.json +++ b/apps/hello-world/package.json @@ -5,12 +5,14 @@ "description": "Simple 'Hello World' nx.js app", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 --format=esm src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/repl-server/.gitignore b/apps/repl-server/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/repl-server/.gitignore +++ b/apps/repl-server/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/repl-server/package.json b/apps/repl-server/package.json index dafb2a6c..557be0f8 100644 --- a/apps/repl-server/package.json +++ b/apps/repl-server/package.json @@ -5,7 +5,8 @@ "description": "nx.js REPL (read-eval-print-loop) app accessed over TCP", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 --format=esm src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "dependencies": { @@ -13,8 +14,9 @@ "sisteransi": "^1.0.5" }, "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/repl/.gitignore b/apps/repl/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/repl/.gitignore +++ b/apps/repl/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/repl/package.json b/apps/repl/package.json index ec58b39f..8945df57 100644 --- a/apps/repl/package.json +++ b/apps/repl/package.json @@ -5,7 +5,8 @@ "description": "nx.js REPL (read-eval-print-loop) app", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "dependencies": { @@ -13,8 +14,9 @@ "sisteransi": "^1.0.5" }, "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/snake/.gitignore b/apps/snake/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/snake/.gitignore +++ b/apps/snake/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/snake/package.json b/apps/snake/package.json index 68f38f08..bb576375 100644 --- a/apps/snake/package.json +++ b/apps/snake/package.json @@ -5,15 +5,17 @@ "description": "Classic 'snake' game using nx.js", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "dependencies": { "nxjs-constants": "workspace:*" }, "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/starwars/.gitignore b/apps/starwars/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/starwars/.gitignore +++ b/apps/starwars/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/starwars/package.json b/apps/starwars/package.json index 599c9c2b..fce10297 100644 --- a/apps/starwars/package.json +++ b/apps/starwars/package.json @@ -5,12 +5,14 @@ "description": "nx.js app that renders the Star Wars ASCII text", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" }, "dependencies": { diff --git a/apps/svg/.gitignore b/apps/svg/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/svg/.gitignore +++ b/apps/svg/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/svg/package.json b/apps/svg/package.json index 6f31e5b7..df03b8d9 100644 --- a/apps/svg/package.json +++ b/apps/svg/package.json @@ -5,12 +5,14 @@ "description": "nx.js app that renders an SVG image to the screen", "scripts": { "build": "esbuild --bundle --banner:js='globalThis.global = globalThis;' --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" }, "dependencies": { diff --git a/apps/tcp-server/.gitignore b/apps/tcp-server/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/tcp-server/.gitignore +++ b/apps/tcp-server/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/tcp-server/package.json b/apps/tcp-server/package.json index 70138df9..7ec4b49a 100644 --- a/apps/tcp-server/package.json +++ b/apps/tcp-server/package.json @@ -5,12 +5,14 @@ "description": "nx.js app that binds a TCP server to a port", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 --format=esm src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/tests/.gitignore b/apps/tests/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/tests/.gitignore +++ b/apps/tests/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/tests/package.json b/apps/tests/package.json index 0e87dbe4..fd95bdda 100644 --- a/apps/tests/package.json +++ b/apps/tests/package.json @@ -6,12 +6,14 @@ "description": "nx.js API tests", "scripts": { "build": "esbuild --bundle --target=es2022 --sourcemap --sources-content=false --format=esm src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" }, "dependencies": { diff --git a/apps/touchscreen/.gitignore b/apps/touchscreen/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/touchscreen/.gitignore +++ b/apps/touchscreen/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/touchscreen/package.json b/apps/touchscreen/package.json index dc9d839c..01d1409a 100644 --- a/apps/touchscreen/package.json +++ b/apps/touchscreen/package.json @@ -5,13 +5,15 @@ "description": "nx.js app using the touchscreen", "scripts": { "build": "esbuild --bundle --main-fields=module,main --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { + "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", "@types/color-hash": "^1.0.5", "esbuild": "^0.17.19", - "@nx.js/nro": "workspace:^", "nxjs-runtime": "workspace:^" }, "dependencies": { diff --git a/apps/vibrate/.gitignore b/apps/vibrate/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/vibrate/.gitignore +++ b/apps/vibrate/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/vibrate/package.json b/apps/vibrate/package.json index 41b9edbb..6ea89c72 100644 --- a/apps/vibrate/package.json +++ b/apps/vibrate/package.json @@ -5,12 +5,14 @@ "description": "nx.js app demonstrating the `nagivator.vibrate()` API", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/apps/virtual-keyboard/.gitignore b/apps/virtual-keyboard/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/virtual-keyboard/.gitignore +++ b/apps/virtual-keyboard/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/virtual-keyboard/package.json b/apps/virtual-keyboard/package.json index 23bf45f9..829505a6 100644 --- a/apps/virtual-keyboard/package.json +++ b/apps/virtual-keyboard/package.json @@ -5,13 +5,15 @@ "description": "nx.js app that invokes the virtual keyboard", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 --format=esm src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { + "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", "esbuild": "^0.17.19", "nxjs-constants": "workspace:^", - "@nx.js/nro": "workspace:^", "nxjs-runtime": "workspace:^" } } diff --git a/apps/wasm/.gitignore b/apps/wasm/.gitignore index 0bd936ba..d697ee38 100644 --- a/apps/wasm/.gitignore +++ b/apps/wasm/.gitignore @@ -1,4 +1,5 @@ /*.nro +/*.nsp /node_modules /romfs/main.js /romfs/main.js.map diff --git a/apps/wasm/package.json b/apps/wasm/package.json index 419a49a2..bfb5cde6 100644 --- a/apps/wasm/package.json +++ b/apps/wasm/package.json @@ -5,12 +5,14 @@ "description": "nx.js app that loads a WASM binary", "scripts": { "build": "esbuild --bundle --sourcemap --sources-content=false --target=es2022 src/main.ts --outfile=romfs/main.js", - "nro": "nxjs-nro" + "nro": "nxjs-nro", + "nsp": "nxjs-nsp" }, "license": "MIT", "devDependencies": { - "esbuild": "^0.17.19", "@nx.js/nro": "workspace:^", + "@nx.js/nsp": "workspace:^", + "esbuild": "^0.17.19", "nxjs-runtime": "workspace:^" } } diff --git a/nxjs.jpg b/icon.jpg similarity index 100% rename from nxjs.jpg rename to icon.jpg diff --git a/npdm.json b/npdm.json new file mode 100644 index 00000000..b5452417 --- /dev/null +++ b/npdm.json @@ -0,0 +1,162 @@ +{ + "name": "nx.js", + "title_id": "0x016e782e6a730000", + "title_id_range_min": "0x0100000000000000", + "title_id_range_max": "0x01ffffffffffffff", + "main_thread_stack_size": "0x100000", + "main_thread_priority": 44, + "default_cpu_id": 0, + "process_category": 0, + "pool_partition": 0, + "is_64_bit": true, + "address_space_type": 1, + "is_retail": true, + "filesystem_access": { + "permissions": "0xFFFFFFFFFFFFFFFF" + }, + "service_host": [ + "*" + ], + "service_access": [ + "*" + ], + "kernel_capabilities": [ + { + "type": "kernel_flags", + "value": { + "highest_thread_priority": 59, + "lowest_thread_priority": 28, + "highest_cpu_id": 2, + "lowest_cpu_id": 0 + } + }, + { + "type": "syscalls", + "value": { + "svcUnknown00": "0x00", + "svcSetHeapSize": "0x01", + "svcSetMemoryPermission": "0x02", + "svcSetMemoryAttribute": "0x03", + "svcMapMemory": "0x04", + "svcUnmapMemory": "0x05", + "svcQueryMemory": "0x06", + "svcExitProcess": "0x07", + "svcCreateThread": "0x08", + "svcStartThread": "0x09", + "svcExitThread": "0x0A", + "svcSleepThread": "0x0B", + "svcGetThreadPriority": "0x0C", + "svcSetThreadPriority": "0x0D", + "svcGetThreadCoreMask": "0x0E", + "svcSetThreadCoreMask": "0x0F", + "svcGetCurrentProcessorNumber": "0x10", + "svcSignalEvent": "0x11", + "svcClearEvent": "0x12", + "svcMapSharedMemory": "0x13", + "svcUnmapSharedMemory": "0x14", + "svcCreateTransferMemory": "0x15", + "svcCloseHandle": "0x16", + "svcResetSignal": "0x17", + "svcWaitSynchronization": "0x18", + "svcCancelSynchronization": "0x19", + "svcArbitrateLock": "0x1A", + "svcArbitrateUnlock": "0x1B", + "svcWaitProcessWideKeyAtomic": "0x1C", + "svcSignalProcessWideKey": "0x1D", + "svcGetSystemTick": "0x1E", + "svcConnectToNamedPort": "0x1F", + "svcSendSyncRequestLight": "0x20", + "svcSendSyncRequest": "0x21", + "svcSendSyncRequestWithUserBuffer": "0x22", + "svcSendAsyncRequestWithUserBuffer": "0x23", + "svcGetProcessId": "0x24", + "svcGetThreadId": "0x25", + "svcBreak": "0x26", + "svcOutputDebugString": "0x27", + "svcReturnFromException": "0x28", + "svcGetInfo": "0x29", + "svcFlushEntireDataCache": "0x2A", + "svcFlushDataCache": "0x2B", + "svcMapPhysicalMemory": "0x2C", + "svcUnmapPhysicalMemory": "0x2D", + "svcGetFutureThreadInfo": "0x2E", + "svcGetLastThreadInfo": "0x2F", + "svcGetResourceLimitLimitValue": "0x30", + "svcGetResourceLimitCurrentValue": "0x31", + "svcSetThreadActivity": "0x32", + "svcGetThreadContext3": "0x33", + "svcWaitForAddress": "0x34", + "svcSignalToAddress": "0x35", + "svcUnknown36": "0x36", + "svcUnknown37": "0x37", + "svcUnknown38": "0x38", + "svcUnknown39": "0x39", + "svcUnknown3a": "0x3A", + "svcUnknown3b": "0x3B", + "svcDumpInfo": "0x3C", + "svcDumpInfoNew": "0x3D", + "svcUnknown3e": "0x3E", + "svcUnknown3f": "0x3F", + "svcCreateSession": "0x40", + "svcAcceptSession": "0x41", + "svcReplyAndReceiveLight": "0x42", + "svcReplyAndReceive": "0x43", + "svcReplyAndReceiveWithUserBuffer": "0x44", + "svcCreateEvent": "0x45", + "svcUnknown46": "0x46", + "svcUnknown47": "0x47", + "svcMapPhysicalMemoryUnsafe": "0x48", + "svcUnmapPhysicalMemoryUnsafe": "0x49", + "svcSetUnsafeLimit": "0x4A", + "svcCreateCodeMemory": "0x4B", + "svcControlCodeMemory": "0x4C", + "svcSleepSystem": "0x4D", + "svcReadWriteRegister": "0x4E", + "svcSetProcessActivity": "0x4F", + "svcCreateSharedMemory": "0x50", + "svcMapTransferMemory": "0x51", + "svcUnmapTransferMemory": "0x52", + "svcDebugActiveProcess": "0x60", + "svcBreakDebugProcess": "0x61", + "svcTerminateDebugProcess": "0x62", + "svcGetDebugEvent": "0x63", + "svcContinueDebugEvent": "0x64", + "svcGetProcessList": "0x65", + "svcGetThreadList": "0x66", + "svcGetDebugThreadContext": "0x67", + "svcSetDebugThreadContext": "0x68", + "svcQueryDebugProcessMemory": "0x69", + "svcReadDebugProcessMemory": "0x6A", + "svcWriteDebugProcessMemory": "0x6B", + "svcSetHardwareBreakPoint": "0x6C", + "svcGetDebugThreadParam": "0x6D", + "svcConnectToPort": "0x72", + "svcSetProcessMemoryPermission": "0x73", + "svcMapProcessMemory": "0x74", + "svcUnmapProcessMemory": "0x75", + "svcQueryProcessMemory": "0x76", + "svcMapProcessCodeMemory": "0x77", + "svcUnmapProcessCodeMemory": "0x78" + } + }, + { + "type": "application_type", + "value": 1 + }, + { + "type": "min_kernel_version", + "value": "0x30" + }, + { + "type": "handle_table_size", + "value": 512 + }, + { + "type": "debug_flags", + "value": { + "allow_debug": true, + "force_debug": true + } + } + ] +} diff --git a/packages/nro/package.json b/packages/nro/package.json index 35b44512..1fee29c1 100644 --- a/packages/nro/package.json +++ b/packages/nro/package.json @@ -15,7 +15,7 @@ "author": "Nathan Rajlich ", "license": "MIT", "dependencies": { - "@nx.js/patch-nacp": "^0.0.0", + "@nx.js/patch-nacp": "0.0.0", "@tootallnate/nacp": "^0.0.1", "@tootallnate/nro": "^0.1.0", "@tootallnate/romfs": "^0.1.0", diff --git a/packages/nro/src/main.ts b/packages/nro/src/main.ts index 5f3860dd..6a2b748f 100755 --- a/packages/nro/src/main.ts +++ b/packages/nro/src/main.ts @@ -17,12 +17,7 @@ import * as RomFS from '@tootallnate/romfs'; import terminalImage from 'terminal-image'; const cwd = process.cwd(); -const packageRoot = new URL(`${pathToFileURL(cwd)}/`); - -// Read the `package.json` file to get the information that will -// be embedded in the NACP section of the output `.nro` file -const packageJsonUrl = new URL('package.json', packageRoot); - +const appRoot = new URL(`${pathToFileURL(cwd)}/`); const isSrcMode = existsSync(new URL('../tsconfig.json', import.meta.url)); const nxjsNroUrl = new URL( isSrcMode ? '../../../nxjs.nro' : '../dist/nxjs.nro', @@ -37,7 +32,7 @@ let icon = nxjsNro.icon; console.log(chalk.bold('Icon:')); const iconName = 'icon.jpg'; try { - const iconUrl = new URL(iconName, packageRoot); + const iconUrl = new URL(iconName, appRoot); const iconData = readFileSync(iconUrl); icon = new Blob([iconData]); } catch (err: any) { @@ -60,14 +55,14 @@ console.log( const nacp = new NACP(await nxjsNro.nacp!.arrayBuffer()); console.log(); console.log(chalk.bold('Setting metadata:')); -patchNACP(nacp, packageJsonUrl); +patchNACP(nacp, new URL('package.json', appRoot)); console.log(` ID: ${chalk.green(nacp.id.toString(16).padStart(16, '0'))}`); console.log(` Title: ${chalk.green(nacp.title)}`); console.log(` Version: ${chalk.green(nacp.version)}`); console.log(` Author: ${chalk.green(nacp.author)}`); // RomFS -const romfsDir = new URL('romfs/', packageRoot); +const romfsDir = new URL('romfs/', appRoot); const romfsDirPath = fileURLToPath(romfsDir); const romfs = await RomFS.decode(nxjsNro.romfs!); console.log(); @@ -139,7 +134,7 @@ const outputNro = await NRO.encode({ nacp: new Blob([new Uint8Array(nacp.buffer)]), romfs: await RomFS.encode(romfs), }); -const outputNroUrl = new URL(outputNroName, packageRoot); +const outputNroUrl = new URL(outputNroName, appRoot); writeFileSync(outputNroUrl, Buffer.from(await outputNro.arrayBuffer())); console.log( chalk.green( diff --git a/packages/nsp/package.json b/packages/nsp/package.json new file mode 100644 index 00000000..a94c72b4 --- /dev/null +++ b/packages/nsp/package.json @@ -0,0 +1,32 @@ +{ + "name": "@nx.js/nsp", + "version": "0.0.0", + "description": "", + "bin": { + "nxjs-nsp": "dist/main.js" + }, + "type": "module", + "scripts": { + "build": "tsc" + }, + "files": [ + "dist", + "exefs", + "nxjs.nacp", + "icon.jpg" + ], + "author": "Nathan Rajlich ", + "license": "MIT", + "dependencies": { + "@nx.js/patch-nacp": "0.0.0", + "@tootallnate/nacp": "^0.0.1", + "bytes": "^3.1.2", + "chalk": "^5.3.0", + "terminal-image": "^2.0.0" + }, + "devDependencies": { + "@types/bytes": "^3.1.4", + "@types/node": "^20.10.3", + "typescript": "^5.3.2" + } +} diff --git a/packages/nsp/src/main.ts b/packages/nsp/src/main.ts new file mode 100644 index 00000000..691c1fc5 --- /dev/null +++ b/packages/nsp/src/main.ts @@ -0,0 +1,142 @@ +#!/usr/bin/env node +import bytes from 'bytes'; +import chalk from 'chalk'; +import { + cpSync, + existsSync, + rmSync, + mkdtempSync, + readFileSync, + writeFileSync, + readdirSync, + statSync, +} from 'node:fs'; +import { join } from 'node:path'; +import { once } from 'node:events'; +import { spawn } from 'node:child_process'; +import { tmpdir } from 'node:os'; +import { pathToFileURL, fileURLToPath } from 'node:url'; +import { NACP } from '@tootallnate/nacp'; +import { patchNACP } from '@nx.js/patch-nacp'; +import terminalImage from 'terminal-image'; + +const tmpPaths: URL[] = []; +const tmpDir = tmpdir(); +const cwd = process.cwd(); +const root = new URL('../', import.meta.url); +const appRoot = new URL(`${pathToFileURL(cwd)}/`); +const isSrcMode = existsSync(new URL('tsconfig.json', root)); + +const createTmpDir = (type: string) => { + const dir = new URL( + `${pathToFileURL(mkdtempSync(join(tmpDir, `nxjs-nsp_${type}.`)))}/` + ); + tmpPaths.push(dir); + return dir; +}; + +let nacpPath = new URL('nxjs.nacp', root); +let iconPath = new URL('icon.jpg', root); +let exefsDir = new URL('exefs/', root); +let baseRomfsDir = new URL('romfs/', root); +const romfsDir = new URL('romfs/', appRoot); +const nspDir = createTmpDir('nsp'); +const ncaDir = createTmpDir('nca'); +const tempDir = createTmpDir('temp'); +const backupDir = createTmpDir('backup'); +let logoDir = new URL('logo/', appRoot); +if (!existsSync(logoDir)) { + logoDir = createTmpDir('logo'); +} +const controlDir = createTmpDir('control'); + +if (isSrcMode) { + nacpPath = new URL('../../nxjs.nacp', root); + iconPath = new URL('../../icon.jpg', root); + exefsDir = new URL('../../build/exefs/', root); + baseRomfsDir = new URL('../../romfs/', root); +} + +try { + // Icon + cpSync(iconPath, new URL('icon_AmericanEnglish.dat', controlDir)); + console.log(chalk.bold('Icon:')); + console.log( + await terminalImage.file(fileURLToPath(iconPath), { height: 12 }) + ); + + // NACP + const nacp = new NACP(readFileSync(nacpPath).buffer); + patchNACP(nacp, new URL('package.json', appRoot)); + writeFileSync( + new URL('control.nacp', controlDir), + Buffer.from(nacp.buffer) + ); + const titleid = nacp.id.toString(16).padStart(16, '0'); + console.log(); + console.log(chalk.bold('Setting metadata:')); + console.log(` ID: ${chalk.green(titleid)}`); + console.log(` Title: ${chalk.green(nacp.title)}`); + console.log(` Version: ${chalk.green(nacp.version)}`); + console.log(` Author: ${chalk.green(nacp.author)}`); + + // RomFS + for (const file of readdirSync(baseRomfsDir)) { + const src = new URL(file, baseRomfsDir); + const dest = new URL(file, romfsDir); + cpSync(src, dest); + tmpPaths.push(dest); + } + + // TODO: validate `romfs/main.js` exists + + // Generate NSP file via `hacbrewpack` + const argv = [ + '--nspdir', + fileURLToPath(nspDir), + '--ncadir', + fileURLToPath(ncaDir), + '--tempdir', + fileURLToPath(tempDir), + '--backupdir', + fileURLToPath(backupDir), + '--exefsdir', + fileURLToPath(exefsDir), + '--romfsdir', + fileURLToPath(romfsDir), + '--logodir', + fileURLToPath(logoDir), + '--controldir', + fileURLToPath(controlDir), + '--titleid', + titleid, + '--nopatchnacplogo', + ...process.argv.slice(2), + ]; + + const child = spawn('hacbrewpack', argv, { stdio: 'inherit', shell: true }); + const [exitCode, signal] = await once(child, 'exit'); + if (signal) { + process.kill(process.pid, signal); + } else if (exitCode) { + process.exitCode = exitCode; + } else { + // move NSP file + const nspFileName = readdirSync(nspDir)[0]; + const nspSrc = new URL(nspFileName, nspDir); + const outputNspName = `${nacp.title}.nsp`; + const nspDest = new URL(outputNspName, appRoot); + cpSync(nspSrc, nspDest); + console.log( + chalk.green( + `\nšŸŽ‰ Success! Generated NSP file ${chalk.bold( + `"${outputNspName}"` + )}` + ) + ` (${bytes(statSync(nspDest).size).toLowerCase()})` + ); + } +} finally { + for (const dir of tmpPaths) { + rmSync(dir, { recursive: true, force: true }); + } +} diff --git a/packages/nsp/tsconfig.json b/packages/nsp/tsconfig.json new file mode 100644 index 00000000..30735a3a --- /dev/null +++ b/packages/nsp/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "NodeNext", + "sourceMap": true, + "outDir": "./dist", + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, + "isolatedModules": true, + "strict": true, + "skipLibCheck": true + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70fa1ee5..a57b1d2e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -54,6 +57,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -66,6 +72,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -78,6 +87,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -90,6 +102,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -102,6 +117,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -114,6 +132,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -133,6 +154,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -152,6 +176,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -168,6 +195,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -184,6 +214,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -203,6 +236,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -215,6 +251,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -231,6 +270,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -247,6 +289,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp '@types/color-hash': specifier: ^1.0.5 version: 1.0.5 @@ -262,6 +307,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -274,6 +322,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -289,6 +340,9 @@ importers: '@nx.js/nro': specifier: workspace:^ version: link:../../packages/nro + '@nx.js/nsp': + specifier: workspace:^ + version: link:../../packages/nsp esbuild: specifier: ^0.17.19 version: 0.17.19 @@ -339,7 +393,7 @@ importers: packages/nro: dependencies: '@nx.js/patch-nacp': - specifier: ^0.0.0 + specifier: 0.0.0 version: link:../patch-nacp '@tootallnate/nacp': specifier: ^0.0.1 @@ -370,6 +424,34 @@ importers: specifier: ^5.3.2 version: 5.3.2 + packages/nsp: + dependencies: + '@nx.js/patch-nacp': + specifier: 0.0.0 + version: link:../patch-nacp + '@tootallnate/nacp': + specifier: ^0.0.1 + version: 0.0.1 + bytes: + specifier: ^3.1.2 + version: 3.1.2 + chalk: + specifier: ^5.3.0 + version: 5.3.0 + terminal-image: + specifier: ^2.0.0 + version: 2.0.0 + devDependencies: + '@types/bytes': + specifier: ^3.1.4 + version: 3.1.4 + '@types/node': + specifier: ^20.10.3 + version: 20.10.3 + typescript: + specifier: ^5.3.2 + version: 5.3.2 + packages/patch-nacp: dependencies: parse-author: @@ -4360,7 +4442,3 @@ packages: kleur: 4.1.5 sade: 1.8.1 dev: false - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false diff --git a/source/main.c b/source/main.c index 4e044388..971dd0e1 100644 --- a/source/main.c +++ b/source/main.c @@ -507,14 +507,14 @@ int main(int argc, char *argv[]) // First try the `main.js` file on the RomFS size_t user_code_size; - int js_path_needs_free = 0; + bool js_path_needs_free = false; char *js_path = "romfs:/main.js"; char *user_code = (char *)read_file(js_path, &user_code_size); - if (user_code == NULL && errno == ENOENT) + if (user_code == NULL && errno == ENOENT && argc > 0) { // If no `main.js`, then try the `.js file with the // matching name as the `.nro` file on the SD card - js_path_needs_free = 1; + js_path_needs_free = true; js_path = strdup(argv[0]); size_t js_path_len = strlen(js_path); char *dot_nro = strstr(js_path, ".nro");