@gtkx/cli 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +2 -0
- package/dist/builder.js.map +1 -1
- package/dist/deploy/freedesktop/copyright.d.ts +2 -2
- package/dist/deploy/freedesktop/copyright.d.ts.map +1 -1
- package/dist/deploy/freedesktop/copyright.js +105 -14
- package/dist/deploy/freedesktop/copyright.js.map +1 -1
- package/dist/deploy/node-runtime/download.d.ts +5 -1
- package/dist/deploy/node-runtime/download.d.ts.map +1 -1
- package/dist/deploy/node-runtime/download.js +6 -3
- package/dist/deploy/node-runtime/download.js.map +1 -1
- package/dist/deploy/node-runtime/index.d.ts +2 -1
- package/dist/deploy/node-runtime/index.d.ts.map +1 -1
- package/dist/deploy/node-runtime/index.js +10 -9
- package/dist/deploy/node-runtime/index.js.map +1 -1
- package/dist/deploy/node-runtime/license.d.ts +4 -0
- package/dist/deploy/node-runtime/license.d.ts.map +1 -0
- package/dist/deploy/node-runtime/license.js +19 -0
- package/dist/deploy/node-runtime/license.js.map +1 -0
- package/dist/deploy/notices/collect.d.ts +8 -0
- package/dist/deploy/notices/collect.d.ts.map +1 -0
- package/dist/deploy/notices/collect.js +17 -0
- package/dist/deploy/notices/collect.js.map +1 -0
- package/dist/deploy/notices/dependencies.d.ts +5 -0
- package/dist/deploy/notices/dependencies.d.ts.map +1 -0
- package/dist/deploy/notices/dependencies.js +39 -0
- package/dist/deploy/notices/dependencies.js.map +1 -0
- package/dist/deploy/notices/gtkx.d.ts +6 -0
- package/dist/deploy/notices/gtkx.d.ts.map +1 -0
- package/dist/deploy/notices/gtkx.js +68 -0
- package/dist/deploy/notices/gtkx.js.map +1 -0
- package/dist/deploy/notices/libraries.d.ts +4 -0
- package/dist/deploy/notices/libraries.d.ts.map +1 -0
- package/dist/deploy/notices/libraries.js +60 -0
- package/dist/deploy/notices/libraries.js.map +1 -0
- package/dist/deploy/notices/node-runtime.d.ts +4 -0
- package/dist/deploy/notices/node-runtime.d.ts.map +1 -0
- package/dist/deploy/notices/node-runtime.js +78 -0
- package/dist/deploy/notices/node-runtime.js.map +1 -0
- package/dist/deploy/notices/packages.d.ts +13 -0
- package/dist/deploy/notices/packages.d.ts.map +1 -0
- package/dist/deploy/notices/packages.js +115 -0
- package/dist/deploy/notices/packages.js.map +1 -0
- package/dist/deploy/notices/render.d.ts +4 -0
- package/dist/deploy/notices/render.d.ts.map +1 -0
- package/dist/deploy/notices/render.js +41 -0
- package/dist/deploy/notices/render.js.map +1 -0
- package/dist/deploy/notices/text.d.ts +5 -0
- package/dist/deploy/notices/text.d.ts.map +1 -0
- package/dist/deploy/notices/text.js +34 -0
- package/dist/deploy/notices/text.js.map +1 -0
- package/dist/deploy/payload/copy-tree.d.ts +2 -1
- package/dist/deploy/payload/copy-tree.d.ts.map +1 -1
- package/dist/deploy/payload/copy-tree.js +3 -1
- package/dist/deploy/payload/copy-tree.js.map +1 -1
- package/dist/deploy/payload/stage.d.ts +7 -3
- package/dist/deploy/payload/stage.d.ts.map +1 -1
- package/dist/deploy/payload/stage.js +25 -14
- package/dist/deploy/payload/stage.js.map +1 -1
- package/dist/deploy/run-deploy.d.ts.map +1 -1
- package/dist/deploy/run-deploy.js +22 -5
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/settings/extra-files.d.ts +4 -0
- package/dist/deploy/settings/extra-files.d.ts.map +1 -0
- package/dist/deploy/settings/extra-files.js +11 -0
- package/dist/deploy/settings/extra-files.js.map +1 -0
- package/dist/deploy/settings/index.d.ts.map +1 -1
- package/dist/deploy/settings/index.js +2 -1
- package/dist/deploy/settings/index.js.map +1 -1
- package/dist/deploy/settings/package-manifest.d.ts +1 -0
- package/dist/deploy/settings/package-manifest.d.ts.map +1 -1
- package/dist/deploy/settings/package-manifest.js +7 -0
- package/dist/deploy/settings/package-manifest.js.map +1 -1
- package/dist/deploy/settings/paths.d.ts +2 -1
- package/dist/deploy/settings/paths.d.ts.map +1 -1
- package/dist/deploy/settings/paths.js +1 -1
- package/dist/deploy/settings/paths.js.map +1 -1
- package/dist/deploy/targets/flatpak-manifest.d.ts +3 -1
- package/dist/deploy/targets/flatpak-manifest.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-manifest.js +50 -4
- package/dist/deploy/targets/flatpak-manifest.js.map +1 -1
- package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-source.js +55 -1
- package/dist/deploy/targets/flatpak-source.js.map +1 -1
- package/dist/deploy/types.d.ts +22 -2
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/deploy/types.js.map +1 -1
- package/dist/vite-plugins/bundled-packages.d.ts +5 -0
- package/dist/vite-plugins/bundled-packages.d.ts.map +1 -0
- package/dist/vite-plugins/bundled-packages.js +63 -0
- package/dist/vite-plugins/bundled-packages.js.map +1 -0
- package/package.json +9 -9
- package/src/builder.ts +2 -0
- package/src/deploy/freedesktop/copyright.ts +153 -18
- package/src/deploy/node-runtime/download.ts +13 -4
- package/src/deploy/node-runtime/index.ts +17 -11
- package/src/deploy/node-runtime/license.ts +24 -0
- package/src/deploy/notices/collect.ts +26 -0
- package/src/deploy/notices/dependencies.ts +53 -0
- package/src/deploy/notices/gtkx.ts +92 -0
- package/src/deploy/notices/libraries.ts +81 -0
- package/src/deploy/notices/node-runtime.ts +101 -0
- package/src/deploy/notices/packages.ts +168 -0
- package/src/deploy/notices/render.ts +52 -0
- package/src/deploy/notices/text.ts +42 -0
- package/src/deploy/payload/copy-tree.ts +5 -1
- package/src/deploy/payload/stage.ts +40 -16
- package/src/deploy/run-deploy.ts +27 -5
- package/src/deploy/settings/extra-files.ts +21 -0
- package/src/deploy/settings/index.ts +2 -1
- package/src/deploy/settings/package-manifest.ts +10 -0
- package/src/deploy/settings/paths.ts +1 -1
- package/src/deploy/targets/flatpak-manifest.ts +69 -4
- package/src/deploy/targets/flatpak-source.ts +87 -1
- package/src/deploy/types.ts +27 -1
- package/src/vite-plugins/bundled-packages.ts +95 -0
- package/LICENSE +0 -373
|
@@ -12,10 +12,76 @@ const DEFAULT_RUNTIME_VERSION = "50";
|
|
|
12
12
|
const DEFAULT_SDK = "org.gnome.Sdk";
|
|
13
13
|
const DEFAULT_FINISH_ARGS = ["--share=ipc", "--socket=wayland", "--socket=fallback-x11", "--device=dri"];
|
|
14
14
|
const DEFAULT_CLEANUP = ["/include", "/share/pkgconfig", "*.la", "*.a"];
|
|
15
|
+
const DISPLAY_SOCKETS = ["fallback-x11", "wayland", "x11"];
|
|
16
|
+
const SOCKET_ARG = "--socket=";
|
|
17
|
+
const NO_SOCKET_ARG = "--nosocket=";
|
|
18
|
+
|
|
19
|
+
const NEGATED_ARGS: [string, string][] = [
|
|
20
|
+
["--device=", "--nodevice="],
|
|
21
|
+
["--share=", "--unshare="],
|
|
22
|
+
[SOCKET_ARG, NO_SOCKET_ARG],
|
|
23
|
+
];
|
|
15
24
|
|
|
16
25
|
const branchFor = (settings: DeploySettings): string => settings.deploy.flatpak?.branch ?? DEFAULT_BRANCH;
|
|
17
26
|
const isSourceMode = (settings: DeploySettings): boolean => settings.deploy.flatpak?.mode === "source";
|
|
18
27
|
|
|
28
|
+
const negationFor = (arg: string): string | null => {
|
|
29
|
+
const negated = NEGATED_ARGS.find(([prefix]) => arg.startsWith(prefix));
|
|
30
|
+
|
|
31
|
+
if (negated === undefined) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const [prefix, negation] = negated;
|
|
36
|
+
|
|
37
|
+
return `${negation}${arg.slice(prefix.length)}`;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const mergeArgs = (defaults: string[], overrides: string[]): string[] => {
|
|
41
|
+
const kept = defaults.filter((arg) => {
|
|
42
|
+
const negation = negationFor(arg);
|
|
43
|
+
|
|
44
|
+
return negation === null || !overrides.includes(negation);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return [...new Set([...kept, ...overrides])];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const finishArgsFor = (settings: DeploySettings): string[] =>
|
|
51
|
+
mergeArgs(DEFAULT_FINISH_ARGS, settings.deploy.flatpak?.finishArgs ?? []);
|
|
52
|
+
|
|
53
|
+
const cleanupFor = (settings: DeploySettings): string[] => {
|
|
54
|
+
const cleanup = settings.deploy.flatpak?.cleanup;
|
|
55
|
+
|
|
56
|
+
if (cleanup === undefined) {
|
|
57
|
+
return DEFAULT_CLEANUP;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return cleanup.length === 0 ? [] : mergeArgs(DEFAULT_CLEANUP, cleanup);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const grantedSockets = (args: string[]): Set<string> => {
|
|
64
|
+
const granted: Set<string> = new Set();
|
|
65
|
+
|
|
66
|
+
for (const arg of args) {
|
|
67
|
+
if (arg.startsWith(SOCKET_ARG)) {
|
|
68
|
+
granted.add(arg.slice(SOCKET_ARG.length));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (arg.startsWith(NO_SOCKET_ARG)) {
|
|
72
|
+
granted.delete(arg.slice(NO_SOCKET_ARG.length));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return granted;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const hasDisplaySocket = (args: string[]): boolean => {
|
|
80
|
+
const granted = grantedSockets(args);
|
|
81
|
+
|
|
82
|
+
return DISPLAY_SOCKETS.some((socket) => granted.has(socket));
|
|
83
|
+
};
|
|
84
|
+
|
|
19
85
|
const sdkExtensionsFor = (settings: DeploySettings): string[] => {
|
|
20
86
|
const flatpak = settings.deploy.flatpak ?? {};
|
|
21
87
|
const nodeExtension = isSourceMode(settings) ? [nodeExtensionFor(settings)] : [];
|
|
@@ -46,16 +112,15 @@ const runtimeKeys = (settings: DeploySettings): FlatpakManifest => {
|
|
|
46
112
|
|
|
47
113
|
const renderFlatpakManifest = (payload: DeployPayload): FlatpakManifest => {
|
|
48
114
|
const settings = payload.settings;
|
|
49
|
-
const flatpak = settings.deploy.flatpak ?? {};
|
|
50
115
|
|
|
51
116
|
return {
|
|
52
117
|
id: settings.applicationId,
|
|
53
118
|
...runtimeKeys(settings),
|
|
54
119
|
command: settings.binaryName,
|
|
55
|
-
"finish-args":
|
|
56
|
-
cleanup:
|
|
120
|
+
"finish-args": finishArgsFor(settings),
|
|
121
|
+
cleanup: cleanupFor(settings),
|
|
57
122
|
modules: modulesFor(payload),
|
|
58
123
|
};
|
|
59
124
|
};
|
|
60
125
|
|
|
61
|
-
export { branchFor, renderFlatpakManifest };
|
|
126
|
+
export { branchFor, finishArgsFor, hasDisplaySocket, renderFlatpakManifest };
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
2
|
+
import { posix, relative, resolve } from "node:path";
|
|
2
3
|
import type { DeployPayload, DeploySettings } from "../types.js";
|
|
3
4
|
import { listFilesRecursive } from "../../internal/list-files.js";
|
|
4
5
|
import { BUNDLE_FILENAME } from "../../vite-plugins/esm-extension.js";
|
|
5
6
|
import { renderDbusService } from "../freedesktop/dbus-service.js";
|
|
6
7
|
import { renderDesktopEntry } from "../freedesktop/desktop-entry.js";
|
|
7
8
|
import { renderMetainfo } from "../freedesktop/metainfo.js";
|
|
9
|
+
import { renderMimePackage } from "../freedesktop/mime-package.js";
|
|
8
10
|
import { optional } from "../nfpm/optional.js";
|
|
11
|
+
import { renderNotices } from "../notices/render.js";
|
|
12
|
+
import { executableModeFor } from "../payload/copy-tree.js";
|
|
9
13
|
import { iconPathFor } from "../payload/icons.js";
|
|
10
14
|
import { renderLauncher } from "../payload/launcher.js";
|
|
15
|
+
import { licenseDestination, nodeLicenseDestination, NOTICES_FILENAME, noticesDestination } from "../payload/stage.js";
|
|
16
|
+
import { isInside } from "../settings/paths.js";
|
|
11
17
|
import { pnpmPathFor, type PnpmPin, pnpmSources } from "./flatpak-pnpm.js";
|
|
12
18
|
import { DESTINATION, type FlatpakModule, postInstallCommands, validationCommands } from "./flatpak-prebuilt.js";
|
|
13
19
|
import {
|
|
@@ -20,6 +26,12 @@ import {
|
|
|
20
26
|
resolveGitSource,
|
|
21
27
|
} from "./flatpak-sources.js";
|
|
22
28
|
|
|
29
|
+
type InstalledFile = {
|
|
30
|
+
destination: string;
|
|
31
|
+
source: string;
|
|
32
|
+
resolved: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
23
35
|
const LAUNCHER_FILENAME = "launcher.sh";
|
|
24
36
|
const MODULE_BUILD_ROOT = "/run/build";
|
|
25
37
|
const RUNTIME_PREFIX = "/app";
|
|
@@ -27,6 +39,7 @@ const NPM_CACHE_DIR = "flatpak-node/npm-cache";
|
|
|
27
39
|
const YARN_MIRROR_DIR = "flatpak-node/yarn-mirror";
|
|
28
40
|
const PLAIN_ARGUMENT = /^[\w./-]+$/;
|
|
29
41
|
const QUOTE_ESCAPE = String.raw`'\''`;
|
|
42
|
+
const OCTAL_RADIX = 8;
|
|
30
43
|
|
|
31
44
|
const inlineSource = (fileName: string, contents: string): FlatpakModule => ({
|
|
32
45
|
type: "inline",
|
|
@@ -74,6 +87,21 @@ const activationInstallCommands = (settings: DeploySettings): string[] =>
|
|
|
74
87
|
)]
|
|
75
88
|
: [];
|
|
76
89
|
|
|
90
|
+
const mimeSources = (settings: DeploySettings): FlatpakModule[] => {
|
|
91
|
+
const contents = renderMimePackage(settings);
|
|
92
|
+
|
|
93
|
+
return contents === null ? [] : [inlineSource(`${settings.applicationId}.xml`, contents)];
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const mimeInstallCommands = (settings: DeploySettings): string[] =>
|
|
97
|
+
settings.fileAssociations.length === 0
|
|
98
|
+
? []
|
|
99
|
+
: [installCommand(
|
|
100
|
+
`${settings.applicationId}.xml`,
|
|
101
|
+
`${DESTINATION}/share/mime/packages/${settings.applicationId}.xml`,
|
|
102
|
+
"m644",
|
|
103
|
+
)];
|
|
104
|
+
|
|
77
105
|
const metadataInstallCommands = (settings: DeploySettings): string[] => [
|
|
78
106
|
installCommand(
|
|
79
107
|
`${settings.applicationId}.desktop`,
|
|
@@ -86,6 +114,7 @@ const metadataInstallCommands = (settings: DeploySettings): string[] => [
|
|
|
86
114
|
"m644",
|
|
87
115
|
),
|
|
88
116
|
...activationInstallCommands(settings),
|
|
117
|
+
...mimeInstallCommands(settings),
|
|
89
118
|
];
|
|
90
119
|
|
|
91
120
|
const schemaInstallCommands = (settings: DeploySettings): string[] =>
|
|
@@ -120,6 +149,58 @@ const iconInstallCommands = (settings: DeploySettings): string[] => {
|
|
|
120
149
|
return listFilesRecursive(iconsDir).map((icon) => iconInstallCommand(settings, icon.absPath, icon.rel));
|
|
121
150
|
};
|
|
122
151
|
|
|
152
|
+
const assertInsideProject = (settings: DeploySettings, installed: InstalledFile): void => {
|
|
153
|
+
const { resolved } = installed;
|
|
154
|
+
const target = existsSync(resolved) ? realpathSync(resolved) : resolved;
|
|
155
|
+
|
|
156
|
+
if (isInside(settings.paths.root, target)) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Cannot install "${installed.destination}" from "${installed.source}": a source-mode manifest builds from ` +
|
|
162
|
+
`your git checkout, so every file it installs has to live inside ${settings.paths.root} and be committed. ` +
|
|
163
|
+
"Move it into the project, or drop it from the source build.",
|
|
164
|
+
);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const licenseInstallCommands = (settings: DeploySettings): string[] => {
|
|
168
|
+
const licenseFile = settings.paths.licenseFile;
|
|
169
|
+
|
|
170
|
+
if (licenseFile === null) {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const destination = licenseDestination(settings);
|
|
175
|
+
assertInsideProject(settings, { destination, source: licenseFile, resolved: licenseFile });
|
|
176
|
+
const target = `${DESTINATION}/${shellArgument(destination)}`;
|
|
177
|
+
|
|
178
|
+
return [installCommand(projectRelative(settings, licenseFile), target, "m644")];
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const noticesInstallCommands = (settings: DeploySettings): string[] => {
|
|
182
|
+
const extensionLicense = `${nodeExtensionPathFor(settings)}/LICENSE`;
|
|
183
|
+
const nodeTarget = `${DESTINATION}/${shellArgument(nodeLicenseDestination(settings))}`;
|
|
184
|
+
|
|
185
|
+
return [
|
|
186
|
+
installCommand(NOTICES_FILENAME, `${DESTINATION}/${shellArgument(noticesDestination(settings))}`, "m644"),
|
|
187
|
+
`test ! -f ${extensionLicense} || ${installCommand(extensionLicense, nodeTarget, "m644")}`,
|
|
188
|
+
];
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const extraFileInstallCommands = (settings: DeploySettings): string[] =>
|
|
192
|
+
settings.extraFiles.map((file) => {
|
|
193
|
+
const resolved = resolve(settings.paths.root, file.source);
|
|
194
|
+
assertInsideProject(settings, { destination: file.destination, source: file.source, resolved });
|
|
195
|
+
const mode = file.mode ?? executableModeFor(resolved);
|
|
196
|
+
|
|
197
|
+
return installCommand(
|
|
198
|
+
projectRelative(settings, resolved),
|
|
199
|
+
`${DESTINATION}/${shellArgument(file.destination)}`,
|
|
200
|
+
`m${mode.toString(OCTAL_RADIX)}`,
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
|
|
123
204
|
const moduleDirFor = (settings: DeploySettings): string => `${MODULE_BUILD_ROOT}/${settings.binaryName}`;
|
|
124
205
|
|
|
125
206
|
const offlineEnvFor = (manager: PackageManager, settings: DeploySettings): Record<string, string> => {
|
|
@@ -161,7 +242,9 @@ const flatpakSourceModule = (payload: DeployPayload): FlatpakModule => {
|
|
|
161
242
|
GENERATED_SOURCES,
|
|
162
243
|
inlineSource(`${settings.applicationId}.desktop`, renderDesktopEntry(settings)),
|
|
163
244
|
inlineSource(`${settings.applicationId}.metainfo.xml`, renderMetainfo(settings)),
|
|
245
|
+
...mimeSources(settings),
|
|
164
246
|
inlineSource(LAUNCHER_FILENAME, renderLauncher(settings)),
|
|
247
|
+
inlineSource(NOTICES_FILENAME, renderNotices(settings, payload.notices)),
|
|
165
248
|
...activationSource(settings),
|
|
166
249
|
],
|
|
167
250
|
"build-commands": [
|
|
@@ -171,6 +254,9 @@ const flatpakSourceModule = (payload: DeployPayload): FlatpakModule => {
|
|
|
171
254
|
...metadataInstallCommands(settings),
|
|
172
255
|
...schemaInstallCommands(settings),
|
|
173
256
|
...iconInstallCommands(settings),
|
|
257
|
+
...licenseInstallCommands(settings),
|
|
258
|
+
...noticesInstallCommands(settings),
|
|
259
|
+
...extraFileInstallCommands(settings),
|
|
174
260
|
...(settings.deploy.flatpak?.buildCommands ?? []),
|
|
175
261
|
...validationCommands(settings),
|
|
176
262
|
],
|
package/src/deploy/types.ts
CHANGED
|
@@ -19,11 +19,27 @@ type StagedFile = {
|
|
|
19
19
|
|
|
20
20
|
type NodeRuntime = {
|
|
21
21
|
path: string;
|
|
22
|
+
licenseFile: string | null;
|
|
22
23
|
version: string;
|
|
23
24
|
glibcFloor: string | null;
|
|
24
25
|
isStripped: boolean;
|
|
25
26
|
};
|
|
26
27
|
|
|
28
|
+
type Notice = {
|
|
29
|
+
subject: string;
|
|
30
|
+
license: string;
|
|
31
|
+
source: string | null;
|
|
32
|
+
copyright: string[];
|
|
33
|
+
text: string | null;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type NoticeSection = {
|
|
37
|
+
title: string;
|
|
38
|
+
files: string[];
|
|
39
|
+
summary: string[];
|
|
40
|
+
notices: Notice[];
|
|
41
|
+
};
|
|
42
|
+
|
|
27
43
|
type DeployDeveloper = {
|
|
28
44
|
id: string | null;
|
|
29
45
|
name: string;
|
|
@@ -51,6 +67,12 @@ type DeployFileAssociation = {
|
|
|
51
67
|
description: string | null;
|
|
52
68
|
};
|
|
53
69
|
|
|
70
|
+
type DeployExtraFile = {
|
|
71
|
+
destination: string;
|
|
72
|
+
source: string;
|
|
73
|
+
mode: number | null;
|
|
74
|
+
};
|
|
75
|
+
|
|
54
76
|
type DeployDesktopAction = {
|
|
55
77
|
id: string;
|
|
56
78
|
name: string;
|
|
@@ -118,7 +140,7 @@ type DeploySettings = {
|
|
|
118
140
|
desktopActions: DeployDesktopAction[];
|
|
119
141
|
desktopEntry: Record<string, string>;
|
|
120
142
|
isDbusActivatable: boolean;
|
|
121
|
-
extraFiles:
|
|
143
|
+
extraFiles: DeployExtraFile[];
|
|
122
144
|
versions: DeployVersions;
|
|
123
145
|
arch: DeployArch;
|
|
124
146
|
paths: DeployPaths;
|
|
@@ -130,6 +152,7 @@ type DeployPayload = {
|
|
|
130
152
|
settings: DeploySettings;
|
|
131
153
|
node: NodeRuntime | null;
|
|
132
154
|
stage: StagedFile[];
|
|
155
|
+
notices: NoticeSection[];
|
|
133
156
|
overlays: Record<DeployTargetName, StagedFile[]>;
|
|
134
157
|
};
|
|
135
158
|
|
|
@@ -157,6 +180,7 @@ export type {
|
|
|
157
180
|
DeployConfig,
|
|
158
181
|
DeployDesktopAction,
|
|
159
182
|
DeployDeveloper,
|
|
183
|
+
DeployExtraFile,
|
|
160
184
|
DeployFileAssociation,
|
|
161
185
|
DeployManifest,
|
|
162
186
|
DeployPaths,
|
|
@@ -169,6 +193,8 @@ export type {
|
|
|
169
193
|
DeployTool,
|
|
170
194
|
DeployVersions,
|
|
171
195
|
NodeRuntime,
|
|
196
|
+
Notice,
|
|
197
|
+
NoticeSection,
|
|
172
198
|
PackageFamily,
|
|
173
199
|
StagedFile,
|
|
174
200
|
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import { isRecord, sortStringsBy } from "@gtkx/utils";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
5
|
+
import { stripQuery } from "./strip-query.js";
|
|
6
|
+
|
|
7
|
+
type PackageIdentity = {
|
|
8
|
+
name: string;
|
|
9
|
+
version: string | null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type RecordedPackage = PackageIdentity & {
|
|
13
|
+
dir: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
type PackagesState = {
|
|
17
|
+
outDir: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const BUNDLED_PACKAGES_FILENAME = "gtkx-packages.json";
|
|
21
|
+
const MANIFEST_FILENAME = "package.json";
|
|
22
|
+
const DEFAULT_OUT_DIR = "dist";
|
|
23
|
+
const JSON_INDENT = 4;
|
|
24
|
+
|
|
25
|
+
const identityIn = (dir: string): PackageIdentity | null => {
|
|
26
|
+
try {
|
|
27
|
+
const parsed: unknown = JSON.parse(readFileSync(join(dir, MANIFEST_FILENAME), "utf8"));
|
|
28
|
+
|
|
29
|
+
if (!isRecord(parsed) || typeof parsed.name !== "string") {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return { name: parsed.name, version: typeof parsed.version === "string" ? parsed.version : null };
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const packageIn = (dir: string): RecordedPackage | null => {
|
|
40
|
+
const identity = identityIn(dir);
|
|
41
|
+
|
|
42
|
+
if (identity !== null) {
|
|
43
|
+
return { ...identity, dir };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const parent = dirname(dir);
|
|
47
|
+
|
|
48
|
+
return parent === dir ? null : packageIn(parent);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const packageForModule = (id: string): RecordedPackage | null => {
|
|
52
|
+
const path = stripQuery(id);
|
|
53
|
+
|
|
54
|
+
return path.startsWith("/") ? packageIn(dirname(path)) : null;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const keyFor = (entry: RecordedPackage): string => `${entry.name}@${entry.version ?? ""}`;
|
|
58
|
+
|
|
59
|
+
const relativeTo = (outDir: string, entry: RecordedPackage): RecordedPackage => ({
|
|
60
|
+
...entry,
|
|
61
|
+
dir: relative(outDir, entry.dir),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const renderPackages = (outDir: string, ids: string[]): string => {
|
|
65
|
+
const found = ids.map((id) => packageForModule(id)).filter((entry) => entry !== null);
|
|
66
|
+
const unique: Map<string, RecordedPackage> = new Map(found.map((entry) => [keyFor(entry), entry]));
|
|
67
|
+
const packages = sortStringsBy(unique.values(), keyFor).map((entry) => relativeTo(outDir, entry));
|
|
68
|
+
|
|
69
|
+
return `${JSON.stringify({ packages }, null, JSON_INDENT)}\n`;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
function gtkxBundledPackages(root: string): Plugin {
|
|
73
|
+
const state: PackagesState = { outDir: join(root, DEFAULT_OUT_DIR) };
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
name: "gtkx:bundled-packages",
|
|
77
|
+
apply: "build",
|
|
78
|
+
|
|
79
|
+
configResolved(config) {
|
|
80
|
+
state.outDir = resolve(config.root, config.build.outDir);
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
generateBundle(_options, bundle) {
|
|
84
|
+
const ids = Object.values(bundle).flatMap((output) => (output.type === "chunk" ? output.moduleIds : []));
|
|
85
|
+
|
|
86
|
+
this.emitFile({
|
|
87
|
+
type: "asset",
|
|
88
|
+
fileName: BUNDLED_PACKAGES_FILENAME,
|
|
89
|
+
source: renderPackages(state.outDir, ids),
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { BUNDLED_PACKAGES_FILENAME, gtkxBundledPackages };
|