docker-client-mx 1.42.0 → 1.44.0

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 (102) hide show
  1. package/dist/docker-desktop-mx/browser/{chunk-C22Z7vgK.js → chunk-5u_BJ6JX.js} +1 -1
  2. package/dist/docker-desktop-mx/browser/chunk-6988XP3w.js +1 -0
  3. package/dist/docker-desktop-mx/browser/{chunk-CMrtklQ1.js → chunk-7mU3uVaN.js} +2 -2
  4. package/dist/docker-desktop-mx/browser/{chunk-Ba_z6LGV.js → chunk-B23Afk52.js} +1 -1
  5. package/dist/docker-desktop-mx/browser/{chunk-Bx2_SrZM.js → chunk-B7xGbGa9.js} +1 -1
  6. package/dist/docker-desktop-mx/browser/{chunk-Zom3ankA.js → chunk-B8Uu84pE.js} +1 -1
  7. package/dist/docker-desktop-mx/browser/chunk-BCYusaqm.js +1 -0
  8. package/dist/docker-desktop-mx/browser/chunk-BEtYD0_3.js +1 -0
  9. package/dist/docker-desktop-mx/browser/chunk-BG-O4Nb_.js +1 -0
  10. package/dist/docker-desktop-mx/browser/{chunk-Cbit44lz.js → chunk-BJsftgmt.js} +1 -1
  11. package/dist/docker-desktop-mx/browser/chunk-Bho6QLGs.js +1 -0
  12. package/dist/docker-desktop-mx/browser/{chunk-Ckq_aT3A.js → chunk-C1Nu6ZjD.js} +1 -1
  13. package/dist/docker-desktop-mx/browser/chunk-C3hTwhog.js +4 -0
  14. package/dist/docker-desktop-mx/browser/chunk-C52HI2A-.js +1 -0
  15. package/dist/docker-desktop-mx/browser/chunk-CGKsmblG.js +6 -0
  16. package/dist/docker-desktop-mx/browser/{chunk-DsuW5Ksa2.js → chunk-CMi-ZnXy.js} +1 -1
  17. package/dist/docker-desktop-mx/browser/{chunk-ep62jwHG.js → chunk-CYFxPPxo2.js} +1 -1
  18. package/dist/docker-desktop-mx/browser/chunk-Cl4e4J9q.js +1 -0
  19. package/dist/docker-desktop-mx/browser/{chunk-D0xC_xVf.js → chunk-Cr28jI1A.js} +1 -1
  20. package/dist/docker-desktop-mx/browser/{chunk-DvoPI4MU.js → chunk-CzkAHty9.js} +1 -1
  21. package/dist/docker-desktop-mx/browser/{chunk-CI9I9Npi.js → chunk-D1tQa5OM.js} +2 -2
  22. package/dist/docker-desktop-mx/browser/chunk-D3PaEk7L.js +1 -0
  23. package/dist/docker-desktop-mx/browser/chunk-DApzx4cc2.js +1 -0
  24. package/dist/docker-desktop-mx/browser/chunk-DNiq9JXI.js +1 -0
  25. package/dist/docker-desktop-mx/browser/{chunk-CSrKHPxR.js → chunk-DSfTqCF0.js} +1 -1
  26. package/dist/docker-desktop-mx/browser/{chunk-KUYJNmP22.js → chunk-DeEfJWMH2.js} +1 -1
  27. package/dist/docker-desktop-mx/browser/chunk-DeROY6LN.js +1 -0
  28. package/dist/docker-desktop-mx/browser/{chunk-D-7d5O7f.js → chunk-DffEUxgS.js} +1 -1
  29. package/dist/docker-desktop-mx/browser/chunk-Di7dDUYN2.js +6 -0
  30. package/dist/docker-desktop-mx/browser/{chunk-CRNeTD5E.js → chunk-DiB8MPYS.js} +1 -1
  31. package/dist/docker-desktop-mx/browser/{chunk-3VyqMz_T.js → chunk-Dp9UsDfH.js} +16 -16
  32. package/dist/docker-desktop-mx/browser/chunk-DtM-X5Eh.js +1 -0
  33. package/dist/docker-desktop-mx/browser/{chunk-DZjRtM2K.js → chunk-DtY6mcWb.js} +1 -1
  34. package/dist/docker-desktop-mx/browser/{chunk-DLeqF0uQ.js → chunk-DtbAIphi.js} +1 -1
  35. package/dist/docker-desktop-mx/browser/{chunk-wa_VZZFY.js → chunk-DvJZmDzM2.js} +1 -1
  36. package/dist/docker-desktop-mx/browser/chunk-Dy3d-reD.js +1 -0
  37. package/dist/docker-desktop-mx/browser/{chunk-C6u6rXYb2.js → chunk-DzyPSjiy2.js} +1 -1
  38. package/dist/docker-desktop-mx/browser/{chunk-V7ftX_10.js → chunk-MyEYCSP-.js} +1 -1
  39. package/dist/docker-desktop-mx/browser/{chunk-Zcfhi-RM.js → chunk-bSfpBwIa.js} +1 -1
  40. package/dist/docker-desktop-mx/browser/chunk-e16wEMMK.js +1 -0
  41. package/dist/docker-desktop-mx/browser/{chunk-CWusqRG0.js → chunk-eoU2TjRt.js} +1 -1
  42. package/dist/docker-desktop-mx/browser/chunk-xPy8hpGV.js +1 -0
  43. package/dist/docker-desktop-mx/browser/index.html +2 -2
  44. package/dist/docker-desktop-mx/browser/main-WTPCDZAO.js +1 -0
  45. package/dist/docker-desktop-mx/browser/styles-2WH7TMRX.css +1 -0
  46. package/dist-electron/channels.js +13 -0
  47. package/dist-electron/channels.js.map +1 -1
  48. package/dist-electron/compose-known.js +135 -0
  49. package/dist-electron/compose-known.js.map +1 -0
  50. package/dist-electron/compose.js +4 -1
  51. package/dist-electron/compose.js.map +1 -1
  52. package/dist-electron/container-adjust.js +182 -0
  53. package/dist-electron/container-adjust.js.map +1 -0
  54. package/dist-electron/container-duplicate.js +196 -0
  55. package/dist-electron/container-duplicate.js.map +1 -0
  56. package/dist-electron/containers.js +15 -0
  57. package/dist-electron/containers.js.map +1 -1
  58. package/dist-electron/docker-client.js +1 -0
  59. package/dist-electron/docker-client.js.map +1 -1
  60. package/dist-electron/exec.js +78 -7
  61. package/dist-electron/exec.js.map +1 -1
  62. package/dist-electron/file-edit.js +206 -0
  63. package/dist-electron/file-edit.js.map +1 -0
  64. package/dist-electron/image-build.js +173 -0
  65. package/dist-electron/image-build.js.map +1 -0
  66. package/dist-electron/image-search.js +58 -0
  67. package/dist-electron/image-search.js.map +1 -0
  68. package/dist-electron/ipc.js +68 -7
  69. package/dist-electron/ipc.js.map +1 -1
  70. package/dist-electron/known-projects.js +129 -0
  71. package/dist-electron/known-projects.js.map +1 -0
  72. package/dist-electron/log-export.js +5 -4
  73. package/dist-electron/log-export.js.map +1 -1
  74. package/dist-electron/logs.js +26 -10
  75. package/dist-electron/logs.js.map +1 -1
  76. package/dist-electron/main.js +15 -0
  77. package/dist-electron/main.js.map +1 -1
  78. package/dist-electron/preload.js +30 -4
  79. package/dist-electron/preload.js.map +1 -1
  80. package/dist-electron/processes.js +77 -0
  81. package/dist-electron/processes.js.map +1 -0
  82. package/package.json +1 -1
  83. package/dist/docker-desktop-mx/browser/chunk-BW20bBdg.js +0 -1
  84. package/dist/docker-desktop-mx/browser/chunk-BdOOWVGY.js +0 -4
  85. package/dist/docker-desktop-mx/browser/chunk-BgNCBUvw2.js +0 -1
  86. package/dist/docker-desktop-mx/browser/chunk-BoN9ZlqT.js +0 -1
  87. package/dist/docker-desktop-mx/browser/chunk-BsAqguck2.js +0 -3
  88. package/dist/docker-desktop-mx/browser/chunk-C-yEXU2P.js +0 -6
  89. package/dist/docker-desktop-mx/browser/chunk-C1Wg9uje.js +0 -1
  90. package/dist/docker-desktop-mx/browser/chunk-CC84vXik.js +0 -1
  91. package/dist/docker-desktop-mx/browser/chunk-CT1ZUgmS.js +0 -1
  92. package/dist/docker-desktop-mx/browser/chunk-Cc4_zCxe2.js +0 -1
  93. package/dist/docker-desktop-mx/browser/chunk-CrBxmi_g.js +0 -1
  94. package/dist/docker-desktop-mx/browser/chunk-D29s9m84.js +0 -1
  95. package/dist/docker-desktop-mx/browser/chunk-DKpHNjiv.js +0 -1
  96. package/dist/docker-desktop-mx/browser/chunk-DzG5R5Kk.js +0 -1
  97. package/dist/docker-desktop-mx/browser/chunk-QaMufr3I.js +0 -1
  98. package/dist/docker-desktop-mx/browser/chunk-cYufOe8J.js +0 -1
  99. package/dist/docker-desktop-mx/browser/chunk-eG8Su12W.js +0 -1
  100. package/dist/docker-desktop-mx/browser/chunk-iwVkNYYA.js +0 -1
  101. package/dist/docker-desktop-mx/browser/main-DECBD64Q.js +0 -1
  102. package/dist/docker-desktop-mx/browser/styles-5TXFXUUF.css +0 -1
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EXEC_USER = exports.STOP_SCRIPT = void 0;
4
+ exports.terminalMark = terminalMark;
3
5
  exports.wrapSession = wrapSession;
