@gtkx/cli 1.5.0 → 2.0.0-beta.1

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 (211) hide show
  1. package/README.md +5 -5
  2. package/dist/cli.js +4 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/codegen/freshness.d.ts.map +1 -1
  5. package/dist/codegen/freshness.js +45 -15
  6. package/dist/codegen/freshness.js.map +1 -1
  7. package/dist/codegen/reference.d.ts +17 -0
  8. package/dist/codegen/reference.d.ts.map +1 -0
  9. package/dist/codegen/reference.js +31 -0
  10. package/dist/codegen/reference.js.map +1 -0
  11. package/dist/codegen/report.d.ts.map +1 -1
  12. package/dist/codegen/report.js +18 -15
  13. package/dist/codegen/report.js.map +1 -1
  14. package/dist/codegen/run-codegen.d.ts +5 -5
  15. package/dist/codegen/run-codegen.d.ts.map +1 -1
  16. package/dist/codegen/run-codegen.js +24 -59
  17. package/dist/codegen/run-codegen.js.map +1 -1
  18. package/dist/codegen/store-resolver.d.ts +0 -1
  19. package/dist/codegen/store-resolver.d.ts.map +1 -1
  20. package/dist/codegen/store-resolver.js +8 -17
  21. package/dist/codegen/store-resolver.js.map +1 -1
  22. package/dist/commands/docs.d.ts.map +1 -1
  23. package/dist/commands/docs.js +6 -22
  24. package/dist/commands/docs.js.map +1 -1
  25. package/dist/commands/mcp.d.ts +13 -0
  26. package/dist/commands/mcp.d.ts.map +1 -0
  27. package/dist/commands/mcp.js +68 -0
  28. package/dist/commands/mcp.js.map +1 -0
  29. package/dist/deploy/freedesktop/copyright.d.ts.map +1 -1
  30. package/dist/deploy/freedesktop/copyright.js +2 -13
  31. package/dist/deploy/freedesktop/copyright.js.map +1 -1
  32. package/dist/deploy/freedesktop/xml.d.ts.map +1 -1
  33. package/dist/deploy/freedesktop/xml.js +21 -25
  34. package/dist/deploy/freedesktop/xml.js.map +1 -1
  35. package/dist/deploy/node-runtime/license.d.ts.map +1 -1
  36. package/dist/deploy/node-runtime/license.js +2 -9
  37. package/dist/deploy/node-runtime/license.js.map +1 -1
  38. package/dist/deploy/notices/gtkx.js +1 -1
  39. package/dist/deploy/notices/gtkx.js.map +1 -1
  40. package/dist/deploy/notices/libraries.d.ts.map +1 -1
  41. package/dist/deploy/notices/libraries.js +2 -1
  42. package/dist/deploy/notices/libraries.js.map +1 -1
  43. package/dist/deploy/notices/packages.d.ts.map +1 -1
  44. package/dist/deploy/notices/packages.js +3 -10
  45. package/dist/deploy/notices/packages.js.map +1 -1
  46. package/dist/deploy/payload/copy-tree.d.ts.map +1 -1
  47. package/dist/deploy/payload/copy-tree.js +3 -3
  48. package/dist/deploy/payload/copy-tree.js.map +1 -1
  49. package/dist/deploy/payload/stage.d.ts.map +1 -1
  50. package/dist/deploy/payload/stage.js +1 -3
  51. package/dist/deploy/payload/stage.js.map +1 -1
  52. package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
  53. package/dist/deploy/settings/build-manifest.js +4 -15
  54. package/dist/deploy/settings/build-manifest.js.map +1 -1
  55. package/dist/deploy/settings/libraries.d.ts.map +1 -1
  56. package/dist/deploy/settings/libraries.js +2 -21
  57. package/dist/deploy/settings/libraries.js.map +1 -1
  58. package/dist/deploy/settings/paths.d.ts +1 -2
  59. package/dist/deploy/settings/paths.d.ts.map +1 -1
  60. package/dist/deploy/settings/paths.js +5 -15
  61. package/dist/deploy/settings/paths.js.map +1 -1
  62. package/dist/deploy/settings/screenshots.d.ts.map +1 -1
  63. package/dist/deploy/settings/screenshots.js +6 -31
  64. package/dist/deploy/settings/screenshots.js.map +1 -1
  65. package/dist/deploy/targets/flatpak-pnpm.js +4 -4
  66. package/dist/deploy/targets/flatpak-pnpm.js.map +1 -1
  67. package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
  68. package/dist/deploy/targets/flatpak-source.js +4 -4
  69. package/dist/deploy/targets/flatpak-source.js.map +1 -1
  70. package/dist/deploy/targets/flatpak-sources.js +1 -1
  71. package/dist/deploy/targets/flatpak-sources.js.map +1 -1
  72. package/dist/deploy/tools.d.ts.map +1 -1
  73. package/dist/deploy/tools.js +1 -3
  74. package/dist/deploy/tools.js.map +1 -1
  75. package/dist/dev/runner-main.js +1 -1
  76. package/dist/dev/runner-main.js.map +1 -1
  77. package/dist/dev/schema-dir.d.ts +1 -1
  78. package/dist/dev/schema-dir.d.ts.map +1 -1
  79. package/dist/dev/schema-dir.js +2 -4
  80. package/dist/dev/schema-dir.js.map +1 -1
  81. package/dist/i18n/catalogs.d.ts.map +1 -1
  82. package/dist/i18n/catalogs.js +2 -1
  83. package/dist/i18n/catalogs.js.map +1 -1
  84. package/dist/i18n/metadata-templates.d.ts.map +1 -1
  85. package/dist/i18n/metadata-templates.js +2 -1
  86. package/dist/i18n/metadata-templates.js.map +1 -1
  87. package/dist/i18n/source-messages.d.ts +3 -21
  88. package/dist/i18n/source-messages.d.ts.map +1 -1
  89. package/dist/i18n/source-messages.js +66 -85
  90. package/dist/i18n/source-messages.js.map +1 -1
  91. package/dist/i18n/types.d.ts +6 -7
  92. package/dist/i18n/types.d.ts.map +1 -1
  93. package/dist/i18n/types.js +83 -96
  94. package/dist/i18n/types.js.map +1 -1
  95. package/dist/internal/agent-rules.d.ts +7 -0
  96. package/dist/internal/agent-rules.d.ts.map +1 -0
  97. package/dist/internal/agent-rules.js +106 -0
  98. package/dist/internal/agent-rules.js.map +1 -0
  99. package/dist/internal/docs-elements.d.ts +8 -0
  100. package/dist/internal/docs-elements.d.ts.map +1 -0
  101. package/dist/internal/docs-elements.js +12 -0
  102. package/dist/internal/docs-elements.js.map +1 -0
  103. package/dist/internal/icon-path.d.ts.map +1 -1
  104. package/dist/internal/icon-path.js +5 -16
  105. package/dist/internal/icon-path.js.map +1 -1
  106. package/dist/internal/source-imports.d.ts.map +1 -1
  107. package/dist/internal/source-imports.js +10 -42
  108. package/dist/internal/source-imports.js.map +1 -1
  109. package/dist/mcp/client-config.d.ts +22 -0
  110. package/dist/mcp/client-config.d.ts.map +1 -0
  111. package/dist/mcp/client-config.js +94 -0
  112. package/dist/mcp/client-config.js.map +1 -0
  113. package/dist/settings/render.d.ts +0 -1
  114. package/dist/settings/render.d.ts.map +1 -1
  115. package/dist/settings/render.js +1 -11
  116. package/dist/settings/render.js.map +1 -1
  117. package/dist/settings/schema.d.ts +2 -2
  118. package/dist/settings/schema.d.ts.map +1 -1
  119. package/dist/settings/schema.js +21 -62
  120. package/dist/settings/schema.js.map +1 -1
  121. package/dist/vite-plugins/asset-imports.d.ts +1 -2
  122. package/dist/vite-plugins/asset-imports.d.ts.map +1 -1
  123. package/dist/vite-plugins/asset-imports.js +19 -32
  124. package/dist/vite-plugins/asset-imports.js.map +1 -1
  125. package/dist/vite-plugins/asset-specifier.d.ts +1 -3
  126. package/dist/vite-plugins/asset-specifier.d.ts.map +1 -1
  127. package/dist/vite-plugins/asset-specifier.js +1 -4
  128. package/dist/vite-plugins/asset-specifier.js.map +1 -1
  129. package/dist/vite-plugins/i18n.d.ts.map +1 -1
  130. package/dist/vite-plugins/i18n.js +2 -1
  131. package/dist/vite-plugins/i18n.js.map +1 -1
  132. package/dist/vite-plugins/index.js +2 -2
  133. package/dist/vite-plugins/index.js.map +1 -1
  134. package/dist/vite-plugins/resources.d.ts.map +1 -1
  135. package/dist/vite-plugins/resources.js +31 -96
  136. package/dist/vite-plugins/resources.js.map +1 -1
  137. package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
  138. package/dist/vite-plugins/settings-worker-env.js +1 -3
  139. package/dist/vite-plugins/settings-worker-env.js.map +1 -1
  140. package/dist/vite-plugins/settings.d.ts +1 -2
  141. package/dist/vite-plugins/settings.d.ts.map +1 -1
  142. package/dist/vite-plugins/settings.js +8 -13
  143. package/dist/vite-plugins/settings.js.map +1 -1
  144. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
  145. package/dist/vite-plugins/undeclared-library.js +10 -13
  146. package/dist/vite-plugins/undeclared-library.js.map +1 -1
  147. package/dist/vite-plugins/worker.d.ts.map +1 -1
  148. package/dist/vite-plugins/worker.js +0 -1
  149. package/dist/vite-plugins/worker.js.map +1 -1
  150. package/package.json +21 -14
  151. package/src/cli.ts +5 -0
  152. package/src/codegen/freshness.ts +66 -16
  153. package/src/codegen/reference.ts +52 -0
  154. package/src/codegen/report.ts +16 -17
  155. package/src/codegen/run-codegen.ts +31 -91
  156. package/src/codegen/store-resolver.ts +8 -24
  157. package/src/commands/docs.ts +6 -36
  158. package/src/commands/mcp.ts +81 -0
  159. package/src/deploy/freedesktop/copyright.ts +2 -14
  160. package/src/deploy/freedesktop/xml.ts +24 -32
  161. package/src/deploy/node-runtime/license.ts +2 -8
  162. package/src/deploy/notices/gtkx.ts +1 -1
  163. package/src/deploy/notices/libraries.ts +2 -1
  164. package/src/deploy/notices/packages.ts +3 -11
  165. package/src/deploy/payload/copy-tree.ts +3 -4
  166. package/src/deploy/payload/stage.ts +2 -6
  167. package/src/deploy/settings/build-manifest.ts +4 -16
  168. package/src/deploy/settings/libraries.ts +1 -25
  169. package/src/deploy/settings/paths.ts +6 -16
  170. package/src/deploy/settings/screenshots.ts +8 -46
  171. package/src/deploy/targets/flatpak-pnpm.ts +4 -4
  172. package/src/deploy/targets/flatpak-source.ts +4 -4
  173. package/src/deploy/targets/flatpak-sources.ts +1 -1
  174. package/src/deploy/tools.ts +1 -3
  175. package/src/dev/runner-main.ts +1 -1
  176. package/src/dev/schema-dir.ts +2 -4
  177. package/src/i18n/catalogs.ts +2 -1
  178. package/src/i18n/metadata-templates.ts +2 -1
  179. package/src/i18n/source-messages.ts +77 -115
  180. package/src/i18n/types.ts +97 -131
  181. package/src/internal/agent-rules.ts +135 -0
  182. package/src/internal/docs-elements.ts +21 -0
  183. package/src/internal/icon-path.ts +6 -19
  184. package/src/internal/source-imports.ts +14 -50
  185. package/src/mcp/client-config.ts +130 -0
  186. package/src/settings/render.ts +1 -13
  187. package/src/settings/schema.ts +19 -81
  188. package/src/vite-plugins/asset-imports.ts +20 -44
  189. package/src/vite-plugins/asset-specifier.ts +0 -5
  190. package/src/vite-plugins/i18n.ts +2 -1
  191. package/src/vite-plugins/index.ts +2 -2
  192. package/src/vite-plugins/resources.ts +36 -139
  193. package/src/vite-plugins/settings-worker-env.ts +1 -3
  194. package/src/vite-plugins/settings.ts +11 -19
  195. package/src/vite-plugins/undeclared-library.ts +14 -20
  196. package/src/vite-plugins/worker.ts +0 -1
  197. package/dist/i18n/binding-extractor.d.ts +0 -30
  198. package/dist/i18n/binding-extractor.d.ts.map +0 -1
  199. package/dist/i18n/binding-extractor.js +0 -1324
  200. package/dist/i18n/binding-extractor.js.map +0 -1
  201. package/dist/i18n/extractor-plugin.d.ts +0 -8
  202. package/dist/i18n/extractor-plugin.d.ts.map +0 -1
  203. package/dist/i18n/extractor-plugin.js +0 -247
  204. package/dist/i18n/extractor-plugin.js.map +0 -1
  205. package/dist/internal/data-dir.d.ts +0 -4
  206. package/dist/internal/data-dir.d.ts.map +0 -1
  207. package/dist/internal/data-dir.js +0 -52
  208. package/dist/internal/data-dir.js.map +0 -1
  209. package/src/i18n/binding-extractor.ts +0 -1969
  210. package/src/i18n/extractor-plugin.ts +0 -413
  211. package/src/internal/data-dir.ts +0 -70
