@git.zone/cli 3.2.1 → 4.0.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 (125) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/classes.gitzoneconfig.js +1 -1
  3. package/dist_ts/classes.project.js +1 -1
  4. package/dist_ts/gitzone.cli.js +1 -1
  5. package/dist_ts/gitzone.logging.js +1 -1
  6. package/dist_ts/helpers.changelog.js +1 -1
  7. package/dist_ts/helpers.climode.js +1 -1
  8. package/dist_ts/helpers.smartconfig.js +61 -11
  9. package/dist_ts/helpers.smartconfigmigrations.js +1 -1
  10. package/dist_ts/helpers.tsdocker.js +1 -1
  11. package/dist_ts/helpers.workflow.js +1 -1
  12. package/dist_ts/index.js +1 -1
  13. package/dist_ts/mod_audit/index.js +1 -1
  14. package/dist_ts/mod_commit/index.js +1 -1
  15. package/dist_ts/mod_commit/mod.helpers.js +1 -1
  16. package/dist_ts/mod_commit/mod.plugins.js +1 -1
  17. package/dist_ts/mod_commit/mod.ui.js +1 -1
  18. package/dist_ts/mod_config/classes.commitconfig.js +1 -1
  19. package/dist_ts/mod_config/classes.releaseconfig.js +1 -1
  20. package/dist_ts/mod_config/index.js +2 -2
  21. package/dist_ts/mod_config/mod.plugins.js +1 -1
  22. package/dist_ts/mod_deprecate/index.js +1 -1
  23. package/dist_ts/mod_deprecate/mod.plugins.js +1 -1
  24. package/dist_ts/mod_docker/classes.dockerpruner.js +7 -1
  25. package/dist_ts/mod_docker/index.js +1 -1
  26. package/dist_ts/mod_docker/mod.plugins.js +1 -1
  27. package/dist_ts/mod_format/classes.baseformatter.js +1 -1
  28. package/dist_ts/mod_format/classes.diffreporter.js +1 -1
  29. package/dist_ts/mod_format/classes.formatcontext.js +1 -1
  30. package/dist_ts/mod_format/classes.formatplanner.js +1 -1
  31. package/dist_ts/mod_format/classes.formatstats.js +1 -1
  32. package/dist_ts/mod_format/formatters/assets.formatter.js +1 -1
  33. package/dist_ts/mod_format/formatters/cleanup.formatter.js +1 -1
  34. package/dist_ts/mod_format/formatters/copy.formatter.js +1 -1
  35. package/dist_ts/mod_format/formatters/gitignore.formatter.js +1 -1
  36. package/dist_ts/mod_format/formatters/license.formatter.js +1 -1
  37. package/dist_ts/mod_format/formatters/packagejson.formatter.js +1 -1
  38. package/dist_ts/mod_format/formatters/prettier.formatter.js +1 -1
  39. package/dist_ts/mod_format/formatters/readme.formatter.js +1 -1
  40. package/dist_ts/mod_format/formatters/smartconfig.formatter.js +1 -1
  41. package/dist_ts/mod_format/formatters/templates.formatter.js +1 -1
  42. package/dist_ts/mod_format/formatters/tsconfig.formatter.js +1 -1
  43. package/dist_ts/mod_format/index.js +1 -1
  44. package/dist_ts/mod_format/interfaces.format.js +1 -1
  45. package/dist_ts/mod_format/mod.plugins.js +1 -1
  46. package/dist_ts/mod_helpers/index.js +1 -1
  47. package/dist_ts/mod_helpers/mod.plugins.js +1 -1
  48. package/dist_ts/mod_meta/index.js +1 -1
  49. package/dist_ts/mod_meta/meta.classes.meta.js +1 -1
  50. package/dist_ts/mod_meta/meta.interfaces.js +1 -1
  51. package/dist_ts/mod_meta/meta.plugins.js +1 -1
  52. package/dist_ts/mod_open/index.js +1 -1
  53. package/dist_ts/mod_open/mod.plugins.js +1 -1
  54. package/dist_ts/mod_release/index.js +1 -1
  55. package/dist_ts/mod_release/mod.plugins.js +1 -1
  56. package/dist_ts/mod_services/classes.dockercontainer.d.ts +50 -3
  57. package/dist_ts/mod_services/classes.dockercontainer.js +646 -84
  58. package/dist_ts/mod_services/classes.globalregistry.d.ts +10 -24
  59. package/dist_ts/mod_services/classes.globalregistry.js +210 -62
  60. package/dist_ts/mod_services/classes.globalregistrystore.d.ts +48 -0
  61. package/dist_ts/mod_services/classes.globalregistrystore.js +156 -0
  62. package/dist_ts/mod_services/classes.interprocesslock.d.ts +21 -0
  63. package/dist_ts/mod_services/classes.interprocesslock.js +141 -0
  64. package/dist_ts/mod_services/classes.serviceconfiguration.d.ts +15 -12
  65. package/dist_ts/mod_services/classes.serviceconfiguration.js +188 -91
  66. package/dist_ts/mod_services/classes.servicedatamarker.d.ts +32 -7
  67. package/dist_ts/mod_services/classes.servicedatamarker.js +145 -49
  68. package/dist_ts/mod_services/classes.servicemanager.d.ts +70 -28
  69. package/dist_ts/mod_services/classes.servicemanager.js +995 -421
  70. package/dist_ts/mod_services/classes.servicenames.d.ts +8 -0
  71. package/dist_ts/mod_services/classes.servicenames.js +54 -0
  72. package/dist_ts/mod_services/classes.serviceoptions.js +1 -1
  73. package/dist_ts/mod_services/classes.servicepruner.d.ts +3 -0
  74. package/dist_ts/mod_services/classes.servicepruner.js +208 -46
  75. package/dist_ts/mod_services/helpers.js +1 -1
  76. package/dist_ts/mod_services/index.d.ts +2 -0
  77. package/dist_ts/mod_services/index.js +81 -58
  78. package/dist_ts/mod_services/mod.plugins.js +1 -1
  79. package/dist_ts/mod_standard/index.js +2 -2
  80. package/dist_ts/mod_standard/mod.plugins.js +1 -1
  81. package/dist_ts/mod_start/index.js +1 -1
  82. package/dist_ts/mod_start/mod.plugins.js +1 -1
  83. package/dist_ts/mod_template/index.js +1 -1
  84. package/dist_ts/mod_template/mod.plugins.js +1 -1
  85. package/dist_ts/mod_tools/classes.packagemanager.js +1 -1
  86. package/dist_ts/mod_tools/index.js +1 -1
  87. package/dist_ts/mod_tools/mod.plugins.js +1 -1
  88. package/dist_ts/paths.js +1 -1
  89. package/dist_ts/plugins.d.ts +3 -1
  90. package/dist_ts/plugins.js +4 -2
  91. package/dist_ts_migration/001.service-selection.d.ts +9 -0
  92. package/dist_ts_migration/001.service-selection.js +51 -0
  93. package/dist_ts_migration/002.runtime-config.d.ts +19 -0
  94. package/dist_ts_migration/002.runtime-config.js +170 -0
  95. package/dist_ts_migration/003.service-data-marker.d.ts +9 -0
  96. package/dist_ts_migration/003.service-data-marker.js +156 -0
  97. package/dist_ts_migration/004.global-registry.d.ts +13 -0
  98. package/dist_ts_migration/004.global-registry.js +165 -0
  99. package/dist_ts_migration/index.d.ts +11 -0
  100. package/dist_ts_migration/index.js +59 -0
  101. package/package.json +6 -3
  102. package/readme.hints.md +102 -25
  103. package/readme.md +123 -28
  104. package/readme.plan.md +29 -16
  105. package/ts/00_commitinfo_data.ts +1 -1
  106. package/ts/helpers.smartconfig.ts +63 -10
  107. package/ts/mod_config/index.ts +1 -1
  108. package/ts/mod_docker/classes.dockerpruner.ts +6 -0
  109. package/ts/mod_services/classes.dockercontainer.ts +912 -96
  110. package/ts/mod_services/classes.globalregistry.ts +290 -89
  111. package/ts/mod_services/classes.globalregistrystore.ts +279 -0
  112. package/ts/mod_services/classes.interprocesslock.ts +189 -0
  113. package/ts/mod_services/classes.serviceconfiguration.ts +215 -108
  114. package/ts/mod_services/classes.servicedatamarker.ts +210 -52
  115. package/ts/mod_services/classes.servicemanager.ts +1332 -512
  116. package/ts/mod_services/classes.servicenames.ts +76 -0
  117. package/ts/mod_services/classes.servicepruner.ts +310 -52
  118. package/ts/mod_services/index.ts +89 -62
  119. package/ts/mod_standard/index.ts +1 -1
  120. package/ts/plugins.ts +4 -0
  121. package/ts_migration/001.service-selection.ts +77 -0
  122. package/ts_migration/002.runtime-config.ts +218 -0
  123. package/ts_migration/003.service-data-marker.ts +216 -0
  124. package/ts_migration/004.global-registry.ts +272 -0
  125. package/ts_migration/index.ts +83 -0