4
6
  exports.openExec = openExec;
7
+ const node_crypto_1 = require("node:crypto");
5
8
  const docker_client_1 = require("./docker-client");
6
9
  const i18n_1 = require("./i18n");
7
10
  /**
@@ -12,6 +15,31 @@ const i18n_1 = require("./i18n");
12
15
  * vragen het eerst. Dat kost één korte exec, en het antwoord is eenduidig.
13
16
  */
14
17
  const PROBE = 'for c in /bin/bash /usr/bin/bash /bin/sh /usr/bin/sh /bin/ash; do [ -x "$c" ] && echo "$c" && exit 0; done; exit 1';
18
+ /**
19
+ * Ruimt de processen van één terminal op (fase 79): alles met dit kenmerk in de omgeving, dus de
20
+ * shell en wat erin gestart is. Eerst SIGHUP, zoals een terminal die ophangt; wat na een seconde nog
21
+ * leeft, SIGKILL. `$1` is het kenmerk; het script zelf heeft het niet in zijn omgeving.
22
+ */
23
+ exports.STOP_SCRIPT = [
24
+ 'm="MX_TERMINAL=$1"',
25
+ 'hit() { for p in /proc/[0-9]*; do tr \'\\000\' \'\\n\' < "$p/environ" 2>/dev/null | grep -qx "$m" && echo "${p#/proc/}"; done; }',
26
+ 'pids=$(hit); [ -z "$pids" ] && exit 0',
27
+ 'kill -HUP $pids 2>/dev/null; sleep 1',
28
+ 'pids=$(hit); [ -n "$pids" ] && kill -KILL $pids 2>/dev/null; exit 0',
29
+ ].join('\n');
30
+ /** Het kenmerk dat een terminal meekrijgt: zo vindt het opruimen precies zijn eigen processen terug. */
31
+ function terminalMark() {
32
+ return (0, node_crypto_1.randomUUID)();
33
+ }
34
+ /**
35
+ * Wat Docker als gebruiker van een exec aanneemt: een naam of een uid, eventueel met `:groep`.
36
+ * Strenger dan nodig, zodat er nooit iets anders in de API-aanroep terechtkomt.
37
+ */
38
+ exports.EXEC_USER = /^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,31}(:[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,31})?$/;
39
+ /** Alleen meegeven als er een gebruiker gekozen is; zonder `User` neemt Docker die van de image. */
40
+ function asUser(user) {
41
+ return user === null ? {} : { User: user };
42
+ }
15
43
  /** Leest de uitvoer van een korte exec uit; de shell-probe schrijft één regel. */
