@ecmaos/coreutils 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +37 -0
  3. package/LICENSE +1 -1
  4. package/dist/commands/cal.js +2 -2
  5. package/dist/commands/cal.js.map +1 -1
  6. package/dist/commands/cat.js +2 -2
  7. package/dist/commands/cd.js +2 -2
  8. package/dist/commands/chmod.d.ts.map +1 -1
  9. package/dist/commands/chmod.js +16 -11
  10. package/dist/commands/chmod.js.map +1 -1
  11. package/dist/commands/cp.js +2 -2
  12. package/dist/commands/cp.js.map +1 -1
  13. package/dist/commands/cron.d.ts +4 -0
  14. package/dist/commands/cron.d.ts.map +1 -0
  15. package/dist/commands/cron.js +439 -0
  16. package/dist/commands/cron.js.map +1 -0
  17. package/dist/commands/date.js +2 -2
  18. package/dist/commands/date.js.map +1 -1
  19. package/dist/commands/echo.js +2 -2
  20. package/dist/commands/echo.js.map +1 -1
  21. package/dist/commands/false.js +2 -2
  22. package/dist/commands/fetch.d.ts +4 -0
  23. package/dist/commands/fetch.d.ts.map +1 -0
  24. package/dist/commands/fetch.js +210 -0
  25. package/dist/commands/fetch.js.map +1 -0
  26. package/dist/commands/format.d.ts +4 -0
  27. package/dist/commands/format.d.ts.map +1 -0
  28. package/dist/commands/format.js +178 -0
  29. package/dist/commands/format.js.map +1 -0
  30. package/dist/commands/hash.d.ts +4 -0
  31. package/dist/commands/hash.d.ts.map +1 -0
  32. package/dist/commands/hash.js +200 -0
  33. package/dist/commands/hash.js.map +1 -0
  34. package/dist/commands/head.js +2 -2
  35. package/dist/commands/id.js +2 -2
  36. package/dist/commands/id.js.map +1 -1
  37. package/dist/commands/less.d.ts.map +1 -1
  38. package/dist/commands/less.js +53 -2
  39. package/dist/commands/less.js.map +1 -1
  40. package/dist/commands/ls.d.ts.map +1 -1
  41. package/dist/commands/ls.js +41 -15
  42. package/dist/commands/ls.js.map +1 -1
  43. package/dist/commands/man.d.ts +4 -0
  44. package/dist/commands/man.d.ts.map +1 -0
  45. package/dist/commands/man.js +564 -0
  46. package/dist/commands/man.js.map +1 -0
  47. package/dist/commands/mkdir.js +2 -2
  48. package/dist/commands/mkdir.js.map +1 -1
  49. package/dist/commands/mktemp.d.ts +4 -0
  50. package/dist/commands/mktemp.d.ts.map +1 -0
  51. package/dist/commands/mktemp.js +229 -0
  52. package/dist/commands/mktemp.js.map +1 -0
  53. package/dist/commands/nc.js +2 -2
  54. package/dist/commands/nc.js.map +1 -1
  55. package/dist/commands/open.d.ts +4 -0
  56. package/dist/commands/open.d.ts.map +1 -0
  57. package/dist/commands/open.js +74 -0
  58. package/dist/commands/open.js.map +1 -0
  59. package/dist/commands/passkey.js +3 -3
  60. package/dist/commands/play.d.ts +4 -0
  61. package/dist/commands/play.d.ts.map +1 -0
  62. package/dist/commands/play.js +231 -0
  63. package/dist/commands/play.js.map +1 -0
  64. package/dist/commands/pwd.js +2 -2
  65. package/dist/commands/pwd.js.map +1 -1
  66. package/dist/commands/rm.d.ts.map +1 -1
  67. package/dist/commands/rm.js +57 -12
  68. package/dist/commands/rm.js.map +1 -1
  69. package/dist/commands/rmdir.js +2 -2
  70. package/dist/commands/rmdir.js.map +1 -1
  71. package/dist/commands/sockets.js +1 -1
  72. package/dist/commands/stat.d.ts.map +1 -1
  73. package/dist/commands/stat.js +37 -15
  74. package/dist/commands/stat.js.map +1 -1
  75. package/dist/commands/tail.js +2 -2
  76. package/dist/commands/tar.d.ts +4 -0
  77. package/dist/commands/tar.d.ts.map +1 -0
  78. package/dist/commands/tar.js +743 -0
  79. package/dist/commands/tar.js.map +1 -0
  80. package/dist/commands/touch.js +2 -2
  81. package/dist/commands/touch.js.map +1 -1
  82. package/dist/commands/true.js +2 -2
  83. package/dist/commands/unzip.d.ts +4 -0
  84. package/dist/commands/unzip.d.ts.map +1 -0
  85. package/dist/commands/unzip.js +443 -0
  86. package/dist/commands/unzip.js.map +1 -0
  87. package/dist/commands/user.js +1 -1
  88. package/dist/commands/video.d.ts +4 -0
  89. package/dist/commands/video.d.ts.map +1 -0
  90. package/dist/commands/video.js +250 -0
  91. package/dist/commands/video.js.map +1 -0
  92. package/dist/commands/view.d.ts +4 -0
  93. package/dist/commands/view.d.ts.map +1 -0
  94. package/dist/commands/view.js +488 -0
  95. package/dist/commands/view.js.map +1 -0
  96. package/dist/commands/web.d.ts +4 -0
  97. package/dist/commands/web.d.ts.map +1 -0
  98. package/dist/commands/web.js +348 -0
  99. package/dist/commands/web.js.map +1 -0
  100. package/dist/commands/whoami.js +2 -2
  101. package/dist/commands/whoami.js.map +1 -1
  102. package/dist/commands/zip.d.ts +4 -0
  103. package/dist/commands/zip.d.ts.map +1 -0
  104. package/dist/commands/zip.js +264 -0
  105. package/dist/commands/zip.js.map +1 -0
  106. package/dist/index.d.ts +14 -0
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +44 -2
  109. package/dist/index.js.map +1 -1
  110. package/package.json +7 -4
  111. package/src/commands/cal.ts +2 -2
  112. package/src/commands/cat.ts +2 -2
  113. package/src/commands/cd.ts +2 -2
  114. package/src/commands/chmod.ts +19 -11
  115. package/src/commands/cp.ts +2 -2
  116. package/src/commands/cron.ts +499 -0
  117. package/src/commands/date.ts +2 -2
  118. package/src/commands/echo.ts +2 -2
  119. package/src/commands/false.ts +2 -2
  120. package/src/commands/fetch.ts +205 -0
  121. package/src/commands/format.ts +204 -0
  122. package/src/commands/hash.ts +215 -0
  123. package/src/commands/head.ts +2 -2
  124. package/src/commands/id.ts +2 -2
  125. package/src/commands/less.ts +50 -2
  126. package/src/commands/ls.ts +40 -14
  127. package/src/commands/man.ts +651 -0
  128. package/src/commands/mkdir.ts +2 -2
  129. package/src/commands/mktemp.ts +235 -0
  130. package/src/commands/nc.ts +2 -2
  131. package/src/commands/open.ts +84 -0
  132. package/src/commands/passkey.ts +3 -3
  133. package/src/commands/play.ts +249 -0
  134. package/src/commands/pwd.ts +2 -2
  135. package/src/commands/rm.ts +54 -12
  136. package/src/commands/rmdir.ts +2 -2
  137. package/src/commands/sockets.ts +1 -1
  138. package/src/commands/stat.ts +44 -16
  139. package/src/commands/tail.ts +2 -2
  140. package/src/commands/tar.ts +780 -0
  141. package/src/commands/touch.ts +2 -2
  142. package/src/commands/true.ts +2 -2
  143. package/src/commands/unzip.ts +517 -0
  144. package/src/commands/user.ts +1 -1
  145. package/src/commands/video.ts +267 -0
  146. package/src/commands/view.ts +526 -0
  147. package/src/commands/web.ts +377 -0
  148. package/src/commands/whoami.ts +2 -2
  149. package/src/commands/zip.ts +319 -0
  150. package/src/index.ts +44 -2
