@gtkx/cli 2.0.0-beta.1 → 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 (165) hide show
  1. package/dist/builder.d.ts +1 -0
  2. package/dist/builder.d.ts.map +1 -1
  3. package/dist/builder.js +17 -5
  4. package/dist/builder.js.map +1 -1
  5. package/dist/cli.js +2 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/codegen/run-codegen.d.ts +4 -2
  8. package/dist/codegen/run-codegen.d.ts.map +1 -1
  9. package/dist/codegen/run-codegen.js +13 -8
  10. package/dist/codegen/run-codegen.js.map +1 -1
  11. package/dist/codegen/store-resolver.d.ts +1 -1
  12. package/dist/codegen/store-resolver.d.ts.map +1 -1
  13. package/dist/codegen/store-resolver.js +2 -2
  14. package/dist/codegen/store-resolver.js.map +1 -1
  15. package/dist/commands/build.d.ts +5 -0
  16. package/dist/commands/build.d.ts.map +1 -1
  17. package/dist/commands/build.js +83 -10
  18. package/dist/commands/build.js.map +1 -1
  19. package/dist/commands/codegen.d.ts +1 -0
  20. package/dist/commands/codegen.d.ts.map +1 -1
  21. package/dist/commands/codegen.js +6 -5
  22. package/dist/commands/codegen.js.map +1 -1
  23. package/dist/commands/deploy.d.ts +1 -0
  24. package/dist/commands/deploy.d.ts.map +1 -1
  25. package/dist/commands/deploy.js +4 -2
  26. package/dist/commands/deploy.js.map +1 -1
  27. package/dist/commands/dev.d.ts +8 -0
  28. package/dist/commands/dev.d.ts.map +1 -1
  29. package/dist/commands/dev.js +19 -1
  30. package/dist/commands/dev.js.map +1 -1
  31. package/dist/deploy/freedesktop/metainfo.d.ts.map +1 -1
  32. package/dist/deploy/freedesktop/metainfo.js +41 -2
  33. package/dist/deploy/freedesktop/metainfo.js.map +1 -1
  34. package/dist/deploy/nfpm/config.d.ts.map +1 -1
  35. package/dist/deploy/nfpm/config.js +5 -2
  36. package/dist/deploy/nfpm/config.js.map +1 -1
  37. package/dist/deploy/nfpm/contents.d.ts.map +1 -1
  38. package/dist/deploy/nfpm/contents.js +8 -0
  39. package/dist/deploy/nfpm/contents.js.map +1 -1
  40. package/dist/deploy/node-runtime/elf.d.ts +2 -1
  41. package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
  42. package/dist/deploy/node-runtime/elf.js +32 -5
  43. package/dist/deploy/node-runtime/elf.js.map +1 -1
  44. package/dist/deploy/node-runtime/index.d.ts +2 -1
  45. package/dist/deploy/node-runtime/index.d.ts.map +1 -1
  46. package/dist/deploy/node-runtime/index.js +73 -4
  47. package/dist/deploy/node-runtime/index.js.map +1 -1
  48. package/dist/deploy/notices/node-runtime.js +2 -2
  49. package/dist/deploy/notices/node-runtime.js.map +1 -1
  50. package/dist/deploy/payload/launcher.d.ts.map +1 -1
  51. package/dist/deploy/payload/launcher.js +14 -1
  52. package/dist/deploy/payload/launcher.js.map +1 -1
  53. package/dist/deploy/payload/stage.js +1 -1
  54. package/dist/deploy/payload/stage.js.map +1 -1
  55. package/dist/deploy/run-deploy.d.ts +1 -0
  56. package/dist/deploy/run-deploy.d.ts.map +1 -1
  57. package/dist/deploy/run-deploy.js +100 -14
  58. package/dist/deploy/run-deploy.js.map +1 -1
  59. package/dist/deploy/settings/build-manifest.d.ts +6 -1
  60. package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
  61. package/dist/deploy/settings/build-manifest.js +15 -4
  62. package/dist/deploy/settings/build-manifest.js.map +1 -1
  63. package/dist/deploy/settings/extra-files.d.ts +1 -1
  64. package/dist/deploy/settings/extra-files.d.ts.map +1 -1
  65. package/dist/deploy/settings/extra-files.js +22 -1
  66. package/dist/deploy/settings/extra-files.js.map +1 -1
  67. package/dist/deploy/settings/index.d.ts +1 -0
  68. package/dist/deploy/settings/index.d.ts.map +1 -1
  69. package/dist/deploy/settings/index.js +2 -1
  70. package/dist/deploy/settings/index.js.map +1 -1
  71. package/dist/deploy/settings/paths.d.ts +2 -1
  72. package/dist/deploy/settings/paths.d.ts.map +1 -1
  73. package/dist/deploy/settings/paths.js +113 -5
  74. package/dist/deploy/settings/paths.js.map +1 -1
  75. package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
  76. package/dist/deploy/targets/flatpak-source.js +11 -2
  77. package/dist/deploy/targets/flatpak-source.js.map +1 -1
  78. package/dist/deploy/types.d.ts +1 -0
  79. package/dist/deploy/types.d.ts.map +1 -1
  80. package/dist/deploy/types.js.map +1 -1
  81. package/dist/dev/headless.d.ts +3 -0
  82. package/dist/dev/headless.d.ts.map +1 -0
  83. package/dist/dev/headless.js +35 -0
  84. package/dist/dev/headless.js.map +1 -0
  85. package/dist/dev/runner-deps.js +1 -1
  86. package/dist/dev/runner-deps.js.map +1 -1
  87. package/dist/i18n/source-messages.d.ts.map +1 -1
  88. package/dist/i18n/source-messages.js +835 -1
  89. package/dist/i18n/source-messages.js.map +1 -1
  90. package/dist/internal/build-manifest.d.ts +5 -2
  91. package/dist/internal/build-manifest.d.ts.map +1 -1
  92. package/dist/internal/build-manifest.js +15 -2
  93. package/dist/internal/build-manifest.js.map +1 -1
  94. package/dist/internal/build-output.d.ts +8 -0
  95. package/dist/internal/build-output.d.ts.map +1 -0
  96. package/dist/internal/build-output.js +69 -0
  97. package/dist/internal/build-output.js.map +1 -0
  98. package/dist/internal/entry-arg.d.ts +4 -1
  99. package/dist/internal/entry-arg.d.ts.map +1 -1
  100. package/dist/internal/entry-arg.js +7 -1
  101. package/dist/internal/entry-arg.js.map +1 -1
  102. package/dist/internal/output-directory.d.ts +15 -0
  103. package/dist/internal/output-directory.d.ts.map +1 -0
  104. package/dist/internal/output-directory.js +490 -0
  105. package/dist/internal/output-directory.js.map +1 -0
  106. package/dist/internal/prepare-project.d.ts +2 -0
  107. package/dist/internal/prepare-project.d.ts.map +1 -1
  108. package/dist/internal/prepare-project.js +3 -3
  109. package/dist/internal/prepare-project.js.map +1 -1
  110. package/dist/internal/source-imports.js +1 -1
  111. package/dist/internal/source-imports.js.map +1 -1
  112. package/dist/mcp/client.js +2 -2
  113. package/dist/mcp/client.js.map +1 -1
  114. package/dist/vite-plugins/build-manifest.d.ts +5 -1
  115. package/dist/vite-plugins/build-manifest.d.ts.map +1 -1
  116. package/dist/vite-plugins/build-manifest.js +2 -1
  117. package/dist/vite-plugins/build-manifest.js.map +1 -1
  118. package/dist/vite-plugins/i18n.d.ts.map +1 -1
  119. package/dist/vite-plugins/i18n.js +58 -6
  120. package/dist/vite-plugins/i18n.js.map +1 -1
  121. package/dist/vite-plugins/index.d.ts +8 -1
  122. package/dist/vite-plugins/index.d.ts.map +1 -1
  123. package/dist/vite-plugins/index.js +6 -2
  124. package/dist/vite-plugins/index.js.map +1 -1
  125. package/dist/vite-plugins/self-contained.d.ts.map +1 -1
  126. package/dist/vite-plugins/self-contained.js +159 -158
  127. package/dist/vite-plugins/self-contained.js.map +1 -1
  128. package/package.json +9 -9
  129. package/src/builder.ts +18 -5
  130. package/src/cli.ts +3 -0
  131. package/src/codegen/run-codegen.ts +15 -7
  132. package/src/codegen/store-resolver.ts +2 -2
  133. package/src/commands/build.ts +13 -2
  134. package/src/commands/codegen.ts +6 -5
  135. package/src/commands/deploy.ts +4 -2
  136. package/src/commands/dev.ts +20 -1
  137. package/src/deploy/freedesktop/metainfo.ts +73 -21
  138. package/src/deploy/nfpm/config.ts +5 -2
  139. package/src/deploy/nfpm/contents.ts +8 -0
  140. package/src/deploy/node-runtime/elf.ts +43 -5
  141. package/src/deploy/node-runtime/index.ts +105 -5
  142. package/src/deploy/notices/node-runtime.ts +2 -2
  143. package/src/deploy/payload/launcher.ts +20 -1
  144. package/src/deploy/payload/stage.ts +1 -1
  145. package/src/deploy/run-deploy.ts +56 -16
  146. package/src/deploy/settings/build-manifest.ts +28 -3
  147. package/src/deploy/settings/extra-files.ts +26 -2
  148. package/src/deploy/settings/index.ts +3 -1
  149. package/src/deploy/settings/paths.ts +70 -5
  150. package/src/deploy/targets/flatpak-source.ts +13 -2
  151. package/src/deploy/types.ts +1 -0
  152. package/src/dev/headless.ts +40 -0
  153. package/src/dev/runner-deps.ts +1 -1
  154. package/src/i18n/source-messages.ts +1220 -2
  155. package/src/internal/build-manifest.ts +25 -1
  156. package/src/internal/build-output.ts +99 -0
  157. package/src/internal/entry-arg.ts +8 -1
  158. package/src/internal/output-directory.ts +699 -0
  159. package/src/internal/prepare-project.ts +5 -5
  160. package/src/internal/source-imports.ts +1 -1
  161. package/src/mcp/client.ts +2 -2
  162. package/src/vite-plugins/build-manifest.ts +7 -1
  163. package/src/vite-plugins/i18n.ts +86 -5
  164. package/src/vite-plugins/index.ts +14 -7
  165. package/src/vite-plugins/self-contained.ts +184 -185
