@c8y/ngx-components 1017.0.92 → 1017.0.93

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.
@@ -38,6 +38,8 @@ var ERROR_TYPE;
38
38
  ERROR_TYPE["INVALID_PACKAGE"] = "INVALID_PACKAGE";
39
39
  ERROR_TYPE["INVALID_APPLICATION"] = "INVALID_APPLICATION";
40
40
  ERROR_TYPE["MICROSERVICE_NAME_TOO_LONG"] = "MICROSERVICE_NAME_TOO_LONG";
41
+ ERROR_TYPE["APPLICATION_CREATION_FAILED"] = "APPLICATION_CREATION_FAILED";
42
+ ERROR_TYPE["KEY_OR_CONTEXT_PATH_MISMATCH"] = "KEY_OR_CONTEXT_PATH_MISMATCH";
41
43
  })(ERROR_TYPE || (ERROR_TYPE = {}));
42
44
  const PRODUCT_EXPERIENCE = {
43
45
  APPLICATIONS: {
@@ -96,7 +98,9 @@ const ERROR_MESSAGES = {
96
98
  [ERROR_TYPE.INVALID_PACKAGE]: gettext('You have not uploaded a valid package.'),
97
99
  [ERROR_TYPE.INVALID_APPLICATION]: gettext('You have not uploaded a valid application.'),
98
100
  [ERROR_TYPE.INTERNAL_ERROR]: gettext('An internal error occurred, try to upload again.'),
99
- [ERROR_TYPE.MICROSERVICE_NAME_TOO_LONG]: gettext('Microservice name "{{ name }}" must not be longer than {{ maxChars }} characters.')
101
+ [ERROR_TYPE.MICROSERVICE_NAME_TOO_LONG]: gettext('Microservice name "{{ name }}" must not be longer than {{ maxChars }} characters.'),
102
+ [ERROR_TYPE.APPLICATION_CREATION_FAILED]: gettext('Application creation failed.'),
103
+ [ERROR_TYPE.KEY_OR_CONTEXT_PATH_MISMATCH]: gettext('The contextPath or key of the uploaded archive do not match with the existing app.')
100
104
  };
101
105
  const APP_STATE = {
102
106
  SUBSCRIBED: {
@@ -160,6 +164,13 @@ const packageProperties = [
160
164
  }
161
165
  ];
162
166
 
167
+ class EcosystemError extends Error {
168
+ constructor(type) {
169
+ super(ERROR_MESSAGES[type]);
170
+ this.type = type;
171
+ }
172
+ }
173
+
163
174
  const CUMULOCITY_JSON = 'cumulocity.json';
164
175
  const MICROSERVICE_NAME_MAX_LENGTH = 23;
165
176
  class EcosystemService {
@@ -420,10 +431,10 @@ class EcosystemService {
420
431
  return yield this.applicationService.update(app);
421
432
  }
422
433
  catch (ex) {
423
- this.alertService.addServerFailure(ex);
434
+ this.alertError(ex);
424
435
  if (deleteOnFailure) {
425
436
  yield this.applicationService.delete(app.id);
426
- throw new Error('Application creation failed.');
437
+ throw new EcosystemError(ERROR_TYPE.APPLICATION_CREATION_FAILED);
427
438
  }
428
439
  }
429
440
  });
@@ -456,7 +467,7 @@ class EcosystemService {
456
467
  this.alertService.success(gettext('Successfully subscribed to application.'));
457
468
  }
458
469
  catch (ex) {
459
- this.alertService.addServerFailure(ex);
470
+ this.alertError(ex);
460
471
  }
461
472
  });
462
473
  }
@@ -468,7 +479,7 @@ class EcosystemService {
468
479
  this.alertService.success(gettext('Successfully unsubscribed from application.'));
469
480
  }
470
481
  catch (ex) {
471
- this.alertService.addServerFailure(ex);
482
+ this.alertError(ex);
472
483
  }
473
484
  });
474
485
  }