@@ -3,6 +3,13 @@ import * as helpers from "./helpers.js";
3
3
  import { ServiceManager } from "./classes.servicemanager.js";
4
4
  import { GlobalRegistry } from "./classes.globalregistry.js";
5
5
  import { getServiceDataDirectory } from "./classes.servicedatamarker.js";
6
+ import {
7
+ allowedServiceNames,
8
+ normalizeUserServiceName,
9
+ normalizeUserServiceNames,
10
+ readPersistedServiceConfiguration,
11
+ } from "./classes.servicenames.js";
12
+ import { runServiceMigrations } from "../../ts_migration/index.js";
6
13
  import {
7
14
  ServicePruner,
8
15
  defaultStaleDays,
@@ -34,6 +41,7 @@ export const run = async (argvArg: any) => {
34
41
 
35
42
  // Handle global commands first
36
43
  if (isGlobal) {
44
+ await runServiceMigrations({ scopes: ["global-registry"] });
37
45
  await handleGlobalCommand(command, argvArg, mode);
38
46
  return;
39
47
  }
@@ -44,26 +52,43 @@ export const run = async (argvArg: any) => {
44
52
  case "config":
45
53
  if (service === "services" || argvArg._[2] === "services") {
46
54
  const serviceManager = new ServiceManager();
47
- await serviceManager.init();
55
+ await serviceManager.init("config");
48
56
  await handleConfigureServices(serviceManager);
49
57
  } else {
58
+ await runServiceMigrations({
59
+ projectPath: process.cwd(),
60
+ scopes: ["service-selection", "runtime-config"],
61
+ });
50
62
  await handleShowConfig(mode);
51
63
  }
52
64
  break;
53
65
 
54
66
  case "set":
67
+ await runServiceMigrations({
68
+ projectPath: process.cwd(),
69
+ scopes: ["service-selection"],
70
+ });
55
71
  await handleSetServices(argvArg._[2], mode);
56
72
  break;
57
73
 
58
74
  case "enable":
75
+ await runServiceMigrations({
76
+ projectPath: process.cwd(),
77
+ scopes: ["service-selection"],
78
+ });
59
79
  await handleEnableServices(argvArg._.slice(2), mode);
60
80
  break;
61
81
 
62
82
  case "disable":
83
+ await runServiceMigrations({
84
+ projectPath: process.cwd(),
85
+ scopes: ["service-selection"],
86
+ });
63
87
  await handleDisableServices(argvArg._.slice(2), mode);
64
88
  break;
65
89
 
66
90
  case "prune":
91
+ await runServiceMigrations({ scopes: ["global-registry"] });
67
92
  await handlePrune(argvArg, mode);
68
93
  break;
69
94
 
@@ -83,7 +108,7 @@ export const run = async (argvArg: any) => {
83
108
  const serviceManager = new ServiceManager();
84
109
  // Initialisation is chatty. In JSON mode that chatter would land on stdout
85
110
  // ahead of the payload and make the output unparseable.
86
- await withJsonSafeOutput(mode, () => serviceManager.init());
111
+ await withJsonSafeOutput(mode, () => serviceManager.init(command));
87
112
 
88
113
  switch (command) {
89
114
  case "start":
@@ -152,34 +177,11 @@ async function withJsonSafeOutput<T>(
152
177
  return runWithSuppressedOutput(work);
153
178
  }
154
179
 
155
- const allowedServices = ["mongodb", "minio", "elasticsearch"];
156
-
157
- const normalizeServiceName = (service: string): string => {
158
- switch (service) {
159
- case "mongo":
160
- case "mongodb":
161
- return "mongodb";
162
- case "minio":
163
- case "s3":
164
- return "minio";
165
- case "elastic":
166
- case "elasticsearch":
167
- case "es":
168
- return "elasticsearch";
169
- default:
170
- return service;
171
- }
172
- };
173
-
174
180
  async function readServicesConfig(): Promise<{
175
181
  enabledServices: string[];
176
182
  environment: Record<string, any> | null;
177
183
  }> {
178
- const smartconfigData = await readSmartconfigFile();
179
- const enabledServices = getCliConfigValueFromData(
180
- smartconfigData,
181
- "services",
182
- );
184
+ const enabledServices = await readPersistedServiceConfiguration();
183
185
  let environment: Record<string, any> | null = null;
184
186
  const envPath = plugins.path.join(process.cwd(), ".nogit", "env.json");
185
187
  if (await plugins.smartfs.file(envPath).exists()) {
@@ -191,7 +193,7 @@ async function readServicesConfig(): Promise<{
191
193
  }
192
194
 
193
195
  return {
194
- enabledServices: Array.isArray(enabledServices) ? enabledServices : [],
196
+ enabledServices,
195
197
  environment,
196
198
  };
197
199
  }
@@ -206,7 +208,15 @@ async function handleShowConfig(mode: ICliMode) {
206
208
  const configData = await readServicesConfig();
207
209
 
208
210
  if (mode.json) {
209
- printJson(configData);
211
+ const environment = configData.environment
212
+ ? {
213
+ ...configData.environment,
214
+ S3_ACCESSKEY: "***",
215
+ S3_SECRETKEY: "***",
216
+ S3_ADMIN_PASSWORD: "***",
217
+ }
218
+ : null;
219
+ printJson({ ...configData, environment });
210
220
  return;
211
221
  }
212
222
 
@@ -242,15 +252,15 @@ async function handleShowConfig(mode: ICliMode) {
242
252
  logger.log("info", ` Connection: ${env.MONGODB_URL}`);
243
253
  console.log();
244
254
 
245
- logger.log("note", "S3/MinIO:");
255
+ logger.log("note", "S3/ObjectStorage:");
246
256
  logger.log("info", ` Host: ${env.S3_HOST}`);
247
257
  logger.log("info", ` API Port: ${env.S3_PORT}`);
248
- logger.log("info", ` Console Port: ${env.S3_CONSOLE_PORT}`);
258
+ logger.log("info", ` Management UI Port: ${env.S3_UI_PORT}`);
249
259
  logger.log("info", ` Bucket: ${env.S3_BUCKET}`);
250
- logger.log("info", ` Container: ${env.PROJECT_NAME}-minio`);
260
+ logger.log("info", ` Container: ${env.PROJECT_NAME}-objectstorage`);
251
261
  logger.log(
252
262
  "info",
253
- ` Data: ${getServiceDataDirectory(process.cwd(), "minio")}`,
263
+ ` Data: ${getServiceDataDirectory(process.cwd(), "objectstorage")}`,
254
264
  );
255
265
  logger.log("info", ` Endpoint: ${env.S3_ENDPOINT}`);
256
266
  console.log();
@@ -274,10 +284,7 @@ async function handleSetServices(rawValue: string | undefined, mode: ICliMode) {
274
284
  throw new Error("Specify a comma-separated list of services");
275
285
  }
276
286
 
277
- const requestedServices = rawValue
278
- .split(",")
279
- .map((service) => normalizeServiceName(service.trim()))
280
- .filter(Boolean);
287
+ const requestedServices = normalizeUserServiceNames(rawValue.split(","));
281
288
  validateRequestedServices(requestedServices);
282
289
  await updateEnabledServices(requestedServices);
283
290
 
@@ -294,7 +301,7 @@ async function handleEnableServices(
294
301
  mode: ICliMode,
295
302
  ) {
296
303
  const normalizedServices = requestedServices.map((service) =>
297
- normalizeServiceName(service),
304
+ normalizeUserServiceName(service),
298
305
  );
299
306
  validateRequestedServices(normalizedServices);
300
307
 
@@ -317,7 +324,7 @@ async function handleDisableServices(
317
324
  mode: ICliMode,
318
325
  ) {
319
326
  const normalizedServices = requestedServices.map((service) =>
320
- normalizeServiceName(service),
327
+ normalizeUserServiceName(service),
321
328
  );
322
329
  validateRequestedServices(normalizedServices);
323
330
 
@@ -341,7 +348,7 @@ function validateRequestedServices(services: string[]): void {
341
348
  }
342
349
 
343
350
  const invalidServices = services.filter(
344
- (service) => !allowedServices.includes(service),
351
+ (service) => !allowedServiceNames.some((allowed) => allowed === service),
345
352
  );
346
353
  if (invalidServices.length > 0) {
347
354
  throw new Error(`Unknown service(s): ${invalidServices.join(", ")}`);
@@ -360,9 +367,9 @@ async function handleStart(
360
367
  await serviceManager.startMongoDB();
361
368
  break;
362
369
 
363
- case "minio":
370
+ case "objectstorage":
364
371
  case "s3":
365
- await serviceManager.startMinIO();
372
+ await serviceManager.startObjectStorage();
366
373
  break;
367
374
 
368
375
  case "elasticsearch":
@@ -389,7 +396,7 @@ async function handleStart(
389
396
  const started = await runWithSuppressedOutput(startService);
390
397
  if (!started) {
391
398
  throw new Error(
392
- `Unknown service: ${service}. Use: mongo, s3, elasticsearch, or all`,
399
+ `Unknown service: ${service}. Use: mongo, objectstorage, s3, elasticsearch, or all`,
393
400
  );
394
401
  }
395
402
  printJson(await serviceManager.collectStatus());
@@ -399,7 +406,7 @@ async function handleStart(
399
406
  helpers.printHeader("Starting Services");
400
407
  if (!(await startService())) {
401
408
  logger.log("error", `Unknown service: ${service}`);
402
- logger.log("note", "Use: mongo, s3, elasticsearch, or all");
409
+ logger.log("note", "Use: mongo, objectstorage, s3, elasticsearch, or all");
403
410
  return;
404
411
  }
405
412
  await printStaleHint();
@@ -447,9 +454,9 @@ async function handleStop(serviceManager: ServiceManager, service: string) {
447
454
  await serviceManager.stopMongoDB();
448
455
  break;
449
456
 
450
- case "minio":
457
+ case "objectstorage":
451
458
  case "s3":
452
- await serviceManager.stopMinIO();
459
+ await serviceManager.stopObjectStorage();
453
460
  break;
454
461
 
455
462
  case "elasticsearch":
@@ -464,13 +471,14 @@ async function handleStop(serviceManager: ServiceManager, service: string) {
464
471
 
465
472
  default:
466
473
  logger.log("error", `Unknown service: ${service}`);
467
- logger.log("note", "Use: mongo, s3, elasticsearch, or all");
474
+ logger.log("note", "Use: mongo, objectstorage, s3, elasticsearch, or all");
468
475
  break;
469
476
  }
470
477
  }
471
478
 
472
- async function handleRestart(serviceManager: ServiceManager, service: string) {
479
+ export async function handleRestart(serviceManager: ServiceManager, service: string) {
473
480
  helpers.printHeader("Restarting Services");
481
+ let restarted = false;
474
482
 
475
483
  switch (service) {
476
484
  case "mongo":
@@ -478,13 +486,16 @@ async function handleRestart(serviceManager: ServiceManager, service: string) {
478
486
  await serviceManager.stopMongoDB();
479
487
  await plugins.smartdelay.delayFor(2000);
480
488
  await serviceManager.startMongoDB();
489
+ restarted = true;
481
490
  break;
482
491
 
483
- case "minio":
492
+ case "objectstorage":
484
493
  case "s3":
485
- await serviceManager.stopMinIO();
494
+ await serviceManager.assertObjectStorageStartupAllowed();
495
+ await serviceManager.stopObjectStorage();
486
496
  await plugins.smartdelay.delayFor(2000);
487
- await serviceManager.startMinIO();
497
+ await serviceManager.startObjectStorage();
498
+ restarted = true;
488
499
  break;
489
500
 
490
501
  case "elasticsearch":
@@ -492,19 +503,28 @@ async function handleRestart(serviceManager: ServiceManager, service: string) {
492
503
  await serviceManager.stopElasticsearch();
493
504
  await plugins.smartdelay.delayFor(2000);
494
505
  await serviceManager.startElasticsearch();
506
+ restarted = true;
495
507
  break;
496
508
 
497
509
  case "all":
498
510
  case "":
511
+ if (serviceManager.isServiceEnabled("objectstorage")) {
512
+ await serviceManager.assertObjectStorageStartupAllowed();
513
+ }
499
514
  await serviceManager.stopAll();
500
515
  await plugins.smartdelay.delayFor(2000);
501
516
  await serviceManager.startAll();
517
+ restarted = true;
502
518
  break;
503
519
 
504
520
  default:
505
521
  logger.log("error", `Unknown service: ${service}`);
506
522
  break;
507
523
  }
524
+
525
+ if (restarted) {
526
+ await serviceManager.registerWithGlobalRegistry();
527
+ }
508
528
  }
509
529
 
510
530
  async function handleRemove(serviceManager: ServiceManager, mode: ICliMode) {
@@ -574,7 +594,7 @@ async function handleAuth(
574
594
  rawValue: string | undefined,
575
595
  mode: ICliMode,
576
596
  ) {
577
- const service = normalizeServiceName((rawService || "").trim());
597
+ const service = normalizeUserServiceName((rawService || "").trim());
578
598
  if (service !== "mongodb") {
579
599
  throw new Error(
580
600
  "Only `mongodb` supports an auth toggle. Usage: gitzone services auth mongodb <on|off>",
@@ -588,7 +608,7 @@ async function handleAuth(
588
608
 
589
609
  const serviceManager = new ServiceManager();
590
610
  const configuration = await withJsonSafeOutput(mode, async () => {
591
- await serviceManager.init();
611
+ await serviceManager.init("auth");
592
612
  const resolvedConfiguration = serviceManager.getConfiguration();
593
613
  await resolvedConfiguration.setMongoAuthEnabled(value === "on");
594
614
  return resolvedConfiguration;
@@ -821,7 +841,7 @@ export function showHelp(mode?: ICliMode) {
821
841
  examples: [
822
842
  "gitzone services config --json",
823
843
  "gitzone services status --json",
824
- "gitzone services set mongodb,minio",
844
+ "gitzone services set mongodb,objectstorage",
825
845
  "gitzone services enable elasticsearch",
826
846
  "gitzone services auth mongodb off",
827
847
  "gitzone services prune",
@@ -839,15 +859,15 @@ export function showHelp(mode?: ICliMode) {
839
859
  logger.log("note", "Commands:");
840
860
  logger.log(
841
861
  "info",
842
- " start [service] Start services (mongo|s3|elasticsearch|all)",
862
+ " start [service] Start services (mongo|objectstorage|s3|elasticsearch|all)",
843
863
  );
844
864
  logger.log(
845
865
  "info",
846
- " stop [service] Stop services (mongo|s3|elasticsearch|all)",
866
+ " stop [service] Stop services (mongo|objectstorage|s3|elasticsearch|all)",
847
867
  );
848
868
  logger.log(
849
869
  "info",
850
- " restart [service] Restart services (mongo|s3|elasticsearch|all)",
870
+ " restart [service] Restart services (mongo|objectstorage|s3|elasticsearch|all)",
851
871
  );
852
872
  logger.log("info", " status Show service status");
853
873
  logger.log("info", " config Show current configuration");
@@ -867,7 +887,7 @@ export function showHelp(mode?: ICliMode) {
867
887
  );
868
888
  logger.log(
869
889
  "info",
870
- " logs [service] Show logs (mongo|s3|elasticsearch|all) [lines]",
890
+ " logs [service] Show logs (mongo|objectstorage|s3|elasticsearch|all) [lines]",
871
891
  );
872
892
  logger.log("info", " reconfigure Reassign ports and restart services");
873
893
  logger.log(
@@ -898,7 +918,7 @@ export function showHelp(mode?: ICliMode) {
898
918
 
899
919
  logger.log("note", "Available Services:");
900
920
  logger.log("info", " • MongoDB (mongo) - Document database");
901
- logger.log("info", " • MinIO (s3) - S3-compatible object storage");
921
+ logger.log("info", " • ObjectStorage (s3) - S3-compatible object storage");
902
922
  logger.log(
903
923
  "info",
904
924
  " • Elasticsearch (elasticsearch) - Search and analytics engine",
@@ -909,7 +929,7 @@ export function showHelp(mode?: ICliMode) {
909
929
  logger.log("info", " • Auto-creates .nogit/env.json with smart defaults");
910
930
  logger.log(
911
931
  "info",
912
- " • Random ports (20000-30000) for MongoDB/MinIO to avoid conflicts",
932
+ " • Random ports (20000-30000) for MongoDB/ObjectStorage to avoid conflicts",
913
933
  );
914
934
  logger.log("info", " • Elasticsearch uses standard port 9200");
915
935
  logger.log(
@@ -951,7 +971,7 @@ export function showHelp(mode?: ICliMode) {
951
971
  );
952
972
  logger.log(
953
973
  "info",
954
- " gitzone services set mongodb,minio # Configure services without prompts",
974
+ " gitzone services set mongodb,objectstorage # Configure services without prompts",
955
975
  );
956
976
  logger.log(
957
977
  "info",
@@ -1077,6 +1097,13 @@ async function handleGlobalStatus(globalRegistry: GlobalRegistry) {
1077
1097
 
1078
1098
  for (const container of project.containers) {
1079
1099
  totalContainers++;
1100
+ if (container.ownership === "conflict") {
1101
+ logger.log(
1102
+ "error",
1103
+ ` ❓ ${container.name}: ownership conflict (not managed)`,
1104
+ );
1105
+ continue;
1106
+ }
1080
1107
  const statusIcon =
1081
1108
  container.status === "running"
1082
1109
  ? "🟢"
@@ -1107,7 +1134,7 @@ async function handleGlobalStop(globalRegistry: GlobalRegistry) {
1107
1134
  let runningCount = 0;
1108
1135
  for (const project of statuses) {
1109
1136
  for (const container of project.containers) {
1110
- if (container.status === "running") runningCount++;
1137
+ if (container.status === "running" && container.ownership !== "conflict") runningCount++;
1111
1138
  }
1112
1139
  }
1113
1140
 
@@ -1125,7 +1152,7 @@ async function handleGlobalStop(globalRegistry: GlobalRegistry) {
1125
1152
  // Show what will be stopped
1126
1153
  for (const project of statuses) {
1127
1154
  const runningContainers = project.containers.filter(
1128
- (c) => c.status === "running",
1155
+ (c) => c.status === "running" && c.ownership !== "conflict",
1129
1156
  );
1130
1157
  if (runningContainers.length > 0) {
1131
1158
  logger.log("info", `${project.projectName}:`);
@@ -206,7 +206,7 @@ export async function showHelp(
206
206
  console.log(" gitzone release --plan");
207
207
  console.log(" gitzone format plan --json");
208
208
  console.log(" gitzone format check");
209
- console.log(" gitzone services set mongodb,minio");
209
+ console.log(" gitzone services set mongodb,objectstorage");
210
210
  console.log(" gitzone tools update");
211
211
  console.log("");
212
212
  console.log("Run gitzone <command> --help for command-specific usage.");
package/ts/plugins.ts CHANGED
@@ -15,6 +15,8 @@ import * as smartfile from '@push.rocks/smartfile';
15
15
  import { SmartFs, SmartFsProviderNode } from '@push.rocks/smartfs';
16
16
  import * as smartinteract from '@push.rocks/smartinteract';
17
17
  import * as smartdelay from '@push.rocks/smartdelay';
18
+ import * as smartbucket from '@push.rocks/smartbucket';
19
+ import * as s3 from '@aws-sdk/client-s3';
18
20
 
19
21
  // Create smartfs instance for filesystem operations
20
22
  export const smartfs = new SmartFs(new SmartFsProviderNode());
@@ -36,4 +38,6 @@ export {
36
38
  smartfile,
37
39
  smartinteract,
38
40
  smartdelay,
41
+ smartbucket,
42
+ s3,
39
43
  };
@@ -0,0 +1,77 @@
1
+ import {
2
+ getCliConfigValueFromData,
3
+ getCliNamespaceConfig,
4
+ readSmartconfigFile,
5
+ setCliConfigValueInData,
6
+ writeSmartconfigFile,
7
+ } from '../ts/helpers.smartconfig.js';
8
+ import {
9
+ allowedServiceNames,
10
+ assertSupportedCliSchema,
11
+ normalizeUserServiceName,
12
+ } from '../ts/mod_services/classes.servicenames.js';
13
+
14
+ export interface IServiceSelectionMigrationResult {
15
+ services: string[];
16
+ migrated: boolean;
17
+ }
18
+
19
+ /** Normalize only persisted values, including the exact shipped legacy identifier. */
20
+ export const migratePersistedServiceNamesValue = (
21
+ servicesArg: unknown,
22
+ ): IServiceSelectionMigrationResult => {
23
+ if (servicesArg === undefined) {
24
+ return { services: [], migrated: false };
25
+ }
26
+ if (!Array.isArray(servicesArg)) {
27
+ throw new Error('Persisted services configuration must be an array of service names.');
28
+ }
29
+ if (!servicesArg.every((service) => typeof service === 'string')) {
30
+ throw new Error('Persisted services configuration must contain only service names.');
31
+ }
32
+
33
+ const services: string[] = [];
34
+ let migrated = false;
35
+ for (const rawService of servicesArg) {
36
+ const canonical =
37
+ rawService === 'minio' ? 'objectstorage' : normalizeUserServiceName(rawService);
38
+ if (!allowedServiceNames.some((allowedService) => allowedService === canonical)) {
39
+ throw new Error('Persisted services configuration contains an unsupported service name.');
40
+ }
41
+ if (canonical !== rawService) {
42
+ migrated = true;
43
+ }
44
+ if (!services.includes(canonical)) {
45
+ services.push(canonical);
46
+ } else {
47
+ migrated = true;
48
+ }
49
+ }
50
+ return { services, migrated };
51
+ };
52
+
53
+ /** Persist canonical service identifiers while retaining the flat tsdeploy input shape. */
54
+ export const preflightServiceSelectionMigration = async (
55
+ cwdArg: string = process.cwd(),
56
+ ): Promise<string[]> => {
57
+ const smartconfigData = await readSmartconfigFile(cwdArg);
58
+ assertSupportedCliSchema(getCliNamespaceConfig(smartconfigData));
59
+ return migratePersistedServiceNamesValue(
60
+ getCliConfigValueFromData(smartconfigData, 'services'),
61
+ ).services;
62
+ };
63
+
64
+ export const runServiceSelectionMigration = async (
65
+ cwdArg: string = process.cwd(),
66
+ ): Promise<string[]> => {
67
+ await preflightServiceSelectionMigration(cwdArg);
68
+ const smartconfigData = await readSmartconfigFile(cwdArg);
69
+ assertSupportedCliSchema(getCliNamespaceConfig(smartconfigData));
70
+ const rawServices = getCliConfigValueFromData(smartconfigData, 'services');
71
+ const migration = migratePersistedServiceNamesValue(rawServices);
72
+ if (migration.migrated) {
73
+ setCliConfigValueInData(smartconfigData, 'services', migration.services);
74
+ await writeSmartconfigFile(smartconfigData, cwdArg);
75
+ }
76
+ return migration.services;
77
+ };