@gtkx/cli 1.6.0 → 2.0.0-beta.2

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 (309) hide show
  1. package/README.md +5 -5
  2. package/dist/builder.d.ts +1 -0
  3. package/dist/builder.d.ts.map +1 -1
  4. package/dist/builder.js +17 -5
  5. package/dist/builder.js.map +1 -1
  6. package/dist/cli.js +2 -0
  7. package/dist/cli.js.map +1 -1
  8. package/dist/codegen/freshness.d.ts.map +1 -1
  9. package/dist/codegen/freshness.js +45 -16
  10. package/dist/codegen/freshness.js.map +1 -1
  11. package/dist/codegen/reference.d.ts.map +1 -1
  12. package/dist/codegen/reference.js +1 -7
  13. package/dist/codegen/reference.js.map +1 -1
  14. package/dist/codegen/report.d.ts.map +1 -1
  15. package/dist/codegen/report.js +5 -16
  16. package/dist/codegen/report.js.map +1 -1
  17. package/dist/codegen/run-codegen.d.ts +7 -7
  18. package/dist/codegen/run-codegen.d.ts.map +1 -1
  19. package/dist/codegen/run-codegen.js +35 -107
  20. package/dist/codegen/run-codegen.js.map +1 -1
  21. package/dist/codegen/store-resolver.d.ts +1 -2
  22. package/dist/codegen/store-resolver.d.ts.map +1 -1
  23. package/dist/codegen/store-resolver.js +10 -19
  24. package/dist/codegen/store-resolver.js.map +1 -1
  25. package/dist/commands/build.d.ts +5 -0
  26. package/dist/commands/build.d.ts.map +1 -1
  27. package/dist/commands/build.js +83 -10
  28. package/dist/commands/build.js.map +1 -1
  29. package/dist/commands/codegen.d.ts +1 -0
  30. package/dist/commands/codegen.d.ts.map +1 -1
  31. package/dist/commands/codegen.js +6 -5
  32. package/dist/commands/codegen.js.map +1 -1
  33. package/dist/commands/deploy.d.ts +1 -0
  34. package/dist/commands/deploy.d.ts.map +1 -1
  35. package/dist/commands/deploy.js +4 -2
  36. package/dist/commands/deploy.js.map +1 -1
  37. package/dist/commands/dev.d.ts +8 -0
  38. package/dist/commands/dev.d.ts.map +1 -1
  39. package/dist/commands/dev.js +19 -1
  40. package/dist/commands/dev.js.map +1 -1
  41. package/dist/commands/docs.d.ts.map +1 -1
  42. package/dist/commands/docs.js +5 -15
  43. package/dist/commands/docs.js.map +1 -1
  44. package/dist/deploy/freedesktop/copyright.d.ts.map +1 -1
  45. package/dist/deploy/freedesktop/copyright.js +2 -13
  46. package/dist/deploy/freedesktop/copyright.js.map +1 -1
  47. package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -1
  48. package/dist/deploy/freedesktop/metainfo.js +41 -2
  49. package/dist/deploy/freedesktop/metainfo.js.map +1 -1
  50. package/dist/deploy/freedesktop/xml.d.ts.map +1 -1
  51. package/dist/deploy/freedesktop/xml.js +21 -25
  52. package/dist/deploy/freedesktop/xml.js.map +1 -1
  53. package/dist/deploy/nfpm/config.d.ts.map +1 -1
  54. package/dist/deploy/nfpm/config.js +5 -2
  55. package/dist/deploy/nfpm/config.js.map +1 -1
  56. package/dist/deploy/nfpm/contents.d.ts.map +1 -1
  57. package/dist/deploy/nfpm/contents.js +8 -0
  58. package/dist/deploy/nfpm/contents.js.map +1 -1
  59. package/dist/deploy/node-runtime/elf.d.ts +2 -1
  60. package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
  61. package/dist/deploy/node-runtime/elf.js +32 -5
  62. package/dist/deploy/node-runtime/elf.js.map +1 -1
  63. package/dist/deploy/node-runtime/index.d.ts +2 -1
  64. package/dist/deploy/node-runtime/index.d.ts.map +1 -1
  65. package/dist/deploy/node-runtime/index.js +73 -4
  66. package/dist/deploy/node-runtime/index.js.map +1 -1
  67. package/dist/deploy/node-runtime/license.d.ts.map +1 -1
  68. package/dist/deploy/node-runtime/license.js +2 -9
  69. package/dist/deploy/node-runtime/license.js.map +1 -1
  70. package/dist/deploy/notices/node-runtime.js +2 -2
  71. package/dist/deploy/notices/node-runtime.js.map +1 -1
  72. package/dist/deploy/notices/packages.d.ts.map +1 -1
  73. package/dist/deploy/notices/packages.js +3 -10
  74. package/dist/deploy/notices/packages.js.map +1 -1
  75. package/dist/deploy/payload/copy-tree.d.ts.map +1 -1
  76. package/dist/deploy/payload/copy-tree.js +3 -3
  77. package/dist/deploy/payload/copy-tree.js.map +1 -1
  78. package/dist/deploy/payload/launcher.d.ts.map +1 -1
  79. package/dist/deploy/payload/launcher.js +14 -1
  80. package/dist/deploy/payload/launcher.js.map +1 -1
  81. package/dist/deploy/payload/stage.d.ts.map +1 -1
  82. package/dist/deploy/payload/stage.js +2 -4
  83. package/dist/deploy/payload/stage.js.map +1 -1
  84. package/dist/deploy/run-deploy.d.ts +1 -0
  85. package/dist/deploy/run-deploy.d.ts.map +1 -1
  86. package/dist/deploy/run-deploy.js +100 -14
  87. package/dist/deploy/run-deploy.js.map +1 -1
  88. package/dist/deploy/settings/build-manifest.d.ts +6 -1
  89. package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
  90. package/dist/deploy/settings/build-manifest.js +17 -17
  91. package/dist/deploy/settings/build-manifest.js.map +1 -1
  92. package/dist/deploy/settings/extra-files.d.ts +1 -1
  93. package/dist/deploy/settings/extra-files.d.ts.map +1 -1
  94. package/dist/deploy/settings/extra-files.js +22 -1
  95. package/dist/deploy/settings/extra-files.js.map +1 -1
  96. package/dist/deploy/settings/index.d.ts +1 -0
  97. package/dist/deploy/settings/index.d.ts.map +1 -1
  98. package/dist/deploy/settings/index.js +2 -1
  99. package/dist/deploy/settings/index.js.map +1 -1
  100. package/dist/deploy/settings/libraries.d.ts.map +1 -1
  101. package/dist/deploy/settings/libraries.js +2 -19
  102. package/dist/deploy/settings/libraries.js.map +1 -1
  103. package/dist/deploy/settings/paths.d.ts +2 -2
  104. package/dist/deploy/settings/paths.d.ts.map +1 -1
  105. package/dist/deploy/settings/paths.js +110 -12
  106. package/dist/deploy/settings/paths.js.map +1 -1
  107. package/dist/deploy/settings/screenshots.d.ts.map +1 -1
  108. package/dist/deploy/settings/screenshots.js +6 -31
  109. package/dist/deploy/settings/screenshots.js.map +1 -1
  110. package/dist/deploy/targets/flatpak-pnpm.js +4 -4
  111. package/dist/deploy/targets/flatpak-pnpm.js.map +1 -1
  112. package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
  113. package/dist/deploy/targets/flatpak-source.js +15 -6
  114. package/dist/deploy/targets/flatpak-source.js.map +1 -1
  115. package/dist/deploy/targets/flatpak-sources.js +1 -1
  116. package/dist/deploy/targets/flatpak-sources.js.map +1 -1
  117. package/dist/deploy/types.d.ts +1 -0
  118. package/dist/deploy/types.d.ts.map +1 -1
  119. package/dist/deploy/types.js.map +1 -1
  120. package/dist/dev/headless.d.ts +3 -0
  121. package/dist/dev/headless.d.ts.map +1 -0
  122. package/dist/dev/headless.js +35 -0
  123. package/dist/dev/headless.js.map +1 -0
  124. package/dist/dev/runner-deps.js +1 -1
  125. package/dist/dev/runner-deps.js.map +1 -1
  126. package/dist/dev/runner-main.d.ts.map +1 -1
  127. package/dist/dev/runner-main.js +1 -2
  128. package/dist/dev/runner-main.js.map +1 -1
  129. package/dist/dev/schema-dir.d.ts +1 -1
  130. package/dist/dev/schema-dir.d.ts.map +1 -1
  131. package/dist/dev/schema-dir.js +2 -4
  132. package/dist/dev/schema-dir.js.map +1 -1
  133. package/dist/i18n/catalogs.d.ts.map +1 -1
  134. package/dist/i18n/catalogs.js +2 -1
  135. package/dist/i18n/catalogs.js.map +1 -1
  136. package/dist/i18n/metadata-templates.d.ts.map +1 -1
  137. package/dist/i18n/metadata-templates.js +2 -1
  138. package/dist/i18n/metadata-templates.js.map +1 -1
  139. package/dist/i18n/source-messages.d.ts +3 -21
  140. package/dist/i18n/source-messages.d.ts.map +1 -1
  141. package/dist/i18n/source-messages.js +900 -85
  142. package/dist/i18n/source-messages.js.map +1 -1
  143. package/dist/i18n/types.d.ts +6 -7
  144. package/dist/i18n/types.d.ts.map +1 -1
  145. package/dist/i18n/types.js +83 -96
  146. package/dist/i18n/types.js.map +1 -1
  147. package/dist/internal/build-manifest.d.ts +5 -2
  148. package/dist/internal/build-manifest.d.ts.map +1 -1
  149. package/dist/internal/build-manifest.js +15 -2
  150. package/dist/internal/build-manifest.js.map +1 -1
  151. package/dist/internal/build-output.d.ts +8 -0
  152. package/dist/internal/build-output.d.ts.map +1 -0
  153. package/dist/internal/build-output.js +69 -0
  154. package/dist/internal/build-output.js.map +1 -0
  155. package/dist/internal/docs-elements.js +2 -2
  156. package/dist/internal/docs-elements.js.map +1 -1
  157. package/dist/internal/entry-arg.d.ts +4 -1
  158. package/dist/internal/entry-arg.d.ts.map +1 -1
  159. package/dist/internal/entry-arg.js +7 -1
  160. package/dist/internal/entry-arg.js.map +1 -1
  161. package/dist/internal/icon-path.d.ts.map +1 -1
  162. package/dist/internal/icon-path.js +5 -16
  163. package/dist/internal/icon-path.js.map +1 -1
  164. package/dist/internal/output-directory.d.ts +15 -0
  165. package/dist/internal/output-directory.d.ts.map +1 -0
  166. package/dist/internal/output-directory.js +490 -0
  167. package/dist/internal/output-directory.js.map +1 -0
  168. package/dist/internal/prepare-project.d.ts +2 -0
  169. package/dist/internal/prepare-project.d.ts.map +1 -1
  170. package/dist/internal/prepare-project.js +3 -3
  171. package/dist/internal/prepare-project.js.map +1 -1
  172. package/dist/internal/source-imports.d.ts.map +1 -1
  173. package/dist/internal/source-imports.js +10 -41
  174. package/dist/internal/source-imports.js.map +1 -1
  175. package/dist/mcp/client.js +2 -2
  176. package/dist/mcp/client.js.map +1 -1
  177. package/dist/settings/render.d.ts +0 -1
  178. package/dist/settings/render.d.ts.map +1 -1
  179. package/dist/settings/render.js +1 -11
  180. package/dist/settings/render.js.map +1 -1
  181. package/dist/settings/schema.d.ts +2 -2
  182. package/dist/settings/schema.d.ts.map +1 -1
  183. package/dist/settings/schema.js +21 -62
  184. package/dist/settings/schema.js.map +1 -1
  185. package/dist/vite-plugins/asset-imports.d.ts +1 -2
  186. package/dist/vite-plugins/asset-imports.d.ts.map +1 -1
  187. package/dist/vite-plugins/asset-imports.js +19 -32
  188. package/dist/vite-plugins/asset-imports.js.map +1 -1
  189. package/dist/vite-plugins/asset-specifier.d.ts +1 -3
  190. package/dist/vite-plugins/asset-specifier.d.ts.map +1 -1
  191. package/dist/vite-plugins/asset-specifier.js +1 -4
  192. package/dist/vite-plugins/asset-specifier.js.map +1 -1
  193. package/dist/vite-plugins/build-manifest.d.ts +5 -1
  194. package/dist/vite-plugins/build-manifest.d.ts.map +1 -1
  195. package/dist/vite-plugins/build-manifest.js +2 -1
  196. package/dist/vite-plugins/build-manifest.js.map +1 -1
  197. package/dist/vite-plugins/i18n.d.ts.map +1 -1
  198. package/dist/vite-plugins/i18n.js +59 -6
  199. package/dist/vite-plugins/i18n.js.map +1 -1
  200. package/dist/vite-plugins/index.d.ts +8 -1
  201. package/dist/vite-plugins/index.d.ts.map +1 -1
  202. package/dist/vite-plugins/index.js +8 -6
  203. package/dist/vite-plugins/index.js.map +1 -1
  204. package/dist/vite-plugins/resources.d.ts.map +1 -1
  205. package/dist/vite-plugins/resources.js +32 -97
  206. package/dist/vite-plugins/resources.js.map +1 -1
  207. package/dist/vite-plugins/self-contained.d.ts.map +1 -1
  208. package/dist/vite-plugins/self-contained.js +159 -158
  209. package/dist/vite-plugins/self-contained.js.map +1 -1
  210. package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
  211. package/dist/vite-plugins/settings-worker-env.js +2 -4
  212. package/dist/vite-plugins/settings-worker-env.js.map +1 -1
  213. package/dist/vite-plugins/settings.d.ts +1 -2
  214. package/dist/vite-plugins/settings.d.ts.map +1 -1
  215. package/dist/vite-plugins/settings.js +8 -14
  216. package/dist/vite-plugins/settings.js.map +1 -1
  217. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
  218. package/dist/vite-plugins/undeclared-library.js +10 -13
  219. package/dist/vite-plugins/undeclared-library.js.map +1 -1
  220. package/dist/vite-plugins/worker.d.ts.map +1 -1
  221. package/dist/vite-plugins/worker.js +0 -1
  222. package/dist/vite-plugins/worker.js.map +1 -1
  223. package/package.json +21 -15
  224. package/src/builder.ts +18 -5
  225. package/src/cli.ts +3 -0
  226. package/src/codegen/freshness.ts +66 -17
  227. package/src/codegen/reference.ts +1 -8
  228. package/src/codegen/report.ts +5 -21
  229. package/src/codegen/run-codegen.ts +42 -151
  230. package/src/codegen/store-resolver.ts +10 -26
  231. package/src/commands/build.ts +13 -2
  232. package/src/commands/codegen.ts +6 -5
  233. package/src/commands/deploy.ts +4 -2
  234. package/src/commands/dev.ts +20 -1
  235. package/src/commands/docs.ts +5 -17
  236. package/src/deploy/freedesktop/copyright.ts +2 -14
  237. package/src/deploy/freedesktop/metainfo.ts +73 -21
  238. package/src/deploy/freedesktop/xml.ts +24 -32
  239. package/src/deploy/nfpm/config.ts +5 -2
  240. package/src/deploy/nfpm/contents.ts +8 -0
  241. package/src/deploy/node-runtime/elf.ts +43 -5
  242. package/src/deploy/node-runtime/index.ts +105 -5
  243. package/src/deploy/node-runtime/license.ts +2 -8
  244. package/src/deploy/notices/node-runtime.ts +2 -2
  245. package/src/deploy/notices/packages.ts +3 -11
  246. package/src/deploy/payload/copy-tree.ts +3 -4
  247. package/src/deploy/payload/launcher.ts +20 -1
  248. package/src/deploy/payload/stage.ts +3 -7
  249. package/src/deploy/run-deploy.ts +56 -16
  250. package/src/deploy/settings/build-manifest.ts +30 -17
  251. package/src/deploy/settings/extra-files.ts +26 -2
  252. package/src/deploy/settings/index.ts +3 -1
  253. package/src/deploy/settings/libraries.ts +1 -22
  254. package/src/deploy/settings/paths.ts +68 -13
  255. package/src/deploy/settings/screenshots.ts +8 -46
  256. package/src/deploy/targets/flatpak-pnpm.ts +4 -4
  257. package/src/deploy/targets/flatpak-source.ts +17 -6
  258. package/src/deploy/targets/flatpak-sources.ts +1 -1
  259. package/src/deploy/types.ts +1 -0
  260. package/src/dev/headless.ts +40 -0
  261. package/src/dev/runner-deps.ts +1 -1
  262. package/src/dev/runner-main.ts +1 -2
  263. package/src/dev/schema-dir.ts +2 -4
  264. package/src/i18n/catalogs.ts +2 -1
  265. package/src/i18n/metadata-templates.ts +2 -1
  266. package/src/i18n/source-messages.ts +1442 -262
  267. package/src/i18n/types.ts +97 -131
  268. package/src/internal/build-manifest.ts +25 -1
  269. package/src/internal/build-output.ts +99 -0
  270. package/src/internal/docs-elements.ts +2 -2
  271. package/src/internal/entry-arg.ts +8 -1
  272. package/src/internal/icon-path.ts +6 -19
  273. package/src/internal/output-directory.ts +699 -0
  274. package/src/internal/prepare-project.ts +5 -5
  275. package/src/internal/source-imports.ts +14 -50
  276. package/src/mcp/client.ts +2 -2
  277. package/src/settings/render.ts +1 -13
  278. package/src/settings/schema.ts +19 -81
  279. package/src/vite-plugins/asset-imports.ts +20 -44
  280. package/src/vite-plugins/asset-specifier.ts +0 -5
  281. package/src/vite-plugins/build-manifest.ts +7 -1
  282. package/src/vite-plugins/i18n.ts +87 -5
  283. package/src/vite-plugins/index.ts +16 -11
  284. package/src/vite-plugins/resources.ts +37 -140
  285. package/src/vite-plugins/self-contained.ts +184 -185
  286. package/src/vite-plugins/settings-worker-env.ts +2 -4
  287. package/src/vite-plugins/settings.ts +11 -20
  288. package/src/vite-plugins/undeclared-library.ts +14 -20
  289. package/src/vite-plugins/worker.ts +0 -1
  290. package/dist/i18n/binding-extractor.d.ts +0 -30
  291. package/dist/i18n/binding-extractor.d.ts.map +0 -1
  292. package/dist/i18n/binding-extractor.js +0 -1324
  293. package/dist/i18n/binding-extractor.js.map +0 -1
  294. package/dist/i18n/extractor-plugin.d.ts +0 -8
  295. package/dist/i18n/extractor-plugin.d.ts.map +0 -1
  296. package/dist/i18n/extractor-plugin.js +0 -247
  297. package/dist/i18n/extractor-plugin.js.map +0 -1
  298. package/dist/internal/data-dir.d.ts +0 -4
  299. package/dist/internal/data-dir.d.ts.map +0 -1
  300. package/dist/internal/data-dir.js +0 -52
  301. package/dist/internal/data-dir.js.map +0 -1
  302. package/dist/vite-plugins/animated.d.ts +0 -5
  303. package/dist/vite-plugins/animated.d.ts.map +0 -1
  304. package/dist/vite-plugins/animated.js +0 -325
  305. package/dist/vite-plugins/animated.js.map +0 -1
  306. package/src/i18n/binding-extractor.ts +0 -1969
  307. package/src/i18n/extractor-plugin.ts +0 -413
  308. package/src/internal/data-dir.ts +0 -70
  309. package/src/vite-plugins/animated.ts +0 -486
