@gtkx/cli 2.0.0-beta.1 → 2.0.0-beta.10
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 +43 -40
- package/bin/gtkx-dev-runner.js +5 -1
- package/bin/gtkx.js +5 -1
- package/dist/builder.d.ts +1 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +44 -12
- package/dist/builder.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -2
- package/dist/cli.js.map +1 -1
- package/dist/codegen/config-dependencies.d.ts +3 -0
- package/dist/codegen/config-dependencies.d.ts.map +1 -0
- package/dist/codegen/config-dependencies.js +355 -0
- package/dist/codegen/config-dependencies.js.map +1 -0
- package/dist/codegen/freshness.d.ts.map +1 -1
- package/dist/codegen/freshness.js +5 -1
- package/dist/codegen/freshness.js.map +1 -1
- package/dist/codegen/reference.d.ts.map +1 -1
- package/dist/codegen/reference.js +1 -0
- package/dist/codegen/reference.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +6 -3
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +42 -18
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/codegen/store-resolver.d.ts +3 -1
- package/dist/codegen/store-resolver.d.ts.map +1 -1
- package/dist/codegen/store-resolver.js +7 -4
- package/dist/codegen/store-resolver.js.map +1 -1
- package/dist/commands/build.d.ts +5 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +83 -10
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/cleanup.d.ts +9 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +42 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/codegen.d.ts +1 -0
- package/dist/commands/codegen.d.ts.map +1 -1
- package/dist/commands/codegen.js +6 -5
- package/dist/commands/codegen.js.map +1 -1
- package/dist/commands/deploy.d.ts +5 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +10 -2
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +9 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +31 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +1 -0
- package/dist/commands/docs.js.map +1 -1
- package/dist/deploy/depends.d.ts.map +1 -1
- package/dist/deploy/depends.js +24 -2
- package/dist/deploy/depends.js.map +1 -1
- package/dist/deploy/download.d.ts +7 -3
- package/dist/deploy/download.d.ts.map +1 -1
- package/dist/deploy/download.js +19 -20
- package/dist/deploy/download.js.map +1 -1
- package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -1
- package/dist/deploy/freedesktop/metainfo.js +41 -2
- package/dist/deploy/freedesktop/metainfo.js.map +1 -1
- package/dist/deploy/freedesktop/validate.d.ts.map +1 -1
- package/dist/deploy/freedesktop/validate.js +58 -14
- package/dist/deploy/freedesktop/validate.js.map +1 -1
- package/dist/deploy/native-addon.d.ts +5 -0
- package/dist/deploy/native-addon.d.ts.map +1 -0
- package/dist/deploy/native-addon.js +134 -0
- package/dist/deploy/native-addon.js.map +1 -0
- package/dist/deploy/nfpm/config.d.ts +3 -2
- package/dist/deploy/nfpm/config.d.ts.map +1 -1
- package/dist/deploy/nfpm/config.js +7 -4
- package/dist/deploy/nfpm/config.js.map +1 -1
- package/dist/deploy/nfpm/contents.d.ts.map +1 -1
- package/dist/deploy/nfpm/contents.js +8 -0
- package/dist/deploy/nfpm/contents.js.map +1 -1
- package/dist/deploy/node-runtime/download.js +2 -2
- package/dist/deploy/node-runtime/download.js.map +1 -1
- package/dist/deploy/node-runtime/elf.d.ts +4 -1
- package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
- package/dist/deploy/node-runtime/elf.js +34 -5
- package/dist/deploy/node-runtime/elf.js.map +1 -1
- package/dist/deploy/node-runtime/guard.d.ts.map +1 -1
- package/dist/deploy/node-runtime/guard.js +7 -14
- package/dist/deploy/node-runtime/guard.js.map +1 -1
- package/dist/deploy/node-runtime/index.d.ts +3 -1
- package/dist/deploy/node-runtime/index.d.ts.map +1 -1
- package/dist/deploy/node-runtime/index.js +103 -10
- package/dist/deploy/node-runtime/index.js.map +1 -1
- package/dist/deploy/node-runtime/sonames.d.ts +5 -0
- package/dist/deploy/node-runtime/sonames.d.ts.map +1 -0
- package/dist/deploy/node-runtime/sonames.js +13 -0
- package/dist/deploy/node-runtime/sonames.js.map +1 -0
- package/dist/deploy/notices/node-runtime.js +2 -2
- package/dist/deploy/notices/node-runtime.js.map +1 -1
- package/dist/deploy/payload/launcher.d.ts.map +1 -1
- package/dist/deploy/payload/launcher.js +14 -1
- package/dist/deploy/payload/launcher.js.map +1 -1
- package/dist/deploy/payload/stage.d.ts +2 -1
- package/dist/deploy/payload/stage.d.ts.map +1 -1
- package/dist/deploy/payload/stage.js +46 -5
- package/dist/deploy/payload/stage.js.map +1 -1
- package/dist/deploy/run-deploy.d.ts +2 -0
- package/dist/deploy/run-deploy.d.ts.map +1 -1
- package/dist/deploy/run-deploy.js +197 -52
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/settings/arch.d.ts +9 -3
- package/dist/deploy/settings/arch.d.ts.map +1 -1
- package/dist/deploy/settings/arch.js +27 -6
- package/dist/deploy/settings/arch.js.map +1 -1
- package/dist/deploy/settings/build-manifest.d.ts +6 -1
- package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
- package/dist/deploy/settings/build-manifest.js +15 -4
- package/dist/deploy/settings/build-manifest.js.map +1 -1
- package/dist/deploy/settings/extra-files.d.ts +1 -1
- package/dist/deploy/settings/extra-files.d.ts.map +1 -1
- package/dist/deploy/settings/extra-files.js +25 -3
- package/dist/deploy/settings/extra-files.js.map +1 -1
- package/dist/deploy/settings/index.d.ts +3 -1
- package/dist/deploy/settings/index.d.ts.map +1 -1
- package/dist/deploy/settings/index.js +4 -2
- package/dist/deploy/settings/index.js.map +1 -1
- package/dist/deploy/settings/libraries.d.ts.map +1 -1
- package/dist/deploy/settings/libraries.js +2 -1
- package/dist/deploy/settings/libraries.js.map +1 -1
- package/dist/deploy/settings/paths.d.ts +4 -2
- package/dist/deploy/settings/paths.d.ts.map +1 -1
- package/dist/deploy/settings/paths.js +121 -12
- package/dist/deploy/settings/paths.js.map +1 -1
- package/dist/deploy/targets/appimage.d.ts.map +1 -1
- package/dist/deploy/targets/appimage.js +1 -0
- package/dist/deploy/targets/appimage.js.map +1 -1
- package/dist/deploy/targets/flatpak-pnpm.js +4 -4
- package/dist/deploy/targets/flatpak-pnpm.js.map +1 -1
- package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-source.js +13 -2
- package/dist/deploy/targets/flatpak-source.js.map +1 -1
- package/dist/deploy/targets/flatpak.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak.js +1 -0
- package/dist/deploy/targets/flatpak.js.map +1 -1
- package/dist/deploy/targets/nfpm-target.d.ts.map +1 -1
- package/dist/deploy/targets/nfpm-target.js +13 -7
- package/dist/deploy/targets/nfpm-target.js.map +1 -1
- package/dist/deploy/types.d.ts +5 -2
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/deploy/types.js.map +1 -1
- package/dist/deploy/vendored/appimagetool.js +2 -2
- package/dist/deploy/vendored/appimagetool.js.map +1 -1
- package/dist/deploy/vendored/nfpm.js +1 -1
- package/dist/deploy/vendored/nfpm.js.map +1 -1
- package/dist/dev/catalog-writes.d.ts +8 -0
- package/dist/dev/catalog-writes.d.ts.map +1 -0
- package/dist/dev/catalog-writes.js +26 -0
- package/dist/dev/catalog-writes.js.map +1 -0
- package/dist/dev/entry-env.d.ts +2 -1
- package/dist/dev/entry-env.d.ts.map +1 -1
- package/dist/dev/entry-env.js +2 -1
- package/dist/dev/entry-env.js.map +1 -1
- package/dist/dev/font-dir.d.ts +3 -0
- package/dist/dev/font-dir.d.ts.map +1 -0
- package/dist/dev/font-dir.js +9 -0
- package/dist/dev/font-dir.js.map +1 -0
- package/dist/dev/headless.d.ts +3 -0
- package/dist/dev/headless.d.ts.map +1 -0
- package/dist/dev/headless.js +35 -0
- package/dist/dev/headless.js.map +1 -0
- package/dist/dev/runner-deps.d.ts +1 -1
- package/dist/dev/runner-deps.d.ts.map +1 -1
- package/dist/dev/runner-deps.js +12 -7
- package/dist/dev/runner-deps.js.map +1 -1
- package/dist/dev/runner-main.d.ts.map +1 -1
- package/dist/dev/runner-main.js +10 -3
- package/dist/dev/runner-main.js.map +1 -1
- package/dist/dev/runner.d.ts +2 -0
- package/dist/dev/runner.d.ts.map +1 -1
- package/dist/dev/runner.js +26 -7
- package/dist/dev/runner.js.map +1 -1
- package/dist/dev/supervisor.d.ts +3 -1
- package/dist/dev/supervisor.d.ts.map +1 -1
- package/dist/dev/supervisor.js +132 -29
- package/dist/dev/supervisor.js.map +1 -1
- package/dist/dev/vite-dev-server.d.ts +1 -1
- package/dist/dev/vite-dev-server.d.ts.map +1 -1
- package/dist/dev/vite-dev-server.js +14 -2
- package/dist/dev/vite-dev-server.js.map +1 -1
- package/dist/dev/watch-ignore.d.ts +3 -0
- package/dist/dev/watch-ignore.d.ts.map +1 -0
- package/dist/dev/watch-ignore.js +11 -0
- package/dist/dev/watch-ignore.js.map +1 -0
- package/dist/i18n/catalogs.d.ts +6 -2
- package/dist/i18n/catalogs.d.ts.map +1 -1
- package/dist/i18n/catalogs.js +10 -7
- package/dist/i18n/catalogs.js.map +1 -1
- package/dist/i18n/source-messages.d.ts +3 -1
- package/dist/i18n/source-messages.d.ts.map +1 -1
- package/dist/i18n/source-messages.js +973 -9
- package/dist/i18n/source-messages.js.map +1 -1
- package/dist/internal/agent-rules.d.ts.map +1 -1
- package/dist/internal/agent-rules.js +7 -2
- package/dist/internal/agent-rules.js.map +1 -1
- package/dist/internal/banner.d.ts +4 -2
- package/dist/internal/banner.d.ts.map +1 -1
- package/dist/internal/banner.js +19 -5
- package/dist/internal/banner.js.map +1 -1
- package/dist/internal/build-manifest.d.ts +5 -2
- package/dist/internal/build-manifest.d.ts.map +1 -1
- package/dist/internal/build-manifest.js +15 -2
- package/dist/internal/build-manifest.js.map +1 -1
- package/dist/internal/build-output.d.ts +8 -0
- package/dist/internal/build-output.d.ts.map +1 -0
- package/dist/internal/build-output.js +116 -0
- package/dist/internal/build-output.js.map +1 -0
- package/dist/internal/cache-root.d.ts +3 -0
- package/dist/internal/cache-root.d.ts.map +1 -0
- package/dist/internal/cache-root.js +9 -0
- package/dist/internal/cache-root.js.map +1 -0
- package/dist/internal/compile-cache-store.d.ts +4 -0
- package/dist/internal/compile-cache-store.d.ts.map +1 -0
- package/dist/internal/compile-cache-store.js +41 -0
- package/dist/internal/compile-cache-store.js.map +1 -0
- package/dist/internal/compile-cache.d.ts +4 -0
- package/dist/internal/compile-cache.d.ts.map +1 -0
- package/dist/internal/compile-cache.js +16 -0
- package/dist/internal/compile-cache.js.map +1 -0
- package/dist/internal/deploy-out-dir.d.ts +4 -0
- package/dist/internal/deploy-out-dir.d.ts.map +1 -0
- package/dist/internal/deploy-out-dir.js +5 -0
- package/dist/internal/deploy-out-dir.js.map +1 -0
- package/dist/internal/docs-elements.d.ts +1 -0
- package/dist/internal/docs-elements.d.ts.map +1 -1
- package/dist/internal/docs-elements.js +5 -4
- package/dist/internal/docs-elements.js.map +1 -1
- package/dist/internal/entry-arg.d.ts +4 -1
- package/dist/internal/entry-arg.d.ts.map +1 -1
- package/dist/internal/entry-arg.js +7 -1
- package/dist/internal/entry-arg.js.map +1 -1
- package/dist/internal/errors.d.ts +2 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +1 -1
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/font-path.d.ts +4 -0
- package/dist/internal/font-path.d.ts.map +1 -0
- package/dist/internal/font-path.js +12 -0
- package/dist/internal/font-path.js.map +1 -0
- package/dist/internal/font-staging.d.ts +6 -0
- package/dist/internal/font-staging.d.ts.map +1 -0
- package/dist/internal/font-staging.js +94 -0
- package/dist/internal/font-staging.js.map +1 -0
- package/dist/internal/icon-staging.d.ts +3 -0
- package/dist/internal/icon-staging.d.ts.map +1 -0
- package/dist/internal/icon-staging.js +40 -0
- package/dist/internal/icon-staging.js.map +1 -0
- package/dist/internal/import-scan.d.ts +4 -0
- package/dist/internal/import-scan.d.ts.map +1 -0
- package/dist/internal/import-scan.js +138 -0
- package/dist/internal/import-scan.js.map +1 -0
- package/dist/internal/module-hash.d.ts +3 -0
- package/dist/internal/module-hash.d.ts.map +1 -0
- package/dist/internal/module-hash.js +19 -0
- package/dist/internal/module-hash.js.map +1 -0
- package/dist/internal/output-directory.d.ts +15 -0
- package/dist/internal/output-directory.d.ts.map +1 -0
- package/dist/internal/output-directory.js +490 -0
- package/dist/internal/output-directory.js.map +1 -0
- package/dist/internal/parent-process.d.ts +12 -0
- package/dist/internal/parent-process.d.ts.map +1 -0
- package/dist/internal/parent-process.js +74 -0
- package/dist/internal/parent-process.js.map +1 -0
- package/dist/internal/prepare-project.d.ts +3 -0
- package/dist/internal/prepare-project.d.ts.map +1 -1
- package/dist/internal/prepare-project.js +9 -3
- package/dist/internal/prepare-project.js.map +1 -1
- package/dist/internal/react-compiler-cache.d.ts +13 -0
- package/dist/internal/react-compiler-cache.d.ts.map +1 -0
- package/dist/internal/react-compiler-cache.js +182 -0
- package/dist/internal/react-compiler-cache.js.map +1 -0
- package/dist/internal/source-imports.d.ts +7 -2
- package/dist/internal/source-imports.d.ts.map +1 -1
- package/dist/internal/source-imports.js +31 -11
- package/dist/internal/source-imports.js.map +1 -1
- package/dist/internal/staging-file.d.ts +5 -0
- package/dist/internal/staging-file.d.ts.map +1 -0
- package/dist/internal/staging-file.js +35 -0
- package/dist/internal/staging-file.js.map +1 -0
- package/dist/internal/xdg-banner.d.ts +4 -0
- package/dist/internal/xdg-banner.d.ts.map +1 -0
- package/dist/internal/xdg-banner.js +11 -0
- package/dist/internal/xdg-banner.js.map +1 -0
- package/dist/internal/xdg-data-dirs.d.ts +2 -1
- package/dist/internal/xdg-data-dirs.d.ts.map +1 -1
- package/dist/internal/xdg-data-dirs.js +1 -1
- package/dist/internal/xdg-data-dirs.js.map +1 -1
- package/dist/mcp/client.js +2 -2
- package/dist/mcp/client.js.map +1 -1
- package/dist/settings/schema.d.ts.map +1 -1
- package/dist/settings/schema.js +3 -8
- package/dist/settings/schema.js.map +1 -1
- package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
- package/dist/vite-plugins/asset-extensions.js +2 -0
- package/dist/vite-plugins/asset-extensions.js.map +1 -1
- package/dist/vite-plugins/asset-imports.d.ts.map +1 -1
- package/dist/vite-plugins/asset-imports.js +20 -6
- package/dist/vite-plugins/asset-imports.js.map +1 -1
- package/dist/vite-plugins/asset-specifier.d.ts +5 -1
- package/dist/vite-plugins/asset-specifier.d.ts.map +1 -1
- package/dist/vite-plugins/asset-specifier.js +10 -1
- package/dist/vite-plugins/asset-specifier.js.map +1 -1
- package/dist/vite-plugins/build-manifest.d.ts +5 -1
- package/dist/vite-plugins/build-manifest.d.ts.map +1 -1
- package/dist/vite-plugins/build-manifest.js +2 -1
- package/dist/vite-plugins/build-manifest.js.map +1 -1
- package/dist/vite-plugins/built-url.d.ts.map +1 -1
- package/dist/vite-plugins/built-url.js +5 -2
- package/dist/vite-plugins/built-url.js.map +1 -1
- package/dist/vite-plugins/css.d.ts.map +1 -1
- package/dist/vite-plugins/css.js +13 -5
- package/dist/vite-plugins/css.js.map +1 -1
- package/dist/vite-plugins/ensure-store.d.ts +1 -1
- package/dist/vite-plugins/ensure-store.d.ts.map +1 -1
- package/dist/vite-plugins/ensure-store.js +2 -2
- package/dist/vite-plugins/ensure-store.js.map +1 -1
- package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts +6 -1
- package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts.map +1 -1
- package/dist/vite-plugins/fast-refresh/refresh-filter.js +3 -1
- package/dist/vite-plugins/fast-refresh/refresh-filter.js.map +1 -1
- package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -1
- package/dist/vite-plugins/fast-refresh/swc-refresh.js +23 -14
- package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -1
- package/dist/vite-plugins/font-name.d.ts +3 -0
- package/dist/vite-plugins/font-name.d.ts.map +1 -0
- package/dist/vite-plugins/font-name.js +406 -0
- package/dist/vite-plugins/font-name.js.map +1 -0
- package/dist/vite-plugins/font-worker-env.d.ts +4 -0
- package/dist/vite-plugins/font-worker-env.d.ts.map +1 -0
- package/dist/vite-plugins/font-worker-env.js +19 -0
- package/dist/vite-plugins/font-worker-env.js.map +1 -0
- package/dist/vite-plugins/font.d.ts +4 -0
- package/dist/vite-plugins/font.d.ts.map +1 -0
- package/dist/vite-plugins/font.js +111 -0
- package/dist/vite-plugins/font.js.map +1 -0
- package/dist/vite-plugins/i18n.d.ts +11 -2
- package/dist/vite-plugins/i18n.d.ts.map +1 -1
- package/dist/vite-plugins/i18n.js +74 -8
- package/dist/vite-plugins/i18n.js.map +1 -1
- package/dist/vite-plugins/icon-worker-env.d.ts +4 -0
- package/dist/vite-plugins/icon-worker-env.d.ts.map +1 -0
- package/dist/vite-plugins/icon-worker-env.js +23 -0
- package/dist/vite-plugins/icon-worker-env.js.map +1 -0
- package/dist/vite-plugins/icons.d.ts.map +1 -1
- package/dist/vite-plugins/icons.js +4 -9
- package/dist/vite-plugins/icons.js.map +1 -1
- package/dist/vite-plugins/index.d.ts +10 -1
- package/dist/vite-plugins/index.d.ts.map +1 -1
- package/dist/vite-plugins/index.js +17 -3
- package/dist/vite-plugins/index.js.map +1 -1
- package/dist/vite-plugins/native.d.ts.map +1 -1
- package/dist/vite-plugins/native.js +0 -4
- package/dist/vite-plugins/native.js.map +1 -1
- package/dist/vite-plugins/react-compiler.d.ts.map +1 -1
- package/dist/vite-plugins/react-compiler.js +57 -18
- package/dist/vite-plugins/react-compiler.js.map +1 -1
- package/dist/vite-plugins/resource-shared.d.ts +3 -1
- package/dist/vite-plugins/resource-shared.d.ts.map +1 -1
- package/dist/vite-plugins/resource-shared.js +3 -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 +9 -6
- package/dist/vite-plugins/resources.js.map +1 -1
- package/dist/vite-plugins/self-contained.d.ts.map +1 -1
- package/dist/vite-plugins/self-contained.js +159 -158
- package/dist/vite-plugins/self-contained.js.map +1 -1
- package/dist/vite-plugins/settings-worker-env.d.ts +1 -1
- package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
- package/dist/vite-plugins/settings-worker-env.js +4 -4
- package/dist/vite-plugins/settings-worker-env.js.map +1 -1
- package/dist/vite-plugins/settings.d.ts.map +1 -1
- package/dist/vite-plugins/settings.js +25 -14
- package/dist/vite-plugins/settings.js.map +1 -1
- package/dist/vite-plugins/store-links.d.ts.map +1 -1
- package/dist/vite-plugins/store-links.js +9 -5
- package/dist/vite-plugins/store-links.js.map +1 -1
- package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
- package/dist/vite-plugins/undeclared-library.js +18 -15
- 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 +21 -13
- package/dist/vite-plugins/worker.js.map +1 -1
- package/dist/vitest-plugin.d.ts +4 -3
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +12 -8
- package/dist/vitest-plugin.js.map +1 -1
- package/env.d.ts +9 -0
- package/package.json +18 -13
- package/src/builder.ts +45 -12
- package/src/cli.ts +15 -2
- package/src/codegen/config-dependencies.ts +470 -0
- package/src/codegen/freshness.ts +5 -1
- package/src/codegen/reference.ts +1 -0
- package/src/codegen/run-codegen.ts +51 -21
- package/src/codegen/store-resolver.ts +9 -4
- package/src/commands/build.ts +13 -2
- package/src/commands/cleanup.ts +48 -0
- package/src/commands/codegen.ts +6 -5
- package/src/commands/deploy.ts +10 -2
- package/src/commands/dev.ts +45 -4
- package/src/commands/docs.ts +1 -0
- package/src/deploy/depends.ts +30 -3
- package/src/deploy/download.ts +33 -24
- package/src/deploy/freedesktop/metainfo.ts +73 -21
- package/src/deploy/freedesktop/validate.ts +80 -15
- package/src/deploy/native-addon.ts +183 -0
- package/src/deploy/nfpm/config.ts +13 -4
- package/src/deploy/nfpm/contents.ts +8 -0
- package/src/deploy/node-runtime/download.ts +2 -2
- package/src/deploy/node-runtime/elf.ts +46 -5
- package/src/deploy/node-runtime/guard.ts +10 -14
- package/src/deploy/node-runtime/index.ts +148 -12
- package/src/deploy/node-runtime/sonames.ts +17 -0
- package/src/deploy/notices/node-runtime.ts +2 -2
- package/src/deploy/payload/launcher.ts +20 -1
- package/src/deploy/payload/stage.ts +76 -5
- package/src/deploy/run-deploy.ts +227 -72
- package/src/deploy/settings/arch.ts +40 -8
- package/src/deploy/settings/build-manifest.ts +28 -3
- package/src/deploy/settings/extra-files.ts +30 -4
- package/src/deploy/settings/index.ts +7 -2
- package/src/deploy/settings/libraries.ts +2 -1
- package/src/deploy/settings/paths.ts +80 -13
- package/src/deploy/targets/appimage.ts +1 -0
- package/src/deploy/targets/flatpak-pnpm.ts +4 -4
- package/src/deploy/targets/flatpak-source.ts +15 -2
- package/src/deploy/targets/flatpak.ts +1 -0
- package/src/deploy/targets/nfpm-target.ts +14 -6
- package/src/deploy/types.ts +5 -1
- package/src/deploy/vendored/appimagetool.ts +2 -2
- package/src/deploy/vendored/nfpm.ts +1 -1
- package/src/dev/catalog-writes.ts +35 -0
- package/src/dev/entry-env.ts +2 -1
- package/src/dev/font-dir.ts +11 -0
- package/src/dev/headless.ts +40 -0
- package/src/dev/runner-deps.ts +20 -7
- package/src/dev/runner-main.ts +12 -3
- package/src/dev/runner.ts +37 -7
- package/src/dev/supervisor.ts +183 -32
- package/src/dev/vite-dev-server.ts +20 -2
- package/src/dev/watch-ignore.ts +16 -0
- package/src/i18n/catalogs.ts +21 -8
- package/src/i18n/source-messages.ts +1446 -29
- package/src/internal/agent-rules.ts +7 -2
- package/src/internal/banner.ts +27 -6
- package/src/internal/build-manifest.ts +25 -1
- package/src/internal/build-output.ts +171 -0
- package/src/internal/cache-root.ts +12 -0
- package/src/internal/compile-cache-store.ts +50 -0
- package/src/internal/compile-cache.ts +20 -0
- package/src/internal/deploy-out-dir.ts +8 -0
- package/src/internal/docs-elements.ts +10 -4
- package/src/internal/entry-arg.ts +8 -1
- package/src/internal/errors.ts +1 -1
- package/src/internal/font-path.ts +15 -0
- package/src/internal/font-staging.ts +131 -0
- package/src/internal/icon-staging.ts +58 -0
- package/src/internal/import-scan.ts +206 -0
- package/src/internal/module-hash.ts +22 -0
- package/src/internal/output-directory.ts +699 -0
- package/src/internal/parent-process.ts +110 -0
- package/src/internal/prepare-project.ts +11 -5
- package/src/internal/react-compiler-cache.ts +246 -0
- package/src/internal/source-imports.ts +57 -12
- package/src/internal/staging-file.ts +42 -0
- package/src/internal/xdg-banner.ts +13 -0
- package/src/internal/xdg-data-dirs.ts +1 -1
- package/src/mcp/client.ts +2 -2
- package/src/settings/schema.ts +4 -10
- package/src/vite-plugins/asset-extensions.ts +2 -0
- package/src/vite-plugins/asset-imports.ts +23 -5
- package/src/vite-plugins/asset-specifier.ts +17 -0
- package/src/vite-plugins/build-manifest.ts +7 -1
- package/src/vite-plugins/built-url.ts +6 -2
- package/src/vite-plugins/css.ts +16 -5
- package/src/vite-plugins/ensure-store.ts +2 -2
- package/src/vite-plugins/fast-refresh/refresh-filter.ts +10 -1
- package/src/vite-plugins/fast-refresh/swc-refresh.ts +33 -14
- package/src/vite-plugins/font-name.ts +582 -0
- package/src/vite-plugins/font-worker-env.ts +25 -0
- package/src/vite-plugins/font.ts +180 -0
- package/src/vite-plugins/i18n.ts +122 -11
- package/src/vite-plugins/icon-worker-env.ts +36 -0
- package/src/vite-plugins/icons.ts +4 -10
- package/src/vite-plugins/index.ts +34 -9
- package/src/vite-plugins/native.ts +0 -5
- package/src/vite-plugins/react-compiler.ts +83 -19
- package/src/vite-plugins/resource-shared.ts +4 -0
- package/src/vite-plugins/resources.ts +11 -5
- package/src/vite-plugins/self-contained.ts +184 -185
- package/src/vite-plugins/settings-worker-env.ts +4 -4
- package/src/vite-plugins/settings.ts +36 -16
- package/src/vite-plugins/store-links.ts +10 -5
- package/src/vite-plugins/undeclared-library.ts +19 -15
- package/src/vite-plugins/worker.ts +31 -15
- package/src/vitest-plugin.ts +12 -8
|
@@ -14,6 +14,54 @@ import { element, renderDocument, text, type XmlNode } from "./xml.js";
|
|
|
14
14
|
|
|
15
15
|
const COMPONENT_TYPE = "desktop-application";
|
|
16
16
|
const DESKTOP_SUFFIX = ".desktop";
|
|
17
|
+
const COMPONENT_CLOSE = "</component>\n";
|
|
18
|
+
const PROVIDES_CLOSE = " </provides>\n";
|
|
19
|
+
const PROVIDES_FRAGMENT = /^<provides\s*>([\s\S]*)<\/provides>$/;
|
|
20
|
+
|
|
21
|
+
const normalizeExtraFragment = (fragment: string, index: number): string => {
|
|
22
|
+
const normalized = fragment.trim();
|
|
23
|
+
|
|
24
|
+
if (normalized.length === 0) {
|
|
25
|
+
throw new Error(`Cannot render deploy.metainfoExtra entry ${String(index + 1)}: it is empty`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return normalized;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const indentFragment = (fragment: string, depth: number): string => {
|
|
32
|
+
const indentation = " ".repeat(depth * 4);
|
|
33
|
+
|
|
34
|
+
return fragment.split(/\r?\n/).map((line) => `${indentation}${line}`).join("\n");
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const appendExtraFragments = (document: string, fragments: string[]): string => {
|
|
38
|
+
if (fragments.length === 0) {
|
|
39
|
+
return document;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let merged = document;
|
|
43
|
+
const componentFragments: string[] = [];
|
|
44
|
+
|
|
45
|
+
for (const [index, rawFragment] of fragments.entries()) {
|
|
46
|
+
const fragment = normalizeExtraFragment(rawFragment, index);
|
|
47
|
+
const provides = PROVIDES_FRAGMENT.exec(fragment)?.[1]?.trim();
|
|
48
|
+
|
|
49
|
+
if (provides === undefined) {
|
|
50
|
+
componentFragments.push(fragment);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
merged = merged.replace(PROVIDES_CLOSE, () => `${indentFragment(provides, 2)}\n${PROVIDES_CLOSE}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (componentFragments.length === 0) {
|
|
58
|
+
return merged;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const extra = componentFragments.map((fragment) => indentFragment(fragment, 1)).join("\n");
|
|
62
|
+
|
|
63
|
+
return merged.replace(COMPONENT_CLOSE, () => `${extra}\n${COMPONENT_CLOSE}`);
|
|
64
|
+
};
|
|
17
65
|
|
|
18
66
|
const launchable = (applicationId: string): XmlNode => ({
|
|
19
67
|
tag: "launchable",
|
|
@@ -21,26 +69,30 @@ const launchable = (applicationId: string): XmlNode => ({
|
|
|
21
69
|
text: `${applicationId}${DESKTOP_SUFFIX}`,
|
|
22
70
|
});
|
|
23
71
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
72
|
+
const metainfoRoot = (settings: DeploySettings): XmlNode =>
|
|
73
|
+
element("component", { type: COMPONENT_TYPE }, [
|
|
74
|
+
text("id", settings.applicationId),
|
|
75
|
+
text("name", settings.name),
|
|
76
|
+
text("summary", settings.summary),
|
|
77
|
+
text("metadata_license", settings.metadataLicense),
|
|
78
|
+
text("project_license", settings.license),
|
|
79
|
+
...developerSection(settings),
|
|
80
|
+
...descriptionSection(settings),
|
|
81
|
+
launchable(settings.applicationId),
|
|
82
|
+
...providesSection(settings),
|
|
83
|
+
...listSection("categories", "category", settings.categories),
|
|
84
|
+
...listSection("keywords", "keyword", settings.keywords),
|
|
85
|
+
...urlsSection(settings),
|
|
86
|
+
...screenshotsSection(settings),
|
|
87
|
+
...releasesSection(settings),
|
|
88
|
+
...contentRatingSection(settings),
|
|
89
|
+
...brandingSection(settings),
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
const renderMetainfo = (settings: DeploySettings): string => {
|
|
93
|
+
const document = renderDocument(metainfoRoot(settings));
|
|
94
|
+
|
|
95
|
+
return appendExtraFragments(document, settings.deploy.metainfoExtra ?? []);
|
|
96
|
+
};
|
|
45
97
|
|
|
46
98
|
export { renderMetainfo };
|
|
@@ -6,12 +6,20 @@ type ToolResult = {
|
|
|
6
6
|
status: number;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
type Diagnostic = {
|
|
10
|
+
severity: string;
|
|
11
|
+
rule: string;
|
|
12
|
+
detail: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
9
15
|
type MetainfoResult = {
|
|
10
16
|
subject: string;
|
|
11
17
|
output: string;
|
|
12
18
|
status: number;
|
|
13
19
|
errors: string[];
|
|
14
20
|
warnings: string[];
|
|
21
|
+
rules: string[];
|
|
22
|
+
notes: string[];
|
|
15
23
|
areWarningsFatal: boolean;
|
|
16
24
|
};
|
|
17
25
|
|
|
@@ -21,10 +29,19 @@ type ToolRequest = {
|
|
|
21
29
|
subject: string;
|
|
22
30
|
};
|
|
23
31
|
|
|
24
|
-
const DIAGNOSTIC = /^(?<severity>[EIPW]): \S+ (?<rule>[\w-]+)
|
|
32
|
+
const DIAGNOSTIC = /^(?<severity>[EIPW]): \S+ (?<rule>[\w-]+)(?: (?<detail>.*))?$/;
|
|
33
|
+
const SUCCESS_SUMMARY = /^\W*Validation was successful/u;
|
|
25
34
|
const ERROR_SEVERITY = "E";
|
|
26
35
|
const WARNING_SEVERITY = "W";
|
|
27
36
|
const INFO_SEVERITY = "I";
|
|
37
|
+
const FATAL_WARNING_RULES: Set<string> = new Set(["unknown-tag"]);
|
|
38
|
+
const DESKTOP_ERROR = /(?:^|:\s)error:/iu;
|
|
39
|
+
|
|
40
|
+
const FATAL_RULE_NOTES: Record<string, (detail: string) => string> = {
|
|
41
|
+
"unknown-tag": (element) =>
|
|
42
|
+
"GTKX treats unknown-tag as fatal for every target, whatever severity appstreamcli assigns it; " +
|
|
43
|
+
`the unsupported element is <${element}>`,
|
|
44
|
+
};
|
|
28
45
|
|
|
29
46
|
const REMEDY_FOR_RULE: Record<string, string> = {
|
|
30
47
|
"component-summary-missing": "set `deploy.summary`",
|
|
@@ -33,6 +50,7 @@ const REMEDY_FOR_RULE: Record<string, string> = {
|
|
|
33
50
|
"metainfo-legacy-path": "this file is generated; report it as a gtkx bug",
|
|
34
51
|
"summary-has-dot-suffix": "drop the trailing period from `deploy.summary`",
|
|
35
52
|
"summary-too-long": "shorten `deploy.summary`",
|
|
53
|
+
"unknown-tag": "remove the unsupported `deploy.metainfoExtra` element or use a `<custom>` value",
|
|
36
54
|
"url-homepage-missing": "set `deploy.homepage`, or `homepage` in package.json",
|
|
37
55
|
};
|
|
38
56
|
|
|
@@ -46,12 +64,31 @@ const runTool = ({ tool, args, subject }: ToolRequest): ToolResult => {
|
|
|
46
64
|
return { output: [result.stdout, result.stderr].join("\n").trim(), status: result.status ?? 0 };
|
|
47
65
|
};
|
|
48
66
|
|
|
49
|
-
const
|
|
67
|
+
const parseDiagnostics = (output: string): Diagnostic[] =>
|
|
68
|
+
output.split("\n").flatMap((line) => {
|
|
69
|
+
const groups = DIAGNOSTIC.exec(line)?.groups;
|
|
70
|
+
|
|
71
|
+
return groups === undefined
|
|
72
|
+
? []
|
|
73
|
+
: [{ severity: groups.severity ?? "", rule: groups.rule ?? "", detail: (groups.detail ?? "").trim() }];
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const rulesIn = (diagnostics: Diagnostic[], severities: string[]): string[] =>
|
|
77
|
+
diagnostics.filter((diagnostic) => severities.includes(diagnostic.severity)).map((diagnostic) => diagnostic.rule);
|
|
78
|
+
|
|
79
|
+
const fatalNotes = (diagnostics: Diagnostic[]): string[] =>
|
|
80
|
+
diagnostics
|
|
81
|
+
.filter((diagnostic) => diagnostic.severity !== ERROR_SEVERITY && FATAL_WARNING_RULES.has(diagnostic.rule))
|
|
82
|
+
.map((diagnostic) =>
|
|
83
|
+
FATAL_RULE_NOTES[diagnostic.rule]?.(diagnostic.detail) ??
|
|
84
|
+
`GTKX treats ${diagnostic.rule} as fatal for every target`);
|
|
85
|
+
|
|
86
|
+
const withoutSuccessSummary = (output: string): string =>
|
|
50
87
|
output
|
|
51
88
|
.split("\n")
|
|
52
|
-
.
|
|
53
|
-
.
|
|
54
|
-
.
|
|
89
|
+
.filter((line) => !SUCCESS_SUMMARY.test(line))
|
|
90
|
+
.join("\n")
|
|
91
|
+
.trimEnd();
|
|
55
92
|
|
|
56
93
|
const remedyLines = (rules: string[]): string[] => {
|
|
57
94
|
const remedies = sortStrings([...new Set(rules)])
|
|
@@ -61,14 +98,23 @@ const remedyLines = (rules: string[]): string[] => {
|
|
|
61
98
|
return remedies.length === 0 ? [] : ["", "Fix it in gtkx.config.ts:", ...remedies];
|
|
62
99
|
};
|
|
63
100
|
|
|
64
|
-
const invalid = (subject: string, output: string, rules: string[]): Error =>
|
|
65
|
-
new Error([
|
|
101
|
+
const invalid = (subject: string, output: string, rules: string[], notes: string[]): Error =>
|
|
102
|
+
new Error([
|
|
103
|
+
`${subject} is not valid:`,
|
|
104
|
+
output.length > 0 ? output : "no output",
|
|
105
|
+
...notes,
|
|
106
|
+
...remedyLines(rules),
|
|
107
|
+
].join("\n"));
|
|
66
108
|
|
|
67
|
-
const isFatalResult = ({ status, errors, warnings, areWarningsFatal }: MetainfoResult): boolean => {
|
|
109
|
+
const isFatalResult = ({ status, errors, warnings, rules, areWarningsFatal }: MetainfoResult): boolean => {
|
|
68
110
|
if (errors.length > 0) {
|
|
69
111
|
return true;
|
|
70
112
|
}
|
|
71
113
|
|
|
114
|
+
if (rules.some((rule) => FATAL_WARNING_RULES.has(rule))) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
72
118
|
if (areWarningsFatal && warnings.length > 0) {
|
|
73
119
|
return true;
|
|
74
120
|
}
|
|
@@ -78,7 +124,7 @@ const isFatalResult = ({ status, errors, warnings, areWarningsFatal }: MetainfoR
|
|
|
78
124
|
|
|
79
125
|
const assertNotFatal = (result: MetainfoResult): void => {
|
|
80
126
|
if (isFatalResult(result)) {
|
|
81
|
-
throw invalid(result.subject, result.output,
|
|
127
|
+
throw invalid(result.subject, result.output, result.rules, result.notes);
|
|
82
128
|
}
|
|
83
129
|
};
|
|
84
130
|
|
|
@@ -101,8 +147,14 @@ const validateDesktopEntry = (path: string): void => {
|
|
|
101
147
|
subject: "The desktop entry",
|
|
102
148
|
});
|
|
103
149
|
|
|
104
|
-
|
|
105
|
-
|
|
150
|
+
const diagnostics = output.split("\n").filter((line) => line.length > 0);
|
|
151
|
+
|
|
152
|
+
if (status !== 0 || diagnostics.some((line) => DESKTOP_ERROR.test(line))) {
|
|
153
|
+
throw invalid("The desktop entry", output, [], []);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (const diagnostic of diagnostics) {
|
|
157
|
+
warn(diagnostic);
|
|
106
158
|
}
|
|
107
159
|
};
|
|
108
160
|
|
|
@@ -115,10 +167,23 @@ const validateMetainfo = (path: string, areWarningsFatal: boolean): void => {
|
|
|
115
167
|
subject,
|
|
116
168
|
});
|
|
117
169
|
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
170
|
+
const diagnostics = parseDiagnostics(output);
|
|
171
|
+
const errors = rulesIn(diagnostics, [ERROR_SEVERITY]);
|
|
172
|
+
const warnings = rulesIn(diagnostics, [WARNING_SEVERITY]);
|
|
173
|
+
const infos = rulesIn(diagnostics, [INFO_SEVERITY]);
|
|
174
|
+
const rules = [...errors, ...warnings, ...infos];
|
|
175
|
+
const notes = fatalNotes(diagnostics);
|
|
176
|
+
assertNotFatal({
|
|
177
|
+
subject,
|
|
178
|
+
output: withoutSuccessSummary(output),
|
|
179
|
+
status,
|
|
180
|
+
errors,
|
|
181
|
+
warnings,
|
|
182
|
+
rules,
|
|
183
|
+
notes,
|
|
184
|
+
areWarningsFatal,
|
|
185
|
+
});
|
|
186
|
+
reportDiagnostics(subject, [...warnings, ...infos]);
|
|
122
187
|
};
|
|
123
188
|
|
|
124
189
|
export { validateDesktopEntry, validateMetainfo };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import type { DeployArchName, DeploySettings } from "./types.js";
|
|
5
|
+
import { runCliTool } from "../internal/run-cli-tool.js";
|
|
6
|
+
import { cacheDir, downloadFile, readCachedDigest, writeAtomically } from "./download.js";
|
|
7
|
+
import { isHostArch } from "./settings/arch.js";
|
|
8
|
+
|
|
9
|
+
type ProjectRequire = ReturnType<typeof createRequire>;
|
|
10
|
+
type Tarball = { url: string; digest: string };
|
|
11
|
+
|
|
12
|
+
const BINDING_FILENAME = "gtkx.node";
|
|
13
|
+
const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
14
|
+
const NATIVE_MANIFEST = "@gtkx/native/package.json";
|
|
15
|
+
const PACKAGE_ROOT = "package";
|
|
16
|
+
const REQUEST_TIMEOUT = 30_000;
|
|
17
|
+
const SRI_PREFIX = "sha512-";
|
|
18
|
+
const STRIP_COMPONENTS = "1";
|
|
19
|
+
const VERSION_PATTERN = /^[\w.+-]+$/;
|
|
20
|
+
|
|
21
|
+
const binaryFilename = (arch: DeployArchName): string => `native.linux-${arch}-gnu.node`;
|
|
22
|
+
const platformStem = (arch: DeployArchName): string => `native-linux-${arch}-gnu`;
|
|
23
|
+
const platformPackage = (arch: DeployArchName): string => `@gtkx/${platformStem(arch)}`;
|
|
24
|
+
|
|
25
|
+
const withoutTrailingSlash = (value: string): string => {
|
|
26
|
+
let end = value.length;
|
|
27
|
+
|
|
28
|
+
while (end > 0 && value[end - 1] === "/") {
|
|
29
|
+
end -= 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return value.slice(0, end);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const registryUrl = (): string => {
|
|
36
|
+
const configured = process.env.npm_config_registry;
|
|
37
|
+
|
|
38
|
+
return withoutTrailingSlash(configured !== undefined && configured.length > 0 ? configured : DEFAULT_REGISTRY);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const projectRequireFor = (root: string): ProjectRequire => createRequire(join(root, "package.json"));
|
|
42
|
+
|
|
43
|
+
const localBinary = (projectRequire: ProjectRequire, arch: DeployArchName): string | null => {
|
|
44
|
+
const nativeRoot = dirname(projectRequire.resolve(NATIVE_MANIFEST));
|
|
45
|
+
const candidate = join(nativeRoot, binaryFilename(arch));
|
|
46
|
+
|
|
47
|
+
return existsSync(candidate) ? candidate : null;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const installedBinary = (projectRequire: ProjectRequire, arch: DeployArchName): string | null => {
|
|
51
|
+
try {
|
|
52
|
+
return projectRequire.resolve(platformPackage(arch));
|
|
53
|
+
} catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const manifestVersion = (manifest: unknown): string | null => {
|
|
59
|
+
if (typeof manifest !== "object" || manifest === null || !("version" in manifest)) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const version = manifest.version;
|
|
64
|
+
|
|
65
|
+
return typeof version === "string" && VERSION_PATTERN.test(version) ? version : null;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const nativeVersion = (projectRequire: ProjectRequire): string => {
|
|
69
|
+
const parsed: unknown = JSON.parse(readFileSync(projectRequire.resolve(NATIVE_MANIFEST), "utf8"));
|
|
70
|
+
const version = manifestVersion(parsed);
|
|
71
|
+
|
|
72
|
+
if (version === null) {
|
|
73
|
+
throw new Error("Cannot read a usable version from @gtkx/native; is it installed?");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return version;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const hexFromIntegrity = (integrity: unknown, subject: string): string => {
|
|
80
|
+
if (typeof integrity !== "string" || !integrity.startsWith(SRI_PREFIX)) {
|
|
81
|
+
throw new Error(`The npm registry publishes no sha512 integrity for ${subject}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return Buffer.from(integrity.slice(SRI_PREFIX.length), "base64").toString("hex");
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const fetchVersionDocument = async (url: string, subject: string): Promise<Record<string, unknown>> => {
|
|
88
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(REQUEST_TIMEOUT) });
|
|
89
|
+
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Cannot fetch ${subject}: HTTP ${String(response.status)} ${response.statusText}. ` +
|
|
93
|
+
`Install ${subject} directly, or drop that architecture from --arch.`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const document: unknown = await response.json();
|
|
98
|
+
|
|
99
|
+
if (typeof document !== "object" || document === null) {
|
|
100
|
+
throw new Error(`The npm registry returned no metadata for ${subject}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return document as Record<string, unknown>;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const publishedTarball = async (arch: DeployArchName, version: string): Promise<Tarball> => {
|
|
107
|
+
const registry = registryUrl();
|
|
108
|
+
const subject = `${platformPackage(arch)}@${version}`;
|
|
109
|
+
const url = `${registry}/${encodeURIComponent(platformPackage(arch))}/${version}`;
|
|
110
|
+
const document = await fetchVersionDocument(url, subject);
|
|
111
|
+
const dist: unknown = document.dist;
|
|
112
|
+
|
|
113
|
+
if (typeof dist !== "object" || dist === null) {
|
|
114
|
+
throw new Error(`The npm registry returned no tarball for ${subject}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const entry = dist as Record<string, unknown>;
|
|
118
|
+
const tarball = entry.tarball;
|
|
119
|
+
|
|
120
|
+
if (typeof tarball !== "string" || new URL(tarball).origin !== new URL(registry).origin) {
|
|
121
|
+
throw new Error(`The npm registry returned an unusable tarball URL for ${subject}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return { url: tarball, digest: hexFromIntegrity(entry.integrity, subject) };
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const extractAddon = (archive: string, dir: string, arch: DeployArchName): void => {
|
|
128
|
+
runCliTool({
|
|
129
|
+
tool: "tar",
|
|
130
|
+
args: ["-xzf", archive, "-C", dir, "--strip-components", STRIP_COMPONENTS,
|
|
131
|
+
`${PACKAGE_ROOT}/${binaryFilename(arch)}`],
|
|
132
|
+
target: platformPackage(arch),
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const cachedTarballUrl = (arch: DeployArchName, version: string): string =>
|
|
137
|
+
`${registryUrl()}/${platformPackage(arch)}/-/${platformStem(arch)}-${version}.tgz`;
|
|
138
|
+
|
|
139
|
+
const tarballFor = async (arch: DeployArchName, version: string, sidecar: string): Promise<Tarball> => {
|
|
140
|
+
const cached = readCachedDigest(sidecar, "sha512");
|
|
141
|
+
|
|
142
|
+
if (cached !== undefined) {
|
|
143
|
+
return { url: cachedTarballUrl(arch, version), digest: cached };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const published = await publishedTarball(arch, version);
|
|
147
|
+
writeAtomically(sidecar, published.digest);
|
|
148
|
+
|
|
149
|
+
return published;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const downloadedBinary = async (arch: DeployArchName, version: string): Promise<string> => {
|
|
153
|
+
const dir = cacheDir(["native", `${version}-linux-${arch}`]);
|
|
154
|
+
const archive = join(dir, `${platformStem(arch)}-${version}.tgz`);
|
|
155
|
+
const tarball = await tarballFor(arch, version, `${archive}.sha512`);
|
|
156
|
+
|
|
157
|
+
await downloadFile({
|
|
158
|
+
url: tarball.url,
|
|
159
|
+
dest: archive,
|
|
160
|
+
label: `${platformPackage(arch)} ${version}`,
|
|
161
|
+
digest: tarball.digest,
|
|
162
|
+
algorithm: "sha512",
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
extractAddon(archive, dir, arch);
|
|
166
|
+
|
|
167
|
+
return join(dir, binaryFilename(arch));
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const resolveStagedAddon = async (settings: DeploySettings): Promise<string | null> => {
|
|
171
|
+
const arch = settings.arch.node;
|
|
172
|
+
|
|
173
|
+
if (isHostArch(arch)) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const projectRequire = projectRequireFor(settings.paths.root);
|
|
178
|
+
const resolved = localBinary(projectRequire, arch) ?? installedBinary(projectRequire, arch);
|
|
179
|
+
|
|
180
|
+
return resolved ?? await downloadedBinary(arch, nativeVersion(projectRequire));
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export { BINDING_FILENAME, resolveStagedAddon };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DeployPayload, DeploySettings, StagedFile } from "../types.js";
|
|
2
2
|
import { resolveDepends } from "../depends.js";
|
|
3
|
+
import { glibcMinimumForFiles } from "../node-runtime/elf.js";
|
|
3
4
|
import { groupForCategories, sectionForCategories } from "../settings/categories.js";
|
|
4
5
|
import { nfpmContents } from "./contents.js";
|
|
5
6
|
import { debDescription, rpmDescription } from "./description.js";
|
|
@@ -113,6 +114,9 @@ const stagedFilesFor = (payload: DeployPayload, packager: NfpmPackager): StagedF
|
|
|
113
114
|
...payload.overlays[packager],
|
|
114
115
|
];
|
|
115
116
|
|
|
117
|
+
const glibcMinimumForPackage = (payload: DeployPayload, packager: NfpmPackager): string | null =>
|
|
118
|
+
glibcMinimumForFiles(stagedFilesFor(payload, packager).map((file) => file.abs));
|
|
119
|
+
|
|
116
120
|
const packagerSettings = (settings: DeploySettings, packager: NfpmPackager): NfpmConfig =>
|
|
117
121
|
packager === "rpm" ? rpmSettings(settings) : debSettings(settings);
|
|
118
122
|
|
|
@@ -122,10 +126,15 @@ const releaseFor = (settings: DeploySettings, packager: NfpmPackager): string =>
|
|
|
122
126
|
const descriptionFor = (settings: DeploySettings, packager: NfpmPackager): string =>
|
|
123
127
|
packager === "rpm" ? rpmDescription(settings) : debDescription(settings);
|
|
124
128
|
|
|
125
|
-
const renderNfpmConfig = (
|
|
129
|
+
const renderNfpmConfig = (
|
|
130
|
+
payload: DeployPayload,
|
|
131
|
+
packager: NfpmPackager,
|
|
132
|
+
glibcMinimum: string | null,
|
|
133
|
+
): NfpmConfig => {
|
|
126
134
|
const settings = payload.settings;
|
|
127
135
|
const isRpm = packager === "rpm";
|
|
128
|
-
const
|
|
136
|
+
const staged = stagedFilesFor(payload, packager);
|
|
137
|
+
const depends = resolveDepends(settings, glibcMinimum);
|
|
129
138
|
|
|
130
139
|
return {
|
|
131
140
|
name: packageNameFor(settings, packager),
|
|
@@ -146,8 +155,8 @@ const renderNfpmConfig = (payload: DeployPayload, packager: NfpmPackager): NfpmC
|
|
|
146
155
|
...relationsFor(settings, packager),
|
|
147
156
|
...optional("scripts", scriptsFor(settings)),
|
|
148
157
|
[packager]: packagerSettings(settings, packager),
|
|
149
|
-
contents: nfpmContents(PREFIX,
|
|
158
|
+
contents: nfpmContents(PREFIX, staged, isRpm),
|
|
150
159
|
};
|
|
151
160
|
};
|
|
152
161
|
|
|
153
|
-
export { type NfpmPackager, packageNameFor, renderNfpmConfig };
|
|
162
|
+
export { glibcMinimumForPackage, type NfpmPackager, packageNameFor, renderNfpmConfig };
|
|
@@ -13,10 +13,16 @@ const FILESYSTEM_OWNED_PREFIXES = new Set([
|
|
|
13
13
|
"/usr",
|
|
14
14
|
"/usr/bin",
|
|
15
15
|
"/usr/lib",
|
|
16
|
+
"/usr/lib/systemd",
|
|
17
|
+
"/usr/lib/systemd/system",
|
|
18
|
+
"/usr/lib/systemd/user",
|
|
19
|
+
"/usr/libexec",
|
|
16
20
|
"/usr/share",
|
|
17
21
|
"/usr/share/applications",
|
|
18
22
|
"/usr/share/dbus-1",
|
|
19
23
|
"/usr/share/dbus-1/services",
|
|
24
|
+
"/usr/share/dbus-1/system-services",
|
|
25
|
+
"/usr/share/dbus-1/system.d",
|
|
20
26
|
"/usr/share/doc",
|
|
21
27
|
"/usr/share/glib-2.0",
|
|
22
28
|
"/usr/share/glib-2.0/schemas",
|
|
@@ -25,6 +31,8 @@ const FILESYSTEM_OWNED_PREFIXES = new Set([
|
|
|
25
31
|
"/usr/share/metainfo",
|
|
26
32
|
"/usr/share/mime",
|
|
27
33
|
"/usr/share/mime/packages",
|
|
34
|
+
"/usr/share/polkit-1",
|
|
35
|
+
"/usr/share/polkit-1/actions",
|
|
28
36
|
]);
|
|
29
37
|
|
|
30
38
|
const ICON_THEME_PREFIX = "/usr/share/icons/";
|
|
@@ -44,8 +44,8 @@ const downloadNode = async (version: string, arch: string, destDir: string): Pro
|
|
|
44
44
|
url: `${DIST_BASE_URL}/v${version}/${assetName}`,
|
|
45
45
|
dest: join(dir, assetName),
|
|
46
46
|
label: `Node.js ${version} for linux-${arch}`,
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
digest: await cachedDigest(request),
|
|
48
|
+
freshDigest: () => publishedDigest(request),
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
mkdirSync(destDir, { recursive: true });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { closeSync, openSync, readFileSync, readSync } from "node:fs";
|
|
2
2
|
|
|
3
3
|
type ElfSection = {
|
|
4
4
|
name: string;
|
|
@@ -7,6 +7,7 @@ type ElfSection = {
|
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
type ElfInfo = {
|
|
10
|
+
machine: number;
|
|
10
11
|
needed: string[];
|
|
11
12
|
glibcMinimum: string | null;
|
|
12
13
|
};
|
|
@@ -17,10 +18,12 @@ type DynamicEntry = {
|
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
const ELF_MAGIC = "ELF";
|
|
21
|
+
const ELF_MAGIC_SIZE = 4;
|
|
20
22
|
const CLASS_64 = 2;
|
|
21
23
|
const LITTLE_ENDIAN = 1;
|
|
22
24
|
const OFFSET_CLASS = 4;
|
|
23
25
|
const OFFSET_DATA = 5;
|
|
26
|
+
const OFFSET_MACHINE = 0x12;
|
|
24
27
|
const OFFSET_SECTION_HEADERS = 0x28;
|
|
25
28
|
const OFFSET_SECTION_ENTRY_SIZE = 0x3A;
|
|
26
29
|
const OFFSET_SECTION_COUNT = 0x3C;
|
|
@@ -35,8 +38,11 @@ const DYNAMIC_VALUE_OFFSET = 8;
|
|
|
35
38
|
const GLIBC_VERSION = /GLIBC_(\d+)\.(\d+)/g;
|
|
36
39
|
const VERSION_RADIX = 1000;
|
|
37
40
|
|
|
41
|
+
const hasElfMagic = (buffer: Buffer): boolean =>
|
|
42
|
+
buffer.length >= OFFSET_CLASS && buffer.subarray(0, 4).toString("latin1") === ELF_MAGIC;
|
|
43
|
+
|
|
38
44
|
const assertElf64 = (buffer: Buffer, path: string): void => {
|
|
39
|
-
if (buffer.length < OFFSET_SECTION_NAME_INDEX || buffer
|
|
45
|
+
if (buffer.length < OFFSET_SECTION_NAME_INDEX || !hasElfMagic(buffer)) {
|
|
40
46
|
throw new Error(`Cannot read ${path}: it is not an ELF binary`);
|
|
41
47
|
}
|
|
42
48
|
|
|
@@ -130,16 +136,51 @@ const readGlibcMinimum = (strings: Buffer): string | null => {
|
|
|
130
136
|
const stringTable = (buffer: Buffer, dynstr: ElfSection | undefined): Buffer =>
|
|
131
137
|
dynstr === undefined ? Buffer.alloc(0) : buffer.subarray(dynstr.offset, dynstr.offset + dynstr.size);
|
|
132
138
|
|
|
133
|
-
const
|
|
134
|
-
const buffer = readFileSync(path);
|
|
139
|
+
const readElfBuffer = (buffer: Buffer, path: string): ElfInfo => {
|
|
135
140
|
assertElf64(buffer, path);
|
|
136
141
|
const sections = readSections(buffer);
|
|
137
142
|
const strings = stringTable(buffer, sectionFor(sections, ".dynstr"));
|
|
138
143
|
|
|
139
144
|
return {
|
|
145
|
+
machine: buffer.readUInt16LE(OFFSET_MACHINE),
|
|
140
146
|
needed: readNeeded(buffer, sectionFor(sections, ".dynamic"), strings),
|
|
141
147
|
glibcMinimum: readGlibcMinimum(strings),
|
|
142
148
|
};
|
|
143
149
|
};
|
|
144
150
|
|
|
145
|
-
|
|
151
|
+
const readElfInfo = (path: string): ElfInfo => readElfBuffer(readFileSync(path), path);
|
|
152
|
+
|
|
153
|
+
const readFilePrefix = (descriptor: number, size: number): Buffer => {
|
|
154
|
+
const buffer = Buffer.alloc(size);
|
|
155
|
+
const bytesRead = readSync(descriptor, buffer, 0, size, 0);
|
|
156
|
+
|
|
157
|
+
return buffer.subarray(0, bytesRead);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const readOptionalElfInfo = (path: string): ElfInfo | null => {
|
|
161
|
+
const descriptor = openSync(path, "r");
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const prefix = readFilePrefix(descriptor, ELF_MAGIC_SIZE);
|
|
165
|
+
|
|
166
|
+
return hasElfMagic(prefix) ? readElfBuffer(readFileSync(descriptor), path) : null;
|
|
167
|
+
} finally {
|
|
168
|
+
closeSync(descriptor);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const glibcMinimumForFiles = (paths: Iterable<string>): string | null => {
|
|
173
|
+
const versions: number[][] = [];
|
|
174
|
+
|
|
175
|
+
for (const path of paths) {
|
|
176
|
+
const minimum = readOptionalElfInfo(path)?.glibcMinimum;
|
|
177
|
+
|
|
178
|
+
if (minimum !== undefined && minimum !== null) {
|
|
179
|
+
versions.push(minimum.split(".").map(Number));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return formatVersion(highestVersion(versions));
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export { type ElfInfo, glibcMinimumForFiles, readElfInfo, readOptionalElfInfo };
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import type { ElfInfo } from "./elf.js";
|
|
2
|
+
import { RUNTIME_SONAMES } from "./sonames.js";
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"libpthread.so.0",
|
|
11
|
-
"librt.so.1",
|
|
12
|
-
"libstdc++.so.6",
|
|
13
|
-
]);
|
|
4
|
+
const DOWNLOAD_REMEDY =
|
|
5
|
+
"The packages GTKX generates declare the libraries an official release links against, and this release " +
|
|
6
|
+
"links against more. Report it to GTKX, and pin `deploy.node.version` to a release it already packages.";
|
|
7
|
+
|
|
8
|
+
const SOURCE_REMEDY = 'Use `deploy.node.source: "download"` to fetch an official self-contained build instead.';
|
|
9
|
+
|
|
10
|
+
const remedyFor = (source: string): string => (source === "download" ? DOWNLOAD_REMEDY : SOURCE_REMEDY);
|
|
14
11
|
|
|
15
12
|
const assertPortableNode = (info: ElfInfo, source: string): void => {
|
|
16
|
-
const foreign = info.needed.filter((library) => !
|
|
13
|
+
const foreign = info.needed.filter((library) => !RUNTIME_SONAMES.has(library));
|
|
17
14
|
|
|
18
15
|
if (foreign.length === 0) {
|
|
19
16
|
return;
|
|
@@ -21,8 +18,7 @@ const assertPortableNode = (info: ElfInfo, source: string): void => {
|
|
|
21
18
|
|
|
22
19
|
throw new Error(
|
|
23
20
|
`Cannot bundle this Node.js binary: \`deploy.node.source: "${source}"\` picked one linked against ` +
|
|
24
|
-
`${foreign.join(", ")}, which the
|
|
25
|
-
'Use `deploy.node.source: "download"` to fetch an official self-contained build instead.',
|
|
21
|
+
`${foreign.join(", ")}, which the packages GTKX generates do not require. ${remedyFor(source)}`,
|
|
26
22
|
);
|
|
27
23
|
};
|
|
28
24
|
|