@@ -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
  };
@@ -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
 
@@ -1,6 +1,6 @@
1
- import { isRecord, sortStrings } from "@gtkx/utils";
1
+ import { isPathInside, isRecord, sortStrings } from "@gtkx/utils";
2
2
  import { existsSync, readFileSync, statSync } from "node:fs";
3
- import { isAbsolute, join, relative, resolve, sep } from "node:path";
3
+ import { isAbsolute, join, resolve } from "node:path";
4
4
  import type { DeploySettings } from "../types.js";
5
5
  import {
6
6
  BUILD_MANIFEST_FILENAME,
@@ -67,19 +67,7 @@ const parseBuildManifest = (value: unknown, path: string): BuildManifest => {
67
67
  };
68
68
  };
69
69
 
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
- };
70
+ const isFile = (path: string): boolean => statSync(path, { throwIfNoEntry: false })?.isFile() === true;
83
71
 
84
72
  const resolveRecordedSchema = (root: string, manifestPath: string, entry: string): string => {
85
73
  if (isAbsolute(entry) || !entry.endsWith(SCHEMA_SUFFIX)) {
@@ -88,7 +76,7 @@ const resolveRecordedSchema = (root: string, manifestPath: string, entry: string
88
76
 
89
77
  const filePath = resolve(root, entry);
90
78
 
91
- if (!isInsideProject(root, filePath)) {
79
+ if (!isPathInside(root, filePath)) {
92
80
  throw new Error(`Cannot deploy: ${manifestPath} records a GSettings schema outside the project.`);
93
81
  }
94
82
 
@@ -3,7 +3,6 @@ import {
3
3
  resolveLibraries as expandLibraries,
4
4
  type GeneratedLibraries,
5
5
  readGeneratedLibraries,
6
- resolveGirPath,
7
6
  resolveStore,
8
7
  } from "@gtkx/codegen";
9
8
 
@@ -12,9 +11,6 @@ type ResolvedLibraries = {
12
11
  minimumLibraryVersions: Record<string, string>;
13
12
  };
14
13
 
15
- const DEFAULT_LIBRARY = "Gtk-4.0";
16
- const DEFAULT_LIBRARY_PREFIX = "Gtk-";
17
-
18
14
  const generatedLibraries = (root: string): GeneratedLibraries | null => {
19
15
  try {
20
16
  return readGeneratedLibraries(resolveStore(root).gi.storeDir);
@@ -23,29 +19,9 @@ const generatedLibraries = (root: string): GeneratedLibraries | null => {
23
19
  }
24
20
  };
25
21
 
26
- const discoveredLibraries = (config: Config): string[] | null => {
27
- try {
28
- return expandLibraries(config.libraries, resolveGirPath(config.girPath));
29
- } catch {
30
- return null;
31
- }
32
- };
33
-
34
- const configLibraries = (config: Config): string[] => {
35
- const libraries = config.libraries;
36
-
37
- if (!Array.isArray(libraries)) {
38
- return discoveredLibraries(config) ?? [DEFAULT_LIBRARY];
39
- }
40
-
41
- return libraries.some((library) => library.startsWith(DEFAULT_LIBRARY_PREFIX))
42
- ? [...libraries]
43
- : [DEFAULT_LIBRARY, ...libraries];
44
- };
45
-
46
22
  const resolveLibraries = (root: string, config: Config): ResolvedLibraries => {
47
23
  const generated = generatedLibraries(root);
48
- const libraries = generated?.libraries ?? configLibraries(config);
24
+ const libraries = generated?.libraries ?? expandLibraries(config.libraries);
49
25
  const deploy = config.deploy ?? {};
50
26
 
51
27
  return {
@@ -1,6 +1,7 @@
1
1
  import type { Config } from "@gtkx/config";
2
+ import { isPathInside } from "@gtkx/utils";
2
3
  import { statSync } from "node:fs";
3
- import { isAbsolute, join, relative, resolve } from "node:path";
4
+ import { join, resolve } from "node:path";
4
5
  import type { DeployConfig, DeployPaths } from "../types.js";
5
6
  import { resolveApplicationIcon } from "../../internal/icon-path.js";
6
7
 
@@ -16,30 +17,19 @@ const DEFAULT_OUT_DIR = "build";
16
17
  const DIST_DIR = "dist";
17
18
  const LICENSE_CANDIDATES = ["LICENSE", "LICENSE.md", "LICENSE.txt", "COPYING", "COPYING.md"];
18
19
 
19
- const isInside = (parent: string, candidate: string): boolean => {
20
- const rel = relative(parent, candidate);
21
-
22
- return rel.length > 0 && !rel.startsWith("..") && !isAbsolute(rel);
23
- };
24
-
25
20
  const resolveOutDir = ({ root, deploy, outDirOverride }: PathsRequest): string => {
26
21
  const configured = outDirOverride ?? deploy.outDir ?? DEFAULT_OUT_DIR;
27
22
  const outDir = resolve(root, configured);
28
23
 
29
- if (!isInside(root, outDir)) {
24
+ if (!isPathInside(root, outDir)) {
30
25
  throw new Error(`Cannot use "${configured}" as the deploy output directory: it is outside ${root}`);
31
26
  }
32
27
 
33
28
  return outDir;
34
29
  };
35
30
 
36
- const existingFile = (path: string): string | null => {
37
- try {
38
- return statSync(path, { throwIfNoEntry: false })?.isFile() === true ? path : null;
39
- } catch {
40
- return null;
41
- }
42
- };
31
+ const existingFile = (path: string): string | null =>
32
+ statSync(path, { throwIfNoEntry: false })?.isFile() === true ? path : null;
43
33
 
44
34
  const resolveLicenseFile = (root: string, configured: string | undefined): string | null => {
45
35
  if (configured !== undefined) {
@@ -75,4 +65,4 @@ const resolvePaths = (request: PathsRequest): DeployPaths => {
75
65
  };
76
66
  };
77
67
 
78
- export { isInside, resolvePaths };
68
+ export { 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";
@@ -1,3 +1,4 @@
1
+ import { isPathInside, toPosixPath } from "@gtkx/utils";
1
2
  import { existsSync, readFileSync, realpathSync } from "node:fs";
2
3
  import { posix, relative, resolve } from "node:path";
3
4
  import type { DeployPayload, DeploySettings } from "../types.js";
@@ -11,7 +12,6 @@ import { executableModeFor } from "../payload/copy-tree.js";
11
12
  import { iconPathFor } from "../payload/icons.js";
12
13
  import { renderLauncher } from "../payload/launcher.js";
13
14
  import { licenseDestination, nodeLicenseDestination, NOTICES_FILENAME, noticesDestination } from "../payload/stage.js";
14
- import { isInside } from "../settings/paths.js";
15
15
  import { pnpmPathFor, type PnpmPin, pnpmSources } from "./flatpak-pnpm.js";
16
16
  import { DESTINATION, type FlatpakModule, postInstallCommands, validationCommands } from "./flatpak-prebuilt.js";
17
17
  import {
@@ -46,7 +46,7 @@ const inlineSource = (fileName: string, contents: string): FlatpakModule => ({
46
46
  });
47
47
 
48
48
  const projectRelative = (settings: DeploySettings, path: string): string =>
49
- relative(settings.paths.root, path).replaceAll("\\", "/");
49
+ toPosixPath(relative(settings.paths.root, path));
50
50
 
51
51
  const shellArgument = (value: string): string =>
52
52
  PLAIN_ARGUMENT.test(value) ? value : `'${value.split("'").join(QUOTE_ESCAPE)}'`;
@@ -155,7 +155,7 @@ const schemaInstallCommands = (settings: DeploySettings): string[] =>
155
155
  const iconInstallCommand = (settings: DeploySettings, source: string, rel: string): string =>
156
156
  installCommand(
157
157
  projectRelative(settings, source),
158
- `${DESTINATION}/share/icons/${shellArgument(rel.replaceAll("\\", "/"))}`,
158
+ `${DESTINATION}/share/icons/${shellArgument(toPosixPath(rel))}`,
159
159
  "m644",
160
160
  );
161
161
 
@@ -177,7 +177,7 @@ const assertInsideProject = (settings: DeploySettings, installed: InstalledFile)
177
177
  const { resolved } = installed;
178
178
  const target = existsSync(resolved) ? realpathSync(resolved) : resolved;
179
179
 
180
- if (isInside(settings.paths.root, target)) {
180
+ if (isPathInside(settings.paths.root, target)) {
181
181
  return;
182
182
  }
183
183
 
@@ -26,7 +26,7 @@ type GitRevision = {
26
26
  const GENERATED_SOURCES = "generated-sources.json";
27
27
  const COMMIT_PEEL = "^{commit}";
28
28
  const FETCHABLE_URL = /^https?:\/\//;
29
- const DEFAULT_NODE_EXTENSION = "org.freedesktop.Sdk.Extension.node24";
29
+ const DEFAULT_NODE_EXTENSION = "org.freedesktop.Sdk.Extension.node26";
30
30
  const NODE_EXTENSION_PREFIX = "org.freedesktop.Sdk.Extension.";
31
31
  const SDK_EXTENSION_ROOT = "/usr/lib/sdk";
32
32
 
@@ -145,11 +145,9 @@ const toolLines = (tool: DeployTool, hints: string[]): string[] => [
145
145
  const missingToolsMessage = (report: ToolReport): string => {
146
146
  const family = detectPackageFamily();
147
147
  const required = report.missingRequired.flatMap((tool) => toolLines(tool, installHints(tool.command, family)));
148
- const count = report.missingRequired.length;
149
- const plural = count === 1 ? "tool is" : "tools are";
150
148
 
151
149
  return [
152
- `Cannot deploy: ${String(count)} required ${plural} missing.`,
150
+ "Cannot deploy without these tools:",
153
151
  "",
154
152
  ...required,
155
153
  "",
@@ -24,7 +24,7 @@ const main = async (): Promise<void> => {
24
24
 
25
25
  const { config, root } = await loadConfig(cwd, { mode: "development" });
26
26
  prepareDevLocaleDir(root, config.applicationId);
27
- prepareDevSchemaDir(root, config.future?.v2ResourceImports === true);
27
+ prepareDevSchemaDir(root);
28
28
  prepareDevIconDir(root, config.applicationId, config.applicationIcon);
29
29
  const entryPath = resolve(cwd, entryArg);
30
30
  const { defaultDevRunnerDeps } = await import("./runner-deps.js");
@@ -1,9 +1,7 @@
1
- import { resolveDataDir } from "../internal/data-dir.js";
2
1
  import { prependSchemaDir, stageAndCompileProjectSchemas } from "../settings/schema.js";
3
2
 
4
- const prepareDevSchemaDir = (root: string, isV2ResourceImports: boolean): string | null => {
5
- const dataDir = isV2ResourceImports ? null : resolveDataDir(root);
6
- const dir = stageAndCompileProjectSchemas(root, dataDir);
3
+ const prepareDevSchemaDir = (root: string): string | null => {
4
+ const dir = stageAndCompileProjectSchemas(root);
7
5
 
8
6
  if (dir === null) {
9
7
  return null;
@@ -1,3 +1,4 @@
1
+ import { isPathInside } from "@gtkx/utils";
1
2
  import {
2
3
  chmodSync,
3
4
  existsSync,
@@ -198,7 +199,7 @@ const isCatalogSource = (root: string, path: string): boolean => {
198
199
  const sourcePath = isAbsolute(path) ? resolve(path) : resolve(projectRoot, path);
199
200
  const poPath = relative(join(projectRoot, PO_DIRNAME), sourcePath);
200
201
 
201
- if (poPath === "" || poPath === ".." || poPath.startsWith(`..${sep}`) || isAbsolute(poPath)) {
202
+ if (!isPathInside(join(projectRoot, PO_DIRNAME), sourcePath)) {
202
203
  return false;
203
204
  }
204
205
 
@@ -1,3 +1,4 @@
1
+ import { toPosixPath } from "@gtkx/utils";
1
2
  import { join, relative } from "node:path";
2
3
  import type { CatalogProject } from "./catalogs.js";
3
4
 
@@ -14,7 +15,7 @@ const METADATA_TEMPLATE_DIRNAME = ".gtkx-metadata";
14
15
 
15
16
  const metadataTemplateFile = (project: CatalogProject, kind: MetadataTemplateKind): MetadataTemplateFile => {
16
17
  const path = join(project.poDir, METADATA_TEMPLATE_DIRNAME, `${project.domain}.template.${kind}`);
17
- const relativePath = relative(project.root, path).replaceAll("\\", "/");
18
+ const relativePath = toPosixPath(relative(project.root, path));
18
19
 
19
20
  return { kind, path, relativePath };
20
21
  };