@@ -27,7 +27,6 @@ type StagedMetadata = {
27
27
  };
28
28
 
29
29
  const DIST_ICONS_DIR = "icons";
30
- const LEGACY_PACKAGES_MANIFEST_FILENAME = "gtkx-packages.json";
31
30
  const NOTICES_FILENAME = "THIRD-PARTY-NOTICES";
32
31
  const NODE_LICENSE_FILENAME = "LICENSE";
33
32
  const SHARE_APPLICATIONS = "share/applications";
@@ -50,10 +49,6 @@ const licenseDirFor = (settings: DeploySettings): string => `${SHARE_LICENSES}/$
50
49
  const licenseDestination = (settings: DeploySettings): string => `${licenseDirFor(settings)}/LICENSE`;
51
50
  const noticesDestination = (settings: DeploySettings): string => `${licenseDirFor(settings)}/${NOTICES_FILENAME}`;
52
51
  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
52
  const isLocaleAsset = (rel: string): boolean => rel === LOCALE_DIRNAME || rel.startsWith(`${LOCALE_DIRNAME}/`);
58
53
 
59
54
  const nodeLicenseDestination = (settings: DeploySettings): string =>
@@ -67,7 +62,8 @@ const stageRuntimeFiles = (settings: DeploySettings, root: string): StagedFile[]
67
62
  }
68
63
 
69
64
  return listFilesRecursive(dist)
70
- .filter((file) => !isIconAsset(file.rel) && !isBuildMetadata(file.rel) && !isLocaleAsset(file.rel))
65
+ .filter((file) =>
66
+ !isIconAsset(file.rel) && file.rel !== BUILD_MANIFEST_FILENAME && !isLocaleAsset(file.rel))
71
67
  .map((file) => copyInto(root, join(libDirFor(settings), file.rel), file.absPath));
72
68
  };
73
69
 
@@ -112,10 +108,10 @@ const stagePayload = ({ settings, node, metadata }: StageRequest): StagedFile[]
112
108
  ...stageNodeBinary(settings, root, node),
113
109
  ...stageRuntimeFiles(settings, root),
114
110
  ...stageCatalogs(settings, root),
111
+ ...stageExtraFiles(settings, root),
115
112
  ...stageMetadata(settings, root, metadata),
116
113
  ...stageIcons(settings, root),
117
114
  ...stageSchemas(settings, root),
118
- ...stageExtraFiles(settings, root),
119
115
  ]);
120
116
  };
121
117
 
@@ -1,4 +1,4 @@
1
- import { loadConfig } from "@gtkx/config";
1
+ import { type Config, loadConfig } from "@gtkx/config";
2
2
  import { info, warn } from "@gtkx/utils";
3
3
  import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join, relative } from "node:path";
@@ -22,6 +22,7 @@ import {
22
22
  synchronizeCatalogs,
23
23
  } from "../i18n/catalogs.js";
24
24
  import { extractSourceCatalogTo } from "../i18n/source-messages.js";
25
+ import { prepareBuildOutDir, resolveBuildOutDir } from "../internal/build-output.js";
25
26
  import { discoverSourceFiles } from "../internal/source-imports.js";
26
27
  import { renderDesktopEntry } from "./freedesktop/desktop-entry.js";
27
28
  import { extractMetadataMessages, localizeMetadata } from "./freedesktop/localize.js";
@@ -35,6 +36,7 @@ import { DEFAULT_TARGETS, parseTargetList, targetsFor } from "./registry.js";
35
36
  import { readBuildManifest } from "./settings/build-manifest.js";
36
37
  import { resolveDeploySettings } from "./settings/index.js";
37
38
  import { readPackageManifest } from "./settings/package-manifest.js";
39
+ import { prepareDeployOutDir } from "./settings/paths.js";
38
40
  import { missingDeployError } from "./settings/starter.js";
39
41
  import { finishArgsFor, hasDisplaySocket, runtimeLabelFor } from "./targets/flatpak-manifest.js";
40
42
  import { detectPackageManager } from "./targets/flatpak-sources.js";
@@ -58,6 +60,7 @@ import {
58
60
  type DeployOptions = {
59
61
  entry: string;
60
62
  cwd: string;
63
+ configFile?: string | undefined;
61
64
  targets?: string | undefined;
62
65
  outDir?: string | undefined;
63
66
  shouldPrintManifests: boolean;
@@ -72,6 +75,20 @@ type PreflightRequest = {
72
75
  shouldSkipBuild: boolean;
73
76
  };
74
77
 
78
+ type LoadedDeploySettings = {
79
+ config: Config;
80
+ configFile: string;
81
+ settings: DeploySettings;
82
+ };
83
+
84
+ type BuildPayloadRequest = {
85
+ options: DeployOptions;
86
+ loaded: LoadedDeploySettings;
87
+ targets: DeployTarget[];
88
+ project: CatalogProject | null;
89
+ buildOutDir: string | null;
90
+ };
91
+
75
92
  const BUILD_MODE = "production";
76
93
  const BYTES_PER_MIB = 1024 * 1024;
77
94
  const WEBKIT_LIBRARY = "WebKit-6.0";
@@ -282,14 +299,26 @@ const resolveTargetNames = (options: DeployOptions, settings: DeploySettings): s
282
299
  return settings.deploy.targets ?? DEFAULT_TARGETS;
283
300
  };
284
301
 
285
- const loadSettings = async (options: DeployOptions): Promise<DeploySettings> => {
286
- const { config, root } = await loadConfig(options.cwd, { mode: BUILD_MODE });
302
+ const loadSettings = async (options: DeployOptions): Promise<LoadedDeploySettings> => {
303
+ const { config, configFile, root } = await loadConfig(options.cwd, {
304
+ mode: BUILD_MODE,
305
+ configFile: options.configFile,
306
+ });
287
307
 
288
308
  if (config.deploy === undefined) {
289
309
  throw missingDeployError(config.applicationId, readPackageManifest(root));
290
310
  }
291
311
 
292
- return resolveDeploySettings({ root, config, outDirOverride: options.outDir });
312
+ return {
313
+ config,
314
+ configFile,
315
+ settings: resolveDeploySettings({
316
+ root,
317
+ config,
318
+ configFile,
319
+ outDirOverride: options.outDir,
320
+ }),
321
+ };
293
322
  };
294
323
 
295
324
  const synchronizeMetadataCatalogs = async (
@@ -318,22 +347,27 @@ const synchronizeMetadataCatalogs = async (
318
347
  }
319
348
  };
320
349
 
321
- const buildPayload = async (
322
- options: DeployOptions,
323
- settings: DeploySettings,
324
- targets: DeployTarget[],
325
- project: CatalogProject | null,
326
- ): Promise<DeployPayload> => {
350
+ const buildPayload = async ({
351
+ options,
352
+ loaded,
353
+ targets,
354
+ project,
355
+ buildOutDir,
356
+ }: BuildPayloadRequest): Promise<DeployPayload> => {
357
+ const settings = loaded.settings;
327
358
  const templates = renderMetadata(settings);
328
359
 
329
- if (!options.shouldSkipBuild) {
360
+ if (buildOutDir !== null) {
330
361
  info(`Building ${options.entry}`);
362
+ using preparedOutput = prepareBuildOutDir(settings.paths.root, buildOutDir);
331
363
 
332
364
  await buildApp({
333
365
  entry: options.entry,
334
- vite: { root: options.cwd },
366
+ configFile: options.configFile,
367
+ vite: { root: options.cwd, build: { outDir: preparedOutput.path, emptyOutDir: false } },
335
368
  });
336
369
 
370
+ preparedOutput.commit();
337
371
  await synchronizeMetadataCatalogs(settings, templates, project);
338
372
  } else if (project !== null) {
339
373
  compileCatalogs(project, join(settings.paths.dist, LOCALE_DIRNAME));
@@ -341,7 +375,7 @@ const buildPayload = async (
341
375
 
342
376
  const metadata = localizeMetadata(templates, project);
343
377
  validateMetadata(settings, metadata, isFlathubSubmission(settings, targets));
344
- const buildManifest = readBuildManifest(settings);
378
+ const buildManifest = readBuildManifest(settings, loaded);
345
379
 
346
380
  const builtSettings: DeploySettings = {
347
381
  ...settings,
@@ -411,9 +445,11 @@ const announce = (settings: DeploySettings, targets: DeployTarget[]): void => {
411
445
  };
412
446
 
413
447
  const runDeploy = async (options: DeployOptions): Promise<void> => {
414
- let settings = await loadSettings(options);
448
+ let loaded = await loadSettings(options);
449
+ let settings = loaded.settings;
415
450
  let project = resolveCatalogProject(settings.paths.root, settings.applicationId);
416
451
  let targets = targetsFor(resolveTargetNames(options, settings));
452
+ let buildOutDir = options.shouldSkipBuild ? null : resolveBuildOutDir(settings.paths.root, settings.paths.dist);
417
453
  announce(settings, targets);
418
454
 
419
455
  preflight({
@@ -428,14 +464,18 @@ const runDeploy = async (options: DeployOptions): Promise<void> => {
428
464
  await ensureGenerated(options.cwd, {
429
465
  shouldAnnounce: true,
430
466
  mode: BUILD_MODE,
467
+ configFile: options.configFile,
431
468
  });
432
469
 
433
- settings = await loadSettings(options);
470
+ loaded = await loadSettings(options);
471
+ settings = loaded.settings;
434
472
  project = resolveCatalogProject(settings.paths.root, settings.applicationId);
435
473
  targets = targetsFor(resolveTargetNames(options, settings));
474
+ buildOutDir = resolveBuildOutDir(settings.paths.root, settings.paths.dist);
436
475
  }
437
476
 
438
- const payload = await buildPayload(options, settings, targets, project);
477
+ prepareDeployOutDir(settings.paths.root, settings.paths.outDir);
478
+ const payload = await buildPayload({ options, loaded, targets, project, buildOutDir });
439
479
  const rendered = renderTargetManifests(targets, payload);
440
480
 
441
481
  if (options.shouldPrintManifests) {
@@ -1,12 +1,14 @@
1
- import { isRecord, sortStrings } from "@gtkx/utils";
1
+ import type { Config } from "@gtkx/config";
2
+ import { isPathInside, isRecord, sortStrings, toPosixPath } from "@gtkx/utils";
2
3
  import { existsSync, readFileSync, statSync } from "node:fs";
3
- import { isAbsolute, join, relative, resolve, sep } from "node:path";
4
+ import { isAbsolute, join, relative, resolve } from "node:path";
4
5
  import type { DeploySettings } from "../types.js";
5
6
  import {
6
7
  BUILD_MANIFEST_FILENAME,
7
8
  BUILD_MANIFEST_FORMAT_VERSION,
8
9
  BUILD_MANIFEST_GENERATOR,
9
10
  type BuildManifest,
11
+ configDigest,
10
12
  type RecordedPackage,
11
13
  } from "../../internal/build-manifest.js";
12
14
  import {
@@ -20,6 +22,11 @@ type ResolvedBuildManifest = {
20
22
  schemaFiles: string[];
21
23
  };
22
24
 
25
+ type ExpectedBuildConfig = {
26
+ config: Config;
27
+ configFile: string;
28
+ };
29
+
23
30
  const invalidManifest = (path: string): Error =>
24
31
  new Error(`Cannot deploy: ${path} is not a valid GTKX build manifest. Run \`gtkx build\` again.`);