@@ -477,7 +488,7 @@ class EcosystemService {
477
488
  try {
478
489
  const currentType = yield this.getAppType(archive);
479
490
  if (currentType !== appType) {
480
- throw new Error(ERROR_TYPE.TYPE_VALIDATION);
491
+ throw new EcosystemError(ERROR_TYPE.TYPE_VALIDATION);
481
492
  }
482
493
  else {
483
494
  this.progress.next(this.progress.value + 10);
@@ -485,7 +496,7 @@ class EcosystemService {
485
496
  }
486
497
  }
487
498
  catch (ex) {
488
- throw new Error(ERROR_TYPE.TYPE_VALIDATION);
499
+ throw new EcosystemError(ERROR_TYPE.TYPE_VALIDATION);
489
500
  }
490
501
  });
491
502
  }
@@ -506,16 +517,32 @@ class EcosystemService {
506
517
  return (yield this.setAppActiveVersion(app, (binaryMo.binaryId || binaryMo.id))).data;
507
518
  });
508
519
  }
509
- validatePackageKeyAndContextPath(archive, app) {
520
+ validateArchiveToAppCompatibility(archive, app) {
510
521
  return __awaiter(this, void 0, void 0, function* () {
511
- const manifest = yield this.getCumulocityJson(archive).toPromise();
512
- const contextPath = get(manifest, 'contextPath');
513
- const appKey = get(manifest, 'key');
514
- if (contextPath !== app.contextPath || appKey !== app.key) {
515
- const error = {
516
- data: { message: this.translateService.instant(ERROR_MESSAGES.INVALID_PACKAGE) }
517
- };
518
- throw error;
522
+ const appType = yield this.getAppType(archive);
523
+ if (appType !== app.type) {
524
+ throw new EcosystemError(ERROR_TYPE.INVALID_APPLICATION);
525
+ }
526
+ else {
527
+ this.progress.next(this.progress.value + 10);
528
+ }
529
+ const manifest = yield this.getCumulocityJson(archive);
530
+ // A user can upload an app without a Cumulocity JSON file (e.g. a react app).
531
+ // This is allowed and should not trigger a validation error.
532
+ if (!manifest) {
533
+ return;
534
+ }
535
+ yield this.validatePackageKeyAndContextPath(manifest, app);
536
+ });
537
+ }
538
+ getCumulocityJson(archive) {
539
+ return __awaiter(this, void 0, void 0, function* () {
540
+ try {
541
+ const c8yManifest = yield this.getCumulocityJson$(archive).toPromise();
542
+ return c8yManifest;
543
+ }
544
+ catch (ex) {
545
+ return null;
519
546
  }
520
547
  });
521
548
  }
@@ -527,7 +554,7 @@ class EcosystemService {
527
554
  const supportedAppTypes = [ApplicationType.HOSTED, ApplicationType.MICROSERVICE];
528
555
  if (supportedAppTypes.includes(appType)) {
529
556
  try {
530
- appModel = yield this.getCumulocityJson(archive).toPromise();
557
+ appModel = yield this.getCumulocityJson$(archive).toPromise();
531
558
  isPackage = appModel.isPackage;
532
559
  }
533
560
  catch (e) {
@@ -546,10 +573,10 @@ class EcosystemService {
546
573
  contextPath
547
574
  };
548
575
  if (isPackageTypeArchive && !isPackage) {
549
- throw new Error(ERROR_TYPE.INVALID_PACKAGE);
576
+ throw new EcosystemError(ERROR_TYPE.INVALID_PACKAGE);
550
577
  }
551
578
  else if (!isPackageTypeArchive && isPackage) {
552
- throw new Error(ERROR_TYPE.INVALID_APPLICATION);
579
+ throw new EcosystemError(ERROR_TYPE.INVALID_APPLICATION);
553
580
  }
554
581
  else if (this.isNameLengthExceeded(name, appType)) {
555
582
  const error = new Error();
@@ -570,7 +597,7 @@ class EcosystemService {
570
597
  this.alertService.success(gettext('Application reactivated.'));
571
598
  }
572
599
  catch (ex) {
573
- this.alertService.addServerFailure(ex);
600
+ this.alertError(ex);
574
601
  }
575
602
  });
576
603
  }
@@ -583,7 +610,7 @@ class EcosystemService {
583
610
  this.alertService.success(gettext('Archive deleted.'));
584
611
  }
585
612
  catch (ex) {
586
- this.alertService.addServerFailure(ex);
613
+ this.alertError(ex);
587
614
  }
588
615
  });
589
616
  }