@@ -1,3 +1,5 @@
1
+ import { createHash } from "node:crypto";
2
+
1
3
  type RecordedPackage = {
2
4
  name: string;
3
5
  version: string | null;
@@ -7,6 +9,8 @@ type RecordedPackage = {
7
9
  type BuildManifest = {
8
10
  generator: typeof BUILD_MANIFEST_GENERATOR;
9
11
  formatVersion: typeof BUILD_MANIFEST_FORMAT_VERSION;
12
+ configFile: string;
13
+ configDigest: string;
10
14
  schemas: string[];
11
15
  packages: RecordedPackage[];
12
16
  };
@@ -17,7 +21,26 @@ type BuildManifestCollector = {
17
21
 
18
22
  const BUILD_MANIFEST_FILENAME = "gtkx-schemas.json";
19
23
  const BUILD_MANIFEST_GENERATOR = "gtkx-build";
20
- const BUILD_MANIFEST_FORMAT_VERSION = 1;
24
+ const BUILD_MANIFEST_FORMAT_VERSION = 2;
25
+
26
+ const canonicalConfig = (value: unknown): unknown => {
27
+ if (Array.isArray(value)) {
28
+ return value.map((entry) => canonicalConfig(entry));
29
+ }
30
+
31
+ if (typeof value !== "object" || value === null) {
32
+ return value;
33
+ }
34
+
35
+ return Object.fromEntries(
36
+ Object.entries(value)
37
+ .toSorted(([left], [right]) => left.localeCompare(right))
38
+ .map(([key, entry]) => [key, canonicalConfig(entry)]),
39
+ );
40
+ };
41
+
42
+ const configDigest = (config: unknown): string =>
43
+ createHash("sha256").update(JSON.stringify(canonicalConfig(config))).digest("hex");
21
44
 
22
45
  const createBuildManifestCollector = (): BuildManifestCollector => ({ schemas: [] });
23
46
 
@@ -25,6 +48,7 @@ export {
25
48
  BUILD_MANIFEST_FILENAME,
26
49
  BUILD_MANIFEST_FORMAT_VERSION,
27
50
  BUILD_MANIFEST_GENERATOR,
51
+ configDigest,
28
52
  createBuildManifestCollector,
29
53
  type BuildManifest,
30
54
  type BuildManifestCollector,
@@ -0,0 +1,99 @@
1
+ import { isPathInside, isRecord } from "@gtkx/utils";
2
+ import { lstatSync, readdirSync } from "node:fs";
3
+ import { join, relative, resolve, sep } from "node:path";
4
+ import {
5
+ BUILD_MANIFEST_FILENAME,
6
+ BUILD_MANIFEST_GENERATOR,
7
+ } from "./build-manifest.js";
8
+ import {
9
+ type OutputDirectoryTransaction,
10
+ prepareOutputDirectory,
11
+ readRegularFile,
12
+ } from "./output-directory.js";
13
+
14
+ const DEFAULT_BUILD_OUT_DIR = "dist";
15
+ const PRESERVED_BUILD_ENTRIES: ReadonlySet<string> = new Set([".git"]);
16
+
17
+ type PreparedBuildOutDir = Disposable & { commit: () => void; path: string };
18
+
19
+ const hasSymlinkComponent = (root: string, target: string): boolean => {
20
+ let current = root;
21
+
22
+ for (const segment of relative(root, target).split(sep)) {
23
+ current = join(current, segment);
24
+
25
+ if (lstatSync(current, { throwIfNoEntry: false })?.isSymbolicLink() === true) {
26
+ return true;
27
+ }
28
+ }
29
+
30
+ return false;
31
+ };
32
+
33
+ const isGtkxBuildDirectory = (path: string): boolean => {
34
+ const manifest = join(path, BUILD_MANIFEST_FILENAME);
35
+ const contents = readRegularFile(manifest);
36
+
37
+ try {
38
+ const parsed: unknown = contents === null ? null : JSON.parse(contents);
39
+
40
+ return isRecord(parsed) && parsed.generator === BUILD_MANIFEST_GENERATOR;
41
+ } catch {
42
+ return false;
43
+ }
44
+ };
45
+
46
+ const isReusableBuildDirectory = (path: string): boolean => {
47
+ const stats = lstatSync(path, { throwIfNoEntry: false });
48
+
49
+ if (stats === undefined) {
50
+ return true;
51
+ }
52
+
53
+ return stats.isDirectory() && (readdirSync(path).length === 0 || isGtkxBuildDirectory(path));
54
+ };
55
+
56
+ const buildOutputError = (root: string): Error =>
57
+ new Error(`Build output must be an empty directory or an earlier GTKX build below the project root ${root}`);
58
+
59
+ const assertSafeBuildLocation = (root: string, outDir: string): void => {
60
+ if (!isPathInside(root, outDir) || hasSymlinkComponent(root, outDir)) {
61
+ throw buildOutputError(root);
62
+ }
63
+ };
64
+
65
+ const resolveBuildOutDir = (root: string, configured?: string): string => {
66
+ const selected = configured ?? DEFAULT_BUILD_OUT_DIR;
67
+ const outDir = resolve(root, selected);
68
+
69
+ assertSafeBuildLocation(root, outDir);
70
+
71
+ if (!isReusableBuildDirectory(outDir)) {
72
+ throw buildOutputError(root);
73
+ }
74
+
75
+ return outDir;
76
+ };
77
+
78
+ const prepareBuildOutDir = (root: string, outDir: string): PreparedBuildOutDir => {
79
+ assertSafeBuildLocation(root, outDir);
80
+ const prepared = prepareOutputDirectory(root, outDir, isReusableBuildDirectory);
81
+
82
+ if (prepared.status === "unsafe") {
83
+ throw buildOutputError(root);
84
+ }
85
+
86
+ const transaction: OutputDirectoryTransaction = prepared.transaction;
87
+
88
+ return {
89
+ path: transaction.path,
90
+ commit: () => {
91
+ transaction.commit(PRESERVED_BUILD_ENTRIES, isGtkxBuildDirectory);
92
+ },
93
+ [Symbol.dispose]: () => {
94
+ transaction[Symbol.dispose]();
95
+ },
96
+ };
97
+ };
98
+
99
+ export { prepareBuildOutDir, resolveBuildOutDir };
@@ -14,6 +14,13 @@ const cwdArg: { cwd: StringArgDef } = {
14
14
  },
15
15
  };
16
16
 
17
+ const configArg: { config: StringArgDef } = {
18
+ config: {
19
+ type: "string",
20
+ description: "Project-relative configuration file (default: gtkx.config.*)",
21
+ },
22
+ };
23
+
17
24
  const entryArg: { entry: PositionalArgDef; cwd: StringArgDef } = {
18
25
  entry: {
19
26
  type: "positional",
@@ -57,4 +64,4 @@ const resolveGivenEntry = (cwd: string, entry: string): string => {
57
64
  const resolveEntry = (cwd: string, entry: string | undefined): string =>
58
65
  entry ? resolveGivenEntry(cwd, entry) : resolveDefaultEntry(cwd);
59
66
 
60
- export { cwdArg, entryArg, resolveCwd, resolveEntry };
67
+ export { configArg, cwdArg, entryArg, resolveCwd, resolveEntry };