@gtkx/cli 2.0.0-beta.3 → 2.0.0-beta.5

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 (88) hide show
  1. package/dist/cli.js +4 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/codegen/config-dependencies.d.ts +3 -0
  4. package/dist/codegen/config-dependencies.d.ts.map +1 -0
  5. package/dist/codegen/config-dependencies.js +355 -0
  6. package/dist/codegen/config-dependencies.js.map +1 -0
  7. package/dist/codegen/run-codegen.d.ts +3 -2
  8. package/dist/codegen/run-codegen.d.ts.map +1 -1
  9. package/dist/codegen/run-codegen.js +31 -6
  10. package/dist/codegen/run-codegen.js.map +1 -1
  11. package/dist/codegen/store-resolver.d.ts +1 -0
  12. package/dist/codegen/store-resolver.d.ts.map +1 -1
  13. package/dist/codegen/store-resolver.js +4 -2
  14. package/dist/codegen/store-resolver.js.map +1 -1
  15. package/dist/commands/cleanup.d.ts +9 -0
  16. package/dist/commands/cleanup.d.ts.map +1 -0
  17. package/dist/commands/cleanup.js +31 -0
  18. package/dist/commands/cleanup.js.map +1 -0
  19. package/dist/commands/dev.d.ts.map +1 -1
  20. package/dist/commands/dev.js +4 -2
  21. package/dist/commands/dev.js.map +1 -1
  22. package/dist/deploy/freedesktop/validate.d.ts.map +1 -1
  23. package/dist/deploy/freedesktop/validate.js +45 -12
  24. package/dist/deploy/freedesktop/validate.js.map +1 -1
  25. package/dist/deploy/payload/stage.d.ts.map +1 -1
  26. package/dist/deploy/payload/stage.js +24 -3
  27. package/dist/deploy/payload/stage.js.map +1 -1
  28. package/dist/deploy/settings/extra-files.d.ts.map +1 -1
  29. package/dist/deploy/settings/extra-files.js +4 -3
  30. package/dist/deploy/settings/extra-files.js.map +1 -1
  31. package/dist/dev/catalog-writes.d.ts +8 -0
  32. package/dist/dev/catalog-writes.d.ts.map +1 -0
  33. package/dist/dev/catalog-writes.js +26 -0
  34. package/dist/dev/catalog-writes.js.map +1 -0
  35. package/dist/dev/runner-deps.d.ts.map +1 -1
  36. package/dist/dev/runner-deps.js +10 -6
  37. package/dist/dev/runner-deps.js.map +1 -1
  38. package/dist/dev/runner.d.ts +1 -0
  39. package/dist/dev/runner.d.ts.map +1 -1
  40. package/dist/dev/runner.js +8 -2
  41. package/dist/dev/runner.js.map +1 -1
  42. package/dist/dev/supervisor.d.ts +2 -1
  43. package/dist/dev/supervisor.d.ts.map +1 -1
  44. package/dist/dev/supervisor.js +128 -26
  45. package/dist/dev/supervisor.js.map +1 -1
  46. package/dist/i18n/catalogs.d.ts +6 -2
  47. package/dist/i18n/catalogs.d.ts.map +1 -1
  48. package/dist/i18n/catalogs.js +9 -7
  49. package/dist/i18n/catalogs.js.map +1 -1
  50. package/dist/i18n/source-messages.d.ts +3 -1
  51. package/dist/i18n/source-messages.d.ts.map +1 -1
  52. package/dist/i18n/source-messages.js +14 -2
  53. package/dist/i18n/source-messages.js.map +1 -1
  54. package/dist/internal/build-output.d.ts.map +1 -1
  55. package/dist/internal/build-output.js +45 -8
  56. package/dist/internal/build-output.js.map +1 -1
  57. package/dist/internal/prepare-project.d.ts +1 -0
  58. package/dist/internal/prepare-project.d.ts.map +1 -1
  59. package/dist/internal/prepare-project.js +8 -2
  60. package/dist/internal/prepare-project.js.map +1 -1
  61. package/dist/vite-plugins/i18n.d.ts +11 -2
  62. package/dist/vite-plugins/i18n.d.ts.map +1 -1
  63. package/dist/vite-plugins/i18n.js +20 -6
  64. package/dist/vite-plugins/i18n.js.map +1 -1
  65. package/dist/vite-plugins/index.d.ts +2 -0
  66. package/dist/vite-plugins/index.d.ts.map +1 -1
  67. package/dist/vite-plugins/index.js +10 -2
  68. package/dist/vite-plugins/index.js.map +1 -1
  69. package/package.json +12 -10
  70. package/src/cli.ts +5 -0
  71. package/src/codegen/config-dependencies.ts +470 -0
  72. package/src/codegen/run-codegen.ts +37 -5
  73. package/src/codegen/store-resolver.ts +5 -2
  74. package/src/commands/cleanup.ts +36 -0
  75. package/src/commands/dev.ts +9 -2
  76. package/src/deploy/freedesktop/validate.ts +63 -13
  77. package/src/deploy/payload/stage.ts +42 -3
  78. package/src/deploy/settings/extra-files.ts +5 -3
  79. package/src/dev/catalog-writes.ts +35 -0
  80. package/src/dev/runner-deps.ts +14 -6
  81. package/src/dev/runner.ts +11 -2
  82. package/src/dev/supervisor.ts +177 -29
  83. package/src/i18n/catalogs.ts +20 -8
  84. package/src/i18n/source-messages.ts +19 -3
  85. package/src/internal/build-output.ts +67 -9
  86. package/src/internal/prepare-project.ts +9 -3
  87. package/src/vite-plugins/i18n.ts +42 -9
  88. package/src/vite-plugins/index.ts +19 -3
