@gtkx/cli 1.6.0 → 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.
Files changed (578) hide show
  1. package/README.md +47 -44
  2. package/bin/gtkx-dev-runner.js +5 -1
  3. package/bin/gtkx.js +5 -1
  4. package/dist/builder.d.ts +1 -0
  5. package/dist/builder.d.ts.map +1 -1
  6. package/dist/builder.js +44 -12
  7. package/dist/builder.js.map +1 -1
  8. package/dist/cli.d.ts +1 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +14 -2
  11. package/dist/cli.js.map +1 -1
  12. package/dist/codegen/config-dependencies.d.ts +3 -0
  13. package/dist/codegen/config-dependencies.d.ts.map +1 -0
  14. package/dist/codegen/config-dependencies.js +355 -0
  15. package/dist/codegen/config-dependencies.js.map +1 -0
  16. package/dist/codegen/freshness.d.ts.map +1 -1
  17. package/dist/codegen/freshness.js +49 -16
  18. package/dist/codegen/freshness.js.map +1 -1
  19. package/dist/codegen/reference.d.ts.map +1 -1
  20. package/dist/codegen/reference.js +2 -7
  21. package/dist/codegen/reference.js.map +1 -1
  22. package/dist/codegen/report.d.ts.map +1 -1
  23. package/dist/codegen/report.js +5 -16
  24. package/dist/codegen/report.js.map +1 -1
  25. package/dist/codegen/run-codegen.d.ts +9 -8
  26. package/dist/codegen/run-codegen.d.ts.map +1 -1
  27. package/dist/codegen/run-codegen.js +60 -113
  28. package/dist/codegen/run-codegen.js.map +1 -1
  29. package/dist/codegen/store-resolver.d.ts +3 -2
  30. package/dist/codegen/store-resolver.d.ts.map +1 -1
  31. package/dist/codegen/store-resolver.js +14 -20
  32. package/dist/codegen/store-resolver.js.map +1 -1
  33. package/dist/commands/build.d.ts +5 -0
  34. package/dist/commands/build.d.ts.map +1 -1
  35. package/dist/commands/build.js +83 -10
  36. package/dist/commands/build.js.map +1 -1
  37. package/dist/commands/cleanup.d.ts +9 -0
  38. package/dist/commands/cleanup.d.ts.map +1 -0
  39. package/dist/commands/cleanup.js +42 -0
  40. package/dist/commands/cleanup.js.map +1 -0
  41. package/dist/commands/codegen.d.ts +1 -0
  42. package/dist/commands/codegen.d.ts.map +1 -1
  43. package/dist/commands/codegen.js +6 -5
  44. package/dist/commands/codegen.js.map +1 -1
  45. package/dist/commands/deploy.d.ts +5 -0
  46. package/dist/commands/deploy.d.ts.map +1 -1
  47. package/dist/commands/deploy.js +10 -2
  48. package/dist/commands/deploy.js.map +1 -1
  49. package/dist/commands/dev.d.ts +9 -0
  50. package/dist/commands/dev.d.ts.map +1 -1
  51. package/dist/commands/dev.js +31 -4
  52. package/dist/commands/dev.js.map +1 -1
  53. package/dist/commands/docs.d.ts.map +1 -1
  54. package/dist/commands/docs.js +6 -15
  55. package/dist/commands/docs.js.map +1 -1
  56. package/dist/deploy/depends.d.ts.map +1 -1
  57. package/dist/deploy/depends.js +24 -2
  58. package/dist/deploy/depends.js.map +1 -1
  59. package/dist/deploy/download.d.ts +7 -3
  60. package/dist/deploy/download.d.ts.map +1 -1
  61. package/dist/deploy/download.js +19 -20
  62. package/dist/deploy/download.js.map +1 -1
  63. package/dist/deploy/freedesktop/copyright.d.ts.map +1 -1
  64. package/dist/deploy/freedesktop/copyright.js +2 -13
  65. package/dist/deploy/freedesktop/copyright.js.map +1 -1
  66. package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -1
  67. package/dist/deploy/freedesktop/metainfo.js +41 -2
  68. package/dist/deploy/freedesktop/metainfo.js.map +1 -1
  69. package/dist/deploy/freedesktop/validate.d.ts.map +1 -1
  70. package/dist/deploy/freedesktop/validate.js +58 -14
  71. package/dist/deploy/freedesktop/validate.js.map +1 -1
  72. package/dist/deploy/freedesktop/xml.d.ts.map +1 -1
  73. package/dist/deploy/freedesktop/xml.js +21 -25
  74. package/dist/deploy/freedesktop/xml.js.map +1 -1
  75. package/dist/deploy/native-addon.d.ts +5 -0
  76. package/dist/deploy/native-addon.d.ts.map +1 -0
  77. package/dist/deploy/native-addon.js +134 -0
  78. package/dist/deploy/native-addon.js.map +1 -0
  79. package/dist/deploy/nfpm/config.d.ts +3 -2
  80. package/dist/deploy/nfpm/config.d.ts.map +1 -1
  81. package/dist/deploy/nfpm/config.js +7 -4
  82. package/dist/deploy/nfpm/config.js.map +1 -1
  83. package/dist/deploy/nfpm/contents.d.ts.map +1 -1
  84. package/dist/deploy/nfpm/contents.js +8 -0
  85. package/dist/deploy/nfpm/contents.js.map +1 -1
  86. package/dist/deploy/node-runtime/download.js +2 -2
  87. package/dist/deploy/node-runtime/download.js.map +1 -1
  88. package/dist/deploy/node-runtime/elf.d.ts +4 -1
  89. package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
  90. package/dist/deploy/node-runtime/elf.js +34 -5
  91. package/dist/deploy/node-runtime/elf.js.map +1 -1
  92. package/dist/deploy/node-runtime/guard.d.ts.map +1 -1
  93. package/dist/deploy/node-runtime/guard.js +7 -14
  94. package/dist/deploy/node-runtime/guard.js.map +1 -1
  95. package/dist/deploy/node-runtime/index.d.ts +3 -1
  96. package/dist/deploy/node-runtime/index.d.ts.map +1 -1
  97. package/dist/deploy/node-runtime/index.js +103 -10
  98. package/dist/deploy/node-runtime/index.js.map +1 -1
  99. package/dist/deploy/node-runtime/license.d.ts.map +1 -1
  100. package/dist/deploy/node-runtime/license.js +2 -9
  101. package/dist/deploy/node-runtime/license.js.map +1 -1
  102. package/dist/deploy/node-runtime/sonames.d.ts +5 -0
  103. package/dist/deploy/node-runtime/sonames.d.ts.map +1 -0
  104. package/dist/deploy/node-runtime/sonames.js +13 -0
  105. package/dist/deploy/node-runtime/sonames.js.map +1 -0
  106. package/dist/deploy/notices/node-runtime.js +2 -2
  107. package/dist/deploy/notices/node-runtime.js.map +1 -1
  108. package/dist/deploy/notices/packages.d.ts.map +1 -1
  109. package/dist/deploy/notices/packages.js +3 -10
  110. package/dist/deploy/notices/packages.js.map +1 -1
  111. package/dist/deploy/payload/copy-tree.d.ts.map +1 -1
  112. package/dist/deploy/payload/copy-tree.js +3 -3
  113. package/dist/deploy/payload/copy-tree.js.map +1 -1
  114. package/dist/deploy/payload/launcher.d.ts.map +1 -1
  115. package/dist/deploy/payload/launcher.js +14 -1
  116. package/dist/deploy/payload/launcher.js.map +1 -1
  117. package/dist/deploy/payload/stage.d.ts +2 -1
  118. package/dist/deploy/payload/stage.d.ts.map +1 -1
  119. package/dist/deploy/payload/stage.js +47 -8
  120. package/dist/deploy/payload/stage.js.map +1 -1
  121. package/dist/deploy/run-deploy.d.ts +2 -0
  122. package/dist/deploy/run-deploy.d.ts.map +1 -1
  123. package/dist/deploy/run-deploy.js +197 -52
  124. package/dist/deploy/run-deploy.js.map +1 -1
  125. package/dist/deploy/settings/arch.d.ts +9 -3
  126. package/dist/deploy/settings/arch.d.ts.map +1 -1
  127. package/dist/deploy/settings/arch.js +27 -6
  128. package/dist/deploy/settings/arch.js.map +1 -1
  129. package/dist/deploy/settings/build-manifest.d.ts +6 -1
  130. package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
  131. package/dist/deploy/settings/build-manifest.js +17 -17
  132. package/dist/deploy/settings/build-manifest.js.map +1 -1
  133. package/dist/deploy/settings/extra-files.d.ts +1 -1
  134. package/dist/deploy/settings/extra-files.d.ts.map +1 -1
  135. package/dist/deploy/settings/extra-files.js +25 -3
  136. package/dist/deploy/settings/extra-files.js.map +1 -1
  137. package/dist/deploy/settings/index.d.ts +3 -1
  138. package/dist/deploy/settings/index.d.ts.map +1 -1
  139. package/dist/deploy/settings/index.js +4 -2
  140. package/dist/deploy/settings/index.js.map +1 -1
  141. package/dist/deploy/settings/libraries.d.ts.map +1 -1
  142. package/dist/deploy/settings/libraries.js +3 -19
  143. package/dist/deploy/settings/libraries.js.map +1 -1
  144. package/dist/deploy/settings/paths.d.ts +4 -3
  145. package/dist/deploy/settings/paths.d.ts.map +1 -1
  146. package/dist/deploy/settings/paths.js +118 -19
  147. package/dist/deploy/settings/paths.js.map +1 -1
  148. package/dist/deploy/settings/screenshots.d.ts.map +1 -1
  149. package/dist/deploy/settings/screenshots.js +6 -31
  150. package/dist/deploy/settings/screenshots.js.map +1 -1
  151. package/dist/deploy/targets/appimage.d.ts.map +1 -1
  152. package/dist/deploy/targets/appimage.js +1 -0
  153. package/dist/deploy/targets/appimage.js.map +1 -1
  154. package/dist/deploy/targets/flatpak-pnpm.js +4 -4
  155. package/dist/deploy/targets/flatpak-pnpm.js.map +1 -1
  156. package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
  157. package/dist/deploy/targets/flatpak-source.js +17 -6
  158. package/dist/deploy/targets/flatpak-source.js.map +1 -1
  159. package/dist/deploy/targets/flatpak-sources.js +1 -1
  160. package/dist/deploy/targets/flatpak-sources.js.map +1 -1
  161. package/dist/deploy/targets/flatpak.d.ts.map +1 -1
  162. package/dist/deploy/targets/flatpak.js +1 -0
  163. package/dist/deploy/targets/flatpak.js.map +1 -1
  164. package/dist/deploy/targets/nfpm-target.d.ts.map +1 -1
  165. package/dist/deploy/targets/nfpm-target.js +13 -7
  166. package/dist/deploy/targets/nfpm-target.js.map +1 -1
  167. package/dist/deploy/types.d.ts +5 -2
  168. package/dist/deploy/types.d.ts.map +1 -1
  169. package/dist/deploy/types.js.map +1 -1
  170. package/dist/deploy/vendored/appimagetool.js +2 -2
  171. package/dist/deploy/vendored/appimagetool.js.map +1 -1
  172. package/dist/deploy/vendored/nfpm.js +1 -1
  173. package/dist/deploy/vendored/nfpm.js.map +1 -1
  174. package/dist/dev/catalog-writes.d.ts +8 -0
  175. package/dist/dev/catalog-writes.d.ts.map +1 -0
  176. package/dist/dev/catalog-writes.js +26 -0
  177. package/dist/dev/catalog-writes.js.map +1 -0
  178. package/dist/dev/entry-env.d.ts +2 -1
  179. package/dist/dev/entry-env.d.ts.map +1 -1
  180. package/dist/dev/entry-env.js +2 -1
  181. package/dist/dev/entry-env.js.map +1 -1
  182. package/dist/dev/font-dir.d.ts +3 -0
  183. package/dist/dev/font-dir.d.ts.map +1 -0
  184. package/dist/dev/font-dir.js +9 -0
  185. package/dist/dev/font-dir.js.map +1 -0
  186. package/dist/dev/headless.d.ts +3 -0
  187. package/dist/dev/headless.d.ts.map +1 -0
  188. package/dist/dev/headless.js +35 -0
  189. package/dist/dev/headless.js.map +1 -0
  190. package/dist/dev/runner-deps.d.ts +1 -1
  191. package/dist/dev/runner-deps.d.ts.map +1 -1
  192. package/dist/dev/runner-deps.js +12 -7
  193. package/dist/dev/runner-deps.js.map +1 -1
  194. package/dist/dev/runner-main.d.ts.map +1 -1
  195. package/dist/dev/runner-main.js +11 -5
  196. package/dist/dev/runner-main.js.map +1 -1
  197. package/dist/dev/runner.d.ts +2 -0
  198. package/dist/dev/runner.d.ts.map +1 -1
  199. package/dist/dev/runner.js +26 -7
  200. package/dist/dev/runner.js.map +1 -1
  201. package/dist/dev/schema-dir.d.ts +1 -1
  202. package/dist/dev/schema-dir.d.ts.map +1 -1
  203. package/dist/dev/schema-dir.js +2 -4
  204. package/dist/dev/schema-dir.js.map +1 -1
  205. package/dist/dev/supervisor.d.ts +3 -1
  206. package/dist/dev/supervisor.d.ts.map +1 -1
  207. package/dist/dev/supervisor.js +132 -29
  208. package/dist/dev/supervisor.js.map +1 -1
  209. package/dist/dev/vite-dev-server.d.ts +1 -1
  210. package/dist/dev/vite-dev-server.d.ts.map +1 -1
  211. package/dist/dev/vite-dev-server.js +14 -2
  212. package/dist/dev/vite-dev-server.js.map +1 -1
  213. package/dist/dev/watch-ignore.d.ts +3 -0
  214. package/dist/dev/watch-ignore.d.ts.map +1 -0
  215. package/dist/dev/watch-ignore.js +11 -0
  216. package/dist/dev/watch-ignore.js.map +1 -0
  217. package/dist/i18n/catalogs.d.ts +6 -2
  218. package/dist/i18n/catalogs.d.ts.map +1 -1
  219. package/dist/i18n/catalogs.js +12 -8
  220. package/dist/i18n/catalogs.js.map +1 -1
  221. package/dist/i18n/metadata-templates.d.ts.map +1 -1
  222. package/dist/i18n/metadata-templates.js +2 -1
  223. package/dist/i18n/metadata-templates.js.map +1 -1
  224. package/dist/i18n/source-messages.d.ts +5 -21
  225. package/dist/i18n/source-messages.d.ts.map +1 -1
  226. package/dist/i18n/source-messages.js +1037 -92
  227. package/dist/i18n/source-messages.js.map +1 -1
  228. package/dist/i18n/types.d.ts +6 -7
  229. package/dist/i18n/types.d.ts.map +1 -1
  230. package/dist/i18n/types.js +83 -96
  231. package/dist/i18n/types.js.map +1 -1
  232. package/dist/internal/agent-rules.d.ts.map +1 -1
  233. package/dist/internal/agent-rules.js +7 -2
  234. package/dist/internal/agent-rules.js.map +1 -1
  235. package/dist/internal/banner.d.ts +4 -2
  236. package/dist/internal/banner.d.ts.map +1 -1
  237. package/dist/internal/banner.js +19 -5
  238. package/dist/internal/banner.js.map +1 -1
  239. package/dist/internal/build-manifest.d.ts +5 -2
  240. package/dist/internal/build-manifest.d.ts.map +1 -1
  241. package/dist/internal/build-manifest.js +15 -2
  242. package/dist/internal/build-manifest.js.map +1 -1
  243. package/dist/internal/build-output.d.ts +8 -0
  244. package/dist/internal/build-output.d.ts.map +1 -0
  245. package/dist/internal/build-output.js +116 -0
  246. package/dist/internal/build-output.js.map +1 -0
  247. package/dist/internal/cache-root.d.ts +3 -0
  248. package/dist/internal/cache-root.d.ts.map +1 -0
  249. package/dist/internal/cache-root.js +9 -0
  250. package/dist/internal/cache-root.js.map +1 -0
  251. package/dist/internal/compile-cache-store.d.ts +4 -0
  252. package/dist/internal/compile-cache-store.d.ts.map +1 -0
  253. package/dist/internal/compile-cache-store.js +41 -0
  254. package/dist/internal/compile-cache-store.js.map +1 -0
  255. package/dist/internal/compile-cache.d.ts +4 -0
  256. package/dist/internal/compile-cache.d.ts.map +1 -0
  257. package/dist/internal/compile-cache.js +16 -0
  258. package/dist/internal/compile-cache.js.map +1 -0
  259. package/dist/internal/deploy-out-dir.d.ts +4 -0
  260. package/dist/internal/deploy-out-dir.d.ts.map +1 -0
  261. package/dist/internal/deploy-out-dir.js +5 -0
  262. package/dist/internal/deploy-out-dir.js.map +1 -0
  263. package/dist/internal/docs-elements.d.ts +1 -0
  264. package/dist/internal/docs-elements.d.ts.map +1 -1
  265. package/dist/internal/docs-elements.js +6 -5
  266. package/dist/internal/docs-elements.js.map +1 -1
  267. package/dist/internal/entry-arg.d.ts +4 -1
  268. package/dist/internal/entry-arg.d.ts.map +1 -1
  269. package/dist/internal/entry-arg.js +7 -1
  270. package/dist/internal/entry-arg.js.map +1 -1
  271. package/dist/internal/errors.d.ts +2 -1
  272. package/dist/internal/errors.d.ts.map +1 -1
  273. package/dist/internal/errors.js +1 -1
  274. package/dist/internal/errors.js.map +1 -1
  275. package/dist/internal/font-path.d.ts +4 -0
  276. package/dist/internal/font-path.d.ts.map +1 -0
  277. package/dist/internal/font-path.js +12 -0
  278. package/dist/internal/font-path.js.map +1 -0
  279. package/dist/internal/font-staging.d.ts +6 -0
  280. package/dist/internal/font-staging.d.ts.map +1 -0
  281. package/dist/internal/font-staging.js +94 -0
  282. package/dist/internal/font-staging.js.map +1 -0
  283. package/dist/internal/icon-path.d.ts.map +1 -1
  284. package/dist/internal/icon-path.js +5 -16
  285. package/dist/internal/icon-path.js.map +1 -1
  286. package/dist/internal/icon-staging.d.ts +3 -0
  287. package/dist/internal/icon-staging.d.ts.map +1 -0
  288. package/dist/internal/icon-staging.js +40 -0
  289. package/dist/internal/icon-staging.js.map +1 -0
  290. package/dist/internal/import-scan.d.ts +4 -0
  291. package/dist/internal/import-scan.d.ts.map +1 -0
  292. package/dist/internal/import-scan.js +138 -0
  293. package/dist/internal/import-scan.js.map +1 -0
  294. package/dist/internal/module-hash.d.ts +3 -0
  295. package/dist/internal/module-hash.d.ts.map +1 -0
  296. package/dist/internal/module-hash.js +19 -0
  297. package/dist/internal/module-hash.js.map +1 -0
  298. package/dist/internal/output-directory.d.ts +15 -0
  299. package/dist/internal/output-directory.d.ts.map +1 -0
  300. package/dist/internal/output-directory.js +490 -0
  301. package/dist/internal/output-directory.js.map +1 -0
  302. package/dist/internal/parent-process.d.ts +12 -0
  303. package/dist/internal/parent-process.d.ts.map +1 -0
  304. package/dist/internal/parent-process.js +74 -0
  305. package/dist/internal/parent-process.js.map +1 -0
  306. package/dist/internal/prepare-project.d.ts +3 -0
  307. package/dist/internal/prepare-project.d.ts.map +1 -1
  308. package/dist/internal/prepare-project.js +9 -3
  309. package/dist/internal/prepare-project.js.map +1 -1
  310. package/dist/internal/react-compiler-cache.d.ts +13 -0
  311. package/dist/internal/react-compiler-cache.d.ts.map +1 -0
  312. package/dist/internal/react-compiler-cache.js +182 -0
  313. package/dist/internal/react-compiler-cache.js.map +1 -0
  314. package/dist/internal/source-imports.d.ts +7 -2
  315. package/dist/internal/source-imports.d.ts.map +1 -1
  316. package/dist/internal/source-imports.js +38 -49
  317. package/dist/internal/source-imports.js.map +1 -1
  318. package/dist/internal/staging-file.d.ts +5 -0
  319. package/dist/internal/staging-file.d.ts.map +1 -0
  320. package/dist/internal/staging-file.js +35 -0
  321. package/dist/internal/staging-file.js.map +1 -0
  322. package/dist/internal/xdg-banner.d.ts +4 -0
  323. package/dist/internal/xdg-banner.d.ts.map +1 -0
  324. package/dist/internal/xdg-banner.js +11 -0
  325. package/dist/internal/xdg-banner.js.map +1 -0
  326. package/dist/internal/xdg-data-dirs.d.ts +2 -1
  327. package/dist/internal/xdg-data-dirs.d.ts.map +1 -1
  328. package/dist/internal/xdg-data-dirs.js +1 -1
  329. package/dist/internal/xdg-data-dirs.js.map +1 -1
  330. package/dist/mcp/client.js +2 -2
  331. package/dist/mcp/client.js.map +1 -1
  332. package/dist/settings/render.d.ts +0 -1
  333. package/dist/settings/render.d.ts.map +1 -1
  334. package/dist/settings/render.js +1 -11
  335. package/dist/settings/render.js.map +1 -1
  336. package/dist/settings/schema.d.ts +2 -2
  337. package/dist/settings/schema.d.ts.map +1 -1
  338. package/dist/settings/schema.js +24 -70
  339. package/dist/settings/schema.js.map +1 -1
  340. package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
  341. package/dist/vite-plugins/asset-extensions.js +2 -0
  342. package/dist/vite-plugins/asset-extensions.js.map +1 -1
  343. package/dist/vite-plugins/asset-imports.d.ts +1 -2
  344. package/dist/vite-plugins/asset-imports.d.ts.map +1 -1
  345. package/dist/vite-plugins/asset-imports.js +36 -35
  346. package/dist/vite-plugins/asset-imports.js.map +1 -1
  347. package/dist/vite-plugins/asset-specifier.d.ts +5 -3
  348. package/dist/vite-plugins/asset-specifier.d.ts.map +1 -1
  349. package/dist/vite-plugins/asset-specifier.js +10 -4
  350. package/dist/vite-plugins/asset-specifier.js.map +1 -1
  351. package/dist/vite-plugins/build-manifest.d.ts +5 -1
  352. package/dist/vite-plugins/build-manifest.d.ts.map +1 -1
  353. package/dist/vite-plugins/build-manifest.js +2 -1
  354. package/dist/vite-plugins/build-manifest.js.map +1 -1
  355. package/dist/vite-plugins/built-url.d.ts.map +1 -1
  356. package/dist/vite-plugins/built-url.js +5 -2
  357. package/dist/vite-plugins/built-url.js.map +1 -1
  358. package/dist/vite-plugins/css.d.ts.map +1 -1
  359. package/dist/vite-plugins/css.js +13 -5
  360. package/dist/vite-plugins/css.js.map +1 -1
  361. package/dist/vite-plugins/ensure-store.d.ts +1 -1
  362. package/dist/vite-plugins/ensure-store.d.ts.map +1 -1
  363. package/dist/vite-plugins/ensure-store.js +2 -2
  364. package/dist/vite-plugins/ensure-store.js.map +1 -1
  365. package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts +6 -1
  366. package/dist/vite-plugins/fast-refresh/refresh-filter.d.ts.map +1 -1
  367. package/dist/vite-plugins/fast-refresh/refresh-filter.js +3 -1
  368. package/dist/vite-plugins/fast-refresh/refresh-filter.js.map +1 -1
  369. package/dist/vite-plugins/fast-refresh/swc-refresh.d.ts.map +1 -1
  370. package/dist/vite-plugins/fast-refresh/swc-refresh.js +23 -14
  371. package/dist/vite-plugins/fast-refresh/swc-refresh.js.map +1 -1
  372. package/dist/vite-plugins/font-name.d.ts +3 -0
  373. package/dist/vite-plugins/font-name.d.ts.map +1 -0
  374. package/dist/vite-plugins/font-name.js +406 -0
  375. package/dist/vite-plugins/font-name.js.map +1 -0
  376. package/dist/vite-plugins/font-worker-env.d.ts +4 -0
  377. package/dist/vite-plugins/font-worker-env.d.ts.map +1 -0
  378. package/dist/vite-plugins/font-worker-env.js +19 -0
  379. package/dist/vite-plugins/font-worker-env.js.map +1 -0
  380. package/dist/vite-plugins/font.d.ts +4 -0
  381. package/dist/vite-plugins/font.d.ts.map +1 -0
  382. package/dist/vite-plugins/font.js +111 -0
  383. package/dist/vite-plugins/font.js.map +1 -0
  384. package/dist/vite-plugins/i18n.d.ts +11 -2
  385. package/dist/vite-plugins/i18n.d.ts.map +1 -1
  386. package/dist/vite-plugins/i18n.js +75 -8
  387. package/dist/vite-plugins/i18n.js.map +1 -1
  388. package/dist/vite-plugins/icon-worker-env.d.ts +4 -0
  389. package/dist/vite-plugins/icon-worker-env.d.ts.map +1 -0
  390. package/dist/vite-plugins/icon-worker-env.js +23 -0
  391. package/dist/vite-plugins/icon-worker-env.js.map +1 -0
  392. package/dist/vite-plugins/icons.d.ts.map +1 -1
  393. package/dist/vite-plugins/icons.js +4 -9
  394. package/dist/vite-plugins/icons.js.map +1 -1
  395. package/dist/vite-plugins/index.d.ts +10 -1
  396. package/dist/vite-plugins/index.d.ts.map +1 -1
  397. package/dist/vite-plugins/index.js +19 -7
  398. package/dist/vite-plugins/index.js.map +1 -1
  399. package/dist/vite-plugins/native.d.ts.map +1 -1
  400. package/dist/vite-plugins/native.js +0 -4
  401. package/dist/vite-plugins/native.js.map +1 -1
  402. package/dist/vite-plugins/react-compiler.d.ts.map +1 -1
  403. package/dist/vite-plugins/react-compiler.js +57 -18
  404. package/dist/vite-plugins/react-compiler.js.map +1 -1
  405. package/dist/vite-plugins/resource-shared.d.ts +3 -1
  406. package/dist/vite-plugins/resource-shared.d.ts.map +1 -1
  407. package/dist/vite-plugins/resource-shared.js +3 -1
  408. package/dist/vite-plugins/resource-shared.js.map +1 -1
  409. package/dist/vite-plugins/resources.d.ts.map +1 -1
  410. package/dist/vite-plugins/resources.js +40 -102
  411. package/dist/vite-plugins/resources.js.map +1 -1
  412. package/dist/vite-plugins/self-contained.d.ts.map +1 -1
  413. package/dist/vite-plugins/self-contained.js +159 -158
  414. package/dist/vite-plugins/self-contained.js.map +1 -1
  415. package/dist/vite-plugins/settings-worker-env.d.ts +1 -1
  416. package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
  417. package/dist/vite-plugins/settings-worker-env.js +5 -7
  418. package/dist/vite-plugins/settings-worker-env.js.map +1 -1
  419. package/dist/vite-plugins/settings.d.ts +1 -2
  420. package/dist/vite-plugins/settings.d.ts.map +1 -1
  421. package/dist/vite-plugins/settings.js +32 -27
  422. package/dist/vite-plugins/settings.js.map +1 -1
  423. package/dist/vite-plugins/store-links.d.ts.map +1 -1
  424. package/dist/vite-plugins/store-links.js +9 -5
  425. package/dist/vite-plugins/store-links.js.map +1 -1
  426. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
  427. package/dist/vite-plugins/undeclared-library.js +25 -25
  428. package/dist/vite-plugins/undeclared-library.js.map +1 -1
  429. package/dist/vite-plugins/worker.d.ts.map +1 -1
  430. package/dist/vite-plugins/worker.js +21 -14
  431. package/dist/vite-plugins/worker.js.map +1 -1
  432. package/dist/vitest-plugin.d.ts +4 -3
  433. package/dist/vitest-plugin.d.ts.map +1 -1
  434. package/dist/vitest-plugin.js +12 -8
  435. package/dist/vitest-plugin.js.map +1 -1
  436. package/env.d.ts +9 -0
  437. package/package.json +28 -17
  438. package/src/builder.ts +45 -12
  439. package/src/cli.ts +15 -2
  440. package/src/codegen/config-dependencies.ts +470 -0
  441. package/src/codegen/freshness.ts +70 -17
  442. package/src/codegen/reference.ts +2 -8
  443. package/src/codegen/report.ts +5 -21
  444. package/src/codegen/run-codegen.ts +73 -160
  445. package/src/codegen/store-resolver.ts +16 -27
  446. package/src/commands/build.ts +13 -2
  447. package/src/commands/cleanup.ts +48 -0
  448. package/src/commands/codegen.ts +6 -5
  449. package/src/commands/deploy.ts +10 -2
  450. package/src/commands/dev.ts +45 -4
  451. package/src/commands/docs.ts +6 -17
  452. package/src/deploy/depends.ts +30 -3
  453. package/src/deploy/download.ts +33 -24
  454. package/src/deploy/freedesktop/copyright.ts +2 -14
  455. package/src/deploy/freedesktop/metainfo.ts +73 -21
  456. package/src/deploy/freedesktop/validate.ts +80 -15
  457. package/src/deploy/freedesktop/xml.ts +24 -32
  458. package/src/deploy/native-addon.ts +183 -0
  459. package/src/deploy/nfpm/config.ts +13 -4
  460. package/src/deploy/nfpm/contents.ts +8 -0
  461. package/src/deploy/node-runtime/download.ts +2 -2
  462. package/src/deploy/node-runtime/elf.ts +46 -5
  463. package/src/deploy/node-runtime/guard.ts +10 -14
  464. package/src/deploy/node-runtime/index.ts +148 -12
  465. package/src/deploy/node-runtime/license.ts +2 -8
  466. package/src/deploy/node-runtime/sonames.ts +17 -0
  467. package/src/deploy/notices/node-runtime.ts +2 -2
  468. package/src/deploy/notices/packages.ts +3 -11
  469. package/src/deploy/payload/copy-tree.ts +3 -4
  470. package/src/deploy/payload/launcher.ts +20 -1
  471. package/src/deploy/payload/stage.ts +78 -11
  472. package/src/deploy/run-deploy.ts +227 -72
  473. package/src/deploy/settings/arch.ts +40 -8
  474. package/src/deploy/settings/build-manifest.ts +30 -17
  475. package/src/deploy/settings/extra-files.ts +30 -4
  476. package/src/deploy/settings/index.ts +7 -2
  477. package/src/deploy/settings/libraries.ts +2 -22
  478. package/src/deploy/settings/paths.ts +78 -21
  479. package/src/deploy/settings/screenshots.ts +8 -46
  480. package/src/deploy/targets/appimage.ts +1 -0
  481. package/src/deploy/targets/flatpak-pnpm.ts +4 -4
  482. package/src/deploy/targets/flatpak-source.ts +19 -6
  483. package/src/deploy/targets/flatpak-sources.ts +1 -1
  484. package/src/deploy/targets/flatpak.ts +1 -0
  485. package/src/deploy/targets/nfpm-target.ts +14 -6
  486. package/src/deploy/types.ts +5 -1
  487. package/src/deploy/vendored/appimagetool.ts +2 -2
  488. package/src/deploy/vendored/nfpm.ts +1 -1
  489. package/src/dev/catalog-writes.ts +35 -0
  490. package/src/dev/entry-env.ts +2 -1
  491. package/src/dev/font-dir.ts +11 -0
  492. package/src/dev/headless.ts +40 -0
  493. package/src/dev/runner-deps.ts +20 -7
  494. package/src/dev/runner-main.ts +13 -5
  495. package/src/dev/runner.ts +37 -7
  496. package/src/dev/schema-dir.ts +2 -4
  497. package/src/dev/supervisor.ts +183 -32
  498. package/src/dev/vite-dev-server.ts +20 -2
  499. package/src/dev/watch-ignore.ts +16 -0
  500. package/src/i18n/catalogs.ts +23 -9
  501. package/src/i18n/metadata-templates.ts +2 -1
  502. package/src/i18n/source-messages.ts +1641 -262
  503. package/src/i18n/types.ts +97 -131
  504. package/src/internal/agent-rules.ts +7 -2
  505. package/src/internal/banner.ts +27 -6
  506. package/src/internal/build-manifest.ts +25 -1
  507. package/src/internal/build-output.ts +171 -0
  508. package/src/internal/cache-root.ts +12 -0
  509. package/src/internal/compile-cache-store.ts +50 -0
  510. package/src/internal/compile-cache.ts +20 -0
  511. package/src/internal/deploy-out-dir.ts +8 -0
  512. package/src/internal/docs-elements.ts +11 -5
  513. package/src/internal/entry-arg.ts +8 -1
  514. package/src/internal/errors.ts +1 -1
  515. package/src/internal/font-path.ts +15 -0
  516. package/src/internal/font-staging.ts +131 -0
  517. package/src/internal/icon-path.ts +6 -19
  518. package/src/internal/icon-staging.ts +58 -0
  519. package/src/internal/import-scan.ts +206 -0
  520. package/src/internal/module-hash.ts +22 -0
  521. package/src/internal/output-directory.ts +699 -0
  522. package/src/internal/parent-process.ts +110 -0
  523. package/src/internal/prepare-project.ts +11 -5
  524. package/src/internal/react-compiler-cache.ts +246 -0
  525. package/src/internal/source-imports.ts +64 -55
  526. package/src/internal/staging-file.ts +42 -0
  527. package/src/internal/xdg-banner.ts +13 -0
  528. package/src/internal/xdg-data-dirs.ts +1 -1
  529. package/src/mcp/client.ts +2 -2
  530. package/src/settings/render.ts +1 -13
  531. package/src/settings/schema.ts +23 -91
  532. package/src/vite-plugins/asset-extensions.ts +2 -0
  533. package/src/vite-plugins/asset-imports.ts +39 -45
  534. package/src/vite-plugins/asset-specifier.ts +17 -5
  535. package/src/vite-plugins/build-manifest.ts +7 -1
  536. package/src/vite-plugins/built-url.ts +6 -2
  537. package/src/vite-plugins/css.ts +16 -5
  538. package/src/vite-plugins/ensure-store.ts +2 -2
  539. package/src/vite-plugins/fast-refresh/refresh-filter.ts +10 -1
  540. package/src/vite-plugins/fast-refresh/swc-refresh.ts +33 -14
  541. package/src/vite-plugins/font-name.ts +582 -0
  542. package/src/vite-plugins/font-worker-env.ts +25 -0
  543. package/src/vite-plugins/font.ts +180 -0
  544. package/src/vite-plugins/i18n.ts +123 -11
  545. package/src/vite-plugins/icon-worker-env.ts +36 -0
  546. package/src/vite-plugins/icons.ts +4 -10
  547. package/src/vite-plugins/index.ts +36 -13
  548. package/src/vite-plugins/native.ts +0 -5
  549. package/src/vite-plugins/react-compiler.ts +83 -19
  550. package/src/vite-plugins/resource-shared.ts +4 -0
  551. package/src/vite-plugins/resources.ts +47 -144
  552. package/src/vite-plugins/self-contained.ts +184 -185
  553. package/src/vite-plugins/settings-worker-env.ts +5 -7
  554. package/src/vite-plugins/settings.ts +44 -33
  555. package/src/vite-plugins/store-links.ts +10 -5
  556. package/src/vite-plugins/undeclared-library.ts +30 -32
  557. package/src/vite-plugins/worker.ts +31 -16
  558. package/src/vitest-plugin.ts +12 -8
  559. package/dist/i18n/binding-extractor.d.ts +0 -30
  560. package/dist/i18n/binding-extractor.d.ts.map +0 -1
  561. package/dist/i18n/binding-extractor.js +0 -1324
  562. package/dist/i18n/binding-extractor.js.map +0 -1
  563. package/dist/i18n/extractor-plugin.d.ts +0 -8
  564. package/dist/i18n/extractor-plugin.d.ts.map +0 -1
  565. package/dist/i18n/extractor-plugin.js +0 -247
  566. package/dist/i18n/extractor-plugin.js.map +0 -1
  567. package/dist/internal/data-dir.d.ts +0 -4
  568. package/dist/internal/data-dir.d.ts.map +0 -1
  569. package/dist/internal/data-dir.js +0 -52
  570. package/dist/internal/data-dir.js.map +0 -1
  571. package/dist/vite-plugins/animated.d.ts +0 -5
  572. package/dist/vite-plugins/animated.d.ts.map +0 -1
  573. package/dist/vite-plugins/animated.js +0 -325
  574. package/dist/vite-plugins/animated.js.map +0 -1
  575. package/src/i18n/binding-extractor.ts +0 -1969
  576. package/src/i18n/extractor-plugin.ts +0 -413
  577. package/src/internal/data-dir.ts +0 -70
  578. package/src/vite-plugins/animated.ts +0 -486
