@edgible-team/cli 1.2.15 → 1.2.19

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 (212) hide show
  1. package/README.md +5 -3
  2. package/dist/client/api-client.d.ts +26 -1
  3. package/dist/client/api-client.d.ts.map +1 -1
  4. package/dist/client/api-client.js +31 -0
  5. package/dist/commands/agent/install.d.ts +2 -1
  6. package/dist/commands/agent/install.d.ts.map +1 -1
  7. package/dist/commands/agent/install.js +24 -7
  8. package/dist/commands/agent/start.d.ts +5 -1
  9. package/dist/commands/agent/start.d.ts.map +1 -1
  10. package/dist/commands/agent/start.js +19 -280
  11. package/dist/commands/agent/uninstall.d.ts.map +1 -1
  12. package/dist/commands/agent/uninstall.js +14 -7
  13. package/dist/commands/agent.d.ts.map +1 -1
  14. package/dist/commands/agent.js +3 -2
  15. package/dist/commands/ai/setup.d.ts +1 -1
  16. package/dist/commands/ai/setup.d.ts.map +1 -1
  17. package/dist/commands/ai.js +1 -1
  18. package/dist/commands/application/create-docker-compose.d.ts +3 -1
  19. package/dist/commands/application/create-docker-compose.d.ts.map +1 -1
  20. package/dist/commands/application/create-docker-compose.js +25 -69
  21. package/dist/commands/application/create-existing.d.ts +2 -2
  22. package/dist/commands/application/create-existing.d.ts.map +1 -1
  23. package/dist/commands/application/create-existing.js +27 -132
  24. package/dist/commands/application/create-managed-process.d.ts +3 -1
  25. package/dist/commands/application/create-managed-process.d.ts.map +1 -1
  26. package/dist/commands/application/create-managed-process.js +31 -75
  27. package/dist/commands/application/create-stubs.d.ts +0 -1
  28. package/dist/commands/application/create-stubs.d.ts.map +1 -1
  29. package/dist/commands/application/create-stubs.js +0 -4
  30. package/dist/commands/application/create-vm.d.ts +19 -0
  31. package/dist/commands/application/create-vm.d.ts.map +1 -0
  32. package/dist/commands/application/create-vm.js +390 -0
  33. package/dist/commands/application/delete.d.ts +2 -1
  34. package/dist/commands/application/delete.d.ts.map +1 -1
  35. package/dist/commands/application/delete.js +19 -5
  36. package/dist/commands/application/get.d.ts.map +1 -1
  37. package/dist/commands/application/get.js +29 -1
  38. package/dist/commands/application/ssh.d.ts +7 -0
  39. package/dist/commands/application/ssh.d.ts.map +1 -0
  40. package/dist/commands/application/ssh.js +146 -0
  41. package/dist/commands/application/update.d.ts +3 -0
  42. package/dist/commands/application/update.d.ts.map +1 -1
  43. package/dist/commands/application/update.js +45 -1
  44. package/dist/commands/application.d.ts.map +1 -1
  45. package/dist/commands/application.js +81 -26
  46. package/dist/commands/auth.d.ts.map +1 -1
  47. package/dist/commands/auth.js +44 -0
  48. package/dist/commands/debug.js +1 -1
  49. package/dist/commands/device/application-health.d.ts +7 -0
  50. package/dist/commands/device/application-health.d.ts.map +1 -0
  51. package/dist/commands/device/application-health.js +103 -0
  52. package/dist/commands/device/delete.d.ts +7 -0
  53. package/dist/commands/device/delete.d.ts.map +1 -0
  54. package/dist/commands/device/delete.js +69 -0
  55. package/dist/commands/device/health.d.ts +7 -0
  56. package/dist/commands/device/health.d.ts.map +1 -0
  57. package/dist/commands/device/health.js +78 -0
  58. package/dist/commands/device/list.d.ts +5 -0
  59. package/dist/commands/device/list.d.ts.map +1 -0
  60. package/dist/commands/device/list.js +46 -0
  61. package/dist/commands/device/telemetry.d.ts +8 -0
  62. package/dist/commands/device/telemetry.d.ts.map +1 -0
  63. package/dist/commands/device/telemetry.js +59 -0
  64. package/dist/commands/device.d.ts +6 -0
  65. package/dist/commands/device.d.ts.map +1 -0
  66. package/dist/commands/device.js +86 -0
  67. package/dist/commands/stack/deploy.d.ts +3 -1
  68. package/dist/commands/stack/deploy.d.ts.map +1 -1
  69. package/dist/commands/stack/deploy.js +5 -2
  70. package/dist/commands/stack/diff.d.ts +1 -1
  71. package/dist/commands/stack/diff.d.ts.map +1 -1
  72. package/dist/commands/stack/diff.js +4 -2
  73. package/dist/commands/stack/status.d.ts +1 -1
  74. package/dist/commands/stack/status.d.ts.map +1 -1
  75. package/dist/commands/stack/status.js +4 -2
  76. package/dist/commands/stack/teardown.d.ts +3 -1
  77. package/dist/commands/stack/teardown.d.ts.map +1 -1
  78. package/dist/commands/stack/teardown.js +5 -2
  79. package/dist/commands/stack/validate.d.ts +1 -1
  80. package/dist/commands/stack/validate.d.ts.map +1 -1
  81. package/dist/commands/stack/validate.js +4 -2
  82. package/dist/commands/stack.d.ts.map +1 -1
  83. package/dist/commands/stack.js +10 -5
  84. package/dist/commands/utils/auth-prompt.d.ts +25 -0
  85. package/dist/commands/utils/auth-prompt.d.ts.map +1 -0
  86. package/dist/commands/utils/auth-prompt.js +115 -0
  87. package/dist/commands/utils/device-prompt.d.ts +18 -0
  88. package/dist/commands/utils/device-prompt.d.ts.map +1 -0
  89. package/dist/commands/utils/device-prompt.js +58 -0
  90. package/dist/commands/utils/output-formatter.d.ts +13 -0
  91. package/dist/commands/utils/output-formatter.d.ts.map +1 -1
  92. package/dist/commands/utils/output-formatter.js +21 -0
  93. package/dist/index.js +2 -0
  94. package/dist/services/LocalAgentManager.d.ts +2 -1
  95. package/dist/services/LocalAgentManager.d.ts.map +1 -1
  96. package/dist/services/LocalAgentManager.js +6 -4
  97. package/dist/services/application/ApplicationService.d.ts +41 -2
  98. package/dist/services/application/ApplicationService.d.ts.map +1 -1
  99. package/dist/services/application/ApplicationService.js +49 -1
  100. package/dist/services/device/DeviceService.d.ts +62 -0
  101. package/dist/services/device/DeviceService.d.ts.map +1 -0
  102. package/dist/services/device/DeviceService.js +235 -0
  103. package/dist/services/edgible.d.ts +3 -1
  104. package/dist/services/edgible.d.ts.map +1 -1
  105. package/dist/services/edgible.js +5 -4
  106. package/dist/services/instances.d.ts +4 -1
  107. package/dist/services/instances.d.ts.map +1 -1
  108. package/dist/services/instances.js +8 -4
  109. package/dist/types/AgentConfig.d.ts +26 -0
  110. package/dist/types/AgentConfig.d.ts.map +1 -1
  111. package/dist/types/ApiRequests.d.ts +5 -1
  112. package/dist/types/ApiRequests.d.ts.map +1 -1
  113. package/dist/types/ApiResponses.d.ts +9 -0
  114. package/dist/types/ApiResponses.d.ts.map +1 -1
  115. package/dist/types/JobTypes.d.ts +103 -0
  116. package/dist/types/JobTypes.d.ts.map +1 -0
  117. package/dist/types/JobTypes.js +80 -0
  118. package/dist/types/WebSocketMessages.d.ts +89 -0
  119. package/dist/types/WebSocketMessages.d.ts.map +1 -0
  120. package/dist/types/WebSocketMessages.js +5 -0
  121. package/dist/types/Workload.d.ts +1 -1
  122. package/dist/types/Workload.d.ts.map +1 -1
  123. package/dist/types/backendJobs.d.ts +102 -0
  124. package/dist/types/backendJobs.d.ts.map +1 -0
  125. package/dist/types/backendJobs.js +5 -0
  126. package/dist/types/models/ApplicationData.d.ts +1 -1
  127. package/dist/types/models/ApplicationData.d.ts.map +1 -1
  128. package/dist/types/models/DeviceData.d.ts +4 -0
  129. package/dist/types/models/DeviceData.d.ts.map +1 -1
  130. package/dist/types/stack.d.ts +9 -1
  131. package/dist/types/stack.d.ts.map +1 -1
  132. package/dist/types/validation/schemas.d.ts +5 -5
  133. package/dist/types/validation/schemas.js +1 -1
  134. package/dist/utils/stack-file.d.ts +11 -0
  135. package/dist/utils/stack-file.d.ts.map +1 -0
  136. package/dist/utils/stack-file.js +66 -0
  137. package/dist/validation/stack-schemas.d.ts +319 -27
  138. package/dist/validation/stack-schemas.d.ts.map +1 -1
  139. package/dist/validation/stack-schemas.js +20 -5
  140. package/package.json +1 -1
  141. package/dist/commands/agent/agent-handlers.d.ts +0 -45
  142. package/dist/commands/agent/agent-handlers.d.ts.map +0 -1
  143. package/dist/commands/agent/agent-handlers.js +0 -1159
  144. package/dist/commands/application/api-keys.d.ts +0 -3
  145. package/dist/commands/application/api-keys.d.ts.map +0 -1
  146. package/dist/commands/application/api-keys.js +0 -227
  147. package/dist/commands/application/create-compose.d.ts +0 -3
  148. package/dist/commands/application/create-compose.d.ts.map +0 -1
  149. package/dist/commands/application/create-compose.js +0 -381
  150. package/dist/commands/application/create-interactive.d.ts +0 -3
  151. package/dist/commands/application/create-interactive.d.ts.map +0 -1
  152. package/dist/commands/application/create-interactive.js +0 -326
  153. package/dist/commands/application/create-workload.d.ts +0 -5
  154. package/dist/commands/application/create-workload.d.ts.map +0 -1
  155. package/dist/commands/application/create-workload.js +0 -48
  156. package/dist/commands/application/short-codes.d.ts +0 -3
  157. package/dist/commands/application/short-codes.d.ts.map +0 -1
  158. package/dist/commands/application/short-codes.js +0 -226
  159. package/dist/commands/application/toggle.d.ts +0 -2
  160. package/dist/commands/application/toggle.d.ts.map +0 -1
  161. package/dist/commands/application/toggle.js +0 -78
  162. package/dist/commands/examples/migrated-command-example.d.ts +0 -31
  163. package/dist/commands/examples/migrated-command-example.d.ts.map +0 -1
  164. package/dist/commands/examples/migrated-command-example.js +0 -180
  165. package/dist/commands/managedGateway/create.d.ts +0 -6
  166. package/dist/commands/managedGateway/create.d.ts.map +0 -1
  167. package/dist/commands/managedGateway/create.js +0 -50
  168. package/dist/commands/managedGateway/delete.d.ts +0 -5
  169. package/dist/commands/managedGateway/delete.d.ts.map +0 -1
  170. package/dist/commands/managedGateway/delete.js +0 -57
  171. package/dist/commands/managedGateway/get.d.ts +0 -4
  172. package/dist/commands/managedGateway/get.d.ts.map +0 -1
  173. package/dist/commands/managedGateway/get.js +0 -71
  174. package/dist/commands/managedGateway/haproxy-stats.d.ts +0 -6
  175. package/dist/commands/managedGateway/haproxy-stats.d.ts.map +0 -1
  176. package/dist/commands/managedGateway/haproxy-stats.js +0 -131
  177. package/dist/commands/managedGateway/list.d.ts +0 -4
  178. package/dist/commands/managedGateway/list.d.ts.map +0 -1
  179. package/dist/commands/managedGateway/list.js +0 -50
  180. package/dist/commands/managedGateway/logs.d.ts +0 -10
  181. package/dist/commands/managedGateway/logs.d.ts.map +0 -1
  182. package/dist/commands/managedGateway/logs.js +0 -100
  183. package/dist/commands/managedGateway/reboot.d.ts +0 -5
  184. package/dist/commands/managedGateway/reboot.d.ts.map +0 -1
  185. package/dist/commands/managedGateway/reboot.js +0 -95
  186. package/dist/commands/managedGateway/resync.d.ts +0 -10
  187. package/dist/commands/managedGateway/resync.d.ts.map +0 -1
  188. package/dist/commands/managedGateway/resync.js +0 -69
  189. package/dist/commands/managedGateway/ssh.d.ts +0 -4
  190. package/dist/commands/managedGateway/ssh.d.ts.map +0 -1
  191. package/dist/commands/managedGateway/ssh.js +0 -130
  192. package/dist/commands/managedGateway/wipe-logs.d.ts +0 -4
  193. package/dist/commands/managedGateway/wipe-logs.d.ts.map +0 -1
  194. package/dist/commands/managedGateway/wipe-logs.js +0 -67
  195. package/dist/commands/managedGateway/wireguard.d.ts +0 -4
  196. package/dist/commands/managedGateway/wireguard.d.ts.map +0 -1
  197. package/dist/commands/managedGateway/wireguard.js +0 -68
  198. package/dist/di/bindings.d.ts +0 -15
  199. package/dist/di/bindings.d.ts.map +0 -1
  200. package/dist/di/bindings.js +0 -99
  201. package/dist/di/container.d.ts +0 -44
  202. package/dist/di/container.d.ts.map +0 -1
  203. package/dist/di/container.js +0 -88
  204. package/dist/di/types.d.ts +0 -23
  205. package/dist/di/types.d.ts.map +0 -1
  206. package/dist/di/types.js +0 -32
  207. package/dist/repositories/config-repository.d.ts +0 -46
  208. package/dist/repositories/config-repository.d.ts.map +0 -1
  209. package/dist/repositories/config-repository.js +0 -62
  210. package/dist/repositories/gateway-repository.d.ts +0 -37
  211. package/dist/repositories/gateway-repository.d.ts.map +0 -1
  212. package/dist/repositories/gateway-repository.js +0 -35
