@lvce-editor/extension-detail-view 4.6.0 → 4.8.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.
|
@@ -30,6 +30,7 @@ const Id = 'ID';
|
|
|
30
30
|
const Identifier = 'Identifier';
|
|
31
31
|
const ImportTime = 'Import Time: ';
|
|
32
32
|
const Installation = 'Installation';
|
|
33
|
+
const InvalidLink = 'Invalid link';
|
|
33
34
|
const Issues = 'Issues';
|
|
34
35
|
const JsonValidation$1 = 'Json Validation';
|
|
35
36
|
const Label = 'Label';
|
|
@@ -42,18 +43,21 @@ const NoReadmeFound = 'No Readme Found.';
|
|
|
42
43
|
const OpenImageInNewTab = 'Open Image in New Tab';
|
|
43
44
|
const OpenInNewTab = 'Open in New Tab';
|
|
44
45
|
const ProgrammingLanguages$1 = 'Programming Languages';
|
|
46
|
+
const PropertyMustBeOfTypeString = 'Property must be a string';
|
|
45
47
|
const Published = 'Published';
|
|
46
48
|
const Repository = 'Repository';
|
|
47
49
|
const Resources$1 = 'Resources';
|
|
48
50
|
const RuntimeStatus$1 = 'Runtime Status';
|
|
49
51
|
const SaveImageAs = 'Save Image as';
|
|
50
52
|
const Schema = 'Schema';
|
|
53
|
+
const SchemaNotFound = 'Schema not found';
|
|
51
54
|
const ScrollToTop$1 = 'Scroll to top';
|
|
52
55
|
const SelectedFeatureUnknownOrUnsupported = 'Selected feature is unknown or unsupported';
|
|
53
56
|
const Selector = 'Selector';
|
|
54
57
|
const SetColorTheme$1 = 'Set Color Theme';
|
|
55
58
|
const Settings$1 = 'Settings';
|
|
56
59
|
const Size = 'Size';
|
|
60
|
+
const StringMustNotBeEmpty = 'String must not be empty';
|
|
57
61
|
const Theme$1 = 'Theme';
|
|
58
62
|
const Uninstall$1 = 'Uninstall';
|
|
59
63
|
const UnsupportedFeature = 'Unsupported Feature';
|
|
@@ -207,11 +211,50 @@ const repository = () => {
|
|
|
207
211
|
const license = () => {
|
|
208
212
|
return i18nString(License);
|
|
209
213
|
};
|
|
214
|
+
const propertyMustBeOfTypeString = () => {
|
|
215
|
+
return i18nString(PropertyMustBeOfTypeString);
|
|
216
|
+
};
|
|
217
|
+
const stringMustNotBeEmpty = () => {
|
|
218
|
+
return i18nString(StringMustNotBeEmpty);
|
|
219
|
+
};
|
|
220
|
+
const schemaNotFound = () => {
|
|
221
|
+
return i18nString(SchemaNotFound);
|
|
222
|
+
};
|
|
223
|
+
const invalidLink = () => {
|
|
224
|
+
return i18nString(InvalidLink);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const getActivationEntry = value => {
|
|
228
|
+
if (typeof value !== 'string') {
|
|
229
|
+
return {
|
|
230
|
+
isValid: false,
|
|
231
|
+
stringValue: JSON.stringify(value),
|
|
232
|
+
errorMessage: propertyMustBeOfTypeString()
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
if (!value) {
|
|
236
|
+
return {
|
|
237
|
+
isValid: false,
|
|
238
|
+
stringValue: '',
|
|
239
|
+
errorMessage: stringMustNotBeEmpty()
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
isValid: true,
|
|
244
|
+
stringValue: value,
|
|
245
|
+
errorMessage: ''
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
const getActivationEntries = activation => {
|
|
249
|
+
return activation.map(getActivationEntry);
|
|
250
|
+
};
|
|
210
251
|
|
|
211
252
|
const getActivationEventsDetails = async extension => {
|
|
212
253
|
const activationEvents = extension.activation || [];
|
|
254
|
+
const activationEntries = getActivationEntries(activationEvents);
|
|
213
255
|
return {
|
|
214
|
-
activationEvents
|
|
256
|
+
activationEvents,
|
|
257
|
+
activationEntries
|
|
215
258
|
};
|
|
216
259
|
};
|
|
217
260
|
|
|
@@ -336,7 +379,20 @@ const code = {
|
|
|
336
379
|
childCount: 1
|
|
337
380
|
};
|
|
338
381
|
const getActivationEventVirtualDom = event => {
|
|
339
|
-
|
|
382
|
+
const {
|
|
383
|
+
stringValue,
|
|
384
|
+
errorMessage,
|
|
385
|
+
isValid
|
|
386
|
+
} = event;
|
|
387
|
+
if (!isValid) {
|
|
388
|
+
return [{
|
|
389
|
+
type: Li,
|
|
390
|
+
childCount: 1,
|
|
391
|
+
title: errorMessage,
|
|
392
|
+
className: 'ListItem ListItemInvalid'
|
|
393
|
+
}, code, text(stringValue)];
|
|
394
|
+
}
|
|
395
|
+
return [li, code, text(stringValue)];
|
|
340
396
|
};
|
|
341
397
|
|
|
342
398
|
const getFeatureContentHeadingVirtualDom = heading => {
|
|
@@ -359,7 +415,7 @@ const getFeatureActivationEventsVirtualDom = activationEvents$1 => {
|
|
|
359
415
|
};
|
|
360
416
|
|
|
361
417
|
const getActivationEventsVirtualDom = state => {
|
|
362
|
-
return getFeatureActivationEventsVirtualDom(state.
|
|
418
|
+
return getFeatureActivationEventsVirtualDom(state.activationEntries);
|
|
363
419
|
};
|
|
364
420
|
|
|
365
421
|
const Text = 1;
|
|
@@ -441,16 +497,19 @@ const getCellCodeVirtualDom = (value, props) => {
|
|
|
441
497
|
}, text(value)];
|
|
442
498
|
};
|
|
443
499
|
|
|
444
|
-
const getCellLinkVirtualDom = (value, {
|
|
445
|
-
|
|
446
|
-
}) => {
|
|
500
|
+
const getCellLinkVirtualDom = (value, props) => {
|
|
501
|
+
const tdClassName = props?.className ? `${TableCell} ${props.className}` : TableCell;
|
|
447
502
|
return [{
|
|
448
503
|
type: Td,
|
|
449
|
-
className:
|
|
450
|
-
childCount: 1
|
|
504
|
+
className: tdClassName,
|
|
505
|
+
childCount: 1,
|
|
506
|
+
...(props?.title ? {
|
|
507
|
+
title: props.title
|
|
508
|
+
} : {})
|
|
451
509
|
}, {
|
|
452
510
|
type: A,
|
|
453
|
-
|
|
511
|
+
className: Link$1,
|
|
512
|
+
href: props?.href,
|
|
454
513
|
childCount: 1
|
|
455
514
|
}, text(value)];
|
|
456
515
|
};
|
|
@@ -536,94 +595,187 @@ const getCommandsVirtualDom = state => {
|
|
|
536
595
|
return getFeatureCommandsVirtualDom(state.commands);
|
|
537
596
|
};
|
|
538
597
|
|
|
539
|
-
const
|
|
540
|
-
return
|
|
598
|
+
const isExternalLink = schema => {
|
|
599
|
+
return schema.startsWith('http://') || schema.startsWith('https://');
|
|
541
600
|
};
|
|
542
|
-
const
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
601
|
+
const hasWhitespace = value => {
|
|
602
|
+
return /\s/.test(value);
|
|
603
|
+
};
|
|
604
|
+
const isOnlyDotsOrEmpty = value => {
|
|
605
|
+
const trimmed = value.trim();
|
|
606
|
+
return trimmed === '' || /^\.*$/.test(trimmed);
|
|
607
|
+
};
|
|
608
|
+
const isValidHttpUrl = value => {
|
|
609
|
+
try {
|
|
610
|
+
const url = new URL(value);
|
|
611
|
+
return (url.protocol === 'http:' || url.protocol === 'https:') && !!url.hostname;
|
|
612
|
+
} catch {
|
|
613
|
+
return false;
|
|
555
614
|
}
|
|
556
|
-
return {
|
|
557
|
-
type: Text,
|
|
558
|
-
value: schema
|
|
559
|
-
};
|
|
560
615
|
};
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
616
|
+
const isValidRelativePath = value => {
|
|
617
|
+
// Disallow schemes and whitespace
|
|
618
|
+
if (hasWhitespace(value)) {
|
|
619
|
+
return false;
|
|
620
|
+
}
|
|
621
|
+
if (value.includes('://')) {
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
if (isOnlyDotsOrEmpty(value)) {
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
// Allow paths like ./a.json, ../a.json, /a.json, schemas/a.json, a/b.json
|
|
628
|
+
if (!/^[./]?[A-Za-z0-9._\-/]+$/.test(value)) {
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
// Must contain at least one alphanumeric character
|
|
632
|
+
if (!/[A-Za-z0-9]/.test(value)) {
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
return true;
|
|
564
636
|
};
|
|
565
637
|
const getSchemaLinkUrl = (schema, extensionUri) => {
|
|
566
|
-
if (!schema) {
|
|
638
|
+
if (!schema || typeof schema !== 'string') {
|
|
567
639
|
return '';
|
|
568
640
|
}
|
|
569
|
-
|
|
641
|
+
const trimmed = schema.trim();
|
|
642
|
+
if (trimmed !== schema) {
|
|
570
643
|
return '';
|
|
571
644
|
}
|
|
572
645
|
if (isExternalLink(schema)) {
|
|
573
|
-
return schema;
|
|
646
|
+
return isValidHttpUrl(schema) ? schema : '';
|
|
647
|
+
}
|
|
648
|
+
if (!isValidRelativePath(schema)) {
|
|
649
|
+
return '';
|
|
650
|
+
}
|
|
651
|
+
try {
|
|
652
|
+
return new URL(schema, extensionUri).toString();
|
|
653
|
+
} catch {
|
|
654
|
+
return '';
|
|
574
655
|
}
|
|
575
|
-
return new URL(schema, extensionUri).toString();
|
|
576
656
|
};
|
|
577
657
|
|
|
578
|
-
const
|
|
658
|
+
const existsJson = async schemaUrl => {
|
|
579
659
|
try {
|
|
580
|
-
|
|
660
|
+
// TODO verify that response header is json
|
|
661
|
+
const response = await fetch(schemaUrl, {
|
|
662
|
+
method: 'HEAD'
|
|
663
|
+
});
|
|
664
|
+
return response.ok;
|
|
581
665
|
} catch {
|
|
582
|
-
return
|
|
666
|
+
return false;
|
|
583
667
|
}
|
|
584
668
|
};
|
|
585
|
-
const
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
669
|
+
const getJsonValidationInfos = async (extensionUri, validations) => {
|
|
670
|
+
const validationInfos = [];
|
|
671
|
+
for (const validation of validations) {
|
|
672
|
+
const schema = validation.schema ?? validation.url;
|
|
673
|
+
const schemaLinkUrl = getSchemaLinkUrl(schema, extensionUri);
|
|
674
|
+
const {
|
|
675
|
+
fileMatch
|
|
676
|
+
} = validation;
|
|
677
|
+
if (typeof schema !== 'string') {
|
|
678
|
+
validationInfos.push({
|
|
679
|
+
isValid: false,
|
|
680
|
+
stringValue: JSON.stringify(schema),
|
|
681
|
+
schemaUrl: '',
|
|
682
|
+
errorMessage: propertyMustBeOfTypeString(),
|
|
683
|
+
fileMatch
|
|
684
|
+
});
|
|
685
|
+
} else if (schema && !schemaLinkUrl) {
|
|
686
|
+
validationInfos.push({
|
|
687
|
+
isValid: false,
|
|
688
|
+
stringValue: schema,
|
|
689
|
+
schemaUrl: schemaLinkUrl,
|
|
690
|
+
errorMessage: invalidLink(),
|
|
691
|
+
fileMatch
|
|
692
|
+
});
|
|
693
|
+
} else if (schemaLinkUrl) {
|
|
694
|
+
if (await existsJson(schemaLinkUrl)) {
|
|
695
|
+
validationInfos.push({
|
|
696
|
+
isValid: true,
|
|
697
|
+
stringValue: schema,
|
|
698
|
+
schemaUrl: schemaLinkUrl,
|
|
699
|
+
errorMessage: '',
|
|
700
|
+
fileMatch
|
|
701
|
+
});
|
|
702
|
+
} else {
|
|
703
|
+
validationInfos.push({
|
|
704
|
+
isValid: false,
|
|
705
|
+
stringValue: schema,
|
|
706
|
+
schemaUrl: schemaLinkUrl,
|
|
707
|
+
errorMessage: schemaNotFound(),
|
|
708
|
+
fileMatch
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
} else {
|
|
712
|
+
validationInfos.push({
|
|
713
|
+
isValid: true,
|
|
714
|
+
stringValue: schema,
|
|
715
|
+
schemaUrl: schemaLinkUrl,
|
|
716
|
+
errorMessage: '',
|
|
717
|
+
fileMatch
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
return validationInfos;
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
const getJsonValidationTableEntry = validationInfo => {
|
|
725
|
+
const {
|
|
726
|
+
isValid,
|
|
727
|
+
errorMessage,
|
|
728
|
+
schemaUrl,
|
|
729
|
+
stringValue,
|
|
730
|
+
fileMatch
|
|
731
|
+
} = validationInfo;
|
|
732
|
+
if (!isValid && schemaUrl) {
|
|
733
|
+
return [{
|
|
734
|
+
type: Code,
|
|
735
|
+
value: fileMatch
|
|
736
|
+
}, {
|
|
737
|
+
type: Link,
|
|
738
|
+
value: stringValue,
|
|
739
|
+
href: schemaUrl,
|
|
740
|
+
className: TableCellInvalid,
|
|
741
|
+
title: errorMessage
|
|
742
|
+
}];
|
|
743
|
+
}
|
|
744
|
+
if (!isValid) {
|
|
592
745
|
return [{
|
|
593
746
|
type: Text,
|
|
594
|
-
value:
|
|
595
|
-
...invalidProps
|
|
747
|
+
value: fileMatch
|
|
596
748
|
}, {
|
|
597
749
|
type: Text,
|
|
598
|
-
value:
|
|
599
|
-
|
|
750
|
+
value: stringValue,
|
|
751
|
+
className: TableCellInvalid,
|
|
752
|
+
title: errorMessage
|
|
600
753
|
}];
|
|
601
754
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
755
|
+
if (schemaUrl) {
|
|
756
|
+
return [{
|
|
757
|
+
type: Code,
|
|
758
|
+
value: fileMatch
|
|
759
|
+
}, {
|
|
760
|
+
type: Link,
|
|
761
|
+
value: stringValue,
|
|
762
|
+
href: schemaUrl
|
|
763
|
+
}];
|
|
764
|
+
}
|
|
765
|
+
return [{
|
|
608
766
|
type: Code,
|
|
609
767
|
value: fileMatch
|
|
610
|
-
}
|
|
611
|
-
type: Text,
|
|
612
|
-
value: stringify(fileMatch),
|
|
613
|
-
...invalidProps
|
|
614
|
-
};
|
|
615
|
-
const rightEntry = typeof schema === 'string' ? getLinkOrTextEntry(schema, schemaLinkUrl) : {
|
|
768
|
+
}, {
|
|
616
769
|
type: Text,
|
|
617
|
-
value:
|
|
618
|
-
|
|
619
|
-
};
|
|
620
|
-
return [leftCell, rightEntry];
|
|
770
|
+
value: stringValue
|
|
771
|
+
}];
|
|
621
772
|
};
|
|
622
773
|
|
|
623
774
|
const getJsonValidationDetails = async extension => {
|
|
624
775
|
const validations = extension.jsonValidation || [];
|
|
625
776
|
const extensionUri = extension.uri || '';
|
|
626
|
-
const
|
|
777
|
+
const validationInfos = await getJsonValidationInfos(extensionUri, validations);
|
|
778
|
+
const rows = validationInfos.map(getJsonValidationTableEntry);
|
|
627
779
|
return {
|
|
628
780
|
jsonValidation: rows
|
|
629
781
|
};
|
|
@@ -835,7 +987,7 @@ class AssertionError extends Error {
|
|
|
835
987
|
const Object$1 = 1;
|
|
836
988
|
const Number$1 = 2;
|
|
837
989
|
const Array$1 = 3;
|
|
838
|
-
const String
|
|
990
|
+
const String = 4;
|
|
839
991
|
const Boolean$1 = 5;
|
|
840
992
|
const Function = 6;
|
|
841
993
|
const Null = 7;
|
|
@@ -847,7 +999,7 @@ const getType = value => {
|
|
|
847
999
|
case 'function':
|
|
848
1000
|
return Function;
|
|
849
1001
|
case 'string':
|
|
850
|
-
return String
|
|
1002
|
+
return String;
|
|
851
1003
|
case 'object':
|
|
852
1004
|
if (value === null) {
|
|
853
1005
|
return Null;
|
|
@@ -864,7 +1016,7 @@ const getType = value => {
|
|
|
864
1016
|
};
|
|
865
1017
|
const string = value => {
|
|
866
1018
|
const type = getType(value);
|
|
867
|
-
if (type !== String
|
|
1019
|
+
if (type !== String) {
|
|
868
1020
|
throw new AssertionError('expected value to be of type string');
|
|
869
1021
|
}
|
|
870
1022
|
};
|
|
@@ -3112,7 +3264,8 @@ const create = (uid, uri, x, y, width, height, platform, assetDir) => {
|
|
|
3112
3264
|
paddingRight: 0,
|
|
3113
3265
|
showSideBar: true,
|
|
3114
3266
|
sideBarWidth: 0,
|
|
3115
|
-
locationProtocol: ''
|
|
3267
|
+
locationProtocol: '',
|
|
3268
|
+
activationEntries: []
|
|
3116
3269
|
};
|
|
3117
3270
|
set(uid, state, state);
|
|
3118
3271
|
};
|