@@ -0,0 +1,348 @@
1
+ import chalk from 'chalk';
2
+ import { TerminalCommand } from '../shared/terminal-command.js';
3
+ import { writelnStderr } from '../shared/helpers.js';
4
+ function printUsage(process, terminal) {
5
+ const usage = `Usage: web [OPTIONS] [URL]
6
+ Open a URL in a new contained window.
7
+ Many sites will block the COR, so this is mostly useful for local/bespoke/credentialless resources.
8
+ To open in a new tab/browser window, use the 'open' command instead.
9
+
10
+ --help display this help and exit
11
+ --no-navbar hide the navigation bar
12
+
13
+ Examples:
14
+ web https://example.com open a URL in a browser window
15
+ web --no-navbar https://example.com open a URL without navigation bar
16
+ web example.com open a URL (https:// will be prepended)
17
+ web http://example.com open a URL with http protocol`;
18
+ writelnStderr(process, terminal, usage);
19
+ }
20
+ function normalizeUrl(url) {
21
+ const urlPattern = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
22
+ if (urlPattern.test(url))
23
+ return url;
24
+ return `https://${url}`;
25
+ }
26
+ export function createCommand(kernel, shell, terminal) {
27
+ return new TerminalCommand({
28
+ command: 'web',
29
+ description: 'Open a URL in a browser window',
30
+ kernel,
31
+ shell,
32
+ terminal,
33
+ run: async (pid, argv) => {
34
+ const process = kernel.processes.get(pid);
35
+ if (!process)
36
+ return 1;
37
+ if (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h')) {
38
+ printUsage(process, terminal);
39
+ return 0;
40
+ }
41
+ // Parse arguments
42
+ let hideNavbar = false;
43
+ const urlArgs = [];
44
+ for (const arg of argv) {
45
+ const trimmedArg = arg.trim();
46
+ if (trimmedArg === '--no-navbar' || trimmedArg === '--hide-navbar') {
47
+ hideNavbar = true;
48
+ }
49
+ else if (trimmedArg && trimmedArg !== '--help' && trimmedArg !== '-h') {
50
+ // Remove any flag prefixes that might have been concatenated
51
+ let cleanArg = trimmedArg;
52
+ if (cleanArg.startsWith('--no-navbar')) {
53
+ cleanArg = cleanArg.replace(/^--no-navbar/, '').trim();
54
+ hideNavbar = true;
55
+ }
56
+ else if (cleanArg.startsWith('--hide-navbar')) {
57
+ cleanArg = cleanArg.replace(/^--hide-navbar/, '').trim();
58
+ hideNavbar = true;
59
+ }
60
+ if (cleanArg) {
61
+ urlArgs.push(cleanArg);
62
+ }
63
+ }
64
+ }
65
+ if (urlArgs.length === 0) {
66
+ await writelnStderr(process, terminal, `web: missing URL argument`);
67
+ await writelnStderr(process, terminal, `Try 'web --help' for more information.`);
68
+ return 1;
69
+ }
70
+ const urlString = urlArgs.join(' ').trim();
71
+ if (!urlString) {
72
+ await writelnStderr(process, terminal, `web: missing URL argument`);
73
+ return 1;
74
+ }
75
+ const url = normalizeUrl(urlString);
76
+ try {
77
+ // Validate URL
78
+ new URL(url);
79
+ }
80
+ catch (error) {
81
+ await writelnStderr(process, terminal, chalk.red(`web: invalid URL: ${urlString}`));
82
+ return 1;
83
+ }
84
+ // Create container for browser UI
85
+ const container = document.createElement('div');
86
+ container.style.width = '100%';
87
+ container.style.height = '100%';
88
+ container.style.display = 'flex';
89
+ container.style.flexDirection = 'column';
90
+ container.style.background = '#fff';
91
+ container.style.overflow = 'hidden';
92
+ container.style.boxSizing = 'border-box';
93
+ // Create navigation bar
94
+ const navBar = document.createElement('div');
95
+ navBar.style.display = 'flex';
96
+ navBar.style.alignItems = 'center';
97
+ navBar.style.gap = '4px';
98
+ navBar.style.padding = '6px 8px';
99
+ navBar.style.borderBottom = '1px solid #ccc';
100
+ navBar.style.background = '#f5f5f5';
101
+ navBar.style.flexShrink = '0';
102
+ navBar.style.boxSizing = 'border-box';
103
+ // Back button
104
+ const backButton = document.createElement('button');
105
+ backButton.innerHTML = '←';
106
+ backButton.style.padding = '0';
107
+ backButton.style.margin = '0';
108
+ backButton.style.cursor = 'pointer';
109
+ backButton.style.border = '1px solid #ccc';
110
+ backButton.style.borderRadius = '4px';
111
+ backButton.style.background = '#fff';
112
+ backButton.style.color = '#000';
113
+ backButton.style.fontSize = '16px';
114
+ backButton.style.width = '32px';
115
+ backButton.style.height = '28px';
116
+ backButton.style.display = 'flex';
117
+ backButton.style.alignItems = 'center';
118
+ backButton.style.justifyContent = 'center';
119
+ backButton.style.flexShrink = '0';
120
+ backButton.style.boxSizing = 'border-box';
121
+ backButton.style.lineHeight = '1';
122
+ backButton.style.verticalAlign = 'middle';
123
+ backButton.disabled = true;
124
+ backButton.style.opacity = backButton.disabled ? '0.5' : '1';
125
+ // Forward button
126
+ const forwardButton = document.createElement('button');
127
+ forwardButton.innerHTML = '→';
128
+ forwardButton.style.padding = '0';
129
+ forwardButton.style.margin = '0';
130
+ forwardButton.style.cursor = 'pointer';
131
+ forwardButton.style.border = '1px solid #ccc';
132
+ forwardButton.style.borderRadius = '4px';
133
+ forwardButton.style.background = '#fff';
134
+ forwardButton.style.color = '#000';
135
+ forwardButton.style.fontSize = '16px';
136
+ forwardButton.style.width = '32px';
137
+ forwardButton.style.height = '28px';
138
+ forwardButton.style.display = 'flex';
139
+ forwardButton.style.alignItems = 'center';
140
+ forwardButton.style.justifyContent = 'center';
141
+ forwardButton.style.flexShrink = '0';
142
+ forwardButton.style.boxSizing = 'border-box';
143
+ forwardButton.style.lineHeight = '1';
144
+ forwardButton.style.verticalAlign = 'middle';
145
+ forwardButton.disabled = true;
146
+ forwardButton.style.opacity = forwardButton.disabled ? '0.5' : '1';
147
+ // URL input
148
+ const urlInput = document.createElement('input');
149
+ urlInput.type = 'text';
150
+ urlInput.value = url;
151
+ urlInput.style.flex = '1';
152
+ urlInput.style.minWidth = '0';
153
+ urlInput.style.padding = '6px 12px';
154
+ urlInput.style.border = '1px solid #ccc';
155
+ urlInput.style.borderRadius = '4px';
156
+ urlInput.style.fontSize = '14px';
157
+ urlInput.style.height = '28px';
158
+ urlInput.style.boxSizing = 'border-box';
159
+ urlInput.style.margin = '0';
160
+ urlInput.style.verticalAlign = 'middle';
161
+ // Refresh button
162
+ const refreshButton = document.createElement('button');
163
+ refreshButton.innerHTML = '↻';
164
+ refreshButton.style.padding = '0';
165
+ refreshButton.style.margin = '0';
166
+ refreshButton.style.cursor = 'pointer';
167
+ refreshButton.style.border = '1px solid #ccc';
168
+ refreshButton.style.borderRadius = '4px';
169
+ refreshButton.style.background = '#fff';
170
+ refreshButton.style.color = '#000';
171
+ refreshButton.style.fontSize = '16px';
172
+ refreshButton.style.width = '32px';
173
+ refreshButton.style.height = '28px';
174
+ refreshButton.style.display = 'flex';
175
+ refreshButton.style.alignItems = 'center';
176
+ refreshButton.style.justifyContent = 'center';
177
+ refreshButton.style.flexShrink = '0';
178
+ refreshButton.style.boxSizing = 'border-box';
179
+ refreshButton.style.lineHeight = '1';
180
+ refreshButton.style.verticalAlign = 'middle';
181
+ navBar.appendChild(backButton);
182
+ navBar.appendChild(forwardButton);
183
+ navBar.appendChild(urlInput);
184
+ navBar.appendChild(refreshButton);
185
+ const iframeContainer = document.createElement('div');
186
+ iframeContainer.style.flex = '1';
187
+ iframeContainer.style.position = 'relative';
188
+ iframeContainer.style.overflow = 'hidden';
189
+ const iframe = document.createElement('iframe');
190
+ iframe.style.width = '100%';
191
+ iframe.style.height = '100%';
192
+ iframe.style.border = 'none';
193
+ iframe.setAttribute('credentialless', '');
194
+ iframe.src = url;
195
+ iframeContainer.appendChild(iframe);
196
+ // Only append navbar if not hidden
197
+ if (!hideNavbar)
198
+ container.appendChild(navBar);
199
+ container.appendChild(iframeContainer);
200
+ // Navigation history
201
+ const history = [url];
202
+ let historyIndex = 0;
203
+ // Update navigation buttons state
204
+ const updateNavButtons = () => {
205
+ if (!hideNavbar) {
206
+ backButton.disabled = historyIndex <= 0;
207
+ backButton.style.opacity = backButton.disabled ? '0.5' : '1';
208
+ forwardButton.disabled = historyIndex >= history.length - 1;
209
+ forwardButton.style.opacity = forwardButton.disabled ? '0.5' : '1';
210
+ }
211
+ };
212
+ // Navigate to URL
213
+ const navigateTo = (targetUrl, addToHistory = true) => {
214
+ try {
215
+ const normalizedUrl = normalizeUrl(targetUrl);
216
+ new URL(normalizedUrl); // Validate URL
217
+ if (addToHistory) {
218
+ // Remove forward history if we're navigating to a new URL
219
+ if (historyIndex < history.length - 1)
220
+ history.splice(historyIndex + 1);
221
+ history.push(normalizedUrl);
222
+ historyIndex = history.length - 1;
223
+ }
224
+ iframe.src = normalizedUrl;
225
+ if (!hideNavbar) {
226
+ urlInput.value = normalizedUrl;
227
+ }
228
+ updateNavButtons();
229
+ }
230
+ catch (error) {
231
+ terminal.writeln(chalk.red(`Invalid URL: ${targetUrl}`));
232
+ }
233
+ };
234
+ // Only set up button handlers if navbar is visible
235
+ if (!hideNavbar) {
236
+ // Add hover effects
237
+ const addHoverEffect = (button) => {
238
+ button.addEventListener('mouseenter', () => {
239
+ if (!button.disabled) {
240
+ button.style.background = '#f0f0f0';
241
+ }
242
+ });
243
+ button.addEventListener('mouseleave', () => {
244
+ button.style.background = '#fff';
245
+ });
246
+ };
247
+ addHoverEffect(backButton);
248
+ addHoverEffect(forwardButton);
249
+ addHoverEffect(refreshButton);
250
+ // Back button handler
251
+ backButton.addEventListener('click', () => {
252
+ if (historyIndex > 0) {
253
+ historyIndex--;
254
+ const targetUrl = history[historyIndex];
255
+ if (targetUrl) {
256
+ iframe.src = targetUrl;
257
+ urlInput.value = targetUrl;
258
+ updateNavButtons();
259
+ }
260
+ }
261
+ });
262
+ // Forward button handler
263
+ forwardButton.addEventListener('click', () => {
264
+ if (historyIndex < history.length - 1) {
265
+ historyIndex++;
266
+ const targetUrl = history[historyIndex];
267
+ if (targetUrl) {
268
+ iframe.src = targetUrl;
269
+ urlInput.value = targetUrl;
270
+ updateNavButtons();
271
+ }
272
+ }
273
+ });
274
+ }
275
+ // Only set up navbar event handlers if navbar is visible
276
+ if (!hideNavbar) {
277
+ // URL input handler (Enter key or blur)
278
+ const handleUrlSubmit = () => {
279
+ const inputValue = urlInput.value.trim();
280
+ if (inputValue) {
281
+ navigateTo(inputValue);
282
+ }
283
+ };
284
+ urlInput.addEventListener('keydown', (e) => {
285
+ if (e.key === 'Enter') {
286
+ e.preventDefault();
287
+ handleUrlSubmit();
288
+ }
289
+ });
290
+ urlInput.addEventListener('blur', handleUrlSubmit);
291
+ // Refresh button handler
292
+ refreshButton.addEventListener('click', () => {
293
+ iframe.src = iframe.src;
294
+ });
295
+ // Update URL bar when iframe navigates (for same-origin or when possible)
296
+ iframe.addEventListener('load', () => {
297
+ try {
298
+ // Try to get the current URL from iframe (may fail due to CORS)
299
+ const iframeUrl = iframe.contentWindow?.location.href;
300
+ if (iframeUrl && iframeUrl !== urlInput.value) {
301
+ urlInput.value = iframeUrl;
302
+ // Only add to history if it's a different URL
303
+ if (iframeUrl !== history[historyIndex])
304
+ navigateTo(iframeUrl);
305
+ }
306
+ }
307
+ catch (e) {
308
+ // CORS: Can't access iframe location, that's okay
309
+ // The URL bar will show what we set it to
310
+ }
311
+ updateNavButtons();
312
+ });
313
+ }
314
+ else {
315
+ // Still track history even without navbar
316
+ iframe.addEventListener('load', () => {
317
+ try {
318
+ const iframeUrl = iframe.contentWindow?.location.href;
319
+ if (iframeUrl && iframeUrl !== history[historyIndex]) {
320
+ navigateTo(iframeUrl, true);
321
+ }
322
+ }
323
+ catch (e) {
324
+ // CORS: Can't access iframe location
325
+ }
326
+ });
327
+ }
328
+ // Create window
329
+ const win = kernel.windows.create({
330
+ title: url,
331
+ width: Math.floor(window.innerWidth * 0.75),
332
+ height: Math.floor(window.innerHeight * 0.75),
333
+ x: 'center',
334
+ y: 'center',
335
+ onclose: () => false
336
+ });
337
+ // Mount container to window
338
+ win.mount(container);
339
+ // Update window title when URL changes (only if navbar is visible)
340
+ if (!hideNavbar) {
341
+ const updateTitle = () => win.setTitle(urlInput.value);
342
+ urlInput.addEventListener('input', updateTitle);
343
+ }
344
+ return 0;
345
+ }
346
+ });
347
+ }
348
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  import { TerminalCommand } from '../shared/terminal-command.js';
2
- import { writelnStdout } from '../shared/helpers.js';
2
+ import { writelnStdout, writelnStderr } from '../shared/helpers.js';
3
3
  function printUsage(process, terminal) {
4
4
  const usage = `Usage: whoami
5
5
  Print effective user ID.
6
6
 
7
7
  --help display this help and exit`;
8
- writelnStdout(process, terminal, usage);
8
+ writelnStderr(process, terminal, usage);
9
9
  }
