@gtkx/cli 1.0.0 → 1.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 +1 -1
- package/dist/builder.d.ts +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +20 -3
- package/dist/builder.js.map +1 -1
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/codegen/freshness.js +2 -2
- package/dist/codegen/freshness.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +8 -5
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +24 -19
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/codegen/store-resolver.d.ts +1 -1
- package/dist/codegen/store-resolver.d.ts.map +1 -1
- package/dist/codegen/store-resolver.js.map +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +5 -6
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/codegen.d.ts.map +1 -1
- package/dist/commands/codegen.js +11 -1
- package/dist/commands/codegen.js.map +1 -1
- package/dist/commands/deploy.d.ts +22 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +44 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +4 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs.d.ts +2 -2
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +27 -4
- package/dist/commands/docs.js.map +1 -1
- package/dist/deploy/depends.d.ts +8 -0
- package/dist/deploy/depends.d.ts.map +1 -0
- package/dist/deploy/depends.js +27 -0
- package/dist/deploy/depends.js.map +1 -0
- package/dist/deploy/download.d.ts +20 -0
- package/dist/deploy/download.d.ts.map +1 -0
- package/dist/deploy/download.js +98 -0
- package/dist/deploy/download.js.map +1 -0
- package/dist/deploy/freedesktop/copyright.d.ts +4 -0
- package/dist/deploy/freedesktop/copyright.d.ts.map +1 -0
- package/dist/deploy/freedesktop/copyright.js +33 -0
- package/dist/deploy/freedesktop/copyright.js.map +1 -0
- package/dist/deploy/freedesktop/dbus-service.d.ts +4 -0
- package/dist/deploy/freedesktop/dbus-service.d.ts.map +1 -0
- package/dist/deploy/freedesktop/dbus-service.js +15 -0
- package/dist/deploy/freedesktop/dbus-service.js.map +1 -0
- package/dist/deploy/freedesktop/desktop-entry.d.ts +4 -0
- package/dist/deploy/freedesktop/desktop-entry.d.ts.map +1 -0
- package/dist/deploy/freedesktop/desktop-entry.js +73 -0
- package/dist/deploy/freedesktop/desktop-entry.js.map +1 -0
- package/dist/deploy/freedesktop/ini.d.ts +7 -0
- package/dist/deploy/freedesktop/ini.d.ts.map +1 -0
- package/dist/deploy/freedesktop/ini.js +22 -0
- package/dist/deploy/freedesktop/ini.js.map +1 -0
- package/dist/deploy/freedesktop/metainfo-sections.d.ts +13 -0
- package/dist/deploy/freedesktop/metainfo-sections.d.ts.map +1 -0
- package/dist/deploy/freedesktop/metainfo-sections.js +73 -0
- package/dist/deploy/freedesktop/metainfo-sections.js.map +1 -0
- package/dist/deploy/freedesktop/metainfo.d.ts +4 -0
- package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -0
- package/dist/deploy/freedesktop/metainfo.js +29 -0
- package/dist/deploy/freedesktop/metainfo.js.map +1 -0
- package/dist/deploy/freedesktop/mime-package.d.ts +4 -0
- package/dist/deploy/freedesktop/mime-package.d.ts.map +1 -0
- package/dist/deploy/freedesktop/mime-package.js +16 -0
- package/dist/deploy/freedesktop/mime-package.js.map +1 -0
- package/dist/deploy/freedesktop/validate.d.ts +4 -0
- package/dist/deploy/freedesktop/validate.d.ts.map +1 -0
- package/dist/deploy/freedesktop/validate.js +81 -0
- package/dist/deploy/freedesktop/validate.js.map +1 -0
- package/dist/deploy/freedesktop/xml.d.ts +11 -0
- package/dist/deploy/freedesktop/xml.d.ts.map +1 -0
- package/dist/deploy/freedesktop/xml.js +33 -0
- package/dist/deploy/freedesktop/xml.js.map +1 -0
- package/dist/deploy/git.d.ts +4 -0
- package/dist/deploy/git.d.ts.map +1 -0
- package/dist/deploy/git.js +17 -0
- package/dist/deploy/git.js.map +1 -0
- package/dist/deploy/install-hints.d.ts +5 -0
- package/dist/deploy/install-hints.d.ts.map +1 -0
- package/dist/deploy/install-hints.js +85 -0
- package/dist/deploy/install-hints.js.map +1 -0
- package/dist/deploy/nfpm/config.d.ts +8 -0
- package/dist/deploy/nfpm/config.d.ts.map +1 -0
- package/dist/deploy/nfpm/config.js +119 -0
- package/dist/deploy/nfpm/config.js.map +1 -0
- package/dist/deploy/nfpm/contents.d.ts +12 -0
- package/dist/deploy/nfpm/contents.d.ts.map +1 -0
- package/dist/deploy/nfpm/contents.js +48 -0
- package/dist/deploy/nfpm/contents.js.map +1 -0
- package/dist/deploy/nfpm/description.d.ts +5 -0
- package/dist/deploy/nfpm/description.d.ts.map +1 -0
- package/dist/deploy/nfpm/description.js +5 -0
- package/dist/deploy/nfpm/description.js.map +1 -0
- package/dist/deploy/nfpm/optional.d.ts +5 -0
- package/dist/deploy/nfpm/optional.d.ts.map +1 -0
- package/dist/deploy/nfpm/optional.js +4 -0
- package/dist/deploy/nfpm/optional.js.map +1 -0
- package/dist/deploy/nfpm/pack.d.ts +5 -0
- package/dist/deploy/nfpm/pack.d.ts.map +1 -0
- package/dist/deploy/nfpm/pack.js +32 -0
- package/dist/deploy/nfpm/pack.js.map +1 -0
- package/dist/deploy/node-runtime/download.d.ts +3 -0
- package/dist/deploy/node-runtime/download.d.ts.map +1 -0
- package/dist/deploy/node-runtime/download.js +39 -0
- package/dist/deploy/node-runtime/download.js.map +1 -0
- package/dist/deploy/node-runtime/elf.d.ts +7 -0
- package/dist/deploy/node-runtime/elf.d.ts.map +1 -0
- package/dist/deploy/node-runtime/elf.js +100 -0
- package/dist/deploy/node-runtime/elf.js.map +1 -0
- package/dist/deploy/node-runtime/guard.d.ts +4 -0
- package/dist/deploy/node-runtime/guard.d.ts.map +1 -0
- package/dist/deploy/node-runtime/guard.js +22 -0
- package/dist/deploy/node-runtime/guard.js.map +1 -0
- package/dist/deploy/node-runtime/index.d.ts +4 -0
- package/dist/deploy/node-runtime/index.d.ts.map +1 -0
- package/dist/deploy/node-runtime/index.js +61 -0
- package/dist/deploy/node-runtime/index.js.map +1 -0
- package/dist/deploy/payload/copy-tree.d.ts +7 -0
- package/dist/deploy/payload/copy-tree.d.ts.map +1 -0
- package/dist/deploy/payload/copy-tree.js +36 -0
- package/dist/deploy/payload/copy-tree.js.map +1 -0
- package/dist/deploy/payload/icons.d.ts +6 -0
- package/dist/deploy/payload/icons.d.ts.map +1 -0
- package/dist/deploy/payload/icons.js +53 -0
- package/dist/deploy/payload/icons.js.map +1 -0
- package/dist/deploy/payload/launcher.d.ts +5 -0
- package/dist/deploy/payload/launcher.d.ts.map +1 -0
- package/dist/deploy/payload/launcher.js +22 -0
- package/dist/deploy/payload/launcher.js.map +1 -0
- package/dist/deploy/payload/schemas.d.ts +4 -0
- package/dist/deploy/payload/schemas.d.ts.map +1 -0
- package/dist/deploy/payload/schemas.js +17 -0
- package/dist/deploy/payload/schemas.js.map +1 -0
- package/dist/deploy/payload/stage.d.ts +15 -0
- package/dist/deploy/payload/stage.d.ts.map +1 -0
- package/dist/deploy/payload/stage.js +100 -0
- package/dist/deploy/payload/stage.js.map +1 -0
- package/dist/deploy/registry.d.ts +7 -0
- package/dist/deploy/registry.d.ts.map +1 -0
- package/dist/deploy/registry.js +30 -0
- package/dist/deploy/registry.js.map +1 -0
- package/dist/deploy/run-deploy.d.ts +11 -0
- package/dist/deploy/run-deploy.d.ts.map +1 -0
- package/dist/deploy/run-deploy.js +153 -0
- package/dist/deploy/run-deploy.js.map +1 -0
- package/dist/deploy/settings/arch.d.ts +4 -0
- package/dist/deploy/settings/arch.d.ts.map +1 -0
- package/dist/deploy/settings/arch.js +13 -0
- package/dist/deploy/settings/arch.js.map +1 -0
- package/dist/deploy/settings/categories.d.ts +4 -0
- package/dist/deploy/settings/categories.d.ts.map +1 -0
- package/dist/deploy/settings/categories.js +29 -0
- package/dist/deploy/settings/categories.js.map +1 -0
- package/dist/deploy/settings/exec.d.ts +6 -0
- package/dist/deploy/settings/exec.d.ts.map +1 -0
- package/dist/deploy/settings/exec.js +20 -0
- package/dist/deploy/settings/exec.js.map +1 -0
- package/dist/deploy/settings/identity.d.ts +18 -0
- package/dist/deploy/settings/identity.d.ts.map +1 -0
- package/dist/deploy/settings/identity.js +73 -0
- package/dist/deploy/settings/identity.js.map +1 -0
- package/dist/deploy/settings/index.d.ts +11 -0
- package/dist/deploy/settings/index.d.ts.map +1 -0
- package/dist/deploy/settings/index.js +103 -0
- package/dist/deploy/settings/index.js.map +1 -0
- package/dist/deploy/settings/package-manifest.d.ts +15 -0
- package/dist/deploy/settings/package-manifest.d.ts.map +1 -0
- package/dist/deploy/settings/package-manifest.js +41 -0
- package/dist/deploy/settings/package-manifest.js.map +1 -0
- package/dist/deploy/settings/paths.d.ts +9 -0
- package/dist/deploy/settings/paths.d.ts.map +1 -0
- package/dist/deploy/settings/paths.js +82 -0
- package/dist/deploy/settings/paths.js.map +1 -0
- package/dist/deploy/settings/screenshots.d.ts +8 -0
- package/dist/deploy/settings/screenshots.d.ts.map +1 -0
- package/dist/deploy/settings/screenshots.js +79 -0
- package/dist/deploy/settings/screenshots.js.map +1 -0
- package/dist/deploy/settings/starter.d.ts +4 -0
- package/dist/deploy/settings/starter.d.ts.map +1 -0
- package/dist/deploy/settings/starter.js +28 -0
- package/dist/deploy/settings/starter.js.map +1 -0
- package/dist/deploy/settings/version.d.ts +9 -0
- package/dist/deploy/settings/version.d.ts.map +1 -0
- package/dist/deploy/settings/version.js +37 -0
- package/dist/deploy/settings/version.js.map +1 -0
- package/dist/deploy/targets/appimage.d.ts +4 -0
- package/dist/deploy/targets/appimage.d.ts.map +1 -0
- package/dist/deploy/targets/appimage.js +105 -0
- package/dist/deploy/targets/appimage.js.map +1 -0
- package/dist/deploy/targets/deb.d.ts +4 -0
- package/dist/deploy/targets/deb.d.ts.map +1 -0
- package/dist/deploy/targets/deb.js +4 -0
- package/dist/deploy/targets/deb.js.map +1 -0
- package/dist/deploy/targets/flatpak-manifest.d.ts +6 -0
- package/dist/deploy/targets/flatpak-manifest.d.ts.map +1 -0
- package/dist/deploy/targets/flatpak-manifest.js +48 -0
- package/dist/deploy/targets/flatpak-manifest.js.map +1 -0
- package/dist/deploy/targets/flatpak-prebuilt.d.ts +8 -0
- package/dist/deploy/targets/flatpak-prebuilt.d.ts.map +1 -0
- package/dist/deploy/targets/flatpak-prebuilt.js +43 -0
- package/dist/deploy/targets/flatpak-prebuilt.js.map +1 -0
- package/dist/deploy/targets/flatpak-source.d.ts +5 -0
- package/dist/deploy/targets/flatpak-source.d.ts.map +1 -0
- package/dist/deploy/targets/flatpak-source.js +110 -0
- package/dist/deploy/targets/flatpak-source.js.map +1 -0
- package/dist/deploy/targets/flatpak-sources.d.ts +17 -0
- package/dist/deploy/targets/flatpak-sources.d.ts.map +1 -0
- package/dist/deploy/targets/flatpak-sources.js +108 -0
- package/dist/deploy/targets/flatpak-sources.js.map +1 -0
- package/dist/deploy/targets/flatpak.d.ts +4 -0
- package/dist/deploy/targets/flatpak.d.ts.map +1 -0
- package/dist/deploy/targets/flatpak.js +112 -0
- package/dist/deploy/targets/flatpak.js.map +1 -0
- package/dist/deploy/targets/nfpm-target.d.ts +5 -0
- package/dist/deploy/targets/nfpm-target.d.ts.map +1 -0
- package/dist/deploy/targets/nfpm-target.js +26 -0
- package/dist/deploy/targets/nfpm-target.js.map +1 -0
- package/dist/deploy/targets/rpm.d.ts +4 -0
- package/dist/deploy/targets/rpm.d.ts.map +1 -0
- package/dist/deploy/targets/rpm.js +4 -0
- package/dist/deploy/targets/rpm.js.map +1 -0
- package/dist/deploy/tools.d.ts +18 -0
- package/dist/deploy/tools.d.ts.map +1 -0
- package/dist/deploy/tools.js +92 -0
- package/dist/deploy/tools.js.map +1 -0
- package/dist/deploy/types.d.ts +140 -0
- package/dist/deploy/types.d.ts.map +1 -0
- package/dist/deploy/types.js +2 -0
- package/dist/deploy/types.js.map +1 -0
- package/dist/deploy/vendored/appimagetool.d.ts +7 -0
- package/dist/deploy/vendored/appimagetool.d.ts.map +1 -0
- package/dist/deploy/vendored/appimagetool.js +42 -0
- package/dist/deploy/vendored/appimagetool.js.map +1 -0
- package/dist/deploy/vendored/nfpm.d.ts +3 -0
- package/dist/deploy/vendored/nfpm.d.ts.map +1 -0
- package/dist/deploy/vendored/nfpm.js +60 -0
- package/dist/deploy/vendored/nfpm.js.map +1 -0
- package/dist/dev/change-queue.d.ts +11 -0
- package/dist/dev/change-queue.d.ts.map +1 -0
- package/dist/dev/change-queue.js +34 -0
- package/dist/dev/change-queue.js.map +1 -0
- package/dist/dev/failure-tracker.d.ts +10 -0
- package/dist/dev/failure-tracker.d.ts.map +1 -0
- package/dist/dev/failure-tracker.js +61 -0
- package/dist/dev/failure-tracker.js.map +1 -0
- package/dist/dev/missing-import.d.ts +4 -0
- package/dist/dev/missing-import.d.ts.map +1 -0
- package/dist/dev/missing-import.js +23 -0
- package/dist/dev/missing-import.js.map +1 -0
- package/dist/dev/runner-deps.d.ts.map +1 -1
- package/dist/dev/runner-deps.js +25 -6
- package/dist/dev/runner-deps.js.map +1 -1
- package/dist/dev/runner.d.ts +8 -4
- package/dist/dev/runner.d.ts.map +1 -1
- package/dist/dev/runner.js +334 -66
- package/dist/dev/runner.js.map +1 -1
- package/dist/dev/supervisor.d.ts +1 -2
- package/dist/dev/supervisor.d.ts.map +1 -1
- package/dist/dev/supervisor.js +1 -1
- package/dist/dev/supervisor.js.map +1 -1
- package/dist/dev/vite-dev-server.d.ts +13 -2
- package/dist/dev/vite-dev-server.d.ts.map +1 -1
- package/dist/dev/vite-dev-server.js +30 -2
- package/dist/dev/vite-dev-server.js.map +1 -1
- package/dist/internal/entry-arg.d.ts +1 -7
- package/dist/internal/entry-arg.d.ts.map +1 -1
- package/dist/internal/entry-arg.js +18 -11
- package/dist/internal/entry-arg.js.map +1 -1
- package/dist/internal/module-loads.d.ts +7 -0
- package/dist/internal/module-loads.d.ts.map +1 -0
- package/dist/internal/module-loads.js +21 -0
- package/dist/internal/module-loads.js.map +1 -0
- package/dist/internal/prepare-project.d.ts +16 -0
- package/dist/internal/prepare-project.d.ts.map +1 -0
- package/dist/internal/prepare-project.js +15 -0
- package/dist/internal/prepare-project.js.map +1 -0
- package/dist/internal/run-cli-tool.d.ts +2 -1
- package/dist/internal/run-cli-tool.d.ts.map +1 -1
- package/dist/internal/run-cli-tool.js +15 -6
- package/dist/internal/run-cli-tool.js.map +1 -1
- package/dist/internal/staging-dir.d.ts +8 -1
- package/dist/internal/staging-dir.d.ts.map +1 -1
- package/dist/internal/staging-dir.js +38 -2
- package/dist/internal/staging-dir.js.map +1 -1
- package/dist/mcp/serialize-widget.d.ts +2 -1
- package/dist/mcp/serialize-widget.d.ts.map +1 -1
- package/dist/mcp/serialize-widget.js +1 -1
- package/dist/mcp/serialize-widget.js.map +1 -1
- package/dist/mcp/testing-loader.d.ts +5 -2
- package/dist/mcp/testing-loader.d.ts.map +1 -1
- package/dist/mcp/testing-loader.js +7 -3
- package/dist/mcp/testing-loader.js.map +1 -1
- package/dist/refresh-runtime.d.ts +2 -1
- package/dist/refresh-runtime.d.ts.map +1 -1
- package/dist/refresh-runtime.js +32 -2
- package/dist/refresh-runtime.js.map +1 -1
- package/dist/settings/schema.d.ts +1 -2
- package/dist/settings/schema.d.ts.map +1 -1
- package/dist/settings/schema.js +1 -1
- package/dist/settings/schema.js.map +1 -1
- package/dist/vite-plugins/asset-extensions.d.ts +2 -1
- package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
- package/dist/vite-plugins/asset-extensions.js +2 -1
- package/dist/vite-plugins/asset-extensions.js.map +1 -1
- package/dist/vite-plugins/asset-imports.d.ts +4 -0
- package/dist/vite-plugins/asset-imports.d.ts.map +1 -0
- package/dist/vite-plugins/asset-imports.js +88 -0
- package/dist/vite-plugins/asset-imports.js.map +1 -0
- package/dist/vite-plugins/asset-specifier.d.ts +5 -0
- package/dist/vite-plugins/asset-specifier.d.ts.map +1 -0
- package/dist/vite-plugins/asset-specifier.js +7 -0
- package/dist/vite-plugins/asset-specifier.js.map +1 -0
- package/dist/vite-plugins/esm-extension.d.ts +4 -0
- package/dist/vite-plugins/esm-extension.d.ts.map +1 -0
- package/dist/vite-plugins/esm-extension.js +4 -0
- package/dist/vite-plugins/esm-extension.js.map +1 -0
- package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts +1 -3
- package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -1
- package/dist/vite-plugins/fast-refresh/swc-refresh.js +1 -1
- package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -1
- package/dist/vite-plugins/index.d.ts.map +1 -1
- package/dist/vite-plugins/index.js +4 -0
- package/dist/vite-plugins/index.js.map +1 -1
- package/dist/vite-plugins/resource-shared.d.ts +2 -1
- package/dist/vite-plugins/resource-shared.d.ts.map +1 -1
- package/dist/vite-plugins/resource-shared.js +2 -1
- package/dist/vite-plugins/resource-shared.js.map +1 -1
- package/dist/vite-plugins/resources.d.ts.map +1 -1
- package/dist/vite-plugins/resources.js +30 -29
- package/dist/vite-plugins/resources.js.map +1 -1
- package/dist/vite-plugins/self-contained.d.ts +4 -0
- package/dist/vite-plugins/self-contained.d.ts.map +1 -0
- package/dist/vite-plugins/self-contained.js +244 -0
- package/dist/vite-plugins/self-contained.js.map +1 -0
- package/dist/vite-plugins/settings.d.ts.map +1 -1
- package/dist/vite-plugins/settings.js +19 -40
- package/dist/vite-plugins/settings.js.map +1 -1
- package/dist/vite-plugins/store-links.d.ts +4 -0
- package/dist/vite-plugins/store-links.d.ts.map +1 -0
- package/dist/vite-plugins/store-links.js +19 -0
- package/dist/vite-plugins/store-links.js.map +1 -0
- package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
- package/dist/vite-plugins/undeclared-library.js +51 -12
- package/dist/vite-plugins/undeclared-library.js.map +1 -1
- package/dist/vite-plugins/worker.d.ts.map +1 -1
- package/dist/vite-plugins/worker.js +3 -1
- package/dist/vite-plugins/worker.js.map +1 -1
- package/env.d.ts +106 -25
- package/package.json +20 -13
- package/src/builder.ts +22 -4
- package/src/cli.ts +7 -2
- package/src/codegen/freshness.ts +2 -2
- package/src/codegen/run-codegen.ts +37 -23
- package/src/codegen/store-resolver.ts +1 -1
- package/src/commands/build.ts +5 -6
- package/src/commands/codegen.ts +14 -1
- package/src/commands/deploy.ts +47 -0
- package/src/commands/dev.ts +4 -4
- package/src/commands/docs.ts +39 -4
- package/src/deploy/depends.ts +42 -0
- package/src/deploy/download.ts +148 -0
- package/src/deploy/freedesktop/copyright.ts +41 -0
- package/src/deploy/freedesktop/dbus-service.ts +19 -0
- package/src/deploy/freedesktop/desktop-entry.ts +102 -0
- package/src/deploy/freedesktop/ini.ts +39 -0
- package/src/deploy/freedesktop/metainfo-sections.ts +116 -0
- package/src/deploy/freedesktop/metainfo.ts +46 -0
- package/src/deploy/freedesktop/mime-package.ts +28 -0
- package/src/deploy/freedesktop/validate.ts +124 -0
- package/src/deploy/freedesktop/xml.ts +53 -0
- package/src/deploy/git.ts +20 -0
- package/src/deploy/install-hints.ts +108 -0
- package/src/deploy/nfpm/config.ts +153 -0
- package/src/deploy/nfpm/contents.ts +69 -0
- package/src/deploy/nfpm/description.ts +11 -0
- package/src/deploy/nfpm/optional.ts +8 -0
- package/src/deploy/nfpm/pack.ts +44 -0
- package/src/deploy/node-runtime/download.ts +48 -0
- package/src/deploy/node-runtime/elf.ts +145 -0
- package/src/deploy/node-runtime/guard.ts +29 -0
- package/src/deploy/node-runtime/index.ts +80 -0
- package/src/deploy/payload/copy-tree.ts +51 -0
- package/src/deploy/payload/icons.ts +80 -0
- package/src/deploy/payload/launcher.ts +27 -0
- package/src/deploy/payload/schemas.ts +27 -0
- package/src/deploy/payload/stage.ts +145 -0
- package/src/deploy/registry.ts +40 -0
- package/src/deploy/run-deploy.ts +235 -0
- package/src/deploy/settings/arch.ts +18 -0
- package/src/deploy/settings/categories.ts +39 -0
- package/src/deploy/settings/exec.ts +29 -0
- package/src/deploy/settings/identity.ts +133 -0
- package/src/deploy/settings/index.ts +189 -0
- package/src/deploy/settings/package-manifest.ts +66 -0
- package/src/deploy/settings/paths.ts +115 -0
- package/src/deploy/settings/screenshots.ts +125 -0
- package/src/deploy/settings/starter.ts +41 -0
- package/src/deploy/settings/version.ts +59 -0
- package/src/deploy/targets/appimage.ts +140 -0
- package/src/deploy/targets/deb.ts +6 -0
- package/src/deploy/targets/flatpak-manifest.ts +61 -0
- package/src/deploy/targets/flatpak-prebuilt.ts +59 -0
- package/src/deploy/targets/flatpak-source.ts +168 -0
- package/src/deploy/targets/flatpak-sources.ts +171 -0
- package/src/deploy/targets/flatpak.ts +143 -0
- package/src/deploy/targets/nfpm-target.ts +33 -0
- package/src/deploy/targets/rpm.ts +6 -0
- package/src/deploy/tools.ts +135 -0
- package/src/deploy/types.ts +174 -0
- package/src/deploy/vendored/appimagetool.ts +57 -0
- package/src/deploy/vendored/nfpm.ts +79 -0
- package/src/dev/change-queue.ts +59 -0
- package/src/dev/failure-tracker.ts +92 -0
- package/src/dev/missing-import.ts +32 -0
- package/src/dev/runner-deps.ts +34 -6
- package/src/dev/runner.ts +506 -102
- package/src/dev/supervisor.ts +0 -3
- package/src/dev/vite-dev-server.ts +54 -3
- package/src/internal/entry-arg.ts +25 -11
- package/src/internal/module-loads.ts +32 -0
- package/src/internal/prepare-project.ts +23 -0
- package/src/internal/run-cli-tool.ts +22 -6
- package/src/internal/staging-dir.ts +57 -2
- package/src/mcp/serialize-widget.ts +3 -2
- package/src/mcp/testing-loader.ts +19 -4
- package/src/refresh-runtime.ts +48 -2
- package/src/settings/schema.ts +0 -1
- package/src/vite-plugins/asset-extensions.ts +2 -1
- package/src/vite-plugins/asset-imports.ts +134 -0
- package/src/vite-plugins/asset-specifier.ts +9 -0
- package/src/vite-plugins/esm-extension.ts +4 -0
- package/src/vite-plugins/fast-refresh/swc-refresh.ts +1 -1
- package/src/vite-plugins/index.ts +4 -0
- package/src/vite-plugins/resource-shared.ts +2 -0
- package/src/vite-plugins/resources.ts +33 -33
- package/src/vite-plugins/self-contained.ts +352 -0
- package/src/vite-plugins/settings.ts +21 -48
- package/src/vite-plugins/store-links.ts +25 -0
- package/src/vite-plugins/undeclared-library.ts +74 -12
- package/src/vite-plugins/worker.ts +4 -1
- package/dist/internal.d.ts +0 -3
- package/dist/internal.d.ts.map +0 -1
- package/dist/internal.js +0 -3
- package/dist/internal.js.map +0 -1
- package/src/internal.ts +0 -2
package/src/commands/dev.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { defineCommand } from "citty";
|
|
2
|
-
import {
|
|
2
|
+
import { resolveConfigWatch } from "../codegen/run-codegen.js";
|
|
3
3
|
import { type DevWatch, runDevSupervisor } from "../dev/supervisor.js";
|
|
4
4
|
import { splitApplicationArgs } from "../internal/application-args.js";
|
|
5
|
-
import { entryArg
|
|
5
|
+
import { entryArg } from "../internal/entry-arg.js";
|
|
6
|
+
import { prepareProject } from "../internal/prepare-project.js";
|
|
6
7
|
|
|
7
8
|
const DEV_MODE = "development";
|
|
8
9
|
|
|
@@ -15,8 +16,7 @@ const dev = defineCommand({
|
|
|
15
16
|
...entryArg,
|
|
16
17
|
},
|
|
17
18
|
async run({ args }) {
|
|
18
|
-
const { cwd, entry: entryPath } =
|
|
19
|
-
await ensureGenerated(cwd, { shouldAnnounce: true, mode: DEV_MODE });
|
|
19
|
+
const { cwd, entry: entryPath } = await prepareProject(args, DEV_MODE);
|
|
20
20
|
const watch: DevWatch | undefined = await resolveConfigWatch(cwd, DEV_MODE);
|
|
21
21
|
const { applicationArgs } = splitApplicationArgs(process.argv.slice(2));
|
|
22
22
|
await runDevSupervisor({ entryPath, cwd, args: applicationArgs, watch });
|
package/src/commands/docs.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { resolveOmittedProps } from "@gtkx/config/internal";
|
|
|
13
13
|
import { info } from "@gtkx/utils";
|
|
14
14
|
import { defineCommand } from "citty";
|
|
15
15
|
import { existsSync } from "node:fs";
|
|
16
|
-
import { resolve } from "node:path";
|
|
16
|
+
import { isAbsolute, relative, resolve, sep } from "node:path";
|
|
17
17
|
import { cwdArg, resolveCwd } from "../internal/entry-arg.js";
|
|
18
18
|
|
|
19
19
|
const docs = defineCommand({
|
|
@@ -25,7 +25,9 @@ const docs = defineCommand({
|
|
|
25
25
|
args: {
|
|
26
26
|
out: {
|
|
27
27
|
type: "string",
|
|
28
|
-
description:
|
|
28
|
+
description:
|
|
29
|
+
"Output directory for the generated markdown pages, below the project root. It must be empty " +
|
|
30
|
+
"or hold an earlier `gtkx docs` run, whose pages are replaced",
|
|
29
31
|
default: "docs/reference",
|
|
30
32
|
},
|
|
31
33
|
"base-path": {
|
|
@@ -35,7 +37,9 @@ const docs = defineCommand({
|
|
|
35
37
|
},
|
|
36
38
|
force: {
|
|
37
39
|
type: "boolean",
|
|
38
|
-
description:
|
|
40
|
+
description:
|
|
41
|
+
"Regenerate even when the pages are up to date with the GIR libraries, the base path, " +
|
|
42
|
+
"and the element props the project configures",
|
|
39
43
|
default: false,
|
|
40
44
|
},
|
|
41
45
|
...cwdArg,
|
|
@@ -63,7 +67,7 @@ const docs = defineCommand({
|
|
|
63
67
|
|
|
64
68
|
const libraries = resolveLibraries(config.libraries, girPath);
|
|
65
69
|
const startedAt = Date.now();
|
|
66
|
-
const outDir =
|
|
70
|
+
const outDir = resolveOutDir(cwd, args.out);
|
|
67
71
|
const builtin = await resolveDocsElements(cwd);
|
|
68
72
|
|
|
69
73
|
const { isRegenerated, namespaces } = writeDocs({
|
|
@@ -91,6 +95,37 @@ const docs = defineCommand({
|
|
|
91
95
|
},
|
|
92
96
|
});
|
|
93
97
|
|
|
98
|
+
const isBelow = (parent: string, child: string): boolean => {
|
|
99
|
+
const path = relative(parent, child);
|
|
100
|
+
|
|
101
|
+
return path !== "" && path !== ".." && !path.startsWith(`..${sep}`) && !isAbsolute(path);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const outDirReason = (cwd: string, out: string, outDir: string): string => {
|
|
105
|
+
if (out.trim() === "") {
|
|
106
|
+
return "it was empty, which names the project root itself";
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (outDir === cwd) {
|
|
110
|
+
return "it names the project root itself";
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return `${outDir} is outside it`;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const resolveOutDir = (cwd: string, out: string): string => {
|
|
117
|
+
const outDir = out.trim() === "" ? cwd : resolve(cwd, out);
|
|
118
|
+
|
|
119
|
+
if (isBelow(cwd, outDir)) {
|
|
120
|
+
return outDir;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
throw new Error(
|
|
124
|
+
`--out must name a directory below the project root ${cwd}, and ${outDirReason(cwd, out, outDir)}. ` +
|
|
125
|
+
"Pass a path such as --out=docs/reference.",
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
|
|
94
129
|
const resolveDocsElements = async (cwd: string): Promise<{ props: ElementProps; omittedProps: OmittedProps }> => {
|
|
95
130
|
const { gi, reactSubexports } = resolveStore(cwd);
|
|
96
131
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { DeployConfig } from "./types.js";
|
|
2
|
+
|
|
3
|
+
type Relations = {
|
|
4
|
+
deb: string[];
|
|
5
|
+
rpm: string[];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const GLES_SONAME = "libGLESv2.so.2()(64bit)";
|
|
9
|
+
|
|
10
|
+
const BASE_DEPENDS: Relations = {
|
|
11
|
+
deb: ["hicolor-icon-theme", "adwaita-icon-theme", "gsettings-desktop-schemas"],
|
|
12
|
+
rpm: ["hicolor-icon-theme", "adwaita-icon-theme", "gsettings-desktop-schemas"],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const DEPENDS_BY_LIBRARY: Record<string, Relations> = {
|
|
16
|
+
"Adw-1": { deb: ["libadwaita-1-0"], rpm: ["libadwaita"] },
|
|
17
|
+
"Gtk-4.0": { deb: ["libgtk-4-1"], rpm: ["gtk4", GLES_SONAME] },
|
|
18
|
+
"GtkSource-5": { deb: ["libgtksourceview-5-0"], rpm: ["gtksourceview5"] },
|
|
19
|
+
"WebKit-6.0": { deb: ["libwebkitgtk-6.0-4"], rpm: ["webkitgtk6.0"] },
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const libraryDepends = (libraries: string[]): Relations => ({
|
|
23
|
+
deb: libraries.flatMap((library) => DEPENDS_BY_LIBRARY[library]?.deb ?? []),
|
|
24
|
+
rpm: libraries.flatMap((library) => DEPENDS_BY_LIBRARY[library]?.rpm ?? []),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const glibcDepends = (glibcFloor: string | null): Relations =>
|
|
28
|
+
glibcFloor === null ? { deb: [], rpm: [] } : { deb: [`libc6 (>= ${glibcFloor})`], rpm: [`glibc >= ${glibcFloor}`] };
|
|
29
|
+
|
|
30
|
+
const dedupe = (entries: string[]): string[] => [...new Set(entries)];
|
|
31
|
+
|
|
32
|
+
const resolveDepends = (deploy: DeployConfig, libraries: string[], glibcFloor: string | null): Relations => {
|
|
33
|
+
const fromLibraries = libraryDepends(libraries);
|
|
34
|
+
const fromGlibc = glibcDepends(glibcFloor);
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
deb: dedupe([...fromLibraries.deb, ...BASE_DEPENDS.deb, ...fromGlibc.deb, ...(deploy.depends?.deb ?? [])]),
|
|
38
|
+
rpm: dedupe([...fromLibraries.rpm, ...BASE_DEPENDS.rpm, ...fromGlibc.rpm, ...(deploy.depends?.rpm ?? [])]),
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { resolveDepends };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { info, warn } from "@gtkx/utils";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
|
|
7
|
+
type DigestRequest = {
|
|
8
|
+
url: string;
|
|
9
|
+
dest: string;
|
|
10
|
+
assetName: string;
|
|
11
|
+
subject: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type DownloadRequest = {
|
|
15
|
+
url: string;
|
|
16
|
+
dest: string;
|
|
17
|
+
label: string;
|
|
18
|
+
sha256: string;
|
|
19
|
+
freshSha256?: (() => Promise<string>) | undefined;
|
|
20
|
+
mode?: number | undefined;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const CACHE_NAMESPACE = "gtkx";
|
|
24
|
+
const DIGEST_PATTERN = /^[\da-f]{64}$/;
|
|
25
|
+
|
|
26
|
+
const cacheRoot = (): string => {
|
|
27
|
+
const base = process.env.XDG_CACHE_HOME;
|
|
28
|
+
|
|
29
|
+
return join(base !== undefined && base.length > 0 ? base : join(homedir(), ".cache"), CACHE_NAMESPACE);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const cacheDir = (segments: string[]): string => {
|
|
33
|
+
const dir = join(cacheRoot(), ...segments);
|
|
34
|
+
mkdirSync(dir, { recursive: true });
|
|
35
|
+
|
|
36
|
+
return dir;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const getDigest = (contents: Buffer): string => createHash("sha256").update(contents).digest("hex");
|
|
40
|
+
|
|
41
|
+
const assertDigest = (url: string, contents: Buffer, expected: string): void => {
|
|
42
|
+
const actual = getDigest(contents);
|
|
43
|
+
|
|
44
|
+
if (actual !== expected) {
|
|
45
|
+
throw new Error(`Checksum mismatch for ${url}\n expected ${expected}\n received ${actual}`);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const fetchBytes = async (url: string): Promise<Buffer> => {
|
|
50
|
+
const response = await fetch(url);
|
|
51
|
+
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
throw new Error(`Cannot download ${url}: HTTP ${String(response.status)} ${response.statusText}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return Buffer.from(await response.arrayBuffer());
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const fetchText = async (url: string): Promise<string> => {
|
|
60
|
+
const bytes = await fetchBytes(url);
|
|
61
|
+
|
|
62
|
+
return bytes.toString("utf8");
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const readCachedDigest = (dest: string): string | undefined => {
|
|
66
|
+
try {
|
|
67
|
+
const cached = readFileSync(dest, "utf8").trim();
|
|
68
|
+
|
|
69
|
+
return DIGEST_PATTERN.test(cached) ? cached : undefined;
|
|
70
|
+
} catch {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const writeAtomically = (dest: string, contents: string): void => {
|
|
76
|
+
const staging = `${dest}.partial`;
|
|
77
|
+
writeFileSync(staging, contents);
|
|
78
|
+
renameSync(staging, dest);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const publishedDigest = async (request: DigestRequest): Promise<string> => {
|
|
82
|
+
const checksums = await fetchText(request.url);
|
|
83
|
+
const digest = digestFromChecksums(checksums, request.assetName, request.subject);
|
|
84
|
+
|
|
85
|
+
if (!DIGEST_PATTERN.test(digest)) {
|
|
86
|
+
throw new Error(`${request.subject} published a malformed checksum for ${request.assetName}: "${digest}"`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
writeAtomically(request.dest, digest);
|
|
90
|
+
|
|
91
|
+
return digest;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const cachedDigest = async (request: DigestRequest): Promise<string> => {
|
|
95
|
+
const cached = readCachedDigest(request.dest);
|
|
96
|
+
|
|
97
|
+
return cached ?? publishedDigest(request);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const isCacheUsable = (dest: string, sha256: string): boolean => {
|
|
101
|
+
if (!existsSync(dest)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (getDigest(readFileSync(dest)) === sha256) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
warn(`Discarding the cached ${dest}: its checksum no longer matches`);
|
|
110
|
+
|
|
111
|
+
return false;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const downloadFile = async (request: DownloadRequest): Promise<string> => {
|
|
115
|
+
const { url, dest, label, sha256, mode } = request;
|
|
116
|
+
|
|
117
|
+
if (isCacheUsable(dest, sha256)) {
|
|
118
|
+
return dest;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
info(`Downloading ${label}`);
|
|
122
|
+
const expected = request.freshSha256 === undefined ? sha256 : await request.freshSha256();
|
|
123
|
+
const contents = await fetchBytes(url);
|
|
124
|
+
assertDigest(url, contents, expected);
|
|
125
|
+
const staging = `${dest}.partial`;
|
|
126
|
+
writeFileSync(staging, contents);
|
|
127
|
+
|
|
128
|
+
if (mode !== undefined) {
|
|
129
|
+
chmodSync(staging, mode);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
renameSync(staging, dest);
|
|
133
|
+
|
|
134
|
+
return dest;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const digestFromChecksums = (checksums: string, assetName: string, subject: string): string => {
|
|
138
|
+
const line = checksums.split("\n").find((entry) => entry.trim().endsWith(` ${assetName}`));
|
|
139
|
+
const digest = line?.trim().split(/\s+/, 1)[0];
|
|
140
|
+
|
|
141
|
+
if (digest === undefined) {
|
|
142
|
+
throw new Error(`${subject} publishes no checksum for ${assetName}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return digest;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export { cacheDir, cachedDigest, type DigestRequest, downloadFile, publishedDigest };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import type { DeploySettings } from "../types.js";
|
|
3
|
+
|
|
4
|
+
const FORMAT_URL = "https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/";
|
|
5
|
+
const CONTINUATION_BLANK = " .";
|
|
6
|
+
|
|
7
|
+
const indentLicenseBody = (body: string): string[] =>
|
|
8
|
+
body
|
|
9
|
+
.split("\n")
|
|
10
|
+
.map((line) => (line.trim().length === 0 ? CONTINUATION_BLANK : ` ${line}`));
|
|
11
|
+
|
|
12
|
+
const licenseBody = (licenseFile: string | null): string[] => {
|
|
13
|
+
if (licenseFile === null) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
return indentLicenseBody(readFileSync(licenseFile, "utf8").trimEnd());
|
|
19
|
+
} catch {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const headerLines = (settings: DeploySettings): string[] => [
|
|
25
|
+
`Format: ${FORMAT_URL}`,
|
|
26
|
+
`Upstream-Name: ${settings.name}`,
|
|
27
|
+
...(settings.homepage === null ? [] : [`Source: ${settings.homepage}`]),
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const renderCopyright = (settings: DeploySettings): string =>
|
|
31
|
+
[
|
|
32
|
+
...headerLines(settings),
|
|
33
|
+
"",
|
|
34
|
+
"Files: *",
|
|
35
|
+
`Copyright: ${settings.copyright}`,
|
|
36
|
+
`License: ${settings.license}`,
|
|
37
|
+
...licenseBody(settings.paths.licenseFile),
|
|
38
|
+
"",
|
|
39
|
+
].join("\n");
|
|
40
|
+
|
|
41
|
+
export { renderCopyright };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { posix } from "node:path";
|
|
2
|
+
import type { DeploySettings } from "../types.js";
|
|
3
|
+
import { renderIni } from "./ini.js";
|
|
4
|
+
|
|
5
|
+
const SERVICE_GROUP = "D-BUS Service";
|
|
6
|
+
const SERVICE_FLAG = "--gapplication-service";
|
|
7
|
+
|
|
8
|
+
const renderDbusService = (settings: DeploySettings, prefix: string): string =>
|
|
9
|
+
renderIni([
|
|
10
|
+
{
|
|
11
|
+
name: SERVICE_GROUP,
|
|
12
|
+
entries: [
|
|
13
|
+
["Name", settings.applicationId],
|
|
14
|
+
["Exec", `${posix.join(prefix, "bin", settings.binaryName)} ${SERVICE_FLAG}`],
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
export { renderDbusService };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { DeployDesktopAction, DeploySettings } from "../types.js";
|
|
2
|
+
import { type IniGroup, renderIni } from "./ini.js";
|
|
3
|
+
|
|
4
|
+
type Entries = [string, string | string[]][];
|
|
5
|
+
|
|
6
|
+
const DESKTOP_ENTRY_GROUP = "Desktop Entry";
|
|
7
|
+
const EXEC_QUOTED_CHARACTERS = /["`$\\]/g;
|
|
8
|
+
const EXEC_RESERVED_CHARACTERS = /[\s"'\\><~|&;$*?#()`]/;
|
|
9
|
+
|
|
10
|
+
const RESERVED_KEYS = new Map([
|
|
11
|
+
["DBusActivatable", "use `deploy.isDbusActivatable` instead"],
|
|
12
|
+
["Version", "it names the desktop entry spec version, not the application's"],
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
const quoteExecToken = (token: string): string => {
|
|
16
|
+
const escaped = token.replaceAll("%", "%%");
|
|
17
|
+
|
|
18
|
+
if (!EXEC_RESERVED_CHARACTERS.test(escaped)) {
|
|
19
|
+
return escaped;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const quoted = escaped.replaceAll(EXEC_QUOTED_CHARACTERS, (character) => `\\${character}`);
|
|
23
|
+
|
|
24
|
+
return `"${quoted}"`;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const execLine = (settings: DeploySettings): string =>
|
|
28
|
+
[
|
|
29
|
+
...[settings.binaryName, ...settings.execArgs].map((part) => quoteExecToken(part)),
|
|
30
|
+
settings.execToken ?? "",
|
|
31
|
+
]
|
|
32
|
+
.filter((part) => part.length > 0)
|
|
33
|
+
.join(" ");
|
|
34
|
+
|
|
35
|
+
const optionalEntry = (key: string, value: string | null): Entries => (value === null ? [] : [[key, value]]);
|
|
36
|
+
const listEntry = (key: string, values: string[]): Entries => (values.length === 0 ? [] : [[key, values]]);
|
|
37
|
+
|
|
38
|
+
const assertNoReservedOverrides = (settings: DeploySettings): void => {
|
|
39
|
+
for (const key of Object.keys(settings.desktopEntry)) {
|
|
40
|
+
const remedy = RESERVED_KEYS.get(key);
|
|
41
|
+
|
|
42
|
+
if (remedy !== undefined) {
|
|
43
|
+
throw new Error(`Cannot set "${key}" through \`deploy.desktopEntry\`: gtkx deploy writes it, ${remedy}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const baseEntries = (settings: DeploySettings): Entries => [
|
|
49
|
+
["Type", "Application"],
|
|
50
|
+
["Name", settings.name],
|
|
51
|
+
...optionalEntry("GenericName", settings.genericName),
|
|
52
|
+
["Comment", settings.summary],
|
|
53
|
+
["Exec", execLine(settings)],
|
|
54
|
+
["Icon", settings.applicationId],
|
|
55
|
+
["Terminal", "false"],
|
|
56
|
+
...listEntry("Categories", settings.categories),
|
|
57
|
+
...listEntry("Keywords", settings.keywords),
|
|
58
|
+
...listEntry("MimeType", settings.mimeTypes),
|
|
59
|
+
["StartupNotify", "true"],
|
|
60
|
+
["StartupWMClass", settings.applicationId],
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
const actionEntries = (settings: DeploySettings): Entries =>
|
|
64
|
+
settings.desktopActions.length === 0 ? [] : [["Actions", settings.desktopActions.map((action) => action.id)]];
|
|
65
|
+
|
|
66
|
+
const activationEntries = (settings: DeploySettings): Entries =>
|
|
67
|
+
settings.isDbusActivatable ? [["DBusActivatable", "true"]] : [];
|
|
68
|
+
|
|
69
|
+
const actionGroup = (settings: DeploySettings, action: DeployDesktopAction): IniGroup => ({
|
|
70
|
+
name: `Desktop Action ${action.id}`,
|
|
71
|
+
entries: [
|
|
72
|
+
["Name", action.name],
|
|
73
|
+
["Exec", [settings.binaryName, ...action.args].map((part) => quoteExecToken(part)).join(" ")],
|
|
74
|
+
...optionalEntry("Icon", action.icon),
|
|
75
|
+
],
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const mergeEntries = (entries: Entries, overrides: Entries): Entries => {
|
|
79
|
+
const merged = new Map(entries);
|
|
80
|
+
|
|
81
|
+
for (const [key, value] of overrides) {
|
|
82
|
+
merged.set(key, value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return merged.entries().toArray();
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const renderDesktopEntry = (settings: DeploySettings): string => {
|
|
89
|
+
assertNoReservedOverrides(settings);
|
|
90
|
+
|
|
91
|
+
const main: IniGroup = {
|
|
92
|
+
name: DESKTOP_ENTRY_GROUP,
|
|
93
|
+
entries: mergeEntries(
|
|
94
|
+
[...baseEntries(settings), ...actionEntries(settings), ...activationEntries(settings)],
|
|
95
|
+
Object.entries(settings.desktopEntry),
|
|
96
|
+
),
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return renderIni([main, ...settings.desktopActions.map((action) => actionGroup(settings, action))]);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export { renderDesktopEntry };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
type IniGroup = {
|
|
2
|
+
name: string;
|
|
3
|
+
entries: [string, string | string[]][];
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const FORBIDDEN_VALUE_CHARACTERS = /[\n\r]/;
|
|
7
|
+
|
|
8
|
+
const assertValue = (key: string, value: string): void => {
|
|
9
|
+
if (FORBIDDEN_VALUE_CHARACTERS.test(value)) {
|
|
10
|
+
throw new Error(`Cannot write "${key}" into a desktop entry: its value contains a line break`);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const escapeValue = (key: string, value: string): string => {
|
|
15
|
+
assertValue(key, value);
|
|
16
|
+
|
|
17
|
+
return value.replaceAll("\\", "\\\\");
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const escapeListItem = (key: string, value: string): string => escapeValue(key, value).replaceAll(";", String.raw`\;`);
|
|
21
|
+
|
|
22
|
+
const renderList = (key: string, values: string[]): string =>
|
|
23
|
+
values.length === 0 ? "" : `${values.map((item) => escapeListItem(key, item)).join(";")};`;
|
|
24
|
+
|
|
25
|
+
const renderValue = (key: string, value: string | string[]): string =>
|
|
26
|
+
Array.isArray(value) ? renderList(key, value) : escapeValue(key, value);
|
|
27
|
+
|
|
28
|
+
const renderEntry = ([key, value]: [string, string | string[]]): string => `${key}=${renderValue(key, value)}`;
|
|
29
|
+
|
|
30
|
+
const renderGroup = (group: IniGroup): string[] => [
|
|
31
|
+
`[${group.name}]`,
|
|
32
|
+
...group.entries.map((entry) => renderEntry(entry)),
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const renderIni = (groups: IniGroup[]): string =>
|
|
36
|
+
[...groups.flatMap((group, index) => (index === 0 ? renderGroup(group) : ["", ...renderGroup(group)])), ""]
|
|
37
|
+
.join("\n");
|
|
38
|
+
|
|
39
|
+
export { type IniGroup, renderIni };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { DeployRelease, DeploySettings } from "../types.js";
|
|
2
|
+
import { element, text, type XmlNode } from "./xml.js";
|
|
3
|
+
|
|
4
|
+
const CONTENT_RATING_TYPE = "oars-1.1";
|
|
5
|
+
const DEFAULT_SCREENSHOT_TYPE = "default";
|
|
6
|
+
const PRIMARY_COLOR = "primary";
|
|
7
|
+
|
|
8
|
+
const developerSection = (settings: DeploySettings): XmlNode[] => {
|
|
9
|
+
const attributes = settings.developer.id === null ? {} : { id: settings.developer.id };
|
|
10
|
+
|
|
11
|
+
return [element("developer", attributes, [text("name", settings.developer.name)])];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const descriptionSection = (settings: DeploySettings): XmlNode[] => [
|
|
15
|
+
element("description", {}, settings.description.map((paragraph) => text("p", paragraph))),
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const providesSection = (settings: DeploySettings): XmlNode[] => [
|
|
19
|
+
element("provides", {}, [
|
|
20
|
+
text("binary", settings.binaryName),
|
|
21
|
+
...settings.mimeTypes.map((mimeType) => text("mediatype", mimeType)),
|
|
22
|
+
]),
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const listSection = (tag: string, itemTag: string, values: string[]): XmlNode[] =>
|
|
26
|
+
values.length === 0 ? [] : [element(tag, {}, values.map((value) => text(itemTag, value)))];
|
|
27
|
+
|
|
28
|
+
const urlsSection = (settings: DeploySettings): XmlNode[] => {
|
|
29
|
+
const homepage = settings.homepage === null ? [] : [{ tag: "homepage", url: settings.homepage }];
|
|
30
|
+
const rest = Object.entries(settings.urls).map(([tag, url]) => ({ tag, url }));
|
|
31
|
+
|
|
32
|
+
return [...homepage, ...rest].map((entry) => ({ tag: "url", attributes: { type: entry.tag }, text: entry.url }));
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const screenshotsSection = (settings: DeploySettings): XmlNode[] => {
|
|
36
|
+
if (settings.screenshots.length === 0) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const entries = settings.screenshots.map((screenshot) =>
|
|
41
|
+
element(
|
|
42
|
+
"screenshot",
|
|
43
|
+
screenshot.isDefault ? { type: DEFAULT_SCREENSHOT_TYPE } : {},
|
|
44
|
+
[
|
|
45
|
+
text("image", screenshot.url),
|
|
46
|
+
...(screenshot.caption === null ? [] : [text("caption", screenshot.caption)]),
|
|
47
|
+
],
|
|
48
|
+
));
|
|
49
|
+
|
|
50
|
+
return [element("screenshots", {}, entries)];
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const releaseAttributes = (release: DeployRelease): Record<string, string> => ({
|
|
54
|
+
version: release.version,
|
|
55
|
+
date: release.date,
|
|
56
|
+
...(release.type !== null && { type: release.type }),
|
|
57
|
+
...(release.urgency !== null && { urgency: release.urgency }),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const releaseChildren = (release: DeployRelease): XmlNode[] => [
|
|
61
|
+
...(release.url === null ? [] : [{ tag: "url", attributes: { type: "details" }, text: release.url }]),
|
|
62
|
+
...(release.notes.length === 0
|
|
63
|
+
? []
|
|
64
|
+
: [element("description", {}, release.notes.map((note) => text("p", note)))]),
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const releasesSection = (settings: DeploySettings): XmlNode[] => {
|
|
68
|
+
if (settings.releases.length === 0) {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const entries = settings.releases.map((release) =>
|
|
73
|
+
element("release", releaseAttributes(release), releaseChildren(release)));
|
|
74
|
+
|
|
75
|
+
return [element("releases", {}, entries)];
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const contentRatingSection = (settings: DeploySettings): XmlNode[] => [
|
|
79
|
+
element(
|
|
80
|
+
"content_rating",
|
|
81
|
+
{ type: CONTENT_RATING_TYPE },
|
|
82
|
+
Object.entries(settings.contentRating).map(([id, intensity]) => ({
|
|
83
|
+
tag: "content_attribute",
|
|
84
|
+
attributes: { id },
|
|
85
|
+
text: intensity,
|
|
86
|
+
})),
|
|
87
|
+
),
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
const brandingSection = (settings: DeploySettings): XmlNode[] => {
|
|
91
|
+
const branding = settings.branding;
|
|
92
|
+
|
|
93
|
+
if (branding === null) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const color = (scheme: string, value: string): XmlNode => ({
|
|
98
|
+
tag: "color",
|
|
99
|
+
attributes: { type: PRIMARY_COLOR, scheme_preference: scheme },
|
|
100
|
+
text: value,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return [element("branding", {}, [color("light", branding.light), color("dark", branding.dark)])];
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export {
|
|
107
|
+
brandingSection,
|
|
108
|
+
contentRatingSection,
|
|
109
|
+
descriptionSection,
|
|
110
|
+
developerSection,
|
|
111
|
+
listSection,
|
|
112
|
+
providesSection,
|
|
113
|
+
releasesSection,
|
|
114
|
+
screenshotsSection,
|
|
115
|
+
urlsSection,
|
|
116
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { DeploySettings } from "../types.js";
|
|
2
|
+
import {
|
|
3
|
+
brandingSection,
|
|
4
|
+
contentRatingSection,
|
|
5
|
+
descriptionSection,
|
|
6
|
+
developerSection,
|
|
7
|
+
listSection,
|
|
8
|
+
providesSection,
|
|
9
|
+
releasesSection,
|
|
10
|
+
screenshotsSection,
|
|
11
|
+
urlsSection,
|
|
12
|
+
} from "./metainfo-sections.js";
|
|
13
|
+
import { element, renderDocument, text, type XmlNode } from "./xml.js";
|
|
14
|
+
|
|
15
|
+
const COMPONENT_TYPE = "desktop-application";
|
|
16
|
+
const DESKTOP_SUFFIX = ".desktop";
|
|
17
|
+
|
|
18
|
+
const launchable = (applicationId: string): XmlNode => ({
|
|
19
|
+
tag: "launchable",
|
|
20
|
+
attributes: { type: "desktop-id" },
|
|
21
|
+
text: `${applicationId}${DESKTOP_SUFFIX}`,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const renderMetainfo = (settings: DeploySettings): string =>
|
|
25
|
+
renderDocument(
|
|
26
|
+
element("component", { type: COMPONENT_TYPE }, [
|
|
27
|
+
text("id", settings.applicationId),
|
|
28
|
+
text("name", settings.name),
|
|
29
|
+
text("summary", settings.summary),
|
|
30
|
+
text("metadata_license", settings.metadataLicense),
|
|
31
|
+
text("project_license", settings.license),
|
|
32
|
+
...developerSection(settings),
|
|
33
|
+
...descriptionSection(settings),
|
|
34
|
+
launchable(settings.applicationId),
|
|
35
|
+
...providesSection(settings),
|
|
36
|
+
...listSection("categories", "category", settings.categories),
|
|
37
|
+
...listSection("keywords", "keyword", settings.keywords),
|
|
38
|
+
...urlsSection(settings),
|
|
39
|
+
...screenshotsSection(settings),
|
|
40
|
+
...releasesSection(settings),
|
|
41
|
+
...contentRatingSection(settings),
|
|
42
|
+
...brandingSection(settings),
|
|
43
|
+
]),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
export { renderMetainfo };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DeployFileAssociation, DeploySettings } from "../types.js";
|
|
2
|
+
import { element, renderDocument, text, type XmlNode } from "./xml.js";
|
|
3
|
+
|
|
4
|
+
/* eslint-disable-next-line sonarjs/no-clear-text-protocols, unicorn/prefer-https --
|
|
5
|
+
An XML namespace is a fixed identifier, not a URL to fetch: shared-mime-info only recognizes this exact string. */
|
|
6
|
+
const MIME_INFO_NAMESPACE = "http://www.freedesktop.org/standards/shared-mime-info";
|
|
7
|
+
|
|
8
|
+
const mimeTypeNode = (association: DeployFileAssociation): XmlNode =>
|
|
9
|
+
element("mime-type", { type: association.mimeType }, [
|
|
10
|
+
...(association.description === null ? [] : [text("comment", association.description)]),
|
|
11
|
+
{ tag: "glob", attributes: { pattern: `*.${association.extension}` } },
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
const renderMimePackage = (settings: DeploySettings): string | null => {
|
|
15
|
+
if (settings.fileAssociations.length === 0) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return renderDocument(
|
|
20
|
+
element(
|
|
21
|
+
"mime-info",
|
|
22
|
+
{ xmlns: MIME_INFO_NAMESPACE },
|
|
23
|
+
settings.fileAssociations.map((entry) => mimeTypeNode(entry)),
|
|
24
|
+
),
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { renderMimePackage };
|