@@ -1 +1 @@
1
- {"version":3,"file":"store-resolver.d.ts","sourceRoot":"","sources":["../../src/codegen/store-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,cAAc,CAAC;AAMvD,KAAK,YAAY,GAAG;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,cAAc,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACtB,CAAC;AAgBF,QAAA,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG,YAsB1C,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAU,KAAK,MAAM,EAAE,OAAO,MAAM,EAAE,iBAAiB,MAAM,KAAG,OAAO,CAAC,cAAc,CAIhH,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"store-resolver.d.ts","sourceRoot":"","sources":["../../src/codegen/store-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,cAAc,CAAC;AAOvD,KAAK,YAAY,GAAG;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,cAAc,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAChC,CAAC;AAgBF,QAAA,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG,YAsB1C,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAU,KAAK,MAAM,EAAE,OAAO,MAAM,EAAE,iBAAiB,MAAM,KAAG,OAAO,CAAC,cAAc,CAKhH,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { resolveStore } from "@gtkx/codegen";
2
2
  import { loadConfig } from "@gtkx/config";
3
+ import { configDependenciesFor } from "@gtkx/config/internal";
3
4
  import { existsSync, realpathSync } from "node:fs";
4
5
  import { createRequire } from "node:module";
5
6
  import { dirname, join } from "node:path";
@@ -35,8 +36,9 @@ const resolveCodegenStore = (dir) => {
35
36
  };
36
37
  };
37
38
  const resolveCodegenContext = async (cwd, mode, selectedConfig) => {
38
- const { config, configFile } = await loadConfig(cwd, { mode, configFile: selectedConfig });
39
- return { root: cwd, config, configFile };
39
+ const loaded = await loadConfig(cwd, { mode, configFile: selectedConfig });
40
+ const { config, configFile } = loaded;
41
+ return { root: cwd, config, configFile, configDependencies: configDependenciesFor(loaded) };
40
42
  };
41
43
  export { resolveCodegenStore, resolveCodegenContext };
42
44
  //# sourceMappingURL=store-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store-resolver.js","sourceRoot":"","sources":["../../src/codegen/store-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAe,UAAU,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAsBzC,MAAM,UAAU,GAAG,CAAC,OAAuB,EAAE,GAAW,EAAE,WAAmB,EAAW,EAAE;IACtF,IAAI,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,GAAG,WAAW,eAAe,CAAC,CAAC;QAE/C,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACL,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAEtD,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;IACvE,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AAE5E,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAgB,EAAE;IACtD,MAAM,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAErF,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAE1D,OAAO;QACH,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ;QAC7B,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO;QAC3B,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC;QACnE,UAAU,EAAE,KAAK,CAAC,GAAG,EAAE,OAAO,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC;QAChE,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO;QAChC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,YAAY,CAAC,GAAG,CAAC;QAC1C,KAAK,EACD,eAAe,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI;YACjC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE;YAChC,CAAC,CAAC,IAAI;KACjB,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,KAAK,EAAE,GAAW,EAAE,IAAa,EAAE,cAAuB,EAA2B,EAAE;IACjH,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC;IAE3F,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAC7C,CAAC,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAA0C,CAAC","sourcesContent":["import { resolveStore } from \"@gtkx/codegen\";\nimport { type Config, loadConfig } from \"@gtkx/config\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\ntype CodegenStore = {\n giStoreDir: string;\n giLinkDir: string;\n jsxStoreDir: string;\n jsxLinkDir: string;\n runtimeVersion: string;\n owner: string;\n react: CodegenReactPackage | null;\n};\n\ntype CodegenReactPackage = {\n version: string;\n};\n\ntype CodegenContext = {\n root: string;\n config: Config;\n configFile: string;\n};\n\nconst hasPackage = (require: NodeJS.Require, dir: string, packageName: string): boolean => {\n try {\n require.resolve(`${packageName}/package.json`);\n\n return true;\n } catch {\n const unscoped = packageName.replace(/^@[^/]+\\//, \"\");\n\n return existsSync(join(dir, \"packages\", unscoped, \"package.json\"));\n }\n};\n\nconst siblingStore = (giDir: string): string => join(dirname(giDir), \"jsx\");\n\nconst resolveCodegenStore = (dir: string): CodegenStore => {\n const require = createRequire(pathToFileURL(join(dir, \"__gtkx_resolver__.js\")).href);\n\n if (!hasPackage(require, dir, \"@gtkx/native\")) {\n throw new Error(\"Cannot resolve @gtkx/native from the project; is it installed?\");\n }\n\n const store = resolveStore(dir);\n const hasReactRuntime = hasPackage(require, dir, \"react\");\n\n return {\n giStoreDir: store.gi.storeDir,\n giLinkDir: store.gi.linkDir,\n jsxStoreDir: store.jsx?.storeDir ?? siblingStore(store.gi.storeDir),\n jsxLinkDir: store.jsx?.linkDir ?? siblingStore(store.gi.linkDir),\n runtimeVersion: store.gi.version,\n owner: store.gi.owner ?? realpathSync(dir),\n react:\n hasReactRuntime && store.jsx !== null\n ? { version: store.jsx.version }\n : null,\n };\n};\n\nconst resolveCodegenContext = async (cwd: string, mode?: string, selectedConfig?: string): Promise<CodegenContext> => {\n const { config, configFile } = await loadConfig(cwd, { mode, configFile: selectedConfig });\n\n return { root: cwd, config, configFile };\n};\n\nexport { resolveCodegenStore, resolveCodegenContext, type CodegenContext, type CodegenStore };\n"]}
1
+ {"version":3,"file":"store-resolver.js","sourceRoot":"","sources":["../../src/codegen/store-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveStore } from \"@gtkx/codegen\";\nimport { type Config, loadConfig } from \"@gtkx/config\";\nimport { configDependenciesFor } from \"@gtkx/config/internal\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\ntype CodegenStore = {\n giStoreDir: string;\n giLinkDir: string;\n jsxStoreDir: string;\n jsxLinkDir: string;\n runtimeVersion: string;\n owner: string;\n react: CodegenReactPackage | null;\n};\n\ntype CodegenReactPackage = {\n version: string;\n};\n\ntype CodegenContext = {\n root: string;\n config: Config;\n configFile: string;\n configDependencies: string[];\n};\n\nconst hasPackage = (require: NodeJS.Require, dir: string, packageName: string): boolean => {\n try {\n require.resolve(`${packageName}/package.json`);\n\n return true;\n } catch {\n const unscoped = packageName.replace(/^@[^/]+\\//, \"\");\n\n return existsSync(join(dir, \"packages\", unscoped, \"package.json\"));\n }\n};\n\nconst siblingStore = (giDir: string): string => join(dirname(giDir), \"jsx\");\n\nconst resolveCodegenStore = (dir: string): CodegenStore => {\n const require = createRequire(pathToFileURL(join(dir, \"__gtkx_resolver__.js\")).href);\n\n if (!hasPackage(require, dir, \"@gtkx/native\")) {\n throw new Error(\"Cannot resolve @gtkx/native from the project; is it installed?\");\n }\n\n const store = resolveStore(dir);\n const hasReactRuntime = hasPackage(require, dir, \"react\");\n\n return {\n giStoreDir: store.gi.storeDir,\n giLinkDir: store.gi.linkDir,\n jsxStoreDir: store.jsx?.storeDir ?? siblingStore(store.gi.storeDir),\n jsxLinkDir: store.jsx?.linkDir ?? siblingStore(store.gi.linkDir),\n runtimeVersion: store.gi.version,\n owner: store.gi.owner ?? realpathSync(dir),\n react:\n hasReactRuntime && store.jsx !== null\n ? { version: store.jsx.version }\n : null,\n };\n};\n\nconst resolveCodegenContext = async (cwd: string, mode?: string, selectedConfig?: string): Promise<CodegenContext> => {\n const loaded = await loadConfig(cwd, { mode, configFile: selectedConfig });\n const { config, configFile } = loaded;\n\n return { root: cwd, config, configFile, configDependencies: configDependenciesFor(loaded) };\n};\n\nexport { resolveCodegenStore, resolveCodegenContext, type CodegenContext, type CodegenStore };\n"]}
@@ -0,0 +1,9 @@
1
+ declare const cleanup: import("citty").CommandDef<{
2
+ readonly cwd: import("citty").StringArgDef;
3
+ readonly "dry-run": {
4
+ readonly type: "boolean";
5
+ readonly description: "List stale headless runtime directories without removing them";
6
+ };
7
+ }>;
8
+ export { cleanup };
9
+ //# sourceMappingURL=cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../src/commands/cleanup.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,OAAO;;;;;;EA4BX,CAAC;AAEH,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { info } from "@gtkx/utils";
2
+ import { findStaleHeadlessDisplays, reapStaleHeadlessDisplays } from "@gtkx/vitest/headless";
3
+ import { defineCommand } from "citty";
4
+ import { cwdArg } from "../internal/entry-arg.js";
5
+ const cleanup = defineCommand({
6
+ meta: {
7
+ name: "cleanup",
8
+ description: "Remove stale GTKX headless runtime directories",
9
+ },
10
+ args: {
11
+ "dry-run": {
12
+ type: "boolean",
13
+ description: "List stale headless runtime directories without removing them",
14
+ },
15
+ ...cwdArg,
16
+ },
17
+ run({ args }) {
18
+ const candidates = findStaleHeadlessDisplays();
19
+ for (const candidate of candidates) {
20
+ info(`cleanup: ${candidate.runtimeDir}`);
21
+ }
22
+ if (args["dry-run"] === true) {
23
+ info(`cleanup: found ${String(candidates.length)} stale headless runtime directories`);
24
+ return;
25
+ }
26
+ const removed = reapStaleHeadlessDisplays(candidates);
27
+ info(`cleanup: removed ${String(removed.length)} stale headless runtime directories`);
28
+ },
29
+ });
30
+ export { cleanup };
31
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/commands/cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,MAAM,OAAO,GAAG,aAAa,CAAC;IAC1B,IAAI,EAAE;QACF,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,gDAAgD;KAChE;IACD,IAAI,EAAE;QACF,SAAS,EAAE;YACP,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,+DAA+D;SAC/E;QACD,GAAG,MAAM;KACZ;IACD,GAAG,CAAC,EAAE,IAAI,EAAE;QACR,MAAM,UAAU,GAAG,yBAAyB,EAAE,CAAC;QAE/C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC,YAAY,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3B,IAAI,CAAC,kBAAkB,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,qCAAqC,CAAC,CAAC;YAEvF,OAAO;QACX,CAAC;QAED,MAAM,OAAO,GAAG,yBAAyB,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,oBAAoB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,qCAAqC,CAAC,CAAC;IAC1F,CAAC;CACJ,CAAC,CAAC;AAEH,OAAO,EAAE,OAAO,EAAE,CAAC","sourcesContent":["import { info } from \"@gtkx/utils\";\nimport { findStaleHeadlessDisplays, reapStaleHeadlessDisplays } from \"@gtkx/vitest/headless\";\nimport { defineCommand } from \"citty\";\nimport { cwdArg } from \"../internal/entry-arg.js\";\n\nconst cleanup = defineCommand({\n meta: {\n name: \"cleanup\",\n description: \"Remove stale GTKX headless runtime directories\",\n },\n args: {\n \"dry-run\": {\n type: \"boolean\",\n description: \"List stale headless runtime directories without removing them\",\n },\n ...cwdArg,\n },\n run({ args }) {\n const candidates = findStaleHeadlessDisplays();\n\n for (const candidate of candidates) {\n info(`cleanup: ${candidate.runtimeDir}`);\n }\n\n if (args[\"dry-run\"] === true) {\n info(`cleanup: found ${String(candidates.length)} stale headless runtime directories`);\n\n return;\n }\n\n const removed = reapStaleHeadlessDisplays(candidates);\n info(`cleanup: removed ${String(removed.length)} stale headless runtime directories`);\n },\n});\n\nexport { cleanup };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAYA,QAAA,MAAM,GAAG;;;;;;;;;;;;EA6CP,CAAC;AAEH,OAAO,EAAE,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAaA,QAAA,MAAM,GAAG;;;;;;;;;;;;EAmDP,CAAC;AAEH,OAAO,EAAE,GAAG,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { armParentDeath } from "@gtkx/native/internal";
2
+ import { reapStaleHeadlessDisplaysAtStartup } from "@gtkx/vitest/headless";
2
3
  import { defineCommand } from "citty";
3
4
  import { resolveConfigWatch } from "../codegen/run-codegen.js";
4
5
  import { startHeadlessDevDisplay } from "../dev/headless.js";
@@ -26,6 +27,7 @@ const dev = defineCommand({
26
27
  },
27
28
  },
28
29
  async run({ args }) {
30
+ reapStaleHeadlessDisplaysAtStartup();
29
31
  const initialProcessGroupOwner = getInitialProcessGroupOwner();
30
32
  if (!armParentDeath(initialParentId, initialProcessGroupOwner?.pid, initialProcessGroupOwner?.startTime)) {
31
33
  throw new Error("The process that launched gtkx dev exited during startup");
@@ -33,8 +35,8 @@ const dev = defineCommand({
33
35
  if (args.size !== undefined && !args.headless) {
34
36
  throw new Error("--size requires --headless");
35
37
  }
36
- const { cwd, entry: entryPath, configFile } = await prepareProject(args, DEV_MODE);
37
- const watch = await resolveConfigWatch(cwd, DEV_MODE, configFile);
38
+ const { cwd, entry: entryPath, configFile, configDependencies } = await prepareProject(args, DEV_MODE);
39
+ const watch = await resolveConfigWatch(cwd, DEV_MODE, configFile, configDependencies);
38
40
  const { applicationArgs } = splitApplicationArgs(process.argv.slice(2));
39
41
  const stopHeadless = args.headless ? await startHeadlessDevDisplay(args.size) : undefined;
40
42
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAiB,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,MAAM,QAAQ,GAAG,aAAa,CAAC;AAE/B,MAAM,GAAG,GAAG,aAAa,CAAC;IACtB,IAAI,EAAE;QACF,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,mCAAmC;KACnD;IACD,IAAI,EAAE;QACF,GAAG,QAAQ;QACX,GAAG,SAAS;QACZ,QAAQ,EAAE;YACN,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,6CAA6C;SAC7D;QACD,IAAI,EAAE;YACF,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,uCAAuC;SACvD;KACJ;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACd,MAAM,wBAAwB,GAAG,2BAA2B,EAAE,CAAC;QAE/D,IACI,CAAC,cAAc,CACX,eAAe,EACf,wBAAwB,EAAE,GAAG,EAC7B,wBAAwB,EAAE,SAAS,CACtC,EACH,CAAC;YACC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAChF,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnF,MAAM,KAAK,GAAyB,MAAM,kBAAkB,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACxF,MAAM,EAAE,eAAe,EAAE,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE1F,IAAI,CAAC;YACD,MAAM,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACzF,CAAC;gBAAS,CAAC;YACP,YAAY,EAAE,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;CACJ,CAAC,CAAC;AAEH,OAAO,EAAE,GAAG,EAAE,CAAC","sourcesContent":["import { armParentDeath } from \"@gtkx/native/internal\";\nimport { defineCommand } from \"citty\";\nimport { resolveConfigWatch } from \"../codegen/run-codegen.js\";\nimport { startHeadlessDevDisplay } from \"../dev/headless.js\";\nimport { type DevWatch, runDevSupervisor } from \"../dev/supervisor.js\";\nimport { splitApplicationArgs } from \"../internal/application-args.js\";\nimport { configArg, entryArg } from \"../internal/entry-arg.js\";\nimport { getInitialProcessGroupOwner, initialParentId } from \"../internal/parent-process.js\";\nimport { prepareProject } from \"../internal/prepare-project.js\";\n\nconst DEV_MODE = \"development\";\n\nconst dev = defineCommand({\n meta: {\n name: \"dev\",\n description: \"Start development server with HMR\",\n },\n args: {\n ...entryArg,\n ...configArg,\n headless: {\n type: \"boolean\",\n description: \"Run on an isolated headless Wayland display\",\n },\n size: {\n type: \"string\",\n description: \"Headless display size as WIDTHxHEIGHT\",\n },\n },\n async run({ args }) {\n const initialProcessGroupOwner = getInitialProcessGroupOwner();\n\n if (\n !armParentDeath(\n initialParentId,\n initialProcessGroupOwner?.pid,\n initialProcessGroupOwner?.startTime,\n )\n ) {\n throw new Error(\"The process that launched gtkx dev exited during startup\");\n }\n\n if (args.size !== undefined && !args.headless) {\n throw new Error(\"--size requires --headless\");\n }\n\n const { cwd, entry: entryPath, configFile } = await prepareProject(args, DEV_MODE);\n const watch: DevWatch | undefined = await resolveConfigWatch(cwd, DEV_MODE, configFile);\n const { applicationArgs } = splitApplicationArgs(process.argv.slice(2));\n const stopHeadless = args.headless ? await startHeadlessDevDisplay(args.size) : undefined;\n\n try {\n await runDevSupervisor({ entryPath, cwd, configFile, args: applicationArgs, watch });\n } finally {\n stopHeadless?.();\n }\n },\n});\n\nexport { dev };\n"]}
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,kCAAkC,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAiB,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,MAAM,QAAQ,GAAG,aAAa,CAAC;AAE/B,MAAM,GAAG,GAAG,aAAa,CAAC;IACtB,IAAI,EAAE;QACF,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,mCAAmC;KACnD;IACD,IAAI,EAAE;QACF,GAAG,QAAQ;QACX,GAAG,SAAS;QACZ,QAAQ,EAAE;YACN,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,6CAA6C;SAC7D;QACD,IAAI,EAAE;YACF,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,uCAAuC;SACvD;KACJ;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACd,kCAAkC,EAAE,CAAC;QACrC,MAAM,wBAAwB,GAAG,2BAA2B,EAAE,CAAC;QAE/D,IACI,CAAC,cAAc,CACX,eAAe,EACf,wBAAwB,EAAE,GAAG,EAC7B,wBAAwB,EAAE,SAAS,CACtC,EACH,CAAC;YACC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAChF,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,EAAE,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACvG,MAAM,KAAK,GAAyB,MAAM,kBAAkB,CACxD,GAAG,EACH,QAAQ,EACR,UAAU,EACV,kBAAkB,CACrB,CAAC;QACF,MAAM,EAAE,eAAe,EAAE,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE1F,IAAI,CAAC;YACD,MAAM,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACzF,CAAC;gBAAS,CAAC;YACP,YAAY,EAAE,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;CACJ,CAAC,CAAC;AAEH,OAAO,EAAE,GAAG,EAAE,CAAC","sourcesContent":["import { armParentDeath } from \"@gtkx/native/internal\";\nimport { reapStaleHeadlessDisplaysAtStartup } from \"@gtkx/vitest/headless\";\nimport { defineCommand } from \"citty\";\nimport { resolveConfigWatch } from \"../codegen/run-codegen.js\";\nimport { startHeadlessDevDisplay } from \"../dev/headless.js\";\nimport { type DevWatch, runDevSupervisor } from \"../dev/supervisor.js\";\nimport { splitApplicationArgs } from \"../internal/application-args.js\";\nimport { configArg, entryArg } from \"../internal/entry-arg.js\";\nimport { getInitialProcessGroupOwner, initialParentId } from \"../internal/parent-process.js\";\nimport { prepareProject } from \"../internal/prepare-project.js\";\n\nconst DEV_MODE = \"development\";\n\nconst dev = defineCommand({\n meta: {\n name: \"dev\",\n description: \"Start development server with HMR\",\n },\n args: {\n ...entryArg,\n ...configArg,\n headless: {\n type: \"boolean\",\n description: \"Run on an isolated headless Wayland display\",\n },\n size: {\n type: \"string\",\n description: \"Headless display size as WIDTHxHEIGHT\",\n },\n },\n async run({ args }) {\n reapStaleHeadlessDisplaysAtStartup();\n const initialProcessGroupOwner = getInitialProcessGroupOwner();\n\n if (\n !armParentDeath(\n initialParentId,\n initialProcessGroupOwner?.pid,\n initialProcessGroupOwner?.startTime,\n )\n ) {\n throw new Error(\"The process that launched gtkx dev exited during startup\");\n }\n\n if (args.size !== undefined && !args.headless) {\n throw new Error(\"--size requires --headless\");\n }\n\n const { cwd, entry: entryPath, configFile, configDependencies } = await prepareProject(args, DEV_MODE);\n const watch: DevWatch | undefined = await resolveConfigWatch(\n cwd,\n DEV_MODE,\n configFile,\n configDependencies,\n );\n const { applicationArgs } = splitApplicationArgs(process.argv.slice(2));\n const stopHeadless = args.headless ? await startHeadlessDevDisplay(args.size) : undefined;\n\n try {\n await runDevSupervisor({ entryPath, cwd, configFile, args: applicationArgs, watch });\n } finally {\n stopHeadless?.();\n }\n },\n});\n\nexport { dev };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/deploy/freedesktop/validate.ts"],"names":[],"mappings":"AAsGA,QAAA,MAAM,oBAAoB,GAAI,MAAM,MAAM,KAAG,IAU5C,CAAC;AAEF,QAAA,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,kBAAkB,OAAO,KAAG,IAenE,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/deploy/freedesktop/validate.ts"],"names":[],"mappings":"AA6IA,QAAA,MAAM,oBAAoB,GAAI,MAAM,MAAM,KAAG,IAU5C,CAAC;AAEF,QAAA,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,kBAAkB,OAAO,KAAG,IA0BnE,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,10 +1,15 @@
1
1
  import { resolveExecutable, sortStrings, warn } from "@gtkx/utils";
2
2
  import { spawnSync } from "node:child_process";
3
- const DIAGNOSTIC = /^(?<severity>[EIPW]): \S+ (?<rule>[\w-]+)/;
3
+ const DIAGNOSTIC = /^(?<severity>[EIPW]): \S+ (?<rule>[\w-]+)(?: (?<detail>.*))?$/;
4
+ const SUCCESS_SUMMARY = /^\W*Validation was successful/u;
4
5
  const ERROR_SEVERITY = "E";
5
6
  const WARNING_SEVERITY = "W";
6
7
  const INFO_SEVERITY = "I";
7
8
  const FATAL_WARNING_RULES = new Set(["unknown-tag"]);
9
+ const FATAL_RULE_NOTES = {
10
+ "unknown-tag": (element) => "GTKX treats unknown-tag as fatal for every target, whatever severity appstreamcli assigns it; " +
11
+ `the unsupported element is <${element}>`,
12
+ };
8
13
  const REMEDY_FOR_RULE = {
9
14
  "component-summary-missing": "set `deploy.summary`",
10
15
  "description-first-para-too-short": "open `deploy.description` with a paragraph longer than 80 characters",
@@ -12,6 +17,7 @@ const REMEDY_FOR_RULE = {
12
17
  "metainfo-legacy-path": "this file is generated; report it as a gtkx bug",
13
18
  "summary-has-dot-suffix": "drop the trailing period from `deploy.summary`",
14
19
  "summary-too-long": "shorten `deploy.summary`",
20
+ "unknown-tag": "remove the unsupported `deploy.metainfoExtra` element or use a `<custom>` value",
15
21
  "url-homepage-missing": "set `deploy.homepage`, or `homepage` in package.json",
16
22
  };
17
23
  const runTool = ({ tool, args, subject }) => {
@@ -21,18 +27,34 @@ const runTool = ({ tool, args, subject }) => {
21
27
  }
22
28
  return { output: [result.stdout, result.stderr].join("\n").trim(), status: result.status ?? 0 };
23
29
  };
24
- const rulesIn = (output, severities) => output
30
+ const parseDiagnostics = (output) => output.split("\n").flatMap((line) => {
31
+ const groups = DIAGNOSTIC.exec(line)?.groups;
32
+ return groups === undefined
33
+ ? []
34
+ : [{ severity: groups.severity ?? "", rule: groups.rule ?? "", detail: (groups.detail ?? "").trim() }];
35
+ });
36
+ const rulesIn = (diagnostics, severities) => diagnostics.filter((diagnostic) => severities.includes(diagnostic.severity)).map((diagnostic) => diagnostic.rule);
37
+ const fatalNotes = (diagnostics) => diagnostics
38
+ .filter((diagnostic) => diagnostic.severity !== ERROR_SEVERITY && FATAL_WARNING_RULES.has(diagnostic.rule))
39
+ .map((diagnostic) => FATAL_RULE_NOTES[diagnostic.rule]?.(diagnostic.detail) ??
40
+ `GTKX treats ${diagnostic.rule} as fatal for every target`);
41
+ const withoutSuccessSummary = (output) => output
25
42
  .split("\n")
26
- .map((line) => DIAGNOSTIC.exec(line)?.groups)
27
- .filter((groups) => groups !== undefined && severities.includes(groups.severity ?? ""))
28
- .map((groups) => groups?.rule ?? "");
43
+ .filter((line) => !SUCCESS_SUMMARY.test(line))
44
+ .join("\n")
45
+ .trimEnd();
29
46
  const remedyLines = (rules) => {
30
47
  const remedies = sortStrings([...new Set(rules)])
31
48
  .filter((rule) => REMEDY_FOR_RULE[rule] !== undefined)
32
49
  .map((rule) => ` ${rule}: ${REMEDY_FOR_RULE[rule] ?? ""}`);
33
50
  return remedies.length === 0 ? [] : ["", "Fix it in gtkx.config.ts:", ...remedies];
34
51
  };
35
- const invalid = (subject, output, rules) => new Error([`${subject} is not valid:`, output.length > 0 ? output : "no output", ...remedyLines(rules)].join("\n"));
52
+ const invalid = (subject, output, rules, notes) => new Error([
53
+ `${subject} is not valid:`,
54
+ output.length > 0 ? output : "no output",
55
+ ...notes,
56
+ ...remedyLines(rules),
57
+ ].join("\n"));
36
58
  const isFatalResult = ({ status, errors, warnings, rules, areWarningsFatal }) => {
37
59
  if (errors.length > 0) {
38
60
  return true;
@@ -47,7 +69,7 @@ const isFatalResult = ({ status, errors, warnings, rules, areWarningsFatal }) =>
47
69
  };
48
70
  const assertNotFatal = (result) => {
49
71
  if (isFatalResult(result)) {
50
- throw invalid(result.subject, result.output, result.rules);
72
+ throw invalid(result.subject, result.output, result.rules, result.notes);
51
73
  }
52
74
  };
53
75
  const describeRule = (rule) => {
@@ -66,7 +88,7 @@ const validateDesktopEntry = (path) => {
66
88
  subject: "The desktop entry",
67
89
  });
68
90
  if (status !== 0 || output.length > 0) {
69
- throw invalid("The desktop entry", output, []);
91
+ throw invalid("The desktop entry", output, [], []);
70
92
  }
71
93
  };
72
94
  const validateMetainfo = (path, areWarningsFatal) => {
@@ -76,11 +98,22 @@ const validateMetainfo = (path, areWarningsFatal) => {
76
98
  args: ["validate", "--no-net", "--explain", path],
77
99
  subject,
78
100
  });
79
- const errors = rulesIn(output, [ERROR_SEVERITY]);
80
- const warnings = rulesIn(output, [WARNING_SEVERITY]);
81
- const infos = rulesIn(output, [INFO_SEVERITY]);
101
+ const diagnostics = parseDiagnostics(output);
102
+ const errors = rulesIn(diagnostics, [ERROR_SEVERITY]);
103
+ const warnings = rulesIn(diagnostics, [WARNING_SEVERITY]);
104
+ const infos = rulesIn(diagnostics, [INFO_SEVERITY]);
82
105
  const rules = [...errors, ...warnings, ...infos];
83
- assertNotFatal({ subject, output, status, errors, warnings, rules, areWarningsFatal });
106
+ const notes = fatalNotes(diagnostics);
107
+ assertNotFatal({
108
+ subject,
109
+ output: withoutSuccessSummary(output),
110
+ status,
111
+ errors,
112
+ warnings,
113
+ rules,
114
+ notes,
115
+ areWarningsFatal,
116
+ });
84
117
  reportDiagnostics(subject, [...warnings, ...infos]);
85
118
  };
86
119
  export { validateDesktopEntry, validateMetainfo };
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/deploy/freedesktop/validate.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveExecutable, sortStrings, warn } from \"@gtkx/utils\";\nimport { spawnSync } from \"node:child_process\";\n\ntype ToolResult = {\n output: string;\n status: number;\n};\n\ntype MetainfoResult = {\n subject: string;\n output: string;\n status: number;\n errors: string[];\n warnings: string[];\n rules: string[];\n areWarningsFatal: boolean;\n};\n\ntype ToolRequest = {\n tool: string;\n args: string[];\n subject: string;\n};\n\nconst DIAGNOSTIC = /^(?<severity>[EIPW]): \\S+ (?<rule>[\\w-]+)/;\nconst ERROR_SEVERITY = \"E\";\nconst WARNING_SEVERITY = \"W\";\nconst INFO_SEVERITY = \"I\";\nconst FATAL_WARNING_RULES: Set<string> = new Set([\"unknown-tag\"]);\n\nconst REMEDY_FOR_RULE: Record<string, string> = {\n \"component-summary-missing\": \"set `deploy.summary`\",\n \"description-first-para-too-short\": \"open `deploy.description` with a paragraph longer than 80 characters\",\n \"developer-info-missing\": \"set `deploy.developer.name`\",\n \"metainfo-legacy-path\": \"this file is generated; report it as a gtkx bug\",\n \"summary-has-dot-suffix\": \"drop the trailing period from `deploy.summary`\",\n \"summary-too-long\": \"shorten `deploy.summary`\",\n \"url-homepage-missing\": \"set `deploy.homepage`, or `homepage` in package.json\",\n};\n\nconst runTool = ({ tool, args, subject }: ToolRequest): ToolResult => {\n const result = spawnSync(resolveExecutable(tool), args, { encoding: \"utf8\" });\n\n if (result.error !== undefined) {\n throw new Error(`${subject} could not be validated: ${result.error.message}`, { cause: result.error });\n }\n\n return { output: [result.stdout, result.stderr].join(\"\\n\").trim(), status: result.status ?? 0 };\n};\n\nconst rulesIn = (output: string, severities: string[]): string[] =>\n output\n .split(\"\\n\")\n .map((line) => DIAGNOSTIC.exec(line)?.groups)\n .filter((groups) => groups !== undefined && severities.includes(groups.severity ?? \"\"))\n .map((groups) => groups?.rule ?? \"\");\n\nconst remedyLines = (rules: string[]): string[] => {\n const remedies = sortStrings([...new Set(rules)])\n .filter((rule) => REMEDY_FOR_RULE[rule] !== undefined)\n .map((rule) => ` ${rule}: ${REMEDY_FOR_RULE[rule] ?? \"\"}`);\n\n return remedies.length === 0 ? [] : [\"\", \"Fix it in gtkx.config.ts:\", ...remedies];\n};\n\nconst invalid = (subject: string, output: string, rules: string[]): Error =>\n new Error([`${subject} is not valid:`, output.length > 0 ? output : \"no output\", ...remedyLines(rules)].join(\"\\n\"));\n\nconst isFatalResult = ({ status, errors, warnings, rules, areWarningsFatal }: MetainfoResult): boolean => {\n if (errors.length > 0) {\n return true;\n }\n\n if (rules.some((rule) => FATAL_WARNING_RULES.has(rule))) {\n return true;\n }\n\n if (areWarningsFatal && warnings.length > 0) {\n return true;\n }\n\n return status !== 0 && warnings.length === 0;\n};\n\nconst assertNotFatal = (result: MetainfoResult): void => {\n if (isFatalResult(result)) {\n throw invalid(result.subject, result.output, result.rules);\n }\n};\n\nconst describeRule = (rule: string): string => {\n const remedy = REMEDY_FOR_RULE[rule];\n\n return remedy === undefined ? rule : `${rule} — ${remedy}`;\n};\n\nconst reportDiagnostics = (subject: string, rules: string[]): void => {\n for (const rule of rules) {\n warn(`${subject}: ${describeRule(rule)}`);\n }\n};\n\nconst validateDesktopEntry = (path: string): void => {\n const { output, status } = runTool({\n tool: \"desktop-file-validate\",\n args: [path],\n subject: \"The desktop entry\",\n });\n\n if (status !== 0 || output.length > 0) {\n throw invalid(\"The desktop entry\", output, []);\n }\n};\n\nconst validateMetainfo = (path: string, areWarningsFatal: boolean): void => {\n const subject = \"The AppStream metainfo\";\n\n const { output, status } = runTool({\n tool: \"appstreamcli\",\n args: [\"validate\", \"--no-net\", \"--explain\", path],\n subject,\n });\n\n const errors = rulesIn(output, [ERROR_SEVERITY]);\n const warnings = rulesIn(output, [WARNING_SEVERITY]);\n const infos = rulesIn(output, [INFO_SEVERITY]);\n const rules = [...errors, ...warnings, ...infos];\n assertNotFatal({ subject, output, status, errors, warnings, rules, areWarningsFatal });\n reportDiagnostics(subject, [...warnings, ...infos]);\n};\n\nexport { validateDesktopEntry, validateMetainfo };\n"]}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/deploy/freedesktop/validate.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveExecutable, sortStrings, warn } from \"@gtkx/utils\";\nimport { spawnSync } from \"node:child_process\";\n\ntype ToolResult = {\n output: string;\n status: number;\n};\n\ntype Diagnostic = {\n severity: string;\n rule: string;\n detail: string;\n};\n\ntype MetainfoResult = {\n subject: string;\n output: string;\n status: number;\n errors: string[];\n warnings: string[];\n rules: string[];\n notes: string[];\n areWarningsFatal: boolean;\n};\n\ntype ToolRequest = {\n tool: string;\n args: string[];\n subject: string;\n};\n\nconst DIAGNOSTIC = /^(?<severity>[EIPW]): \\S+ (?<rule>[\\w-]+)(?: (?<detail>.*))?$/;\nconst SUCCESS_SUMMARY = /^\\W*Validation was successful/u;\nconst ERROR_SEVERITY = \"E\";\nconst WARNING_SEVERITY = \"W\";\nconst INFO_SEVERITY = \"I\";\nconst FATAL_WARNING_RULES: Set<string> = new Set([\"unknown-tag\"]);\n\nconst FATAL_RULE_NOTES: Record<string, (detail: string) => string> = {\n \"unknown-tag\": (element) =>\n \"GTKX treats unknown-tag as fatal for every target, whatever severity appstreamcli assigns it; \" +\n `the unsupported element is <${element}>`,\n};\n\nconst REMEDY_FOR_RULE: Record<string, string> = {\n \"component-summary-missing\": \"set `deploy.summary`\",\n \"description-first-para-too-short\": \"open `deploy.description` with a paragraph longer than 80 characters\",\n \"developer-info-missing\": \"set `deploy.developer.name`\",\n \"metainfo-legacy-path\": \"this file is generated; report it as a gtkx bug\",\n \"summary-has-dot-suffix\": \"drop the trailing period from `deploy.summary`\",\n \"summary-too-long\": \"shorten `deploy.summary`\",\n \"unknown-tag\": \"remove the unsupported `deploy.metainfoExtra` element or use a `<custom>` value\",\n \"url-homepage-missing\": \"set `deploy.homepage`, or `homepage` in package.json\",\n};\n\nconst runTool = ({ tool, args, subject }: ToolRequest): ToolResult => {\n const result = spawnSync(resolveExecutable(tool), args, { encoding: \"utf8\" });\n\n if (result.error !== undefined) {\n throw new Error(`${subject} could not be validated: ${result.error.message}`, { cause: result.error });\n }\n\n return { output: [result.stdout, result.stderr].join(\"\\n\").trim(), status: result.status ?? 0 };\n};\n\nconst parseDiagnostics = (output: string): Diagnostic[] =>\n output.split(\"\\n\").flatMap((line) => {\n const groups = DIAGNOSTIC.exec(line)?.groups;\n\n return groups === undefined\n ? []\n : [{ severity: groups.severity ?? \"\", rule: groups.rule ?? \"\", detail: (groups.detail ?? \"\").trim() }];\n });\n\nconst rulesIn = (diagnostics: Diagnostic[], severities: string[]): string[] =>\n diagnostics.filter((diagnostic) => severities.includes(diagnostic.severity)).map((diagnostic) => diagnostic.rule);\n\nconst fatalNotes = (diagnostics: Diagnostic[]): string[] =>\n diagnostics\n .filter((diagnostic) => diagnostic.severity !== ERROR_SEVERITY && FATAL_WARNING_RULES.has(diagnostic.rule))\n .map((diagnostic) =>\n FATAL_RULE_NOTES[diagnostic.rule]?.(diagnostic.detail) ??\n `GTKX treats ${diagnostic.rule} as fatal for every target`);\n\nconst withoutSuccessSummary = (output: string): string =>\n output\n .split(\"\\n\")\n .filter((line) => !SUCCESS_SUMMARY.test(line))\n .join(\"\\n\")\n .trimEnd();\n\nconst remedyLines = (rules: string[]): string[] => {\n const remedies = sortStrings([...new Set(rules)])\n .filter((rule) => REMEDY_FOR_RULE[rule] !== undefined)\n .map((rule) => ` ${rule}: ${REMEDY_FOR_RULE[rule] ?? \"\"}`);\n\n return remedies.length === 0 ? [] : [\"\", \"Fix it in gtkx.config.ts:\", ...remedies];\n};\n\nconst invalid = (subject: string, output: string, rules: string[], notes: string[]): Error =>\n new Error([\n `${subject} is not valid:`,\n output.length > 0 ? output : \"no output\",\n ...notes,\n ...remedyLines(rules),\n ].join(\"\\n\"));\n\nconst isFatalResult = ({ status, errors, warnings, rules, areWarningsFatal }: MetainfoResult): boolean => {\n if (errors.length > 0) {\n return true;\n }\n\n if (rules.some((rule) => FATAL_WARNING_RULES.has(rule))) {\n return true;\n }\n\n if (areWarningsFatal && warnings.length > 0) {\n return true;\n }\n\n return status !== 0 && warnings.length === 0;\n};\n\nconst assertNotFatal = (result: MetainfoResult): void => {\n if (isFatalResult(result)) {\n throw invalid(result.subject, result.output, result.rules, result.notes);\n }\n};\n\nconst describeRule = (rule: string): string => {\n const remedy = REMEDY_FOR_RULE[rule];\n\n return remedy === undefined ? rule : `${rule} — ${remedy}`;\n};\n\nconst reportDiagnostics = (subject: string, rules: string[]): void => {\n for (const rule of rules) {\n warn(`${subject}: ${describeRule(rule)}`);\n }\n};\n\nconst validateDesktopEntry = (path: string): void => {\n const { output, status } = runTool({\n tool: \"desktop-file-validate\",\n args: [path],\n subject: \"The desktop entry\",\n });\n\n if (status !== 0 || output.length > 0) {\n throw invalid(\"The desktop entry\", output, [], []);\n }\n};\n\nconst validateMetainfo = (path: string, areWarningsFatal: boolean): void => {\n const subject = \"The AppStream metainfo\";\n\n const { output, status } = runTool({\n tool: \"appstreamcli\",\n args: [\"validate\", \"--no-net\", \"--explain\", path],\n subject,\n });\n\n const diagnostics = parseDiagnostics(output);\n const errors = rulesIn(diagnostics, [ERROR_SEVERITY]);\n const warnings = rulesIn(diagnostics, [WARNING_SEVERITY]);\n const infos = rulesIn(diagnostics, [INFO_SEVERITY]);\n const rules = [...errors, ...warnings, ...infos];\n const notes = fatalNotes(diagnostics);\n assertNotFatal({\n subject,\n output: withoutSuccessSummary(output),\n status,\n errors,\n warnings,\n rules,\n notes,\n areWarningsFatal,\n });\n reportDiagnostics(subject, [...warnings, ...infos]);\n};\n\nexport { validateDesktopEntry, validateMetainfo };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../../src/deploy/payload/stage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAa5G,KAAK,YAAY,GAAG;IAChB,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;CAC5B,CAAC;AAEF,KAAK,cAAc,GAAG;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAGF,QAAA,MAAM,gBAAgB,wBAAwB,CAAC;AAmB/C,QAAA,MAAM,kBAAkB,GAAI,UAAU,cAAc,KAAG,MAA8C,CAAC;AACtG,QAAA,MAAM,kBAAkB,GAAI,UAAU,cAAc,KAAG,MAA0D,CAAC;AAIlH,QAAA,MAAM,sBAAsB,GAAI,UAAU,cAAc,KAAG,MACe,CAAC;AA+C3E,QAAA,MAAM,YAAY,GAAI,8BAA8B,YAAY,KAAG,UAAU,EAc5E,CAAC;AA0DF,QAAA,MAAM,aAAa,GACf,UAAU,cAAc,EACxB,SAAS,aAAa,EAAE,EACxB,UAAU,cAAc,KACzB,MAAM,CAAC,gBAAgB,EAAE,UAAU,EAAE,CAKtC,CAAC;AAEH,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,cAAc,EACnB,aAAa,EACb,YAAY,GACf,CAAC"}
1
+ {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../../src/deploy/payload/stage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAa5G,KAAK,YAAY,GAAG;IAChB,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;CAC5B,CAAC;AAEF,KAAK,cAAc,GAAG;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAGF,QAAA,MAAM,gBAAgB,wBAAwB,CAAC;AAmB/C,QAAA,MAAM,kBAAkB,GAAI,UAAU,cAAc,KAAG,MAA8C,CAAC;AACtG,QAAA,MAAM,kBAAkB,GAAI,UAAU,cAAc,KAAG,MAA0D,CAAC;AAIlH,QAAA,MAAM,sBAAsB,GAAI,UAAU,cAAc,KAAG,MACe,CAAC;AAsF3E,QAAA,MAAM,YAAY,GAAI,8BAA8B,YAAY,KAAG,UAAU,EAc5E,CAAC;AA0DF,QAAA,MAAM,aAAa,GACf,UAAU,cAAc,EACxB,SAAS,aAAa,EAAE,EACxB,UAAU,cAAc,KACzB,MAAM,CAAC,gBAAgB,EAAE,UAAU,EAAE,CAKtC,CAAC;AAEH,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,cAAc,EACnB,aAAa,EACb,YAAY,GACf,CAAC"}
@@ -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 { LOCALE_DIRNAME } from "../../i18n/catalogs.js";
@@ -54,8 +54,29 @@ const stageMetadata = (settings, root, metadata) => [
54
54
  ? []
55
55
  : [writeInto(root, join(SHARE_MIME_PACKAGES, `${settings.applicationId}.xml`), metadata.mimePackage)]),
56
56
  ];