@@ -660,6 +687,27 @@ class EcosystemService {
660
687
  app.availability = ApplicationAvailability.PRIVATE;
661
688
  return app;
662
689
  }
690
+ /**
691
+ * Shows an error dialog.
692
+ * @param error Either a server error or an internal [[EcosystemError]].
693
+ */
694
+ alertError(error) {
695
+ if (error instanceof EcosystemError) {
696
+ this.alertService.danger(error.message);
697
+ }
698
+ else {
699
+ this.alertService.addServerFailure(error);
700
+ }
701
+ }
702
+ validatePackageKeyAndContextPath(manifest, app) {
703
+ return __awaiter(this, void 0, void 0, function* () {
704
+ const contextPath = get(manifest, 'contextPath');
705
+ const appKey = get(manifest, 'key');
706
+ if (contextPath !== app.contextPath || appKey !== app.key) {
707
+ throw new EcosystemError(ERROR_TYPE.KEY_OR_CONTEXT_PATH_MISMATCH);
708
+ }
709
+ });
710
+ }
663
711
  getAppKey(appModel, name) {
664
712
  let key = appModel === null || appModel === void 0 ? void 0 : appModel.key;
665
713
  if (!key) {
@@ -677,13 +725,13 @@ class EcosystemService {
677
725
  const currentApp = this.appStateService.state.app;
678
726
  return currentApp.contextPath === app.contextPath;
679
727
  }
680
- getCumulocityJson(archive) {
728
+ getCumulocityJson$(archive) {
681
729
  return this.zipService.getJsonData(archive, {
682
730
  filename: CUMULOCITY_JSON
683
731
  });
684
732
  }
685
733
  getAppType(archive) {
686
- return this.getCumulocityJson(archive)
734
+ return this.getCumulocityJson$(archive)
687
735
  .toPromise()
688
736
  .then(data => get(data, 'type') ||
689
737
  (get(data, 'apiVersion') ? ApplicationType.MICROSERVICE : ApplicationType.HOSTED))
@@ -713,7 +761,7 @@ class EcosystemService {
713
761
  getUploadOverrides(archive, app) {
714
762
  var _a;
715
763
  return __awaiter(this, void 0, void 0, function* () {
716
- const { version } = yield this.getCumulocityJson(archive).toPromise();
764
+ const { version } = yield this.getCumulocityJson$(archive).toPromise();
717
765
  const isInitialPackage = ((_a = app.applicationVersions) === null || _a === void 0 ? void 0 : _a.length) === 0;
718
766
  return {
719
767
  listUrl: 'versions',
@@ -1046,7 +1094,7 @@ class UploadArchiveComponent {
1046
1094
  onFile(file) {
1047
1095
  return __awaiter(this, void 0, void 0, function* () {
1048
1096
  try {
1049
- yield this.ecosystemService.isValidAppType(file, this.application.type);
1097
+ yield this.ecosystemService.validateArchiveToAppCompatibility(file, this.application);
1050
1098
  const isCustomMicroservice = this.ecosystemService.isCustomMicroservice(this.application);
1051
1099
  this.archives = isCustomMicroservice
1052
1100
  ? []
@@ -1059,9 +1107,6 @@ class UploadArchiveComponent {
1059
1107
  if (this.archives.length === 6 && !isCustomMicroservice) {
1060
1108
  yield this.ecosystemService.removeOldestArchive(this.application, this.archives);
1061
1109
  }
1062
- if (this.uploadNewVersion) {
1063
- yield this.ecosystemService.validatePackageKeyAndContextPath(file, this.application);
1064
- }
1065
1110
  const app = yield this.ecosystemService.uploadArchiveToApp(file, this.application, this.uploadNewVersion);
1066
1111
  this.applicationChange.emit(app);
1067
1112
  this.uploadProgress.next(100);
@@ -1074,16 +1119,16 @@ class UploadArchiveComponent {
1074
1119
  }
1075
1120
  catch (ex) {
1076
1121
  this.uploadInProgress = false;
1077
- this.alertService.addServerFailure(ex);
1122
+ this.ecosystemService.alertError(ex);
1078
1123
  }
1079
1124
  });
1080
1125
  }
1081
1126
  }
1082
1127
  UploadArchiveComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UploadArchiveComponent, deps: [{ token: EcosystemService }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Component });
1083
- UploadArchiveComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: UploadArchiveComponent, selector: "c8y-upload-archive", inputs: { application: "application", uploadNewVersion: "uploadNewVersion", preUploadCallback: "preUploadCallback" }, outputs: { applicationChange: "applicationChange", refresh: "refresh" }, ngImport: i0, template: "<c8y-drop-area\n (dropped)=\"onFileDroppedEvent($event)\"\n [accept]=\"'.zip'\"\n [files]=\"fileList\"\n [loading]=\"uploadInProgress\"\n [maxAllowedFiles]=\"1\"\n [message]=\"'Upload a *.zip file' | translate\"\n [progress]=\"uploadProgress | async\"\n [forceHideList]=\"true\"\n class=\"drop-area-sm\"\n>\n</c8y-drop-area>\n", dependencies: [{ kind: "component", type: i2.DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "accept"], outputs: ["dropped"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3$1.AsyncPipe, name: "async" }] });
1128
+ UploadArchiveComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: UploadArchiveComponent, selector: "c8y-upload-archive", inputs: { application: "application", uploadNewVersion: "uploadNewVersion", preUploadCallback: "preUploadCallback" }, outputs: { applicationChange: "applicationChange", refresh: "refresh" }, ngImport: i0, template: "<c8y-drop-area\n (dropped)=\"onFileDroppedEvent($event)\"\n [accept]=\"'.zip'\"\n [loading]=\"uploadInProgress\"\n [maxAllowedFiles]=\"1\"\n [message]=\"'Upload a *.zip file' | translate\"\n [progress]=\"uploadProgress | async\"\n [forceHideList]=\"true\"\n class=\"drop-area-sm\"\n>\n</c8y-drop-area>\n", dependencies: [{ kind: "component", type: i2.DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "accept"], outputs: ["dropped"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3$1.AsyncPipe, name: "async" }] });
1084
1129
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UploadArchiveComponent, decorators: [{
1085
1130
  type: Component,
1086
- args: [{ selector: 'c8y-upload-archive', template: "<c8y-drop-area\n (dropped)=\"onFileDroppedEvent($event)\"\n [accept]=\"'.zip'\"\n [files]=\"fileList\"\n [loading]=\"uploadInProgress\"\n [maxAllowedFiles]=\"1\"\n [message]=\"'Upload a *.zip file' | translate\"\n [progress]=\"uploadProgress | async\"\n [forceHideList]=\"true\"\n class=\"drop-area-sm\"\n>\n</c8y-drop-area>\n" }]
1131
+ args: [{ selector: 'c8y-upload-archive', template: "<c8y-drop-area\n (dropped)=\"onFileDroppedEvent($event)\"\n [accept]=\"'.zip'\"\n [loading]=\"uploadInProgress\"\n [maxAllowedFiles]=\"1\"\n [message]=\"'Upload a *.zip file' | translate\"\n [progress]=\"uploadProgress | async\"\n [forceHideList]=\"true\"\n class=\"drop-area-sm\"\n>\n</c8y-drop-area>\n" }]
1087
1132
  }], ctorParameters: function () { return [{ type: EcosystemService }, { type: i2.AlertService }]; }, propDecorators: { application: [{
1088
1133
  type: Input
1089
1134
  }], uploadNewVersion: [{