10
10
  export function createCommand(kernel, shell, terminal) {
11
11
  return new TerminalCommand({
@@ -1 +1 @@
1
- {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEpD,SAAS,UAAU,CAAC,OAA4B,EAAE,QAAkB;IAClE,MAAM,KAAK,GAAG;;;qCAGqB,CAAA;IACnC,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;AACzC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,KAAY,EAAE,QAAkB;IAC5E,OAAO,IAAI,eAAe,CAAC;QACzB,OAAO,EAAE,QAAQ;QACjB,WAAW,EAAE,yBAAyB;QACtC,MAAM;QACN,KAAK;QACL,QAAQ;QACR,GAAG,EAAE,KAAK,EAAE,GAAW,EAAE,IAAc,EAAE,EAAE;YACzC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAwB,CAAA;YAEhE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;gBAClE,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;gBAC7B,OAAO,CAAC,CAAA;YACV,CAAC;YAED,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;YACtD,OAAO,CAAC,CAAA;QACV,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEnE,SAAS,UAAU,CAAC,OAA4B,EAAE,QAAkB;IAClE,MAAM,KAAK,GAAG;;;qCAGqB,CAAA;IACnC,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;AACzC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,KAAY,EAAE,QAAkB;IAC5E,OAAO,IAAI,eAAe,CAAC;QACzB,OAAO,EAAE,QAAQ;QACjB,WAAW,EAAE,yBAAyB;QACtC,MAAM;QACN,KAAK;QACL,QAAQ;QACR,GAAG,EAAE,KAAK,EAAE,GAAW,EAAE,IAAc,EAAE,EAAE;YACzC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAwB,CAAA;YAEhE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;gBAClE,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;gBAC7B,OAAO,CAAC,CAAA;YACV,CAAC;YAED,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;YACtD,OAAO,CAAC,CAAA;QACV,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Kernel, Shell, Terminal } from '@ecmaos/types';
2
+ import { TerminalCommand } from '../shared/terminal-command.js';
3
+ export declare function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand;
4
+ //# sourceMappingURL=zip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip.d.ts","sourceRoot":"","sources":["../../src/commands/zip.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAW,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAiM/D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,eAAe,CA0H/F"}
@@ -0,0 +1,264 @@
1
+ import path from 'path';
2
+ import * as zipjs from '@zip.js/zip.js';
3
+ import { TerminalCommand } from '../shared/terminal-command.js';
4
+ import { writelnStdout, writelnStderr } from '../shared/helpers.js';
5
+ import chalk from 'chalk';
6
+ function printUsage(process, terminal) {
7
+ const usage = `Usage: zip [OPTION]... ZIPFILE FILE...
8
+ Create a zip archive containing the specified files and directories.
9
+
10
+ -r, --recurse recurse into directories
11
+ -l, --list list contents of zip file
12
+ -v, --verbose verbose mode
13
+ -h, --help display this help and exit
14
+
15
+ Examples:
16
+ zip archive.zip file1.txt file2.txt
17
+ zip -r archive.zip directory/
18
+ zip -l archive.zip`;
19
+ writelnStderr(process, terminal, usage);
20
+ }
21
+ function parseArgs(argv) {
22
+ const options = {
23
+ recurse: false,
24
+ list: false,
25
+ verbose: false
26
+ };
27
+ const files = [];
28
+ let zipfile = null;
29
+ let i = 0;
30
+ while (i < argv.length) {
31
+ const arg = argv[i];
32
+ if (!arg) {
33
+ i++;
34
+ continue;
35
+ }
36
+ if (arg === '--help' || arg === '-h') {
37
+ i++;
38
+ continue;
39
+ }
40
+ else if (arg === '-r' || arg === '--recurse') {
41
+ options.recurse = true;
42
+ i++;
43
+ }
44
+ else if (arg === '-l' || arg === '--list') {
45
+ options.list = true;
46
+ i++;
47
+ }
48
+ else if (arg === '-v' || arg === '--verbose') {
49
+ options.verbose = true;
50
+ i++;
51
+ }
52
+ else if (arg.startsWith('-')) {
53
+ // Handle combined flags like -rv
54
+ const flags = arg.slice(1).split('');
55
+ for (const flag of flags) {
56
+ if (flag === 'r')
57
+ options.recurse = true;
58
+ else if (flag === 'l')
59
+ options.list = true;
60
+ else if (flag === 'v')
61
+ options.verbose = true;
62
+ }
63
+ i++;
64
+ }
65
+ else {
66
+ // First non-option argument is the zipfile
67
+ if (!zipfile) {
68
+ zipfile = arg;
69
+ }
70
+ else {
71
+ files.push(arg);
72
+ }
73
+ i++;
74
+ }
75
+ }
76
+ return { options, zipfile, files };
77
+ }
78
+ async function addDirectory(zipWriter, dirPath, basePath, shell, terminal, process, verbose) {
79
+ const entries = await shell.context.fs.promises.readdir(dirPath);
80
+ for (const entry of entries) {
81
+ const entryPath = path.join(dirPath, entry);
82
+ const relativePath = path.relative(basePath, entryPath);
83
+ const entryStat = await shell.context.fs.promises.stat(entryPath);
84
+ if (entryStat.isFile()) {
85
+ const fileData = await shell.context.fs.promises.readFile(entryPath);
86
+ const reader = new zipjs.Uint8ArrayReader(fileData);
87
+ await zipWriter.add(relativePath, reader);
88
+ if (verbose) {
89
+ await writelnStdout(process, terminal, ` adding: ${relativePath}`);
90
+ }
91
+ }
92
+ else if (entryStat.isDirectory()) {
93
+ await addDirectory(zipWriter, entryPath, basePath, shell, terminal, process, verbose);
94
+ }
95
+ }
96
+ }
97
+ async function listZipContents(zipfilePath, shell, terminal, process) {
98
+ try {
99
+ const zipData = await shell.context.fs.promises.readFile(zipfilePath);
100
+ const blob = new Blob([new Uint8Array(zipData)]);
101
+ const zipReader = new zipjs.ZipReader(new zipjs.BlobReader(blob));
102
+ const entries = await zipReader.getEntries();
103
+ if (entries.length === 0) {
104
+ await writelnStdout(process, terminal, 'Archive: ' + path.basename(zipfilePath));
105
+ await writelnStdout(process, terminal, ' Empty archive');
106
+ await zipReader.close();
107
+ return 0;
108
+ }
109
+ // Calculate column widths
110
+ let maxLength = 0;
111
+ let maxSize = 0;
112
+ for (const entry of entries) {
113
+ if (entry.filename.length > maxLength)
114
+ maxLength = entry.filename.length;
115
+ const size = entry.uncompressedSize || 0;
116
+ if (size > maxSize)
117
+ maxSize = size;
118
+ }
119
+ const sizeWidth = Math.max(12, String(maxSize).length);
120
+ const nameWidth = Math.max(20, maxLength);
121
+ await writelnStdout(process, terminal, `Archive: ${path.basename(zipfilePath)}`);
122
+ await writelnStdout(process, terminal, '');
123
+ await writelnStdout(process, terminal, ` Length Date Time Name`.padEnd(nameWidth + sizeWidth + 20));
124
+ await writelnStdout(process, terminal, ` ${'-'.repeat(sizeWidth)} ${'-'.repeat(10)} ${'-'.repeat(5)} ${'-'.repeat(nameWidth)}`);
125
+ let totalLength = 0;
126
+ for (const entry of entries) {
127
+ const length = entry.uncompressedSize || 0;
128
+ totalLength += length;
129
+ let date = '--';
130
+ let time = '--';
131
+ if (entry.lastModDate) {
132
+ const d = new Date(entry.lastModDate);
133
+ const month = String(d.getMonth() + 1).padStart(2, '0');
134
+ const day = String(d.getDate()).padStart(2, '0');
135
+ const year = String(d.getFullYear()).slice(-2);
136
+ date = `${month}-${day}-${year}`;
137
+ const hours = String(d.getHours()).padStart(2, '0');
138
+ const minutes = String(d.getMinutes()).padStart(2, '0');
139
+ time = `${hours}:${minutes}`;
140
+ }
141
+ const name = entry.directory ? entry.filename + '/' : entry.filename;
142
+ const lengthStr = entry.directory ? '' : String(length).padStart(sizeWidth);
143
+ await writelnStdout(process, terminal, ` ${lengthStr.padEnd(sizeWidth)} ${date.padEnd(10)} ${time.padEnd(5)} ${name}`);
144
+ }
145
+ await writelnStdout(process, terminal, ` ${'-'.repeat(sizeWidth)} ${'-'.repeat(10)} ${'-'.repeat(5)} ${'-'.repeat(nameWidth)}`);
146
+ await writelnStdout(process, terminal, ` ${String(totalLength).padStart(sizeWidth)} ${entries.length} file${entries.length !== 1 ? 's' : ''}`);
147
+ await zipReader.close();
148
+ return 0;
149
+ }
150
+ catch (error) {
151
+ await writelnStderr(process, terminal, chalk.red(`zip error: ${error instanceof Error ? error.message : 'Unknown error'}`));
152
+ return 1;
153
+ }
154
+ }
155
+ export function createCommand(kernel, shell, terminal) {
156
+ return new TerminalCommand({
157
+ command: 'zip',
158
+ description: 'Create zip archives',
159
+ kernel,
160
+ shell,
161
+ terminal,
162
+ run: async (pid, argv) => {
163
+ const process = kernel.processes.get(pid);
164
+ if (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h')) {
165
+ printUsage(process, terminal);
166
+ return 0;
167
+ }
168
+ const { options, zipfile, files } = parseArgs(argv);
169
+ // List mode
170
+ if (options.list) {
171
+ if (!zipfile) {
172
+ await writelnStderr(process, terminal, chalk.red('zip error: zipfile name required'));
173
+ await writelnStderr(process, terminal, "Try 'zip --help' for more information.");
174
+ return 1;
175
+ }
176
+ const zipfilePath = path.resolve(shell.cwd, zipfile);
177
+ const exists = await shell.context.fs.promises.exists(zipfilePath);
178
+ if (!exists) {
179
+ await writelnStderr(process, terminal, chalk.red(`zip error: ${zipfile}: No such file or directory`));
180
+ return 1;
181
+ }
182
+ return await listZipContents(zipfilePath, shell, terminal, process);
183
+ }
184
+ // Create mode
185
+ if (!zipfile) {
186
+ await writelnStderr(process, terminal, chalk.red('zip error: zipfile name required'));
187
+ await writelnStderr(process, terminal, "Try 'zip --help' for more information.");
188
+ return 1;
189
+ }
190
+ if (files.length === 0) {
191
+ await writelnStderr(process, terminal, chalk.red('zip error: nothing to do'));
192
+ await writelnStderr(process, terminal, "Try 'zip --help' for more information.");
193
+ return 1;
194
+ }
195
+ const outputPath = path.resolve(shell.cwd, zipfile);
196
+ let zipWriter = null;
197
+ let hasError = false;
198
+ try {
199
+ zipWriter = new zipjs.ZipWriter(new zipjs.BlobWriter());
200
+ for (const inputPath of files) {
201
+ const fullPath = path.resolve(shell.cwd, inputPath);
202
+ try {
203
+ const exists = await shell.context.fs.promises.exists(fullPath);
204
+ if (!exists) {
205
+ await writelnStderr(process, terminal, chalk.red(`zip warning: ${inputPath}: No such file or directory`));
206
+ hasError = true;
207
+ continue;
208
+ }
209
+ const fileStat = await shell.context.fs.promises.stat(fullPath);
210
+ if (fileStat.isFile()) {
211
+ // Add single file
212
+ const relativePath = path.relative(shell.cwd, fullPath);
213
+ const fileData = await shell.context.fs.promises.readFile(fullPath);
214
+ const reader = new zipjs.Uint8ArrayReader(fileData);
215
+ await zipWriter.add(relativePath, reader);
216
+ if (options.verbose) {
217
+ await writelnStdout(process, terminal, ` adding: ${relativePath}`);
218
+ }
219
+ }
220
+ else if (fileStat.isDirectory()) {
221
+ if (options.recurse) {
222
+ // Add directory and contents recursively
223
+ await addDirectory(zipWriter, fullPath, shell.cwd, shell, terminal, process, options.verbose);
224
+ if (options.verbose) {
225
+ await writelnStdout(process, terminal, ` adding: ${path.relative(shell.cwd, fullPath)}/`);
226
+ }
227
+ }
228
+ else {
229
+ await writelnStderr(process, terminal, chalk.yellow(`zip warning: ${inputPath}: is a directory (not added). Use -r to recurse into directories`));
230
+ hasError = true;
231
+ }
232
+ }
233
+ else {
234
+ await writelnStderr(process, terminal, chalk.red(`zip error: ${inputPath}: Not a file or directory`));
235
+ hasError = true;
236
+ }
237
+ }
238
+ catch (err) {
239
+ await writelnStderr(process, terminal, chalk.red(`zip error: ${inputPath}: ${err instanceof Error ? err.message : 'Unknown error'}`));
240
+ hasError = true;
241
+ }
242
+ }
243
+ // Write the zip file
244
+ const blob = await zipWriter.close();
245
+ zipWriter = null; // Clear reference after closing
246
+ await shell.context.fs.promises.writeFile(outputPath, new Uint8Array(await blob.arrayBuffer()));
247
+ if (options.verbose) {
248
+ await writelnStdout(process, terminal, ` zipfile: ${zipfile}`);
249
+ }
250
+ return hasError ? 1 : 0;
251
+ }
252
+ catch (err) {
253
+ await writelnStderr(process, terminal, chalk.red(`zip error: ${err instanceof Error ? err.message : 'Unknown error'}`));
254
+ return 1;
255
+ }
256
+ finally {
257
+ if (zipWriter) {
258
+ await zipWriter.close();
259
+ }
260
+ }
261
+ }
262
+ });
263
+ }
264
+ //# sourceMappingURL=zip.js.map