57
- const stageExtraFiles = (settings, root) => settings.extraFiles.map((file) => {
57
+ const generatedMetadataKind = (settings, metadata, destination) => {
58
+ if (destination === join(SHARE_APPLICATIONS, `${settings.applicationId}.desktop`)) {
59
+ return "desktop entry";
60
+ }
61
+ if (destination === join(SHARE_METAINFO, `${settings.applicationId}.metainfo.xml`)) {
62
+ return "metainfo";
63
+ }
64
+ if (metadata.mimePackage !== null &&
65
+ destination === join(SHARE_MIME_PACKAGES, `${settings.applicationId}.xml`)) {
66
+ return "MIME package";
67
+ }
68
+ return null;
69
+ };
70
+ const warnMetadataCollision = (settings, metadata, file) => {
71
+ const kind = generatedMetadataKind(settings, metadata, file.destination);
72
+ if (kind !== null) {
73
+ warn(`extraFiles source "${file.source}" targeting "${file.destination}" is overridden by the ` +
74
+ `GTKX-generated ${kind}`);
75
+ }
76
+ };
77
+ const stageExtraFiles = (settings, root, metadata) => settings.extraFiles.map((file) => {
58
78
  const source = resolve(settings.paths.root, file.source);
79
+ warnMetadataCollision(settings, metadata, file);
59
80
  return copyInto(root, file.destination, source, file.mode ?? executableModeFor(source));
60
81
  });
61
82
  const byRelativePath = (files) => {
@@ -73,7 +94,7 @@ const stagePayload = ({ settings, node, metadata }) => {
73
94
  ...stageNodeBinary(settings, root, node),
74
95
  ...stageRuntimeFiles(settings, root),
75
96
  ...stageCatalogs(settings, root),
76
- ...stageExtraFiles(settings, root),
97
+ ...stageExtraFiles(settings, root, metadata),
77
98
  ...stageMetadata(settings, root, metadata),
78
99
  ...stageIcons(settings, root),
79
100
  ...stageSchemas(settings, root),
@@ -1 +1 @@
1
- {"version":3,"file":"stage.js","sourceRoot":"","sources":["../../../src/deploy/payload/stage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAc5C,MAAM,cAAc,GAAG,OAAO,CAAC;AAC/B,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAC/C,MAAM,qBAAqB,GAAG,SAAS,CAAC;AACxC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAChD,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAClD,MAAM,SAAS,GAAG,WAAW,CAAC;AAC9B,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AACpD,MAAM,YAAY,GAAG,SAAS,cAAc,EAAE,CAAC;AAE/C,MAAM,UAAU,GAAqC;IACjD,QAAQ,EAAE,MAAM;IAChB,GAAG,EAAE,MAAM;IACX,OAAO,EAAE,MAAM;IACf,GAAG,EAAE,MAAM;CACd,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,QAAwB,EAAU,EAAE,CAAC,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC;AACrF,MAAM,aAAa,GAAG,CAAC,QAAwB,EAAU,EAAE,CAAC,GAAG,cAAc,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;AACvG,MAAM,kBAAkB,GAAG,CAAC,QAAwB,EAAU,EAAE,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC;AACtG,MAAM,kBAAkB,GAAG,CAAC,QAAwB,EAAU,EAAE,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,gBAAgB,EAAE,CAAC;AAClH,MAAM,WAAW,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,GAAG,KAAK,cAAc,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC;AAC7G,MAAM,aAAa,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,GAAG,KAAK,cAAc,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC;AAE/G,MAAM,sBAAsB,GAAG,CAAC,QAAwB,EAAU,EAAE,CAChE,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,aAAa,IAAI,qBAAqB,EAAE,CAAC;AAE3E,MAAM,iBAAiB,GAAG,CAAC,QAAwB,EAAE,IAAY,EAAgB,EAAE;IAC/E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;IAEjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,wCAAwC,CAAC,CAAC;IAC3G,CAAC;IAED,OAAO,kBAAkB,CAAC,IAAI,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CACb,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,uBAAuB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAC9F,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAC1F,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,QAAwB,EAAE,IAAY,EAAgB,EAAE,CAC3E,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;KACxD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAEnF,MAAM,eAAe,GAAG,CAAC,QAAwB,EAAE,IAAY,EAAE,IAAwB,EAAgB,EAAE,CACvG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;AAEhH,MAAM,aAAa,GAAG,CAAC,QAAwB,EAAE,IAAY,EAAE,QAAwB,EAAgB,EAAE,CAAC;IACtG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,GAAG,QAAQ,CAAC,aAAa,UAAU,CAAC,EAAE,QAAQ,CAAC,YAAY,CAAC;IACrG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,aAAa,eAAe,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAClG,GAAG,CAAC,QAAQ,CAAC,WAAW,KAAK,IAAI;QAC7B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,mBAAmB,EAAE,GAAG,QAAQ,CAAC,aAAa,MAAM,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;CAC7G,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,QAAwB,EAAE,IAAY,EAAgB,EAAE,CAC7E,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEzD,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5F,CAAC,CAAC,CAAC;AAEP,MAAM,cAAc,GAAG,CAAC,KAAmB,EAAgB,EAAE;IACzD,MAAM,MAAM,GAA4B,IAAI,GAAG,EAAE,CAAC;IAElD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAgB,EAAgB,EAAE;IAC9E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;IAClC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAE9D,OAAO,cAAc,CAAC;QAClB,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;QAC5F,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC;QACxC,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC;QACpC,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC;QAChC,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC;QAClC,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC;QAC1C,GAAG,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC;QAC7B,GAAG,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC;KAClC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,YAAoB,EAAU,EAAE,CAC3D,YAAY;KACP,KAAK,CAAC,IAAI,CAAC;KACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,sBAAsB,CAAC;KACjD,IAAI,CAAC,IAAI,CAAC,CAAC;AAEpB,MAAM,eAAe,GAAG,CACpB,QAAwB,EACxB,IAAY,EACZ,MAAwB,EACxB,QAAwB,EACZ,EAAE;IACd,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACd,CAAC;IAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QACxB,OAAO,CAAC,SAAS,CACb,IAAI,EACJ,IAAI,CAAC,kBAAkB,EAAE,GAAG,QAAQ,CAAC,aAAa,UAAU,CAAC,EAC7D,qBAAqB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAC/C,CAAC,CAAC;IACP,CAAC;IAED,OAAO,CAAC,SAAS,CACb,IAAI,EACJ,IAAI,CAAC,mBAAmB,EAAE,GAAG,QAAQ,CAAC,aAAa,UAAU,CAAC,EAC9D,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAClD,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CACjB,QAAwB,EACxB,MAAwB,EACxB,OAAwB,EACxB,QAAwB,EACZ,EAAE;IACd,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;IAC/C,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAErE,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO;YACH,GAAG,UAAU;YACb,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;SACzG,CAAC;IACN,CAAC;IAED,OAAO;QACH,GAAG,UAAU;QACb,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;QAC5F,SAAS,CAAC,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;KAClF,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAClB,QAAwB,EACxB,OAAwB,EACxB,QAAwB,EACc,EAAE,CAAC,CAAC;IAC1C,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC;IAC/D,GAAG,EAAE,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC;IACrD,OAAO,EAAE,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC;IAC7D,GAAG,EAAE,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC;CACxD,CAAC,CAAC;AAEH,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAElB,aAAa,EACb,YAAY,GACf,CAAC","sourcesContent":["import { sortStringsBy } from \"@gtkx/utils\";\nimport { existsSync, rmSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { DeploySettings, DeployTargetName, NodeRuntime, NoticeSection, StagedFile } from \"../types.js\";\nimport { LOCALE_DIRNAME } from \"../../i18n/catalogs.js\";\nimport { BUILD_MANIFEST_FILENAME } from \"../../internal/build-manifest.js\";\nimport { listFilesRecursive } from \"../../internal/list-files.js\";\nimport { BUNDLE_FILENAME } from \"../../vite-plugins/esm-extension.js\";\nimport { renderCopyright } from \"../freedesktop/copyright.js\";\nimport { renderDbusService } from \"../freedesktop/dbus-service.js\";\nimport { renderNotices } from \"../notices/render.js\";\nimport { copyInto, EXECUTABLE_MODE, executableModeFor, writeInto } from \"./copy-tree.js\";\nimport { stageIcons } from \"./icons.js\";\nimport { NODE_FILENAME, renderLauncher } from \"./launcher.js\";\nimport { stageSchemas } from \"./schemas.js\";\n\ntype StageRequest = {\n settings: DeploySettings;\n node: NodeRuntime | null;\n metadata: StagedMetadata;\n};\n\ntype StagedMetadata = {\n desktopEntry: string;\n metainfo: string;\n mimePackage: string | null;\n};\n\nconst DIST_ICONS_DIR = \"icons\";\nconst NOTICES_FILENAME = \"THIRD-PARTY-NOTICES\";\nconst NODE_LICENSE_FILENAME = \"LICENSE\";\nconst SHARE_APPLICATIONS = \"share/applications\";\nconst SHARE_METAINFO = \"share/metainfo\";\nconst SHARE_MIME_PACKAGES = \"share/mime/packages\";\nconst SHARE_DOC = \"share/doc\";\nconst SHARE_LICENSES = \"share/licenses\";\nconst SHARE_DBUS_SERVICES = \"share/dbus-1/services\";\nconst SHARE_LOCALE = `share/${LOCALE_DIRNAME}`;\n\nconst PREFIX_FOR: Record<DeployTargetName, string> = {\n appimage: \"/usr\",\n deb: \"/usr\",\n flatpak: \"/app\",\n rpm: \"/usr\",\n};\n\nconst libDirFor = (settings: DeploySettings): string => `lib/${settings.binaryName}`;\nconst licenseDirFor = (settings: DeploySettings): string => `${SHARE_LICENSES}/${settings.binaryName}`;\nconst licenseDestination = (settings: DeploySettings): string => `${licenseDirFor(settings)}/LICENSE`;\nconst noticesDestination = (settings: DeploySettings): string => `${licenseDirFor(settings)}/${NOTICES_FILENAME}`;\nconst isIconAsset = (rel: string): boolean => rel === DIST_ICONS_DIR || rel.startsWith(`${DIST_ICONS_DIR}/`);\nconst isLocaleAsset = (rel: string): boolean => rel === LOCALE_DIRNAME || rel.startsWith(`${LOCALE_DIRNAME}/`);\n\nconst nodeLicenseDestination = (settings: DeploySettings): string =>\n `${licenseDirFor(settings)}/${NODE_FILENAME}/${NODE_LICENSE_FILENAME}`;\n\nconst stageRuntimeFiles = (settings: DeploySettings, root: string): StagedFile[] => {\n const dist = settings.paths.dist;\n\n if (!existsSync(join(dist, BUNDLE_FILENAME))) {\n throw new Error(`Cannot deploy: ${join(dist, BUNDLE_FILENAME)} is missing. Run \\`gtkx build\\` first.`);\n }\n\n return listFilesRecursive(dist)\n .filter((file) =>\n !isIconAsset(file.rel) && file.rel !== BUILD_MANIFEST_FILENAME && !isLocaleAsset(file.rel))\n .map((file) => copyInto(root, join(libDirFor(settings), file.rel), file.absPath));\n};\n\nconst stageCatalogs = (settings: DeploySettings, root: string): StagedFile[] =>\n listFilesRecursive(join(settings.paths.dist, LOCALE_DIRNAME))\n .map((file) => copyInto(root, join(SHARE_LOCALE, file.rel), file.absPath));\n\nconst stageNodeBinary = (settings: DeploySettings, root: string, node: NodeRuntime | null): StagedFile[] =>\n node === null ? [] : [copyInto(root, join(libDirFor(settings), NODE_FILENAME), node.path, EXECUTABLE_MODE)];\n\nconst stageMetadata = (settings: DeploySettings, root: string, metadata: StagedMetadata): StagedFile[] => [\n writeInto(root, join(SHARE_APPLICATIONS, `${settings.applicationId}.desktop`), metadata.desktopEntry),\n writeInto(root, join(SHARE_METAINFO, `${settings.applicationId}.metainfo.xml`), metadata.metainfo),\n ...(metadata.mimePackage === null\n ? []\n : [writeInto(root, join(SHARE_MIME_PACKAGES, `${settings.applicationId}.xml`), metadata.mimePackage)]),\n];\n\nconst stageExtraFiles = (settings: DeploySettings, root: string): StagedFile[] =>\n settings.extraFiles.map((file) => {\n const source = resolve(settings.paths.root, file.source);\n\n return copyInto(root, file.destination, source, file.mode ?? executableModeFor(source));\n });\n\nconst byRelativePath = (files: StagedFile[]): StagedFile[] => {\n const latest: Map<string, StagedFile> = new Map();\n\n for (const file of files) {\n latest.set(file.rel, file);\n }\n\n return sortStringsBy(latest.values(), (file) => file.rel);\n};\n\nconst stagePayload = ({ settings, node, metadata }: StageRequest): StagedFile[] => {\n const root = settings.paths.stage;\n rmSync(root, { recursive: true, force: true, maxRetries: 5 });\n\n return byRelativePath([\n writeInto(root, join(\"bin\", settings.binaryName), renderLauncher(settings), EXECUTABLE_MODE),\n ...stageNodeBinary(settings, root, node),\n ...stageRuntimeFiles(settings, root),\n ...stageCatalogs(settings, root),\n ...stageExtraFiles(settings, root),\n ...stageMetadata(settings, root, metadata),\n ...stageIcons(settings, root),\n ...stageSchemas(settings, root),\n ]);\n};\n\nconst withoutDbusActivation = (desktopEntry: string): string =>\n desktopEntry\n .split(\"\\n\")\n .filter((line) => line !== \"DBusActivatable=true\")\n .join(\"\\n\");\n\nconst stageActivation = (\n settings: DeploySettings,\n root: string,\n target: DeployTargetName,\n metadata: StagedMetadata,\n): StagedFile[] => {\n if (!settings.isDbusActivatable) {\n return [];\n }\n\n if (target === \"appimage\") {\n return [writeInto(\n root,\n join(SHARE_APPLICATIONS, `${settings.applicationId}.desktop`),\n withoutDbusActivation(metadata.desktopEntry),\n )];\n }\n\n return [writeInto(\n root,\n join(SHARE_DBUS_SERVICES, `${settings.applicationId}.service`),\n renderDbusService(settings, PREFIX_FOR[target]),\n )];\n};\n\nconst stageOverlay = (\n settings: DeploySettings,\n target: DeployTargetName,\n notices: NoticeSection[],\n metadata: StagedMetadata,\n): StagedFile[] => {\n const root = join(settings.paths.overlay, target);\n rmSync(root, { recursive: true, force: true, maxRetries: 5 });\n const licenseFile = settings.paths.licenseFile;\n const activation = stageActivation(settings, root, target, metadata);\n\n if (target === \"deb\") {\n return [\n ...activation,\n writeInto(root, join(SHARE_DOC, settings.binaryName, \"copyright\"), renderCopyright(settings, notices)),\n ];\n }\n\n return [\n ...activation,\n ...(licenseFile === null ? [] : [copyInto(root, licenseDestination(settings), licenseFile)]),\n writeInto(root, noticesDestination(settings), renderNotices(settings, notices)),\n ];\n};\n\nconst stageOverlays = (\n settings: DeploySettings,\n notices: NoticeSection[],\n metadata: StagedMetadata,\n): Record<DeployTargetName, StagedFile[]> => ({\n appimage: stageOverlay(settings, \"appimage\", notices, metadata),\n deb: stageOverlay(settings, \"deb\", notices, metadata),\n flatpak: stageOverlay(settings, \"flatpak\", notices, metadata),\n rpm: stageOverlay(settings, \"rpm\", notices, metadata),\n});\n\nexport {\n licenseDestination,\n nodeLicenseDestination,\n NOTICES_FILENAME,\n noticesDestination,\n type StagedMetadata,\n stageOverlays,\n stagePayload,\n};\n"]}
1
+ {"version":3,"file":"stage.js","sourceRoot":"","sources":["../../../src/deploy/payload/stage.ts"],"names":[],"mappings":"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","sourcesContent":["import { sortStringsBy, warn } from \"@gtkx/utils\";\nimport { existsSync, rmSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { DeploySettings, DeployTargetName, NodeRuntime, NoticeSection, StagedFile } from \"../types.js\";\nimport { LOCALE_DIRNAME } from \"../../i18n/catalogs.js\";\nimport { BUILD_MANIFEST_FILENAME } from \"../../internal/build-manifest.js\";\nimport { listFilesRecursive } from \"../../internal/list-files.js\";\nimport { BUNDLE_FILENAME } from \"../../vite-plugins/esm-extension.js\";\nimport { renderCopyright } from \"../freedesktop/copyright.js\";\nimport { renderDbusService } from \"../freedesktop/dbus-service.js\";\nimport { renderNotices } from \"../notices/render.js\";\nimport { copyInto, EXECUTABLE_MODE, executableModeFor, writeInto } from \"./copy-tree.js\";\nimport { stageIcons } from \"./icons.js\";\nimport { NODE_FILENAME, renderLauncher } from \"./launcher.js\";\nimport { stageSchemas } from \"./schemas.js\";\n\ntype StageRequest = {\n settings: DeploySettings;\n node: NodeRuntime | null;\n metadata: StagedMetadata;\n};\n\ntype StagedMetadata = {\n desktopEntry: string;\n metainfo: string;\n mimePackage: string | null;\n};\n\nconst DIST_ICONS_DIR = \"icons\";\nconst NOTICES_FILENAME = \"THIRD-PARTY-NOTICES\";\nconst NODE_LICENSE_FILENAME = \"LICENSE\";\nconst SHARE_APPLICATIONS = \"share/applications\";\nconst SHARE_METAINFO = \"share/metainfo\";\nconst SHARE_MIME_PACKAGES = \"share/mime/packages\";\nconst SHARE_DOC = \"share/doc\";\nconst SHARE_LICENSES = \"share/licenses\";\nconst SHARE_DBUS_SERVICES = \"share/dbus-1/services\";\nconst SHARE_LOCALE = `share/${LOCALE_DIRNAME}`;\n\nconst PREFIX_FOR: Record<DeployTargetName, string> = {\n appimage: \"/usr\",\n deb: \"/usr\",\n flatpak: \"/app\",\n rpm: \"/usr\",\n};\n\nconst libDirFor = (settings: DeploySettings): string => `lib/${settings.binaryName}`;\nconst licenseDirFor = (settings: DeploySettings): string => `${SHARE_LICENSES}/${settings.binaryName}`;\nconst licenseDestination = (settings: DeploySettings): string => `${licenseDirFor(settings)}/LICENSE`;\nconst noticesDestination = (settings: DeploySettings): string => `${licenseDirFor(settings)}/${NOTICES_FILENAME}`;\nconst isIconAsset = (rel: string): boolean => rel === DIST_ICONS_DIR || rel.startsWith(`${DIST_ICONS_DIR}/`);\nconst isLocaleAsset = (rel: string): boolean => rel === LOCALE_DIRNAME || rel.startsWith(`${LOCALE_DIRNAME}/`);\n\nconst nodeLicenseDestination = (settings: DeploySettings): string =>\n `${licenseDirFor(settings)}/${NODE_FILENAME}/${NODE_LICENSE_FILENAME}`;\n\nconst stageRuntimeFiles = (settings: DeploySettings, root: string): StagedFile[] => {\n const dist = settings.paths.dist;\n\n if (!existsSync(join(dist, BUNDLE_FILENAME))) {\n throw new Error(`Cannot deploy: ${join(dist, BUNDLE_FILENAME)} is missing. Run \\`gtkx build\\` first.`);\n }\n\n return listFilesRecursive(dist)\n .filter((file) =>\n !isIconAsset(file.rel) && file.rel !== BUILD_MANIFEST_FILENAME && !isLocaleAsset(file.rel))\n .map((file) => copyInto(root, join(libDirFor(settings), file.rel), file.absPath));\n};\n\nconst stageCatalogs = (settings: DeploySettings, root: string): StagedFile[] =>\n listFilesRecursive(join(settings.paths.dist, LOCALE_DIRNAME))\n .map((file) => copyInto(root, join(SHARE_LOCALE, file.rel), file.absPath));\n\nconst stageNodeBinary = (settings: DeploySettings, root: string, node: NodeRuntime | null): StagedFile[] =>\n node === null ? [] : [copyInto(root, join(libDirFor(settings), NODE_FILENAME), node.path, EXECUTABLE_MODE)];\n\nconst stageMetadata = (settings: DeploySettings, root: string, metadata: StagedMetadata): StagedFile[] => [\n writeInto(root, join(SHARE_APPLICATIONS, `${settings.applicationId}.desktop`), metadata.desktopEntry),\n writeInto(root, join(SHARE_METAINFO, `${settings.applicationId}.metainfo.xml`), metadata.metainfo),\n ...(metadata.mimePackage === null\n ? []\n : [writeInto(root, join(SHARE_MIME_PACKAGES, `${settings.applicationId}.xml`), metadata.mimePackage)]),\n];\n\nconst generatedMetadataKind = (\n settings: DeploySettings,\n metadata: StagedMetadata,\n destination: string,\n): string | null => {\n if (destination === join(SHARE_APPLICATIONS, `${settings.applicationId}.desktop`)) {\n return \"desktop entry\";\n }\n\n if (destination === join(SHARE_METAINFO, `${settings.applicationId}.metainfo.xml`)) {\n return \"metainfo\";\n }\n\n if (\n metadata.mimePackage !== null &&\n destination === join(SHARE_MIME_PACKAGES, `${settings.applicationId}.xml`)\n ) {\n return \"MIME package\";\n }\n\n return null;\n};\n\nconst warnMetadataCollision = (\n settings: DeploySettings,\n metadata: StagedMetadata,\n file: DeploySettings[\"extraFiles\"][number],\n): void => {\n const kind = generatedMetadataKind(settings, metadata, file.destination);\n\n if (kind !== null) {\n warn(\n `extraFiles source \"${file.source}\" targeting \"${file.destination}\" is overridden by the ` +\n `GTKX-generated ${kind}`,\n );\n }\n};\n\nconst stageExtraFiles = (settings: DeploySettings, root: string, metadata: StagedMetadata): StagedFile[] =>\n settings.extraFiles.map((file) => {\n const source = resolve(settings.paths.root, file.source);\n warnMetadataCollision(settings, metadata, file);\n\n return copyInto(root, file.destination, source, file.mode ?? executableModeFor(source));\n });\n\nconst byRelativePath = (files: StagedFile[]): StagedFile[] => {\n const latest: Map<string, StagedFile> = new Map();\n\n for (const file of files) {\n latest.set(file.rel, file);\n }\n\n return sortStringsBy(latest.values(), (file) => file.rel);\n};\n\nconst stagePayload = ({ settings, node, metadata }: StageRequest): StagedFile[] => {\n const root = settings.paths.stage;\n rmSync(root, { recursive: true, force: true, maxRetries: 5 });\n\n return byRelativePath([\n writeInto(root, join(\"bin\", settings.binaryName), renderLauncher(settings), EXECUTABLE_MODE),\n ...stageNodeBinary(settings, root, node),\n ...stageRuntimeFiles(settings, root),\n ...stageCatalogs(settings, root),\n ...stageExtraFiles(settings, root, metadata),\n ...stageMetadata(settings, root, metadata),\n ...stageIcons(settings, root),\n ...stageSchemas(settings, root),\n ]);\n};\n\nconst withoutDbusActivation = (desktopEntry: string): string =>\n desktopEntry\n .split(\"\\n\")\n .filter((line) => line !== \"DBusActivatable=true\")\n .join(\"\\n\");\n\nconst stageActivation = (\n settings: DeploySettings,\n root: string,\n target: DeployTargetName,\n metadata: StagedMetadata,\n): StagedFile[] => {\n if (!settings.isDbusActivatable) {\n return [];\n }\n\n if (target === \"appimage\") {\n return [writeInto(\n root,\n join(SHARE_APPLICATIONS, `${settings.applicationId}.desktop`),\n withoutDbusActivation(metadata.desktopEntry),\n )];\n }\n\n return [writeInto(\n root,\n join(SHARE_DBUS_SERVICES, `${settings.applicationId}.service`),\n renderDbusService(settings, PREFIX_FOR[target]),\n )];\n};\n\nconst stageOverlay = (\n settings: DeploySettings,\n target: DeployTargetName,\n notices: NoticeSection[],\n metadata: StagedMetadata,\n): StagedFile[] => {\n const root = join(settings.paths.overlay, target);\n rmSync(root, { recursive: true, force: true, maxRetries: 5 });\n const licenseFile = settings.paths.licenseFile;\n const activation = stageActivation(settings, root, target, metadata);\n\n if (target === \"deb\") {\n return [\n ...activation,\n writeInto(root, join(SHARE_DOC, settings.binaryName, \"copyright\"), renderCopyright(settings, notices)),\n ];\n }\n\n return [\n ...activation,\n ...(licenseFile === null ? [] : [copyInto(root, licenseDestination(settings), licenseFile)]),\n writeInto(root, noticesDestination(settings), renderNotices(settings, notices)),\n ];\n};\n\nconst stageOverlays = (\n settings: DeploySettings,\n notices: NoticeSection[],\n metadata: StagedMetadata,\n): Record<DeployTargetName, StagedFile[]> => ({\n appimage: stageOverlay(settings, \"appimage\", notices, metadata),\n deb: stageOverlay(settings, \"deb\", notices, metadata),\n flatpak: stageOverlay(settings, \"flatpak\", notices, metadata),\n rpm: stageOverlay(settings, \"rpm\", notices, metadata),\n});\n\nexport {\n licenseDestination,\n nodeLicenseDestination,\n NOTICES_FILENAME,\n noticesDestination,\n type StagedMetadata,\n stageOverlays,\n stagePayload,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"extra-files.d.ts","sourceRoot":"","sources":["../../../src/deploy/settings/extra-files.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA+BjE,QAAA,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,QAAQ,YAAY,KAAG,eAAe,EAS9E,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"extra-files.d.ts","sourceRoot":"","sources":["../../../src/deploy/settings/extra-files.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAiCjE,QAAA,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,QAAQ,YAAY,KAAG,eAAe,EAS9E,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { statSync } from "node:fs";
2
- import { resolve } from "node:path";
2
+ import { normalize, resolve } from "node:path";
3
3
  const OCTAL_RADIX = 8;
4
4
  const assertSourceFile = (root, file) => {
5
5
  const source = resolve(root, file.source);
@@ -14,11 +14,12 @@ const assertSourceFile = (root, file) => {
14
14
  throw new Error(`Cannot install "${file.destination}": its source "${file.source}" is not a file`);
15
15
  };
16
16
  const resolveExtraFile = (destination, entry) => {
17
+ const normalizedDestination = normalize(destination);
17
18
  if (typeof entry === "string") {
18
- return { destination, source: entry, mode: null };
19
+ return { destination: normalizedDestination, source: entry, mode: null };
19
20
  }
20
21
  const mode = entry.mode === undefined ? null : Number.parseInt(entry.mode, OCTAL_RADIX);
21
- return { destination, source: entry.source, mode };
22
+ return { destination: normalizedDestination, source: entry.source, mode };
22
23
  };
23
24
  const resolveExtraFiles = (root, deploy) => {
24
25
  const files = Object.entries(deploy.extraFiles ?? {})
@@ -1 +1 @@
1
- {"version":3,"file":"extra-files.js","sourceRoot":"","sources":["../../../src/deploy/settings/extra-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,IAAqB,EAAQ,EAAE;IACnE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5B,OAAO;QACX,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,WAAW,uBAAuB,IAAI,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAC7G,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,WAAW,kBAAkB,IAAI,CAAC,MAAM,iBAAiB,CAAC,CAAC;AACvG,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,WAAmB,EAAE,KAAqB,EAAmB,EAAE;IACrF,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAExF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,MAAoB,EAAqB,EAAE;IAChF,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAEzE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import { statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { DeployConfig, DeployExtraFile } from \"../types.js\";\n\ntype ExtraFiles = NonNullable<DeployConfig[\"extraFiles\"]>;\ntype ExtraFileEntry = NonNullable<ExtraFiles[string]>;\n\nconst OCTAL_RADIX = 8;\n\nconst assertSourceFile = (root: string, file: DeployExtraFile): void => {\n const source = resolve(root, file.source);\n\n try {\n if (statSync(source).isFile()) {\n return;\n }\n } catch {\n throw new Error(`Cannot install \"${file.destination}\": its source file \"${file.source}\" does not exist`);\n }\n\n throw new Error(`Cannot install \"${file.destination}\": its source \"${file.source}\" is not a file`);\n};\n\nconst resolveExtraFile = (destination: string, entry: ExtraFileEntry): DeployExtraFile => {\n if (typeof entry === \"string\") {\n return { destination, source: entry, mode: null };\n }\n\n const mode = entry.mode === undefined ? null : Number.parseInt(entry.mode, OCTAL_RADIX);\n\n return { destination, source: entry.source, mode };\n};\n\nconst resolveExtraFiles = (root: string, deploy: DeployConfig): DeployExtraFile[] => {\n const files = Object.entries(deploy.extraFiles ?? {})\n .map(([destination, entry]) => resolveExtraFile(destination, entry));\n\n for (const file of files) {\n assertSourceFile(root, file);\n }\n\n return files;\n};\n\nexport { resolveExtraFiles };\n"]}
1
+ {"version":3,"file":"extra-files.js","sourceRoot":"","sources":["../../../src/deploy/settings/extra-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAM/C,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,IAAqB,EAAQ,EAAE;IACnE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5B,OAAO;QACX,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,WAAW,uBAAuB,IAAI,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAC7G,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,WAAW,kBAAkB,IAAI,CAAC,MAAM,iBAAiB,CAAC,CAAC;AACvG,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,WAAmB,EAAE,KAAqB,EAAmB,EAAE;IACrF,MAAM,qBAAqB,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAErD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC7E,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAExF,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AAC9E,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,MAAoB,EAAqB,EAAE;IAChF,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAEzE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import { statSync } from \"node:fs\";\nimport { normalize, resolve } from \"node:path\";\nimport type { DeployConfig, DeployExtraFile } from \"../types.js\";\n\ntype ExtraFiles = NonNullable<DeployConfig[\"extraFiles\"]>;\ntype ExtraFileEntry = NonNullable<ExtraFiles[string]>;\n\nconst OCTAL_RADIX = 8;\n\nconst assertSourceFile = (root: string, file: DeployExtraFile): void => {\n const source = resolve(root, file.source);\n\n try {\n if (statSync(source).isFile()) {\n return;\n }\n } catch {\n throw new Error(`Cannot install \"${file.destination}\": its source file \"${file.source}\" does not exist`);\n }\n\n throw new Error(`Cannot install \"${file.destination}\": its source \"${file.source}\" is not a file`);\n};\n\nconst resolveExtraFile = (destination: string, entry: ExtraFileEntry): DeployExtraFile => {\n const normalizedDestination = normalize(destination);\n\n if (typeof entry === \"string\") {\n return { destination: normalizedDestination, source: entry, mode: null };\n }\n\n const mode = entry.mode === undefined ? null : Number.parseInt(entry.mode, OCTAL_RADIX);\n\n return { destination: normalizedDestination, source: entry.source, mode };\n};\n\nconst resolveExtraFiles = (root: string, deploy: DeployConfig): DeployExtraFile[] => {\n const files = Object.entries(deploy.extraFiles ?? {})\n .map(([destination, entry]) => resolveExtraFile(destination, entry));\n\n for (const file of files) {\n assertSourceFile(root, file);\n }\n\n return files;\n};\n\nexport { resolveExtraFiles };\n"]}
@@ -0,0 +1,8 @@
1
+ import type { WrittenCatalog } from "../i18n/catalogs.js";
2
+ type CatalogWrites = {
3
+ record: (catalogs: WrittenCatalog[]) => void;
4
+ hasWritten: (path: string) => boolean;
5
+ };
6
+ declare const createCatalogWrites: () => CatalogWrites;
7
+ export { type CatalogWrites, createCatalogWrites };
8
+ //# sourceMappingURL=catalog-writes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-writes.d.ts","sourceRoot":"","sources":["../../src/dev/catalog-writes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,KAAK,aAAa,GAAG;IACjB,MAAM,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAC7C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACzC,CAAC;AAUF,QAAA,MAAM,mBAAmB,QAAO,aAe/B,CAAC;AAEF,OAAO,EAAE,KAAK,aAAa,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ const hasContent = (path, content) => {
4
+ try {
5
+ return readFileSync(path).equals(content);
6
+ }
7
+ catch {
8
+ return false;
9
+ }
10
+ };
11
+ const createCatalogWrites = () => {
12
+ const contents = new Map();
13
+ return {
14
+ record: (catalogs) => {
15
+ for (const catalog of catalogs) {
16
+ contents.set(resolve(catalog.path), catalog.content);
17
+ }
18
+ },
19
+ hasWritten: (path) => {
20
+ const content = contents.get(resolve(path));
21
+ return content !== undefined && hasContent(path, content);
22
+ },
23
+ };
24
+ };
25
+ export { createCatalogWrites };
26
+ //# sourceMappingURL=catalog-writes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-writes.js","sourceRoot":"","sources":["../../src/dev/catalog-writes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,OAAe,EAAW,EAAE;IAC1D,IAAI,CAAC;QACD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,GAAkB,EAAE;IAC5C,MAAM,QAAQ,GAAwB,IAAI,GAAG,EAAE,CAAC;IAEhD,OAAO;QACH,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE;YACjB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC7B,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YACzD,CAAC;QACL,CAAC;QACD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;YACjB,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAE5C,OAAO,OAAO,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9D,CAAC;KACJ,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAsB,mBAAmB,EAAE,CAAC","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { WrittenCatalog } from \"../i18n/catalogs.js\";\n\ntype CatalogWrites = {\n record: (catalogs: WrittenCatalog[]) => void;\n hasWritten: (path: string) => boolean;\n};\n\nconst hasContent = (path: string, content: Buffer): boolean => {\n try {\n return readFileSync(path).equals(content);\n } catch {\n return false;\n }\n};\n\nconst createCatalogWrites = (): CatalogWrites => {\n const contents: Map<string, Buffer> = new Map();\n\n return {\n record: (catalogs) => {\n for (const catalog of catalogs) {\n contents.set(resolve(catalog.path), catalog.content);\n }\n },\n hasWritten: (path) => {\n const content = contents.get(resolve(path));\n\n return content !== undefined && hasContent(path, content);\n },\n };\n};\n\nexport { type CatalogWrites, createCatalogWrites };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"runner-deps.d.ts","sourceRoot":"","sources":["../../src/dev/runner-deps.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAsCjD,QAAA,MAAM,oBAAoB,GAAI,YAAY,MAAM,KAAG,aAkDjD,CAAC;AAEH,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"runner-deps.d.ts","sourceRoot":"","sources":["../../src/dev/runner-deps.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA+FjD,QAAA,MAAM,oBAAoB,GAAI,YAAY,MAAM,KAAG,aACO,CAAC;AAE3D,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -11,6 +11,7 @@ import { isRefreshBoundary, performRefresh, staleExportName } from "../refresh-r
11
11
  import { gtkxFastRefresh } from "../vite-plugins/fast-refresh/swc-refresh.js";
12
12
  import { gtkxVitePlugins } from "../vite-plugins/index.js";
13
13
  import { gtkxReactDomPrebundle } from "../vite-plugins/react-dom-prebundle.js";
14
+ import { createCatalogWrites } from "./catalog-writes.js";
14
15
  const DEV_MODE = "development";
15
16
  const APPLICATION_POLL_INTERVAL_MS = 50;
16
17
  const currentApplicationId = () => Gio.Application.getDefault()?.applicationId ?? null;
@@ -28,7 +29,12 @@ const waitForApplicationId = async (timeoutMs, shouldKeepWaiting) => {
28
29
  return applicationId;
29
30
  };
30
31
  const readFileRevision = (path) => readFile(path, "utf8");
31
- const defaultDevRunnerDeps = (configFile) => ({
32
+ const devPlugins = (configFile, catalogWrites) => (entryPath) => [
33
+ ...gtkxVitePlugins({ mode: DEV_MODE, entryPath, configFile, onCatalogsWritten: catalogWrites.record }),
34
+ ...gtkxFastRefresh(),
35
+ gtkxReactDomPrebundle(),
36
+ ];
37
+ const createDevRunnerDeps = (configFile, catalogWrites) => ({
32
38
  createServer,
33
39
  waitForApplicationId,
34
40
  getConfiguredApplicationId: async (root) => {
@@ -67,13 +73,11 @@ const defaultDevRunnerDeps = (configFile) => ({
67
73
  isRefreshBoundary,
68
74
  staleExportName,
69
75
  readFileRevision,
70
- plugins: (entryPath) => [
71
- ...gtkxVitePlugins({ mode: DEV_MODE, entryPath, configFile }),
72
- ...gtkxFastRefresh(),
73
- gtkxReactDomPrebundle(),
74
- ],
76
+ hasWrittenCatalog: catalogWrites.hasWritten,
77
+ plugins: devPlugins(configFile, catalogWrites),
75
78
  log: info,
76
79
  exit: (code) => process.exit(code),
77
80
  });
81
+ const defaultDevRunnerDeps = (configFile) => createDevRunnerDeps(configFile, createCatalogWrites());
78
82
  export { defaultDevRunnerDeps };
79
83
  //# sourceMappingURL=runner-deps.js.map