16
44
  function readAll(stream) {
17
45
  return new Promise((resolve) => {
@@ -22,10 +50,12 @@ function readAll(stream) {
22
50
  });
23
51
  }
24
52
  const dockerBackend = {
25
- detectShell: async (containerId) => {
53
+ detectShell: async (containerId, user) => {
26
54
  const { docker } = (0, docker_client_1.getConnection)();
27
55
  try {
56
+ // Als dezelfde gebruiker als de shell straks: een naam die er niet is, valt dan hier al op.
28
57
  const probe = await docker.getContainer(containerId).exec({
58
+ ...asUser(user),
29
59
  Cmd: ['/bin/sh', '-c', PROBE],
30
60
  AttachStdout: true,
31
61
  AttachStderr: false,
@@ -40,15 +70,18 @@ const dockerBackend = {
40
70
  return null;
41
71
  }
42
72
  },
43
- start: async (containerId, shell, size) => {
73
+ start: async (containerId, shell, size, user) => {
44
74
  const { docker } = (0, docker_client_1.getConnection)();
75
+ const mark = terminalMark();
45
76
  const exec = await docker.getContainer(containerId).exec({
77
+ ...asUser(user),
46
78
  Cmd: [shell],
47
79
  AttachStdin: true,
48
80
  AttachStdout: true,
49
81
  AttachStderr: true,
50
82
  Tty: true,
51
- Env: ['TERM=xterm-256color'],
83
+ // Het kenmerk erven ook de programma's die je in de shell start; zie STOP_SCRIPT.
84
+ Env: ['TERM=xterm-256color', `MX_TERMINAL=${mark}`],
52
85
  });
53
86
  // Drie dingen moeten hier staan, en het derde is een valkuil:
54
87
  // - hijack maakt van de HTTP-verbinding een tweerichtingskanaal in plaats van een antwoord;
@@ -65,15 +98,35 @@ const dockerBackend = {
65
98
  // Een resize op een exec die net gestopt is geeft een 404; dat is geen fout om te melden.
66
99
  void exec.resize({ h: rows, w: cols }).catch(() => undefined);
67
100
  },
101
+ // Met een TTY hangt Docker de terminal niet op als de verbinding sluit: de shell bleef dan
102
+ // draaien, ook als root (fase 79). Dus zelf opruimen, als dezelfde gebruiker.
103
+ stop: () => void stopTerminal(containerId, mark, user),
68
104
  };
69
105
  },
70
106
  };
107
+ /** Draait STOP_SCRIPT in de container. Lukt het niet (container al weg), dan is er ook niets meer op te ruimen. */
108
+ async function stopTerminal(containerId, mark, user) {
109
+ try {
110
+ const exec = await (0, docker_client_1.getConnection)().docker.getContainer(containerId).exec({
111
+ ...asUser(user),
112
+ Cmd: ['/bin/sh', '-c', exports.STOP_SCRIPT, 'mx', mark],
113
+ AttachStdout: true,
114
+ AttachStderr: true,
115
+ });
116
+ const stream = await exec.start({ hijack: true, stdin: false });
117
+ await readAll(stream);
118
+ }
119
+ catch {
120
+ // Niets aan te doen, en niets om te melden: de terminal is al dicht.
121
+ }
122
+ }
71
123
  /**
72
124
  * Maakt van een ruwe TTY-stream een sessie. `stop` ruimt op wat er naast de stream nog draait,
73
125
  * zoals de hulpcontainer van de host-shell.
74
126
  */
75
127
  function wrapSession(shell, stream, resize, onData, onEnd, stop = () => undefined) {
76
128
  let closed = false;
129
+ let destroyed = false;
77
130
  const finish = () => {
78
131
  if (!closed) {
79
132
  closed = true;
@@ -93,6 +146,11 @@ function wrapSession(shell, stream, resize, onData, onEnd, stop = () => undefine
93
146
  },
94
147
  resize,
95
148
  destroy: () => {
149
+ // Sluiten kan van twee kanten komen (de tab en het venster); opruimen hoeft maar één keer.
150
+ if (destroyed) {
151
+ return;
152
+ }
153
+ destroyed = true;
96
154
  closed = true;
97
155
  stream.destroy();
98
156
  stop();
@@ -106,8 +164,21 @@ function wrapSession(shell, stream, resize, onData, onEnd, stop = () => undefine
106
164
  * inclusief de escape-codes, want díé zijn hier juist de bedoeling. Dat is het verschil met de
107
165
  * logweergave, waar we ze er juist uit halen.
108
166
  */
109
- async function openExec(containerId, size, onData, onEnd, backend = dockerBackend) {
110
- const shell = await backend.detectShell(containerId);
167
+ async function openExec(containerId, size, onData, onEnd, backend = dockerBackend, user = null) {
168
+ const shell = await backend.detectShell(containerId, user);
169
+ // Met een gekozen gebruiker is "geen shell" meestal "geen gebruiker met die naam".
170
+ if (shell === null && user !== null) {
171
+ return {
172
+ ok: false,
173
+ problem: (0, i18n_1.t)({
174
+ en: `No shell could be started as ${user}. Does that user exist in this container?`,
175
+ nl: `Als ${user} kon geen shell gestart worden. Bestaat die gebruiker in deze container?`,
176
+ de: `Als ${user} konnte keine Shell gestartet werden. Gibt es diesen Benutzer in diesem Container?`,
177
+ fr: `Aucun shell n’a pu être démarré en tant que ${user}. Cet utilisateur existe-t-il dans ce conteneur ?`,
178
+ es: `No se ha podido iniciar un shell como ${user}. ¿Existe ese usuario en este contenedor?`,
179
+ }),
180
+ };
181
+ }
111
182
  if (shell === null) {
112
183
  return {
113
184
  ok: false,
@@ -121,8 +192,8 @@ async function openExec(containerId, size, onData, onEnd, backend = dockerBacken
121
192
  };
122
193
  }
123
194
  try {
124
- const { stream, resize } = await backend.start(containerId, shell, size);
125
- return { ok: true, session: wrapSession(shell, stream, resize, onData, onEnd) };
195
+ const { stream, resize, stop } = await backend.start(containerId, shell, size, user);
196
+ return { ok: true, session: wrapSession(shell, stream, resize, onData, onEnd, stop) };
126
197
  }
127
198
  catch (err) {
128
199
  const reason = err instanceof Error ? err.message : String(err);
@@ -1 +1 @@
1
- {"version":3,"file":"exec.js","sourceRoot":"","sources":["../electron/exec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../electron/exec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MAX_EDIT_BYTES = void 0;
37
+ exports.asText = asText;
38
+ exports.versionOf = versionOf;
39
+ exports.onMount = onMount;
40
+ exports.readEditableFile = readEditableFile;
41
+ exports.saveEditableFile = saveEditableFile;
42
+ const node_crypto_1 = require("node:crypto");
43
+ const path = __importStar(require("node:path"));
44
+ const tar = __importStar(require("tar-stream"));
45
+ const docker_client_1 = require("./docker-client");
46
+ const files_1 = require("./files");
47
+ const i18n_1 = require("./i18n");
48
+ /**
49
+ * Een tekstbestand in een container bewerken (fase 78): lezen, en terugzetten met dezelfde rechten
50
+ * en eigenaar. Via `getArchive` en `putArchive`, zonder shell, zoals downloaden en uploaden.
51
+ *
52
+ * Alleen tekst en alleen klein: een editor in de app is voor een configuratieregel, niet voor een
53
+ * logbestand van honderd megabyte. De versie is een hash van de inhoud; opslaan leest eerst opnieuw
54
+ * en weigert als het bestand intussen veranderd is, in plaats van het stil te overschrijven.
55
+ */
56
+ /** Groter dan dit is geen bestand om in de app te bewerken; dan blijven downloaden en uploaden. */
57
+ exports.MAX_EDIT_BYTES = 512 * 1024;
58
+ const MAX_LINK_HOPS = 8;
59
+ /** De eerste entry van een archief; de inhoud alleen als het een bestand is dat klein genoeg is. */
60
+ async function firstEntry(archive) {
61
+ const extract = tar.extract();
62
+ let found = null;
63
+ archive.pipe(extract);
64
+ for await (const entry of extract) {
65
+ const header = entry.header;
66
+ if (found === null) {
67
+ const small = header.type === 'file' && (header.size ?? 0) <= exports.MAX_EDIT_BYTES;
68
+ const chunks = [];
69
+ if (small) {
70
+ for await (const chunk of entry) {
71
+ chunks.push(chunk);
72
+ }
73
+ }
74
+ else {
75
+ entry.resume();
76
+ }
77
+ found = {
78
+ type: header.type ?? 'file',
79
+ size: header.size ?? 0,
80
+ mode: header.mode ?? 0o644,
81
+ uid: header.uid ?? 0,
82
+ gid: header.gid ?? 0,
83
+ linkname: header.linkname ?? null,
84
+ content: small ? Buffer.concat(chunks) : null,
85
+ };
86
+ }
87
+ else {
88
+ entry.resume();
89
+ }
90
+ }
91
+ return found;
92
+ }
93
+ /** Of dit tekst is die we heel terugschrijven: geen nul-bytes, en UTF-8 dat heen en terug gelijk blijft. */
94
+ function asText(content) {
95
+ if (content.includes(0)) {
96
+ return null;
97
+ }
98
+ const text = content.toString('utf8');
99
+ return Buffer.from(text, 'utf8').equals(content) ? text : null;
100
+ }
101
+ /** De versie van een bestand: een hash van de inhoud, om bij opslaan te zien of het veranderde. */
102
+ function versionOf(content) {
103
+ return (0, node_crypto_1.createHash)('sha256').update(content).digest('hex');
104
+ }
105
+ /** Of een pad onder een volume of bind mount valt; dan blijft een wijziging na "Opnieuw" staan. */
106
+ function onMount(file, destinations) {
107
+ return destinations.some((destination) => file === destination || file.startsWith(`${destination.replace(/\/$/, '')}/`));
108
+ }
109
+ /** Leest het bestand, en volgt een symlink zoals de container dat zou doen. */
110
+ async function read(id, requested) {
111
+ const container = (0, docker_client_1.getConnection)().docker.getContainer(id);
112
+ let current = (0, files_1.normalizeContainerPath)(requested);
113
+ for (let hop = 0; hop <= MAX_LINK_HOPS; hop += 1) {
114
+ const entry = await firstEntry((await container.getArchive({ path: current })));
115
+ if (entry?.type === 'symlink' && entry.linkname !== null) {
116
+ current = path.posix.resolve(path.posix.dirname(current), entry.linkname);
117
+ continue;
118
+ }
119
+ if (entry === null || entry.type !== 'file') {
120
+ return { ok: false, problem: (0, i18n_1.t)({
121
+ en: `${current} is not a file.`,
122
+ nl: `${current} is geen bestand.`,
123
+ de: `${current} ist keine Datei.`,
124
+ fr: `${current} n’est pas un fichier.`,
125
+ es: `${current} no es un archivo.`,
126
+ }) };
127
+ }
128
+ return { ok: true, path: current, entry };
129
+ }
130
+ return { ok: false, problem: (0, i18n_1.t)({
131
+ en: `too many symlinks in a row from ${requested}.`,
132
+ nl: `te veel symlinks achter elkaar vanaf ${requested}.`,
133
+ de: `zu viele Symlinks hintereinander ab ${requested}.`,
134
+ fr: `trop de liens symboliques à la suite depuis ${requested}.`,
135
+ es: `demasiados symlinks seguidos desde ${requested}.`,
136
+ }) };
137
+ }
138
+ /** Leest een tekstbestand om te bewerken, met de versie om bij opslaan tegen te controleren. */
139
+ async function readEditableFile(id, requested) {
140
+ try {
141
+ const result = await read(id, requested);
142
+ if (!result.ok) {
143
+ return result;
144
+ }
145
+ const { entry } = result;
146
+ if (entry.content === null) {
147
+ return { ok: false, problem: (0, i18n_1.t)({
148
+ en: `${result.path} is larger than ${String(exports.MAX_EDIT_BYTES / 1024)} kB; download it to edit it.`,
149
+ nl: `${result.path} is groter dan ${String(exports.MAX_EDIT_BYTES / 1024)} kB; download het om het te bewerken.`,
150
+ de: `${result.path} ist größer als ${String(exports.MAX_EDIT_BYTES / 1024)} kB; laden Sie es zum Bearbeiten herunter.`,
151
+ fr: `${result.path} dépasse ${String(exports.MAX_EDIT_BYTES / 1024)} ko ; téléchargez-le pour le modifier.`,
152
+ es: `${result.path} supera los ${String(exports.MAX_EDIT_BYTES / 1024)} kB; descárgalo para editarlo.`,
153
+ }) };
154
+ }
155
+ const text = asText(entry.content);
156
+ if (text === null) {
157
+ return { ok: false, problem: (0, i18n_1.t)({
158
+ en: `${result.path} is not text (or not UTF-8); download it to edit it.`,
159
+ nl: `${result.path} is geen tekst (of geen UTF-8); download het om het te bewerken.`,
160
+ de: `${result.path} ist kein Text (oder kein UTF-8); laden Sie es zum Bearbeiten herunter.`,
161
+ fr: `${result.path} n’est pas du texte (ou pas en UTF-8) ; téléchargez-le pour le modifier.`,
162
+ es: `${result.path} no es texto (o no es UTF-8); descárgalo para editarlo.`,
163
+ }) };
164
+ }
165
+ const inspect = (await (0, docker_client_1.getConnection)().docker.getContainer(id).inspect());
166
+ const destinations = (inspect.Mounts ?? []).map((mount) => mount.Destination ?? '').filter((destination) => destination !== '');
167
+ return { ok: true, path: result.path, text, version: versionOf(entry.content), onMount: onMount(result.path, destinations) };
168
+ }
169
+ catch (err) {
170
+ return { ok: false, problem: (0, docker_client_1.readableError)(err, (0, docker_client_1.getConnection)().endpoint).message };
171
+ }
172
+ }
173
+ /**
174
+ * Zet de tekst terug, met de rechten, eigenaar en groep die het bestand had. Is het intussen
175
+ * veranderd (een andere versie dan `version`), dan niet: `conflict` zegt dat, tenzij `force`.
176
+ */
177
+ async function saveEditableFile(id, file, text, version, force) {
178
+ try {
179
+ const current = await read(id, file);
180
+ if (!current.ok) {
181
+ return { ...current, conflict: false };
182
+ }
183
+ if (!force && (current.entry.content === null || versionOf(current.entry.content) !== version)) {
184
+ return { ok: false, conflict: true, problem: (0, i18n_1.t)({
185
+ en: `${current.path} has changed in the container since you opened it.`,
186
+ nl: `${current.path} is in de container veranderd sinds je het opende.`,
187
+ de: `${current.path} hat sich im Container geändert, seit Sie es geöffnet haben.`,
188
+ fr: `${current.path} a changé dans le conteneur depuis que vous l’avez ouvert.`,
189
+ es: `${current.path} ha cambiado en el contenedor desde que lo abriste.`,
190
+ }) };
191
+ }
192
+ const content = Buffer.from(text, 'utf8');
193
+ const pack = tar.pack();
194
+ pack.entry({ name: path.posix.basename(current.path), size: content.length, mode: current.entry.mode, uid: current.entry.uid, gid: current.entry.gid, mtime: new Date() }, content);
195
+ pack.finalize();
196
+ // `copyUIDGID`: de eigenaar en groep uit het archief, en dat zijn die van het oude bestand.
197
+ await (0, docker_client_1.getConnection)()
198
+ .docker.getContainer(id)
199
+ .putArchive(pack, { path: path.posix.dirname(current.path), copyUIDGID: '1' });
200
+ return { ok: true, version: versionOf(content) };
201
+ }
202
+ catch (err) {
203
+ return { ok: false, conflict: false, problem: (0, docker_client_1.readableError)(err, (0, docker_client_1.getConnection)().endpoint).message };
204
+ }
205
+ }
206
+ //# sourceMappingURL=file-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-edit.js","sourceRoot":"","sources":["../electron/file-edit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isDockerfile = isDockerfile;
37
+ exports.dockerfilesIn = dockerfilesIn;
38
+ exports.suggestBuildName = suggestBuildName;
39
+ exports.chooseBuildFolder = chooseBuildFolder;
40
+ exports.buildArgs = buildArgs;
41
+ exports.buildImage = buildImage;
42
+ const node_child_process_1 = require("node:child_process");
43
+ const node_crypto_1 = require("node:crypto");
44
+ const node_fs_1 = require("node:fs");
45
+ const path = __importStar(require("node:path"));
46
+ const compose_1 = require("./compose");
47
+ const i18n_1 = require("./i18n");
48
+ const image_reference_1 = require("./image-reference");
49
+ /**
50
+ * Een image bouwen uit een map (fase 72): `docker build`, via de CLI zoals de build van een service
51
+ * (fase 61), zodat BuildKit, `.dockerignore` en de cache werken zoals je ze kent.
52
+ *
53
+ * De map kies je in de dialoog van Windows, en main onthoudt hem onder een token. De renderer krijgt
54
+ * dat token en de Dockerfiles in die map, en stuurt bij het bouwen het token en een naam uit die
55
+ * lijst terug: nooit een pad. Zo bouwt main alleen in een map die je zelf koos.
56
+ */
57
+ /** Een build mag lang duren; een half uur is ruim, en daarna is er iets mis. */
58
+ const BUILD_TIMEOUT_MS = 30 * 60 * 1000;
59
+ const chosen = new Map();
60
+ /** Wat als Dockerfile telt: `Dockerfile`, `Dockerfile.dev`, `api.Dockerfile`, `Containerfile`. */
61
+ function isDockerfile(name) {
62
+ return /^(dockerfile|containerfile)(\..+)?$/i.test(name) || /\.(dockerfile|containerfile)$/i.test(name);
63
+ }
64
+ /** De Dockerfiles in een map, met `Dockerfile` zelf voorop, daarna op naam. */
65
+ function dockerfilesIn(names) {
66
+ return names
67
+ .filter(isDockerfile)
68
+ .sort((a, b) => Number(/^dockerfile$/i.test(b)) - Number(/^dockerfile$/i.test(a)) || a.localeCompare(b));
69
+ }
70
+ /** Een voorgestelde naam uit de map: `C:\projects\Mijn App` wordt `mijn-app:latest`. */
71
+ function suggestBuildName(dir) {
72
+ const base = path.win32.basename(dir.replace(/[\\/]+$/, '')).toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^[^a-z0-9]+|[^a-z0-9]+$/g, '');
73
+ return `${base || 'image'}:latest`;
74
+ }
75
+ /** Neemt de gekozen map op; `null` is annuleren. Een map zonder Dockerfile zegt dat meteen. */
76
+ function chooseBuildFolder(dir, list = listFiles) {
77
+ if (dir === null) {
78
+ return null;
79
+ }
80
+ const files = dockerfilesIn(list(dir));
81
+ const token = (0, node_crypto_1.randomUUID)();
82
+ chosen.set(token, { dir, files });
83
+ return { token, folder: dir, dockerfiles: files, suggestion: suggestBuildName(dir) };
84
+ }
85
+ function listFiles(dir) {
86
+ try {
87
+ return (0, node_fs_1.readdirSync)(dir).filter((name) => {
88
+ try {
89
+ return (0, node_fs_1.statSync)(path.join(dir, name)).isFile();
90
+ }
91
+ catch {
92
+ return false;
93
+ }
94
+ });
95
+ }
96
+ catch {
97
+ return [];
98
+ }
99
+ }
100
+ /** De argumenten voor `docker`: platte voortgang, zodat de stappen als gewone regels te lezen zijn. */
101
+ function buildArgs(dir, dockerfile, reference) {
102
+ const { repository, tag } = (0, image_reference_1.splitReference)(reference);
103
+ return ['build', '--progress', 'plain', '-t', `${repository}:${tag}`, '-f', path.join(dir, dockerfile), dir];
104
+ }
105
+ const runDocker = (args, cwd) => new Promise((resolve) => {
106
+ (0, node_child_process_1.execFile)('docker', [...args], { cwd, encoding: 'utf8', timeout: BUILD_TIMEOUT_MS, maxBuffer: 50 * 1024 * 1024, windowsHide: true }, (err, stdout, stderr) => {
107
+ // BuildKit schrijft de stappen naar stderr; allebei, in die volgorde, is wat je in een terminal ziet.
108
+ const output = [stderr, stdout].map((part) => part.trim()).filter((part) => part !== '').join('\n');
109
+ resolve({ ok: err === null, output, error: err === null ? '' : err.message });
110
+ });
111
+ });
112
+ /** Bouwt in de gekozen map, met een Dockerfile uit de lijst die main zelf maakte. */
113
+ async function buildImage(token, dockerfile, reference, run = runDocker) {
114
+ const folder = chosen.get(token);
115
+ if (folder === undefined || !folder.files.includes(dockerfile)) {
116
+ return {
117
+ ok: false,
118
+ problem: (0, i18n_1.t)({
119
+ en: 'Choose the folder again; the app only builds in a folder you picked.',
120
+ nl: 'Kies de map opnieuw; de app bouwt alleen in een map die je zelf koos.',
121
+ de: 'Wählen Sie den Ordner erneut; die App baut nur in einem Ordner, den Sie selbst gewählt haben.',
122
+ fr: 'Choisissez à nouveau le dossier ; l’application ne construit que dans un dossier que vous avez choisi.',
123
+ es: 'Elige la carpeta otra vez; la aplicación solo construye en una carpeta que elegiste tú.',
124
+ }),
125
+ output: '',
126
+ };
127
+ }
128
+ const wanted = reference.trim();
129
+ if (!(0, image_reference_1.isReference)(wanted)) {
130
+ return {
131
+ ok: false,
132
+ problem: (0, i18n_1.t)({
133
+ en: 'An image name is in lowercase, like my-app or registry.example.com/team/app, optionally followed by :tag.',
134
+ nl: 'Een imagenaam is in kleine letters, zoals mijn-app of registry.example.com/team/app, eventueel gevolgd door :tag.',
135
+ de: 'Ein Image-Name ist kleingeschrieben, etwa mein-app oder registry.example.com/team/app, optional gefolgt von :tag.',
136
+ fr: 'Un nom d’image est en minuscules, comme mon-app ou registry.example.com/equipe/app, suivi éventuellement de :tag.',
137
+ es: 'Un nombre de imagen va en minúsculas, como mi-app o registry.example.com/equipo/app, seguido opcionalmente de :tag.',
138
+ }),
139
+ output: '',
140
+ };
141
+ }
142
+ const status = await (0, compose_1.readComposeStatus)();
143
+ if (!status.cliAvailable) {
144
+ return {
145
+ ok: false,
146
+ problem: status.problem ?? (0, i18n_1.t)({
147
+ en: 'The docker CLI is not available.',
148
+ nl: 'De docker CLI is niet beschikbaar.',
149
+ de: 'Die docker-CLI ist nicht verfügbar.',
150
+ fr: 'La CLI docker n’est pas disponible.',
151
+ es: 'La CLI de docker no está disponible.',
152
+ }),
153
+ output: '',
154
+ };
155
+ }
156
+ const { repository, tag } = (0, image_reference_1.splitReference)(wanted);
157
+ const result = await run(buildArgs(folder.dir, dockerfile, wanted), folder.dir);
158
+ if (result.ok) {
159
+ return { ok: true, reference: `${repository}:${tag}`, output: result.output };
160
+ }
161
+ return {
162
+ ok: false,
163
+ problem: (0, i18n_1.t)({
164
+ en: `The build of ${repository}:${tag} failed; the output below says why.`,
165
+ nl: `De build van ${repository}:${tag} mislukte; de uitvoer hieronder zegt waarom.`,
166
+ de: `Der Build von ${repository}:${tag} ist fehlgeschlagen; die Ausgabe unten sagt, warum.`,
167
+ fr: `La construction de ${repository}:${tag} a échoué ; la sortie ci-dessous dit pourquoi.`,
168
+ es: `La construcción de ${repository}:${tag} ha fallado; la salida de abajo dice por qué.`,
169
+ }),
170
+ output: result.output === '' ? result.error : result.output,
171
+ };
172
+ }
173
+ //# sourceMappingURL=image-build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-build.js","sourceRoot":"","sources":["../electron/image-build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_HITS = void 0;
4
+ exports.searchTerm = searchTerm;
5
+ exports.toHits = toHits;
6
+ exports.searchImages = searchImages;
7
+ const docker_client_1 = require("./docker-client");
8
+ const image_reference_1 = require("./image-reference");
9
+ /**
10
+ * Zoeken in Docker Hub (fase 71), als hulp bij de naam in "Image ophalen".
11
+ *
12
+ * Via de daemon (`/images/search`), niet zelf naar hub.docker.com: dan gelden de proxy en de
13
+ * mirrors van de daemon, net als bij een pull. Die API kent alleen Docker Hub; een naam met een
14
+ * andere registry ervoor zoekt dus niet. Een fout is geen melding waard: dan geen treffers, en
15
+ * ophalen met een getypte naam werkt zoals altijd.
16
+ */
17
+ /** Meer is geen hulp bij de naam meer maar een catalogus. */
18
+ exports.MAX_HITS = 10;
19
+ /** Wat er van de zoekterm overblijft om te zoeken: zonder tag, en niets bij een andere registry. */
20
+ function searchTerm(input) {
21
+ const trimmed = input.trim();
22
+ if (trimmed.length < 2 || (0, image_reference_1.registryHost)(trimmed) !== null) {
23
+ return null;
24
+ }
25
+ // `nginx:1.27` zoekt op `nginx`; een tag kent de zoek-API niet.
26
+ const withoutTag = trimmed.replace(/[:@].*$/, '');
27
+ return withoutTag.length < 2 ? null : withoutTag;
28
+ }
29
+ /** De treffers zoals de daemon ze geeft, naar onze vorm; officiële images eerst, dan op sterren. */
30
+ function toHits(raw) {
31
+ if (!Array.isArray(raw)) {
32
+ return [];
33
+ }
34
+ return raw
35
+ .filter((hit) => typeof hit.name === 'string' && hit.name !== '')
36
+ .map((hit) => ({
37
+ name: hit.name,
38
+ description: typeof hit.description === 'string' ? hit.description : '',
39
+ stars: typeof hit.star_count === 'number' ? hit.star_count : 0,
40
+ official: hit.is_official === true,
41
+ }))
42
+ .sort((a, b) => Number(b.official) - Number(a.official) || b.stars - a.stars)
43
+ .slice(0, exports.MAX_HITS);
44
+ }
45
+ /** Zoekt in Docker Hub naar wat er getypt is; leeg als er niets te zoeken valt of niets terugkomt. */
46
+ async function searchImages(input) {
47
+ const term = searchTerm(input);
48
+ if (term === null) {
49
+ return [];
50
+ }
51
+ try {
52
+ return toHits(await (0, docker_client_1.getConnection)().docker.searchImages({ term, limit: exports.MAX_HITS }));
53
+ }
54
+ catch {
55
+ return [];
56
+ }
57
+ }
58
+ //# sourceMappingURL=image-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-search.js","sourceRoot":"","sources":["../electron/image-search.ts"],"names":[],"mappings":";;;AAiBA,gCAYC;AAUD,wBAgBC;AAGD,oCAaC;AAtED,mDAAgD;AAChD,uDAAiD;AAEjD;;;;;;;GAOG;AAEH,6DAA6D;AAChD,QAAA,QAAQ,GAAG,EAAE,CAAC;AAE3B,oGAAoG;AACpG,SAAgB,UAAU,CAAC,KAAa;IAEtC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,IAAA,8BAAY,EAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gEAAgE;IAChE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAElD,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;AACnD,CAAC;AASD,oGAAoG;AACpG,SAAgB,MAAM,CAAC,GAAY;IAEjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAQ,GAAgB;SACrB,MAAM,CAAC,CAAC,GAAG,EAAoC,EAAE,CAAC,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC;SAClG,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACb,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;QACvE,KAAK,EAAE,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC9D,QAAQ,EAAE,GAAG,CAAC,WAAW,KAAK,IAAI;KACnC,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SAC5E,KAAK,CAAC,CAAC,EAAE,gBAAQ,CAAC,CAAC;AACxB,CAAC;AAED,sGAAsG;AAC/F,KAAK,UAAU,YAAY,CAAC,KAAa;IAE9C,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAE/B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,IAAA,6BAAa,GAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,gBAAQ,EAAE,CAAC,CAAC,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}