@@ -9,14 +9,16 @@ const chalk_1 = __importDefault(require("chalk"));
9
9
  const instances_1 = require("../../services/instances");
10
10
  const config_validator_1 = require("../utils/config-validator");
11
11
  const input_parser_1 = require("../utils/input-parser");
12
+ const auth_prompt_1 = require("../utils/auth-prompt");
12
13
  async function handleApplicationCreateManagedProcess(options) {
13
14
  (0, config_validator_1.validateConfig)(instances_1.configManager, {
14
15
  requireAuth: true,
15
16
  requireOrganization: true,
16
17
  });
18
+ const isInteractive = options.nonInteractive !== true;
17
19
  // Application name
18
20
  let appName = options.name;
19
- if (!appName && !options.noInteractive) {
21
+ if (!appName && isInteractive) {
20
22
  const { name } = await inquirer_1.default.prompt([
21
23
  {
22
24
  type: 'input',
@@ -32,7 +34,7 @@ async function handleApplicationCreateManagedProcess(options) {
32
34
  }
33
35
  // Command
34
36
  let command = options.command;
35
- if (!command && !options.noInteractive) {
37
+ if (!command && isInteractive) {
36
38
  const { cmd } = await inquirer_1.default.prompt([
37
39
  {
38
40
  type: 'input',
@@ -48,7 +50,7 @@ async function handleApplicationCreateManagedProcess(options) {
48
50
  }
49
51
  // Port
50
52
  let port = options.port ? (0, input_parser_1.parsePort)(options.port) : undefined;
51
- if (!port && !options.noInteractive) {
53
+ if (!port && isInteractive) {
52
54
  const { portInput } = await inquirer_1.default.prompt([
53
55
  {
54
56
  type: 'input',
@@ -68,7 +70,7 @@ async function handleApplicationCreateManagedProcess(options) {
68
70
  }
69
71
  // Working directory
70
72
  let workingDirectory = options.workingDir;
71
- if (!workingDirectory && !options.noInteractive) {
73
+ if (!workingDirectory && isInteractive) {
72
74
  const { dir } = await inquirer_1.default.prompt([
73
75
  {
74
76
  type: 'input',
@@ -91,7 +93,7 @@ async function handleApplicationCreateManagedProcess(options) {
91
93
  }
92
94
  }
93
95
  }
94
- else if (!options.noInteractive) {
96
+ else if (isInteractive) {
95
97
  const { addEnv } = await inquirer_1.default.prompt([
96
98
  {
97
99
  type: 'confirm',
@@ -132,7 +134,7 @@ async function handleApplicationCreateManagedProcess(options) {
132
134
  }
133
135
  // Log file
134
136
  let logFile = options.logFile;
135
- if (!logFile && !options.noInteractive) {
137
+ if (!logFile && isInteractive) {
136
138
  const { addLog } = await inquirer_1.default.prompt([
137
139
  {
138
140
  type: 'confirm',
@@ -155,18 +157,28 @@ async function handleApplicationCreateManagedProcess(options) {
155
157
  }
156
158
  // Description
157
159
  const description = options.description || `Managed process application for ${appName}`;
158
- // Protocol
159
- const protocol = (0, input_parser_1.parseProtocol)(options.protocol);
160
- // Device IDs and Gateway IDs
160
+ // Protocol: default HTTPS for HTTP(S) apps
161
+ const protocol = options.protocol ? (0, input_parser_1.parseProtocol)(options.protocol) : 'https';
162
+ // Device IDs and Gateway IDs. If --gateway-ids provided, use own gateways; else Edgible managed (default).
161
163
  let deviceId = options.deviceId;
162
164
  let gatewayIds = (0, input_parser_1.parseGatewayIds)(options.gatewayIds);
165
+ const useManagedGateway = gatewayIds.length === 0;
163
166
  let hostnames = Array.isArray(options.hostnames)
164
167
  ? options.hostnames
165
168
  : (typeof options.hostnames === 'string' && options.hostnames.trim().length > 0
166
169
  ? options.hostnames.split(',').map(s => s.trim()).filter(Boolean)
167
170
  : []);
168
- let useManagedGateway = false;
169
- if (!options.noInteractive) {
171
+ // Auth: use authModes (none | org | api-key | org+api-key)
172
+ const authModesFromFlag = (0, auth_prompt_1.parseAuthModes)(options.authModes);
173
+ const allowedOrgsFromFlag = options.allowedOrgs
174
+ ? options.allowedOrgs.split(',').map(s => s.trim()).filter(Boolean)
175
+ : [];
176
+ const { authModes, allowedOrganizations } = await (0, auth_prompt_1.promptAuthModes)({
177
+ authModesFromFlag: authModesFromFlag ?? undefined,
178
+ allowedOrgsFromFlag: allowedOrgsFromFlag.length > 0 ? allowedOrgsFromFlag : undefined,
179
+ nonInteractive: !isInteractive,
180
+ });
181
+ if (isInteractive) {
170
182
  // Optional: prompt for additional hostnames
171
183
  const { addHostnames } = await inquirer_1.default.prompt([
172
184
  {
@@ -179,70 +191,6 @@ async function handleApplicationCreateManagedProcess(options) {
179
191
  if (addHostnames && typeof addHostnames === 'string') {
180
192
  hostnames = addHostnames.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
181
193
  }
182
- // Prompt for managed gateway option
183
- if (gatewayIds.length === 0) {
184
- const { useManaged } = await inquirer_1.default.prompt([
185
- {
186
- type: 'confirm',
187
- name: 'useManaged',
188
- message: 'Use Edgible managed gateway?',
189
- default: false,
190
- },
191
- ]);
192
- useManagedGateway = useManaged;
193
- if (!useManagedGateway) {
194
- // Ask if they want to assign a gateway at all
195
- const { assignGateway } = await inquirer_1.default.prompt([
196
- {
197
- type: 'confirm',
198
- name: 'assignGateway',
199
- message: 'Assign a gateway to this application? (No = local/internal access only)',
200
- default: true,
201
- },
202
- ]);
203
- if (assignGateway) {
204
- // Try to offer a list of gateways (via service), else fallback to manual input
205
- try {
206
- const gatewaysResp = await instances_1.gatewayService.listGateways();
207
- const gatewayChoices = gatewaysResp.gateways.map((g) => ({
208
- name: `${g.device.name} (${g.device.id})`,
209
- value: g.device.id,
210
- }));
211
- if (gatewayChoices.length > 0) {
212
- const { selectedGateways } = await inquirer_1.default.prompt([
213
- {
214
- type: 'checkbox',
215
- name: 'selectedGateways',
216
- message: 'Select gateway device(s):',
217
- choices: gatewayChoices,
218
- validate: (vals) => vals.length > 0 ? true : 'Select at least one gateway',
219
- },
220
- ]);
221
- gatewayIds = selectedGateways;
222
- }
223
- }
224
- catch (error) {
225
- instances_1.logger.warn('Failed to list gateways', error);
226
- }
227
- if (gatewayIds.length === 0) {
228
- const ans2 = await inquirer_1.default.prompt([
229
- {
230
- type: 'input',
231
- name: 'gatewayIds',
232
- message: 'Enter comma-separated gateway device IDs (or leave empty for no gateway):',
233
- validate: (v) => true, // Allow empty input
234
- },
235
- ]);
236
- if (ans2.gatewayIds && ans2.gatewayIds.trim()) {
237
- gatewayIds = (0, input_parser_1.parseGatewayIds)(ans2.gatewayIds);
238
- }
239
- }
240
- }
241
- else {
242
- instances_1.logger.info('Application will be created without gateway assignment (local/internal access only)');
243
- }
244
- }
245
- }
246
194
  // Serving device selection
247
195
  if (!deviceId) {
248
196
  try {
@@ -344,6 +292,12 @@ async function handleApplicationCreateManagedProcess(options) {
344
292
  if (hostnames.length > 0) {
345
293
  console.log(chalk_1.default.gray(`Additional hostnames: ${hostnames.join(', ')}`));
346
294
  }
295
+ if (authModes.length > 0 && !authModes.every((m) => m === 'none')) {
296
+ console.log(chalk_1.default.gray(`Auth modes: ${authModes.join(', ')}`));
297
+ if (allowedOrganizations && allowedOrganizations.length > 0) {
298
+ console.log(chalk_1.default.gray(`Allowed organizations: ${allowedOrganizations.join(', ')}`));
299
+ }
300
+ }
347
301
  const result = await instances_1.applicationService.createApplicationProgrammatically({
348
302
  name: appName,
349
303
  description,
@@ -355,6 +309,8 @@ async function handleApplicationCreateManagedProcess(options) {
355
309
  useManagedGateway,
356
310
  subtype: 'managed-process',
357
311
  configuration,
312
+ authModes,
313
+ allowedOrganizations: allowedOrganizations && allowedOrganizations.length > 0 ? allowedOrganizations : undefined,
358
314
  });
359
315
  console.log(chalk_1.default.green('\n✓ Managed process application created successfully!'));
360
316
  console.log(chalk_1.default.blue('\n📋 Application Details:'));
@@ -1,4 +1,3 @@
1
1
  export declare function handleApplicationCreateDocker(): Promise<void>;
2
- export declare function handleApplicationCreateQemu(): Promise<void>;
3
2
  export declare function handleApplicationCreatePodman(): Promise<void>;
4
3
  //# sourceMappingURL=create-stubs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-stubs.d.ts","sourceRoot":"","sources":["../../../src/commands/application/create-stubs.ts"],"names":[],"mappings":"AAEA,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjE;AAED,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnE"}
1
+ {"version":3,"file":"create-stubs.d.ts","sourceRoot":"","sources":["../../../src/commands/application/create-stubs.ts"],"names":[],"mappings":"AAEA,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnE"}
@@ -4,15 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.handleApplicationCreateDocker = handleApplicationCreateDocker;
7
- exports.handleApplicationCreateQemu = handleApplicationCreateQemu;
8
7
  exports.handleApplicationCreatePodman = handleApplicationCreatePodman;
9
8
  const chalk_1 = __importDefault(require("chalk"));
10
9
  async function handleApplicationCreateDocker() {
11
10
  console.log(chalk_1.default.yellow('This workload type is currently not implemented.'));
12
11
  }
13
- async function handleApplicationCreateQemu() {
14
- console.log(chalk_1.default.yellow('This workload type is currently not implemented.'));
15
- }
16
12
  async function handleApplicationCreatePodman() {
17
13
  console.log(chalk_1.default.yellow('This workload type is currently not implemented.'));
18
14
  }
@@ -0,0 +1,19 @@
1
+ export declare function handleApplicationCreateVm(options: {
2
+ name?: string;
3
+ description?: string;
4
+ backend?: string;
5
+ diskImage?: string;
6
+ memory?: string;
7
+ cpus?: string;
8
+ sshPort?: string;
9
+ sshPublicKey?: string;
10
+ arch?: string;
11
+ port?: string;
12
+ deviceId?: string;
13
+ gatewayIds?: string;
14
+ hostnames?: string;
15
+ authModes?: string;
16
+ allowedOrgs?: string;
17
+ nonInteractive?: boolean;
18
+ }): Promise<void>;
19
+ //# sourceMappingURL=create-vm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-vm.d.ts","sourceRoot":"","sources":["../../../src/commands/application/create-vm.ts"],"names":[],"mappings":"AAmCA,wBAAsB,yBAAyB,CAAC,OAAO,EAAE;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CA4UhB"}
@@ -0,0 +1,390 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.handleApplicationCreateVm = handleApplicationCreateVm;
40
+ const inquirer_1 = __importDefault(require("inquirer"));
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ const fs_1 = require("fs");
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ const instances_1 = require("../../services/instances");
46
+ const config_validator_1 = require("../utils/config-validator");
47
+ const input_parser_1 = require("../utils/input-parser");
48
+ const auth_prompt_1 = require("../utils/auth-prompt");
49
+ const SUPPORTED_BACKENDS = ['qemu'];
50
+ const KNOWN_IMAGES = {
51
+ 'ubuntu-24.04': 'https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img',
52
+ 'ubuntu-22.04': 'https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img',
53
+ 'alpine-3.20': 'https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/cloud/alpine-virt-3.20.0-x86_64.qcow2',
54
+ };
55
+ /** Return the content of the first readable well-known public key file, or null. */
56
+ async function detectLocalSshPublicKey() {
57
+ const candidates = [
58
+ path.join(os.homedir(), '.ssh', 'id_ed25519.pub'),
59
+ path.join(os.homedir(), '.ssh', 'id_rsa.pub'),
60
+ ];
61
+ for (const candidate of candidates) {
62
+ try {
63
+ const content = await fs_1.promises.readFile(candidate, 'utf-8');
64
+ return content.trim();
65
+ }
66
+ catch { /* not found or unreadable */ }
67
+ }
68
+ return null;
69
+ }
70
+ async function handleApplicationCreateVm(options) {
71
+ (0, config_validator_1.validateConfig)(instances_1.configManager, {
72
+ requireAuth: true,
73
+ requireOrganization: true,
74
+ });
75
+ const isInteractive = options.nonInteractive !== true;
76
+ // Application name
77
+ let appName = options.name;
78
+ if (!appName && isInteractive) {
79
+ const { name } = await inquirer_1.default.prompt([
80
+ {
81
+ type: 'input',
82
+ name: 'name',
83
+ message: 'Enter application name:',
84
+ validate: (i) => !!i.trim() || 'Application name is required',
85
+ },
86
+ ]);
87
+ appName = name.trim();
88
+ }
89
+ if (!appName)
90
+ throw new Error('Application name is required');
91
+ // VM backend
92
+ let backend = options.backend;
93
+ if (!backend && isInteractive) {
94
+ const { selectedBackend } = await inquirer_1.default.prompt([
95
+ {
96
+ type: 'list',
97
+ name: 'selectedBackend',
98
+ message: 'Select VM backend:',
99
+ choices: SUPPORTED_BACKENDS,
100
+ default: 'qemu',
101
+ },
102
+ ]);
103
+ backend = selectedBackend;
104
+ }
105
+ backend = backend ?? 'qemu';
106
+ if (!SUPPORTED_BACKENDS.includes(backend)) {
107
+ throw new Error(`Unsupported VM backend: ${backend}. Supported: ${SUPPORTED_BACKENDS.join(', ')}`);
108
+ }
109
+ // Disk image — resolve known aliases and offer them as interactive choices
110
+ let diskImage = options.diskImage
111
+ ? (KNOWN_IMAGES[options.diskImage] ?? options.diskImage)
112
+ : undefined;
113
+ if (!diskImage && isInteractive) {
114
+ const knownChoices = Object.entries(KNOWN_IMAGES).map(([label, url]) => ({
115
+ name: `${label} ${chalk_1.default.gray('(' + url.split('/').slice(0, 5).join('/') + '/...)')}`,
116
+ value: url,
117
+ }));
118
+ const { img } = await inquirer_1.default.prompt([
119
+ {
120
+ type: 'list',
121
+ name: 'img',
122
+ message: 'Disk image:',
123
+ choices: [
124
+ ...knownChoices,
125
+ { name: 'Custom path or URL', value: '__custom__' },
126
+ ],
127
+ },
128
+ ]);
129
+ if (img === '__custom__') {
130
+ const { custom } = await inquirer_1.default.prompt([
131
+ {
132
+ type: 'input',
133
+ name: 'custom',
134
+ message: 'Enter disk image path or URL:',
135
+ validate: (i) => !!i.trim() || 'Disk image is required',
136
+ },
137
+ ]);
138
+ diskImage = custom.trim();
139
+ }
140
+ else {
141
+ diskImage = img;
142
+ }
143
+ }
144
+ if (!diskImage)
145
+ throw new Error('--disk-image is required');
146
+ // Memory
147
+ let memory = options.memory ? parseInt(options.memory, 10) : undefined;
148
+ if (!memory && isInteractive) {
149
+ const { mem } = await inquirer_1.default.prompt([
150
+ {
151
+ type: 'input',
152
+ name: 'mem',
153
+ message: 'Memory (MiB):',
154
+ default: '512',
155
+ validate: (i) => parseInt(i, 10) > 0 || 'Must be a positive number',
156
+ },
157
+ ]);
158
+ memory = parseInt(mem, 10);
159
+ }
160
+ memory = memory ?? 512;
161
+ // CPUs
162
+ let cpus = options.cpus ? parseInt(options.cpus, 10) : undefined;
163
+ if (!cpus && isInteractive) {
164
+ const { c } = await inquirer_1.default.prompt([
165
+ {
166
+ type: 'input',
167
+ name: 'c',
168
+ message: 'CPUs:',
169
+ default: '1',
170
+ validate: (i) => parseInt(i, 10) > 0 || 'Must be a positive number',
171
+ },
172
+ ]);
173
+ cpus = parseInt(c, 10);
174
+ }
175
+ cpus = cpus ?? 1;
176
+ // SSH port
177
+ let sshPort = options.sshPort ? parseInt(options.sshPort, 10) : undefined;
178
+ if (!sshPort && isInteractive) {
179
+ const { sp } = await inquirer_1.default.prompt([
180
+ {
181
+ type: 'input',
182
+ name: 'sp',
183
+ message: 'SSH host port (forwarded to VM port 22):',
184
+ default: '2222',
185
+ validate: (i) => {
186
+ const p = parseInt(i, 10);
187
+ return (p > 0 && p <= 65535) || 'Port must be between 1 and 65535';
188
+ },
189
+ },
190
+ ]);
191
+ sshPort = parseInt(sp, 10);
192
+ }
193
+ sshPort = sshPort ?? 2222;
194
+ // The exposed application port is the SSH port (TCP)
195
+ let port = options.port ? (0, input_parser_1.parsePort)(options.port) : sshPort;
196
+ // SSH public key (optional) — auto-detect local key and offer it as a default
197
+ let sshPublicKey = options.sshPublicKey;
198
+ if (!sshPublicKey && isInteractive) {
199
+ const detectedKey = await detectLocalSshPublicKey();
200
+ const keyLabel = detectedKey
201
+ ? `Inject SSH public key into VM? (detected ${detectedKey.split(' ').slice(0, 2).join(' ').slice(0, 60)}...)`
202
+ : 'Inject an SSH public key into the VM? (via cloud-init)';
203
+ const { addKey } = await inquirer_1.default.prompt([
204
+ {
205
+ type: 'confirm',
206
+ name: 'addKey',
207
+ message: keyLabel,
208
+ default: !!detectedKey,
209
+ },
210
+ ]);
211
+ if (addKey) {
212
+ if (detectedKey) {
213
+ const { useDetected } = await inquirer_1.default.prompt([
214
+ {
215
+ type: 'confirm',
216
+ name: 'useDetected',
217
+ message: 'Use detected key?',
218
+ default: true,
219
+ },
220
+ ]);
221
+ if (useDetected) {
222
+ sshPublicKey = detectedKey;
223
+ }
224
+ }
225
+ if (!sshPublicKey) {
226
+ const { key } = await inquirer_1.default.prompt([
227
+ {
228
+ type: 'input',
229
+ name: 'key',
230
+ message: 'SSH public key:',
231
+ validate: (i) => !!i.trim() || 'Public key cannot be empty',
232
+ },
233
+ ]);
234
+ sshPublicKey = key.trim();
235
+ }
236
+ }
237
+ }
238
+ // Architecture
239
+ let arch = options.arch;
240
+ if (!arch && isInteractive) {
241
+ const { selectedArch } = await inquirer_1.default.prompt([
242
+ {
243
+ type: 'list',
244
+ name: 'selectedArch',
245
+ message: 'VM architecture:',
246
+ choices: ['x86_64', 'aarch64'],
247
+ default: 'x86_64',
248
+ },
249
+ ]);
250
+ arch = selectedArch;
251
+ }
252
+ arch = arch ?? 'x86_64';
253
+ // Device selection — auto-select when there's exactly one device (interactive or not)
254
+ let deviceId = options.deviceId;
255
+ if (!deviceId) {
256
+ try {
257
+ const resp = await instances_1.edgibleService.listServingDevices();
258
+ const devices = Array.isArray(resp?.devices) ? resp.devices : [];
259
+ if (devices.length === 1) {
260
+ deviceId = devices[0].id;
261
+ console.log(chalk_1.default.gray(`Device: ${devices[0].name || deviceId} (auto-selected)`));
262
+ }
263
+ else if (isInteractive && devices.length > 1) {
264
+ const choices = devices.map((d) => ({
265
+ name: `${d.name || d.id}${d.description ? ` - ${d.description}` : ''}`,
266
+ value: d.id,
267
+ }));
268
+ const { sel } = await inquirer_1.default.prompt([
269
+ { type: 'list', name: 'sel', message: 'Select serving device:', choices },
270
+ ]);
271
+ deviceId = sel;
272
+ }
273
+ else if (isInteractive) {
274
+ const { id } = await inquirer_1.default.prompt([
275
+ {
276
+ type: 'input',
277
+ name: 'id',
278
+ message: 'Enter serving device ID:',
279
+ validate: (v) => !!v.trim() || 'Device ID is required',
280
+ },
281
+ ]);
282
+ deviceId = id.trim();
283
+ }
284
+ }
285
+ catch {
286
+ if (isInteractive) {
287
+ const { id } = await inquirer_1.default.prompt([
288
+ {
289
+ type: 'input',
290
+ name: 'id',
291
+ message: 'Enter serving device ID:',
292
+ validate: (v) => !!v.trim() || 'Device ID is required',
293
+ },
294
+ ]);
295
+ deviceId = id.trim();
296
+ }
297
+ }
298
+ }
299
+ if (!deviceId)
300
+ throw new Error('--device-id is required');
301
+ // Gateways and hostnames
302
+ const gatewayIds = (0, input_parser_1.parseGatewayIds)(options.gatewayIds);
303
+ const useManagedGateway = gatewayIds.length === 0;
304
+ let hostnames = typeof options.hostnames === 'string' && options.hostnames.trim()
305
+ ? options.hostnames.split(',').map(s => s.trim()).filter(Boolean)
306
+ : [];
307
+ if (isInteractive && hostnames.length === 0) {
308
+ const { addHostnames } = await inquirer_1.default.prompt([
309
+ {
310
+ type: 'input',
311
+ name: 'addHostnames',
312
+ message: 'Additional hostnames (comma-separated, optional):',
313
+ },
314
+ ]);
315
+ if (addHostnames && typeof addHostnames === 'string') {
316
+ hostnames = addHostnames.split(',').map((s) => s.trim()).filter(Boolean);
317
+ }
318
+ }
319
+ // Auth
320
+ const authModesFromFlag = (0, auth_prompt_1.parseAuthModes)(options.authModes);
321
+ const allowedOrgsFromFlag = options.allowedOrgs
322
+ ? options.allowedOrgs.split(',').map(s => s.trim()).filter(Boolean)
323
+ : [];
324
+ const { authModes, allowedOrganizations } = await (0, auth_prompt_1.promptAuthModes)({
325
+ authModesFromFlag: authModesFromFlag ?? undefined,
326
+ allowedOrgsFromFlag: allowedOrgsFromFlag.length > 0 ? allowedOrgsFromFlag : undefined,
327
+ nonInteractive: !isInteractive,
328
+ });
329
+ const description = options.description || `VM application (${backend}) for ${appName}`;
330
+ // Build configuration
331
+ const configuration = {
332
+ vmBackend: backend,
333
+ diskImage,
334
+ memory,
335
+ cpus,
336
+ sshPort,
337
+ vmArch: arch,
338
+ };
339
+ if (sshPublicKey)
340
+ configuration.sshPublicKey = sshPublicKey;
341
+ // Resolve display label for disk image (show alias name if one was used)
342
+ const diskImageAlias = options.diskImage && KNOWN_IMAGES[options.diskImage]
343
+ ? `${options.diskImage} ${chalk_1.default.dim('→ ' + diskImage)}`
344
+ : diskImage;
345
+ // Print summary
346
+ console.log(chalk_1.default.blue(`\nCreating VM application: ${appName}`));
347
+ console.log(chalk_1.default.gray(`Backend: ${backend}`));
348
+ console.log(chalk_1.default.gray(`Disk image: ${diskImageAlias}`));
349
+ console.log(chalk_1.default.gray(`Memory: ${memory} MiB`));
350
+ console.log(chalk_1.default.gray(`CPUs: ${cpus}`));
351
+ console.log(chalk_1.default.gray(`SSH port: ${sshPort}`));
352
+ console.log(chalk_1.default.gray(`Arch: ${arch}`));
353
+ if (!options.deviceId || options.deviceId !== deviceId) {
354
+ // Only re-print if not already printed by auto-select
355
+ console.log(chalk_1.default.gray(`Device: ${deviceId}`));
356
+ }
357
+ if (useManagedGateway) {
358
+ console.log(chalk_1.default.gray('Gateway: Edgible managed gateway'));
359
+ }
360
+ else {
361
+ console.log(chalk_1.default.gray(`Gateways: ${gatewayIds.join(', ')}`));
362
+ }
363
+ const result = await instances_1.applicationService.createApplicationProgrammatically({
364
+ name: appName,
365
+ description,
366
+ port,
367
+ protocol: 'tcp',
368
+ hostnames,
369
+ deviceIds: [deviceId],
370
+ gatewayIds: useManagedGateway ? undefined : gatewayIds,
371
+ useManagedGateway,
372
+ subtype: 'vm',
373
+ configuration,
374
+ authModes,
375
+ allowedOrganizations: allowedOrganizations?.length ? allowedOrganizations : undefined,
376
+ });
377
+ console.log(chalk_1.default.green('\n✓ VM application created successfully!'));
378
+ if (result && typeof result === 'object' && 'name' in result) {
379
+ const app = result;
380
+ console.log(chalk_1.default.blue('\n📋 Application Details:'));
381
+ console.log(chalk_1.default.white(` Name: ${app.name}`));
382
+ console.log(chalk_1.default.white(` ID: ${app.id}`));
383
+ if (app.url)
384
+ console.log(chalk_1.default.white(` URL: ${chalk_1.default.cyan.bold(app.url)}`));
385
+ console.log(chalk_1.default.white(` Status: ${app.status}`));
386
+ }
387
+ console.log(chalk_1.default.yellow('\n⚠ The agent will start the VM when it receives the configuration.'));
388
+ console.log(chalk_1.default.gray(` Once deployed, connect via: edgible application ssh --id <app-id>`));
389
+ }
390
+ //# sourceMappingURL=create-vm.js.map
@@ -1,6 +1,7 @@
1
1
  export declare function handleApplicationDelete(options: {
2
2
  appId?: string;
3
+ name?: string;
3
4
  force?: boolean;
4
- interactive?: boolean;
5
+ nonInteractive?: boolean;
5
6
  }): Promise<void>;
6
7
  //# sourceMappingURL=delete.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/application/delete.ts"],"names":[],"mappings":"AAOA,wBAAsB,uBAAuB,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDhI"}
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/application/delete.ts"],"names":[],"mappings":"AAOA,wBAAsB,uBAAuB,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuElJ"}