@@ -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.subarray(0, 4).toString("latin1") !== ELF_MAGIC) {
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 readElfInfo = (path: string): ElfInfo => {
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
- export { type ElfInfo, readElfInfo };
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 PORTABLE_LIBRARIES = new Set([
4
- "ld-linux-aarch64.so.1",
5
- "ld-linux-x86-64.so.2",
6
- "libc.so.6",
7
- "libdl.so.2",
8
- "libgcc_s.so.1",
9
- "libm.so.6",
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) => !PORTABLE_LIBRARIES.has(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 target machine will not have. ` +
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
 
@@ -1,10 +1,13 @@
1
- import { info, tryResolveExecutable } from "@gtkx/utils";
2
- import { chmodSync, copyFileSync, mkdirSync, statSync } from "node:fs";
1
+ import { MINIMUM_NODE_VERSION } from "@gtkx/config/internal";
2
+ import { info, tryResolveExecutable, warn } from "@gtkx/utils";
3
+ import { execFileSync } from "node:child_process";
4
+ import { chmodSync, copyFileSync, existsSync, mkdirSync, statSync } from "node:fs";
3
5
  import { join, resolve } from "node:path";
4
- import type { DeploySettings, NodeRuntime } from "../types.js";
6
+ import type { DeployConfig, DeploySettings, NodeRuntime } from "../types.js";
5
7
  import { runCliTool } from "../../internal/run-cli-tool.js";
8
+ import { elfMachineFor, hostArchName } from "../settings/arch.js";
6
9
  import { downloadNode } from "./download.js";
7
- import { readElfInfo } from "./elf.js";
10
+ import { type ElfInfo, readElfInfo, readOptionalElfInfo } from "./elf.js";
8
11
  import { assertPortableNode } from "./guard.js";
9
12
  import { licenseBesideNode } from "./license.js";
10
13
 
@@ -13,13 +16,92 @@ type StagedRuntime = {
13
16
  licenseFile: string | null;
14
17
  };
15
18
 
19
+ type NodeSource = "download" | "host" | "path";
20
+
16
21
  const BYTES_PER_MIB = 1024 * 1024;
17
22
  const EXECUTABLE_MODE = 0o755;
18
23
  const NODE_FILENAME = "node";
24
+ const NODE_VERSION_PATTERN = /^v?(\d+)\.(\d+)\.(\d+)$/;
25
+ const VERSION_PROBE_TIMEOUT_MS = 10_000;
26
+ const VERSION_PROBE_MAX_BUFFER = 1024;
27
+
28
+ const nodeSourceFor = (settings: DeploySettings): NodeSource => settings.deploy.node?.source ?? "download";
29
+
30
+ const parseNodeVersion = (value: string, subject: string): { parts: number[]; version: string } => {
31
+ const match = NODE_VERSION_PATTERN.exec(value.trim());
32
+
33
+ if (match === null) {
34
+ throw new Error(`Cannot determine the Node.js version for ${subject}: expected a version such as 26.7.0`);
35
+ }
36
+
37
+ const parts = match.slice(1).map(Number);
38
+
39
+ return { parts, version: parts.map(String).join(".") };
40
+ };
41
+
42
+ const compareVersions = (left: number[], right: number[]): number => {
43
+ for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
44
+ const difference = (left[index] ?? 0) - (right[index] ?? 0);
45
+
46
+ if (difference !== 0) {
47
+ return difference;
48
+ }
49
+ }
50
+
51
+ return 0;
52
+ };
53
+
54
+ const supportedNodeVersion = (value: string, subject: string): string => {
55
+ const parsed = parseNodeVersion(value, subject);
56
+ const minimum = parseNodeVersion(MINIMUM_NODE_VERSION, "GTKX");
57
+
58
+ if (compareVersions(parsed.parts, minimum.parts) < 0) {
59
+ throw new Error(
60
+ `Cannot bundle Node.js ${parsed.version} for ${subject}: GTKX requires ${MINIMUM_NODE_VERSION} or newer`,
61
+ );
62
+ }
63
+
64
+ return parsed.version;
65
+ };
66
+
67
+ const probeNodeVersion = (path: string): string => {
68
+ try {
69
+ const output = execFileSync(path, ["--version"], {
70
+ encoding: "utf8",
71
+ env: { ...process.env, NODE_OPTIONS: "" },
72
+ maxBuffer: VERSION_PROBE_MAX_BUFFER,
73
+ timeout: VERSION_PROBE_TIMEOUT_MS,
74
+ });
75
+
76
+ return supportedNodeVersion(output, path);
77
+ } catch (error) {
78
+ if (error instanceof Error && error.message.startsWith("Cannot bundle Node.js")) {
79
+ throw error;
80
+ }
81
+
82
+ throw new Error(`Cannot determine the Node.js version from ${path}`, { cause: error });
83
+ }
84
+ };
85
+
86
+ const assertExpectedVersion = (configured: string | undefined, actual: string, source: NodeSource): string => {
87
+ if (configured === undefined) {
88
+ return actual;
89
+ }
90
+
91
+ const expected = parseNodeVersion(configured, `deploy.node.source: "${source}"`).version;
92
+
93
+ if (expected !== actual) {
94
+ throw new Error(
95
+ `The Node.js runtime from deploy.node.source "${source}" is ${actual}, not the configured ${expected}`,
96
+ );
97
+ }
98
+
99
+ return actual;
100
+ };
19
101
 
20
102
  const sourcePathFor = (settings: DeploySettings): string => {
21
103
  const node = settings.deploy.node ?? {};
22
- const source = node.source ?? "download";
104
+ const source = nodeSourceFor(settings);
23
105
 
24
106
  if (source === "host") {
25
107
  return process.execPath;
@@ -32,6 +114,36 @@ const sourcePathFor = (settings: DeploySettings): string => {
32
114
  return resolve(settings.paths.root, node.path);
33
115
  };
34
116
 
117
+ const assertPortableRuntimeSource = (settings: DeploySettings): void => {
118
+ const source = nodeSourceFor(settings);
119
+
120
+ if (source === "download") {
121
+ return;
122
+ }
123
+
124
+ const sourcePath = sourcePathFor(settings);
125
+ const elf = existsSync(sourcePath) ? readOptionalElfInfo(sourcePath) : null;
126
+
127
+ if (elf !== null) {
128
+ assertPortableNode(elf, source);
129
+ }
130
+ };
131
+
132
+ const resolveNodeVersion = (settings: DeploySettings): string => {
133
+ const node = settings.deploy.node ?? {};
134
+ const source = nodeSourceFor(settings);
135
+
136
+ if (source === "download") {
137
+ return supportedNodeVersion(node.version ?? MINIMUM_NODE_VERSION, 'deploy.node.source: "download"');
138
+ }
139
+
140
+ const actual = source === "host"
141
+ ? supportedNodeVersion(process.versions.node, 'deploy.node.source: "host"')
142
+ : probeNodeVersion(sourcePathFor(settings));
143
+
144
+ return assertExpectedVersion(node.version, actual, source);
145
+ };
146
+
35
147
  const didStripBinary = (path: string): boolean => {
36
148
  if (tryResolveExecutable("strip") === undefined) {
37
149
  return false;
@@ -60,27 +172,51 @@ const stageDownloadedNode = async (settings: DeploySettings, version: string): P
60
172
  return downloaded;
61
173
  };
62
174
 
63
- const stageFromSource = async (settings: DeploySettings, version: string, source: string): Promise<StagedRuntime> => {
175
+ const stageFromSource = async (
176
+ settings: DeploySettings,
177
+ version: string,
178
+ source: NodeSource,
179
+ ): Promise<StagedRuntime> => {
64
180
  if (source === "download") {
65
181
  return stageDownloadedNode(settings, version);
66
182
  }
67
183
 
68
184
  const sourcePath = sourcePathFor(settings);
69
- assertPortableNode(readElfInfo(sourcePath), source);
70
185
 
71
186
  return { path: stageNode(settings, sourcePath), licenseFile: licenseBesideNode(sourcePath) };
72
187
  };
73
188
 
189
+ type DeployNodeConfig = NonNullable<DeployConfig["node"]>;
190
+
191
+ const shouldStripRuntime = (settings: DeploySettings, node: DeployNodeConfig, elf: ElfInfo): boolean => {
192
+ if (node.shouldStrip === false) {
193
+ return false;
194
+ }
195
+
196
+ if (elf.machine === elfMachineFor(hostArchName())) {
197
+ return true;
198
+ }
199
+
200
+ warn(
201
+ `Skipping \`strip\` on the bundled Node.js: it was built for ${settings.arch.node} and \`strip\` reads ` +
202
+ `only ${hostArchName()}. The ${settings.arch.node} packages carry an unstripped runtime.`,
203
+ );
204
+
205
+ return false;
206
+ };
207
+
74
208
  const resolveNodeRuntime = async (settings: DeploySettings): Promise<NodeRuntime> => {
75
209
  const node = settings.deploy.node ?? {};
76
- const source = node.source ?? "download";
77
- const version = node.version ?? process.versions.node;
210
+ const source = nodeSourceFor(settings);
211
+ const version = resolveNodeVersion(settings);
78
212
  const staged = await stageFromSource(settings, version, source);
79
- const isStripped = node.shouldStrip === false ? false : didStripBinary(staged.path);
80
213
  const elf = readElfInfo(staged.path);
81
- info(`Bundled Node.js v${version} (${megabytes(staged.path)} MiB, glibc >= ${elf.glibcMinimum ?? "unknown"})`);
214
+ assertPortableNode(elf, source);
215
+ const isStripped = shouldStripRuntime(settings, node, elf) && didStripBinary(staged.path);
216
+ const glibcMinimum = elf.glibcMinimum ?? "unknown";
217
+ info(`Bundled Node.js v${version} (${megabytes(staged.path)} MiB, runtime glibc >= ${glibcMinimum})`);
82
218
 
83
219
  return { ...staged, version, glibcMinimum: elf.glibcMinimum, isStripped };
84
220
  };
85
221
 
86
- export { resolveNodeRuntime, sourcePathFor };
222
+ export { assertPortableRuntimeSource, resolveNodeRuntime, resolveNodeVersion, sourcePathFor };
@@ -1,5 +1,5 @@
1
- import { readFileSync } from "node:fs";
2
1
  import { dirname, join } from "node:path";
2
+ import { readLicenseText } from "../notices/text.js";
3
3
 
4
4
  const LICENSE_FILENAME = "LICENSE";
5
5
  const NODE_MARKER = "Node.js";
@@ -10,13 +10,7 @@ const licenseCandidates = (binary: string): string[] => {
10
10
  return [join(dir, LICENSE_FILENAME), join(dir, "..", LICENSE_FILENAME)];
11
11
  };
12
12
 
13
- const isNodeLicense = (path: string): boolean => {
14
- try {
15
- return readFileSync(path, "utf8").includes(NODE_MARKER);
16
- } catch {
17
- return false;
18
- }
19
- };
13
+ const isNodeLicense = (path: string): boolean => readLicenseText(path)?.includes(NODE_MARKER) === true;
20
14
 
21
15
  const licenseBesideNode = (binary: string): string | null =>
22
16
  licenseCandidates(binary).find((candidate) => isNodeLicense(candidate)) ?? null;
@@ -0,0 +1,17 @@
1
+ const GLIBC_SONAMES = [
2
+ "ld-linux-aarch64.so.1",
3
+ "ld-linux-x86-64.so.2",
4
+ "libc.so.6",
5
+ "libdl.so.2",
6
+ "libm.so.6",
7
+ "libpthread.so.0",
8
+ "librt.so.1",
9
+ ] as const;
10
+
11
+ const PACKAGED_SONAMES = ["libatomic.so.1", "libgcc_s.so.1", "libstdc++.so.6"] as const;
12
+
13
+ type PackagedSoname = (typeof PACKAGED_SONAMES)[number];
14
+
15
+ const RUNTIME_SONAMES: Set<string> = new Set([...GLIBC_SONAMES, ...PACKAGED_SONAMES]);
16
+
17
+ export { PACKAGED_SONAMES, type PackagedSoname, RUNTIME_SONAMES };
@@ -1,6 +1,6 @@
1
1
  import { warn } from "@gtkx/utils";
2
2
  import type { DeploySettings, NodeRuntime, NoticeSection } from "../types.js";
3
- import { sourcePathFor } from "../node-runtime/index.js";
3
+ import { resolveNodeVersion, sourcePathFor } from "../node-runtime/index.js";
4
4
  import { licenseBesideNode } from "../node-runtime/license.js";
5
5
  import { NODE_FILENAME } from "../payload/launcher.js";
6
6
  import { nodeLicenseDestination } from "../payload/stage.js";
@@ -32,7 +32,7 @@ const MISSING_LICENSE =
32
32
  const isSourceMode = (settings: DeploySettings): boolean => settings.deploy.flatpak?.mode === "source";
33
33
 
34
34
  const versionFor = (settings: DeploySettings, node: NodeRuntime | null): string =>
35
- node?.version ?? settings.deploy.node?.version ?? process.versions.node;
35
+ node?.version ?? resolveNodeVersion(settings);
36
36
 
37
37
  const licenseFileFor = (settings: DeploySettings, node: NodeRuntime | null): string | null => {
38
38
  if (node !== null) {
@@ -1,4 +1,5 @@
1
1
  import { sortStringsBy, warn } from "@gtkx/utils";
2
+ import hostedGitInfo from "hosted-git-info";
2
3
  import { existsSync, realpathSync } from "node:fs";
3
4
  import { join, resolve } from "node:path";
4
5
  import type { RecordedPackage } from "../../internal/build-manifest.js";
@@ -17,10 +18,6 @@ type BundledPackage = {
17
18
  };
18
19
 
19
20
  const MANIFEST_FILENAME = "package.json";
20
- const GIT_PREFIX = /^git\+/;
21
- const GIT_SUFFIX = /\.git$/;
22
- const GIT_SCHEME = /^git:\/\//;
23
- const GITHUB_SLUG = /^(?:github:)?(?<slug>[\w.-]+\/[\w.-]+)$/;
24
21
 
25
22
  const realPath = (path: string): string => {
26
23
  try {
@@ -47,14 +44,9 @@ const sourceUrl = (manifest: PackageManifest): string | null => {
47
44
  return null;
48
45
  }
49
46
 
50
- const url = configured.replace(GIT_PREFIX, "").replace(GIT_SUFFIX, "").replace(GIT_SCHEME, "https://");
51
- const slug = GITHUB_SLUG.exec(url)?.groups?.slug;
47
+ const url = configured.replace(/^git\+/, "").replace(/\.git$/, "").replace(/^git:\/\//, "https://");
52
48
 
53
- if (slug !== undefined) {
54
- return `https://github.com/${slug}`;
55
- }
56
-
57
- return url.startsWith("http") ? url : null;
49
+ return hostedGitInfo.fromUrl(url)?.browse() ?? (url.startsWith("http") ? url : null);
58
50
  };
59
51
 
60
52
  const missingPackage = (entry: RecordedPackage): BundledPackage => ({
@@ -1,5 +1,6 @@
1
+ import { isPathInside } from "@gtkx/utils";
1
2
  import { chmodSync, copyFileSync, mkdirSync, statSync, writeFileSync } from "node:fs";
2
- import { dirname, isAbsolute, join, relative } from "node:path";
3
+ import { dirname, join } from "node:path";
3
4
  import type { StagedFile } from "../types.js";
4
5
  import { listFilesRecursive } from "../../internal/list-files.js";
5
6
 
@@ -16,9 +17,7 @@ const modeFor = (rel: string): number => {
16
17
  };
17
18
 
18
19
  const assertInsideRoot = (root: string, rel: string, abs: string): void => {
19
- const escape = relative(root, abs);
20
-
21
- if (escape.length === 0 || escape.startsWith("..") || isAbsolute(escape)) {
20
+ if (!isPathInside(root, abs)) {
22
21
  throw new Error(`Cannot stage "${rel}": it resolves outside the staging directory`);
23
22
  }
24
23
  };
@@ -2,6 +2,8 @@ import type { DeploySettings } from "../types.js";
2
2
  import { BUNDLE_FILENAME } from "../../vite-plugins/esm-extension.js";
3
3
 
4
4
  const NODE_FILENAME = "node";
5
+ const SHELL_SINGLE_QUOTE = "'";
6
+ const SHELL_SINGLE_QUOTE_ESCAPE = "'\"'\"'";
5
7
 
6
8
  const compileCacheLines = (binaryName: string): string[] => [
7
9
  "cache_home=${XDG_CACHE_HOME:-${HOME:-/tmp}/.cache}",
@@ -9,6 +11,22 @@ const compileCacheLines = (binaryName: string): string[] => [
9
11
  "export NODE_COMPILE_CACHE",
10
12
  ];
11
13
 
14
+ const shellQuote = (value: string): string =>
15
+ SHELL_SINGLE_QUOTE + value.split(SHELL_SINGLE_QUOTE).join(SHELL_SINGLE_QUOTE_ESCAPE) + SHELL_SINGLE_QUOTE;
16
+
17
+ const launcherEnvLines = (settings: DeploySettings): string[] =>
18
+ Object.entries(settings.deploy.launcherEnv ?? {})
19
+ .toSorted(([left], [right]) => left.localeCompare(right))
20
+ .map(([name, value]) => `export ${name}=${shellQuote(value)}`);
21
+
22
+ const launcherCommand = (settings: DeploySettings, libDir: string): string =>
23
+ [
24
+ `"${libDir}/${NODE_FILENAME}"`,
25
+ ...(settings.deploy.nodeFlags ?? []).map((flag) => shellQuote(flag)),
26
+ `"${libDir}/${BUNDLE_FILENAME}"`,
27
+ '"$@"',
28
+ ].join(" ");
29
+
12
30
  const renderLauncher = (settings: DeploySettings): string => {
13
31
  const libDir = `$prefix/lib/${settings.binaryName}`;
14
32
  const shouldUseCompileCache = settings.deploy.node?.shouldUseCompileCache !== false;
@@ -21,7 +39,8 @@ const renderLauncher = (settings: DeploySettings): string => {
21
39
  'GTKX_LOCALE_DIR="$prefix/share/locale"',
22
40
  "export GTKX_LOCALE_DIR",
23
41
  ...(shouldUseCompileCache ? compileCacheLines(settings.binaryName) : []),
24
- `exec "${libDir}/${NODE_FILENAME}" "${libDir}/${BUNDLE_FILENAME}" "$@"`,
42
+ ...launcherEnvLines(settings),
43
+ `exec ${launcherCommand(settings, libDir)}`,
25
44
  "",
26
45
  ].join("\n");
27
46
  };
@@ -1,4 +1,4 @@
1
- import { sortStringsBy } from "@gtkx/utils";
1
+ import { sortStringsBy, warn } from "@gtkx/utils";
2
2
  import { existsSync, rmSync } from "node:fs";
3
3
  import { join, resolve } from "node:path";
4
4
  import type { DeploySettings, DeployTargetName, NodeRuntime, NoticeSection, StagedFile } from "../types.js";
@@ -8,7 +8,10 @@ import { listFilesRecursive } from "../../internal/list-files.js";
8
8
  import { BUNDLE_FILENAME } from "../../vite-plugins/esm-extension.js";
9
9
  import { renderCopyright } from "../freedesktop/copyright.js";
10
10
  import { renderDbusService } from "../freedesktop/dbus-service.js";
11
+ import { BINDING_FILENAME } from "../native-addon.js";
12
+ import { readOptionalElfInfo } from "../node-runtime/elf.js";
11
13
  import { renderNotices } from "../notices/render.js";
14
+ import { elfMachineFor } from "../settings/arch.js";
12
15
  import { copyInto, EXECUTABLE_MODE, executableModeFor, writeInto } from "./copy-tree.js";
13
16
  import { stageIcons } from "./icons.js";
14
17
  import { NODE_FILENAME, renderLauncher } from "./launcher.js";
@@ -17,6 +20,7 @@ import { stageSchemas } from "./schemas.js";
17
20
  type StageRequest = {
18
21
  settings: DeploySettings;
19
22
  node: NodeRuntime | null;
23
+ addon: string | null;
20
24
  metadata: StagedMetadata;
21
25
  };
22
26
 
@@ -27,7 +31,6 @@ type StagedMetadata = {
27
31
  };
28
32
 
29
33
  const DIST_ICONS_DIR = "icons";
30
- const LEGACY_PACKAGES_MANIFEST_FILENAME = "gtkx-packages.json";
31
34
  const NOTICES_FILENAME = "THIRD-PARTY-NOTICES";
32
35
  const NODE_LICENSE_FILENAME = "LICENSE";
33
36
  const SHARE_APPLICATIONS = "share/applications";
@@ -50,10 +53,6 @@ const licenseDirFor = (settings: DeploySettings): string => `${SHARE_LICENSES}/$
50
53
  const licenseDestination = (settings: DeploySettings): string => `${licenseDirFor(settings)}/LICENSE`;
51
54
  const noticesDestination = (settings: DeploySettings): string => `${licenseDirFor(settings)}/${NOTICES_FILENAME}`;
52
55
  const isIconAsset = (rel: string): boolean => rel === DIST_ICONS_DIR || rel.startsWith(`${DIST_ICONS_DIR}/`);
53
-
54
- const isBuildMetadata = (rel: string): boolean =>
55
- rel === BUILD_MANIFEST_FILENAME || rel === LEGACY_PACKAGES_MANIFEST_FILENAME;
56
-
57
56
  const isLocaleAsset = (rel: string): boolean => rel === LOCALE_DIRNAME || rel.startsWith(`${LOCALE_DIRNAME}/`);
58
57
 
59
58
  const nodeLicenseDestination = (settings: DeploySettings): string =>
@@ -67,10 +66,34 @@ const stageRuntimeFiles = (settings: DeploySettings, root: string): StagedFile[]
67
66
  }
68
67
 
69
68
  return listFilesRecursive(dist)
70
- .filter((file) => !isIconAsset(file.rel) && !isBuildMetadata(file.rel) && !isLocaleAsset(file.rel))
69
+ .filter((file) =>
70
+ !isIconAsset(file.rel) && file.rel !== BUILD_MANIFEST_FILENAME && !isLocaleAsset(file.rel))
71
71
  .map((file) => copyInto(root, join(libDirFor(settings), file.rel), file.absPath));
72
72
  };
73
73
 
74
+ const stageAddon = (settings: DeploySettings, root: string, addon: string | null): StagedFile[] =>
75
+ addon === null ? [] : [copyInto(root, join(libDirFor(settings), BINDING_FILENAME), addon)];
76
+
77
+ const architectureMismatch = (settings: DeploySettings, file: StagedFile): Error =>
78
+ new Error(
79
+ `Cannot deploy ${file.rel} for ${settings.arch.node}: it was built for another architecture. ` +
80
+ "Run `gtkx build` again, or drop --skip-build.",
81
+ );
82
+
83
+ const assertStagedArchitecture = (settings: DeploySettings, staged: StagedFile[]): void => {
84
+ const expected = elfMachineFor(settings.arch.node);
85
+ const lib = libDirFor(settings);
86
+ const checked = new Set([join(lib, BINDING_FILENAME), join(lib, NODE_FILENAME)]);
87
+
88
+ const binaries = staged.filter((entry) => checked.has(entry.rel));
89
+
90
+ for (const file of binaries) {
91
+ if (readOptionalElfInfo(file.abs)?.machine !== expected) {
92
+ throw architectureMismatch(settings, file);
93
+ }
94
+ }
95
+ };
96
+
74
97
  const stageCatalogs = (settings: DeploySettings, root: string): StagedFile[] =>
75
98
  listFilesRecursive(join(settings.paths.dist, LOCALE_DIRNAME))
76
99
  .map((file) => copyInto(root, join(SHARE_LOCALE, file.rel), file.absPath));
@@ -86,9 +109,48 @@ const stageMetadata = (settings: DeploySettings, root: string, metadata: StagedM
86
109
  : [writeInto(root, join(SHARE_MIME_PACKAGES, `${settings.applicationId}.xml`), metadata.mimePackage)]),
87
110
  ];
88
111
 
89
- const stageExtraFiles = (settings: DeploySettings, root: string): StagedFile[] =>
112
+ const generatedMetadataKind = (
113
+ settings: DeploySettings,
114
+ metadata: StagedMetadata,
115
+ destination: string,
116
+ ): string | null => {
117
+ if (destination === join(SHARE_APPLICATIONS, `${settings.applicationId}.desktop`)) {
118
+ return "desktop entry";
119
+ }
120
+
121
+ if (destination === join(SHARE_METAINFO, `${settings.applicationId}.metainfo.xml`)) {
122
+ return "metainfo";
123
+ }
124
+
125
+ if (
126
+ metadata.mimePackage !== null &&
127
+ destination === join(SHARE_MIME_PACKAGES, `${settings.applicationId}.xml`)
128
+ ) {
129
+ return "MIME package";
130
+ }
131
+
132
+ return null;
133
+ };
134
+
135
+ const warnMetadataCollision = (
136
+ settings: DeploySettings,
137
+ metadata: StagedMetadata,
138
+ file: DeploySettings["extraFiles"][number],
139
+ ): void => {
140
+ const kind = generatedMetadataKind(settings, metadata, file.destination);
141
+
142
+ if (kind !== null) {
143
+ warn(
144
+ `extraFiles source "${file.source}" targeting "${file.destination}" is overridden by the ` +
145
+ `GTKX-generated ${kind}`,
146
+ );
147
+ }
148
+ };
149
+
150
+ const stageExtraFiles = (settings: DeploySettings, root: string, metadata: StagedMetadata): StagedFile[] =>
90
151
  settings.extraFiles.map((file) => {
91
152
  const source = resolve(settings.paths.root, file.source);
153
+ warnMetadataCollision(settings, metadata, file);
92
154
 
93
155
  return copyInto(root, file.destination, source, file.mode ?? executableModeFor(source));
94
156
  });
@@ -103,20 +165,25 @@ const byRelativePath = (files: StagedFile[]): StagedFile[] => {
103
165
  return sortStringsBy(latest.values(), (file) => file.rel);
104
166
  };
105
167
 
106
- const stagePayload = ({ settings, node, metadata }: StageRequest): StagedFile[] => {
168
+ const stagePayload = ({ settings, node, addon, metadata }: StageRequest): StagedFile[] => {
107
169
  const root = settings.paths.stage;
108
170
  rmSync(root, { recursive: true, force: true, maxRetries: 5 });
109
171
 
110
- return byRelativePath([
172
+ const staged = byRelativePath([
111
173
  writeInto(root, join("bin", settings.binaryName), renderLauncher(settings), EXECUTABLE_MODE),
112
174
  ...stageNodeBinary(settings, root, node),
113
175
  ...stageRuntimeFiles(settings, root),
176
+ ...stageAddon(settings, root, addon),
114
177
  ...stageCatalogs(settings, root),
178
+ ...stageExtraFiles(settings, root, metadata),
115
179
  ...stageMetadata(settings, root, metadata),
116
180
  ...stageIcons(settings, root),
117
181
  ...stageSchemas(settings, root),
118
- ...stageExtraFiles(settings, root),
119
182
  ]);
183
+
184
+ assertStagedArchitecture(settings, staged);
185
+
186
+ return staged;
120
187
  };
121
188
 
122
189
  const withoutDbusActivation = (desktopEntry: string): string =>