25
32
 
@@ -51,6 +58,8 @@ const parseBuildManifest = (value: unknown, path: string): BuildManifest => {
51
58
  !isRecord(value) ||
52
59
  value.generator !== BUILD_MANIFEST_GENERATOR ||
53
60
  value.formatVersion !== BUILD_MANIFEST_FORMAT_VERSION ||
61
+ typeof value.configFile !== "string" ||
62
+ typeof value.configDigest !== "string" ||
54
63
  !Array.isArray(value.schemas) ||
55
64
  !Array.isArray(value.packages)
56
65
  ) {
@@ -62,24 +71,14 @@ const parseBuildManifest = (value: unknown, path: string): BuildManifest => {
62
71
  return {
63
72
  generator: BUILD_MANIFEST_GENERATOR,
64
73
  formatVersion: BUILD_MANIFEST_FORMAT_VERSION,
74
+ configFile: value.configFile,
75
+ configDigest: value.configDigest,
65
76
  schemas: recordedSchemas(value.schemas, path),
66
77
  packages: packages.map((entry) => recordedPackage(entry, path)),
67
78
  };
68
79
  };
69
80
 
70
- const isFile = (path: string): boolean => {
71
- try {
72
- return statSync(path, { throwIfNoEntry: false })?.isFile() === true;
73
- } catch {
74
- return false;
75
- }
76
- };
77
-
78
- const isInsideProject = (root: string, filePath: string): boolean => {
79
- const rel = relative(root, filePath);
80
-
81
- return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
82
- };
81
+ const isFile = (path: string): boolean => statSync(path, { throwIfNoEntry: false })?.isFile() === true;
83
82
 
84
83
  const resolveRecordedSchema = (root: string, manifestPath: string, entry: string): string => {
85
84
  if (isAbsolute(entry) || !entry.endsWith(SCHEMA_SUFFIX)) {
@@ -88,7 +87,7 @@ const resolveRecordedSchema = (root: string, manifestPath: string, entry: string
88
87
 
89
88
  const filePath = resolve(root, entry);
90
89
 
91
- if (!isInsideProject(root, filePath)) {
90
+ if (!isPathInside(root, filePath)) {
92
91
  throw new Error(`Cannot deploy: ${manifestPath} records a GSettings schema outside the project.`);
93
92
  }
94
93
 
@@ -103,7 +102,20 @@ const resolveRecordedSchema = (root: string, manifestPath: string, entry: string
103
102
  return filePath;
104
103
  };
105
104
 
106
- const readBuildManifest = (settings: DeploySettings): ResolvedBuildManifest => {
105
+ const assertBuildConfig = (
106
+ settings: DeploySettings,
107
+ manifestPath: string,
108
+ manifest: BuildManifest,
109
+ expected: ExpectedBuildConfig,
110
+ ): void => {
111
+ const expectedFile = toPosixPath(relative(settings.paths.root, expected.configFile));
112
+
113
+ if (manifest.configFile !== expectedFile || manifest.configDigest !== configDigest(expected.config)) {
114
+ throw new Error(`Cannot deploy: ${manifestPath} was built from a different GTKX configuration.`);
115
+ }
116
+ };
117
+
118
+ const readBuildManifest = (settings: DeploySettings, expected: ExpectedBuildConfig): ResolvedBuildManifest => {
107
119
  const manifestPath = join(settings.paths.dist, BUILD_MANIFEST_FILENAME);
108
120
 
109
121
  if (!existsSync(manifestPath)) {
@@ -112,6 +124,7 @@ const readBuildManifest = (settings: DeploySettings): ResolvedBuildManifest => {
112
124
 
113
125
  const parsed: unknown = JSON.parse(readFileSync(manifestPath, "utf8"));
114
126
  const manifest = parseBuildManifest(parsed, manifestPath);
127
+ assertBuildConfig(settings, manifestPath, manifest, expected);
115
128
  const files = manifest.schemas.map((entry) => resolveRecordedSchema(settings.paths.root, manifestPath, entry));
116
129
  const unique = sortStrings(new Set(files));
117
130
  assertUniqueSchemaBasenames(unique);
@@ -1,3 +1,5 @@
1
+ import { statSync } from "node:fs";
2
+ import { resolve } from "node:path";
1
3
  import type { DeployConfig, DeployExtraFile } from "../types.js";
2
4
 
3
5
  type ExtraFiles = NonNullable<DeployConfig["extraFiles"]>;
@@ -5,6 +7,20 @@ type ExtraFileEntry = NonNullable<ExtraFiles[string]>;
5
7
 
6
8
  const OCTAL_RADIX = 8;
7
9
 
10
+ const assertSourceFile = (root: string, file: DeployExtraFile): void => {
11
+ const source = resolve(root, file.source);
12
+
13
+ try {
14
+ if (statSync(source).isFile()) {
15
+ return;
16
+ }
17
+ } catch {
18
+ throw new Error(`Cannot install "${file.destination}": its source file "${file.source}" does not exist`);
19
+ }
20
+
21
+ throw new Error(`Cannot install "${file.destination}": its source "${file.source}" is not a file`);
22
+ };
23
+
8
24
  const resolveExtraFile = (destination: string, entry: ExtraFileEntry): DeployExtraFile => {
9
25
  if (typeof entry === "string") {
10
26
  return { destination, source: entry, mode: null };
@@ -15,7 +31,15 @@ const resolveExtraFile = (destination: string, entry: ExtraFileEntry): DeployExt
15
31
  return { destination, source: entry.source, mode };
16
32
  };
17
33
 
18
- const resolveExtraFiles = (deploy: DeployConfig): DeployExtraFile[] =>
19
- Object.entries(deploy.extraFiles ?? {}).map(([destination, entry]) => resolveExtraFile(destination, entry));
34
+ const resolveExtraFiles = (root: string, deploy: DeployConfig): DeployExtraFile[] => {
35
+ const files = Object.entries(deploy.extraFiles ?? {})
36
+ .map(([destination, entry]) => resolveExtraFile(destination, entry));
37
+
38
+ for (const file of files) {
39
+ assertSourceFile(root, file);
40
+ }
41
+
42
+ return files;
43
+ };
20
44
 
21
45
  export { resolveExtraFiles };
@@ -31,6 +31,7 @@ import { resolveVersions } from "./version.js";
31
31
  type SettingsRequest = {
32
32
  root: string;
33
33
  config: Config;
34
+ configFile: string;
34
35
  outDirOverride?: string | undefined;
35
36
  now?: Date | undefined;
36
37
  };
@@ -174,10 +175,11 @@ const resolveDeploySettings = (request: SettingsRequest): DeploySettings => {
174
175
  const deploy = core.identity.deploy;
175
176
 
176
177
  return {
178
+ configFile: request.configFile,
177
179
  ...identitySlice(core),
178
180
  ...metadataSlice(request.root, core),
179
181
  ...desktopSlice(deploy),
180
- extraFiles: resolveExtraFiles(deploy),
182
+ extraFiles: resolveExtraFiles(request.root, deploy),
181
183
  versions: core.versions,
182
184
  arch: resolveArch(),
183
185
  paths: resolvePaths({
@@ -3,10 +3,8 @@ import {
3
3
  resolveLibraries as expandLibraries,
4
4
  type GeneratedLibraries,
5
5
  readGeneratedLibraries,
6
- resolveGirPath,
7
6
  resolveStore,
8
7
  } from "@gtkx/codegen";
9
- import { resolveFuture } from "@gtkx/config/internal";
10
8
 
11
9
  type ResolvedLibraries = {
12
10
  libraries: string[];
@@ -21,28 +19,9 @@ const generatedLibraries = (root: string): GeneratedLibraries | null => {
21
19
  }
22
20
  };
23
21
 
24
- const discoveredLibraries = (config: Config, isAdwaitaDefault: boolean): string[] | null => {
25
- try {
26
- return expandLibraries(config.libraries, resolveGirPath(config.girPath), isAdwaitaDefault);
27
- } catch {
28
- return null;
29
- }
30
- };
31
-
32
- const configLibraries = (config: Config): string[] => {
33
- const { isAdwaitaDefault } = resolveFuture(config.future);
34
- const libraries = config.libraries;
35
-
36
- if (Array.isArray(libraries)) {
37
- return expandLibraries(libraries, [], isAdwaitaDefault);
38
- }
39
-
40
- return discoveredLibraries(config, isAdwaitaDefault) ?? expandLibraries(undefined, [], isAdwaitaDefault);
41
- };
42
-
43
22
  const resolveLibraries = (root: string, config: Config): ResolvedLibraries => {
44
23
  const generated = generatedLibraries(root);
45
- const libraries = generated?.libraries ?? configLibraries(config);
24
+ const libraries = generated?.libraries ?? expandLibraries(config.libraries);
46
25
  const deploy = config.deploy ?? {};
47
26
 
48
27
  return {
@@ -1,8 +1,10 @@
1
1
  import type { Config } from "@gtkx/config";
2
- import { statSync } from "node:fs";
3
- import { isAbsolute, join, relative, resolve } from "node:path";
2
+ import { isPathInside } from "@gtkx/utils";
3
+ import { lstatSync, readdirSync, statSync, writeFileSync } from "node:fs";
4
+ import { join, relative, resolve, sep } from "node:path";
4
5
  import type { DeployConfig, DeployPaths } from "../types.js";
5
6
  import { resolveApplicationIcon } from "../../internal/icon-path.js";
7
+ import { prepareOutputDirectory, readRegularFile } from "../../internal/output-directory.js";
6
8
 
7
9
  type PathsRequest = {
8
10
  root: string;
@@ -14,33 +16,86 @@ type PathsRequest = {
14
16
 
15
17
  const DEFAULT_OUT_DIR = "build";
16
18
  const DIST_DIR = "dist";
19
+ const DEPLOY_MARKER_FILENAME = ".gtkx-deploy.json";
20
+ const DEPLOY_MARKER = `${JSON.stringify({ generator: "gtkx-deploy", formatVersion: 1 })}\n`;
17
21
  const LICENSE_CANDIDATES = ["LICENSE", "LICENSE.md", "LICENSE.txt", "COPYING", "COPYING.md"];
18
22
 
19
- const isInside = (parent: string, candidate: string): boolean => {
20
- const rel = relative(parent, candidate);
23
+ const hasSymlinkComponent = (root: string, target: string): boolean => {
24
+ let current = root;
21
25
 
22
- return rel.length > 0 && !rel.startsWith("..") && !isAbsolute(rel);
26
+ for (const segment of relative(root, target).split(sep)) {
27
+ current = join(current, segment);
28
+
29
+ if (lstatSync(current, { throwIfNoEntry: false })?.isSymbolicLink() === true) {
30
+ return true;
31
+ }
32
+ }
33
+
34
+ return false;
35
+ };
36
+
37
+ const isDeployMarker = (path: string): boolean => {
38
+ return readRegularFile(path) === DEPLOY_MARKER;
39
+ };
40
+
41
+ const isReusableDeployDirectory = (path: string): boolean => {
42
+ const entry = lstatSync(path, { throwIfNoEntry: false });
43
+
44
+ if (entry === undefined) {
45
+ return true;
46
+ }
47
+
48
+ return entry.isDirectory() &&
49
+ (readdirSync(path).length === 0 || isDeployMarker(join(path, DEPLOY_MARKER_FILENAME)));
50
+ };
51
+
52
+ const deployOutputError = (root: string, configured: string): Error =>
53
+ new Error(
54
+ `Cannot use "${configured}" as the deploy output directory: choose an empty directory or an ` +
55
+ `earlier GTKX deploy directory below ${root}`,
56
+ );
57
+
58
+ const assertSafeDeployOutDir = (root: string, outDir: string, configured: string): void => {
59
+ const dist = join(root, DIST_DIR);
60
+
61
+ if (
62
+ outDir === dist ||
63
+ !isPathInside(root, outDir) ||
64
+ isPathInside(dist, outDir) ||
65
+ hasSymlinkComponent(root, outDir)
66
+ ) {
67
+ throw deployOutputError(root, configured);
68
+ }
23
69
  };
24
70
 
25
71
  const resolveOutDir = ({ root, deploy, outDirOverride }: PathsRequest): string => {
26
72
  const configured = outDirOverride ?? deploy.outDir ?? DEFAULT_OUT_DIR;
27
73
  const outDir = resolve(root, configured);
74
+ assertSafeDeployOutDir(root, outDir, configured);
28
75
 
29
- if (!isInside(root, outDir)) {
30
- throw new Error(`Cannot use "${configured}" as the deploy output directory: it is outside ${root}`);
76
+ if (!isReusableDeployDirectory(outDir)) {
77
+ throw deployOutputError(root, configured);
31
78
  }
32
79
 
33
80
  return outDir;
34
81
  };
35
82
 
36
- const existingFile = (path: string): string | null => {
37
- try {
38
- return statSync(path, { throwIfNoEntry: false })?.isFile() === true ? path : null;
39
- } catch {
40
- return null;
83
+ const prepareDeployOutDir = (root: string, outDir: string): void => {
84
+ assertSafeDeployOutDir(root, outDir, outDir);
85
+ const prepared = prepareOutputDirectory(root, outDir, isReusableDeployDirectory);
86
+
87
+ if (prepared.status === "unsafe") {
88
+ throw deployOutputError(root, outDir);
41
89
  }
90
+
91
+ using transaction = prepared.transaction;
92
+ transaction.commit();
93
+ writeFileSync(join(outDir, DEPLOY_MARKER_FILENAME), DEPLOY_MARKER, { flag: "wx" });
42
94
  };
43
95
 
96
+ const existingFile = (path: string): string | null =>
97
+ statSync(path, { throwIfNoEntry: false })?.isFile() === true ? path : null;
98
+
44
99
  const resolveLicenseFile = (root: string, configured: string | undefined): string | null => {
45
100
  if (configured !== undefined) {
46
101
  const path = resolve(root, configured);
@@ -75,4 +130,4 @@ const resolvePaths = (request: PathsRequest): DeployPaths => {
75
130
  };
76
131
  };
77
132
 
78
- export { isInside, resolvePaths };
133
+ export { prepareDeployOutDir, resolvePaths };
@@ -1,3 +1,4 @@
1
+ import hostedGitInfo from "hosted-git-info";
1
2
  import type { DeployConfig, DeployScreenshot } from "../types.js";
2
3
  import { gitRemoteUrl, runGit } from "../git.js";
3
4
 
@@ -6,23 +7,9 @@ type ScreenshotRequest = {
6
7
  deploy: DeployConfig;
7
8
  };
8
9
 
9
- type RemoteParts = {
10
- host: string;
11
- owner: string;
12
- repo: string;
13
- };
14
-
15
10
  const DEFAULT_BRANCH = "main";
16
- const GIT_SUFFIX = ".git";
17
- const PORTED_HOST = /^([^/]*):\d+(?=\/|$)/;
18
- const SCHEME_SEPARATOR = "://";
19
11
  const TRAILING_SLASH = "/";
20
12
 
21
- const RAW_BASE_BY_HOST: Record<string, (owner: string, repo: string, branch: string) => string> = {
22
- "github.com": (owner, repo, branch) => `https://raw.githubusercontent.com/${owner}/${repo}/${branch}`,
23
- "gitlab.com": (owner, repo, branch) => `https://gitlab.com/${owner}/${repo}/-/raw/${branch}`,
24
- };
25
-
26
13
  const readRepositoryPrefix = (root: string): string =>
27
14
  trimTrailingSlash(runGit(root, ["rev-parse", "--show-prefix"]) ?? "");
28
15
 
@@ -35,29 +22,6 @@ const trimLeadingSlash = (value: string): string => {
35
22
  return withoutDot.startsWith(TRAILING_SLASH) ? withoutDot.slice(1) : withoutDot;
36
23
  };
37
24
 
38
- const afterMarker = (value: string, marker: string): string => {
39
- const index = value.indexOf(marker);
40
-
41
- return index === -1 ? value : value.slice(index + marker.length);
42
- };
43
-
44
- const normalizeLocation = (trimmed: string): string => {
45
- const location = afterMarker(afterMarker(trimmed, SCHEME_SEPARATOR), "@");
46
-
47
- return trimmed.includes(SCHEME_SEPARATOR) ? location.replace(PORTED_HOST, "$1") : location.replace(":", "/");
48
- };
49
-
50
- const parseRemote = (remote: string): RemoteParts | null => {
51
- const trimmed = remote.endsWith(GIT_SUFFIX) ? remote.slice(0, -GIT_SUFFIX.length) : remote;
52
- const [host, owner, repo, ...extra] = normalizeLocation(trimmed).split("/");
53
-
54
- if (repo === undefined || extra.length > 0) {
55
- return null;
56
- }
57
-
58
- return { host: host ?? "", owner: owner ?? "", repo };
59
- };
60
-
61
25
  const readDefaultBranch = (root: string): string => {
62
26
  const head = runGit(root, ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"]);
63
27
 
@@ -70,16 +34,16 @@ const readDefaultBranch = (root: string): string => {
70
34
  return separator === -1 ? head : head.slice(separator + 1);
71
35
  };
72
36
 
73
- const baseForRemote = (remote: string, branch: string): string | null => {
74
- const parts = parseRemote(remote);
37
+ const baseForRemote = (root: string, remote: string): string | null => {
38
+ const repository = hostedGitInfo.fromUrl(remote);
75
39
 
76
- if (parts === null) {
40
+ if (repository === undefined || (repository.type !== "github" && repository.type !== "gitlab")) {
77
41
  return null;
78
42
  }
79
43
 
80
- const build = RAW_BASE_BY_HOST[parts.host];
81
-
82
- return build === undefined ? null : build(parts.owner, parts.repo, branch);
44
+ return trimTrailingSlash(
45
+ repository.file(readRepositoryPrefix(root), { committish: readDefaultBranch(root) }),
46
+ );
83
47
  };
84
48
 
85
49
  const resolveScreenshotBaseUrl = ({ root, deploy }: ScreenshotRequest): string | null => {
@@ -88,10 +52,8 @@ const resolveScreenshotBaseUrl = ({ root, deploy }: ScreenshotRequest): string |
88
52
  }
89
53
 
90
54
  const remote = gitRemoteUrl(root);
91
- const base = remote === null ? null : baseForRemote(remote, readDefaultBranch(root));
92
- const prefix = base === null ? "" : readRepositoryPrefix(root);
93
55
 
94
- return base === null || prefix.length === 0 ? base : `${base}/${prefix}`;
56
+ return remote === null ? null : baseForRemote(root, remote);
95
57
  };
96
58
 
97
59
  const urlForScreenshot = (file: string, baseUrl: string | null): string => {
@@ -9,12 +9,12 @@ type PnpmPin = {
9
9
  sha512: string;
10
10
  };
11
11
 
12
- const PNPM_VERSION = "11.22.0";
12
+ const PNPM_VERSION = "11.25.0";
13
13
  const PNPM_MAJOR = 11;
14
- const PNPM_MINOR = 22;
14
+ const PNPM_MINOR = 25;
15
15
 
16
- const PNPM_SHA512 = "1ff870c4c6133dfd88fb2afc46dd13d47f09c9794b438c6fdb47ca98caf3bc16381ee0be9" +
17
- "3a091b8e3824cf01f889f46d7d9e20910fb0be1ab0fb5baa80dd621";
16
+ const PNPM_SHA512 = "5cde925b4f075f725eb71fbae18a42ffe784524789f19b61c731cb8721ec28aaee160e01a" +
17
+ "8d5af4fedb2a42cdbf300efe23db356b0d4a17b4d63e11f8ab7c956";
18
18
 
19
19
  const PNPM_DIR = "flatpak-pnpm";
20
20
  const PNPM_COMMAND = "pnpm";