@lvce-editor/extension-detail-view 7.20.0 → 7.21.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.
|
@@ -1205,12 +1205,26 @@ const existsJson = async schemaUrl => {
|
|
|
1205
1205
|
const isExternalLink$2 = schema => {
|
|
1206
1206
|
return schema.startsWith('http://') || schema.startsWith('https://');
|
|
1207
1207
|
};
|
|
1208
|
+
const isAlphanumeric = char => {
|
|
1209
|
+
const code = char.codePointAt(0) || 0;
|
|
1210
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
1211
|
+
};
|
|
1208
1212
|
const hasWhitespace = value => {
|
|
1209
|
-
|
|
1213
|
+
for (const char of value) {
|
|
1214
|
+
if (char.trim() === '') {
|
|
1215
|
+
return true;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
return false;
|
|
1210
1219
|
};
|
|
1211
1220
|
const isOnlyDotsOrEmpty = value => {
|
|
1212
1221
|
const trimmed = value.trim();
|
|
1213
|
-
|
|
1222
|
+
for (const char of trimmed) {
|
|
1223
|
+
if (char !== '.') {
|
|
1224
|
+
return false;
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
return true;
|
|
1214
1228
|
};
|
|
1215
1229
|
const isValidHttpUrl = value => {
|
|
1216
1230
|
try {
|
|
@@ -1232,11 +1246,17 @@ const isValidRelativePath = value => {
|
|
|
1232
1246
|
return false;
|
|
1233
1247
|
}
|
|
1234
1248
|
// Allow paths like ./a.json, ../a.json, /a.json, schemas/a.json, a/b.json
|
|
1235
|
-
|
|
1236
|
-
|
|
1249
|
+
let hasAlphanumeric = false;
|
|
1250
|
+
for (const char of value) {
|
|
1251
|
+
if (!isAlphanumeric(char) && char !== '.' && char !== '_' && char !== '-' && char !== '/') {
|
|
1252
|
+
return false;
|
|
1253
|
+
}
|
|
1254
|
+
if (isAlphanumeric(char)) {
|
|
1255
|
+
hasAlphanumeric = true;
|
|
1256
|
+
}
|
|
1237
1257
|
}
|
|
1238
1258
|
// Must contain at least one alphanumeric character
|
|
1239
|
-
return
|
|
1259
|
+
return hasAlphanumeric;
|
|
1240
1260
|
};
|
|
1241
1261
|
const getSchemaLinkUrl = (schema, extensionUri) => {
|
|
1242
1262
|
if (!schema || typeof schema !== 'string') {
|
|
@@ -3772,7 +3792,10 @@ const writeText = async text => {
|
|
|
3772
3792
|
};
|
|
3773
3793
|
|
|
3774
3794
|
const copyExtensionId = async state => {
|
|
3775
|
-
|
|
3795
|
+
const {
|
|
3796
|
+
extensionId
|
|
3797
|
+
} = state;
|
|
3798
|
+
await writeText(extensionId);
|
|
3776
3799
|
return state;
|
|
3777
3800
|
};
|
|
3778
3801
|
|
|
@@ -4482,8 +4505,13 @@ const handleClickFeatures = async (state, name) => {
|
|
|
4482
4505
|
};
|
|
4483
4506
|
|
|
4484
4507
|
const handleClickScrollToTop = state => {
|
|
4485
|
-
|
|
4486
|
-
|
|
4508
|
+
const {
|
|
4509
|
+
changelogScrollTop,
|
|
4510
|
+
readmeScrollTop,
|
|
4511
|
+
selectedTab
|
|
4512
|
+
} = state;
|
|
4513
|
+
if (selectedTab === Changelog) {
|
|
4514
|
+
if (changelogScrollTop === 0) {
|
|
4487
4515
|
return state;
|
|
4488
4516
|
}
|
|
4489
4517
|
return {
|
|
@@ -4491,9 +4519,6 @@ const handleClickScrollToTop = state => {
|
|
|
4491
4519
|
changelogScrollTop: 0
|
|
4492
4520
|
};
|
|
4493
4521
|
}
|
|
4494
|
-
const {
|
|
4495
|
-
readmeScrollTop
|
|
4496
|
-
} = state;
|
|
4497
4522
|
if (readmeScrollTop === 0) {
|
|
4498
4523
|
return state;
|
|
4499
4524
|
}
|
|
@@ -4509,7 +4534,9 @@ const setColorTheme = id => {
|
|
|
4509
4534
|
|
|
4510
4535
|
const handleClickSetColorTheme = async state => {
|
|
4511
4536
|
const {
|
|
4512
|
-
|
|
4537
|
+
disabled,
|
|
4538
|
+
extension,
|
|
4539
|
+
hasColorTheme
|
|
4513
4540
|
} = state;
|
|
4514
4541
|
const colorThemeId = getColorThemeId(extension);
|
|
4515
4542
|
if (colorThemeId) {
|
|
@@ -4519,7 +4546,7 @@ const handleClickSetColorTheme = async state => {
|
|
|
4519
4546
|
}
|
|
4520
4547
|
const isBuiltin = extension?.isBuiltin || extension?.builtin || false;
|
|
4521
4548
|
const colorThemeLabel = getColorThemeLabel(extension) || '';
|
|
4522
|
-
const buttons = getExtensionDetailButtons(
|
|
4549
|
+
const buttons = getExtensionDetailButtons(hasColorTheme, isBuiltin, disabled, colorThemeId, colorThemeLabel, colorThemeId);
|
|
4523
4550
|
return {
|
|
4524
4551
|
...state,
|
|
4525
4552
|
buttons,
|
|
@@ -4540,30 +4567,37 @@ const handleClickSettings = async (state, eventX, eventY) => {
|
|
|
4540
4567
|
};
|
|
4541
4568
|
|
|
4542
4569
|
const handleClickSize = async state => {
|
|
4570
|
+
const {
|
|
4571
|
+
extension
|
|
4572
|
+
} = state;
|
|
4543
4573
|
const {
|
|
4544
4574
|
uri
|
|
4545
|
-
} =
|
|
4575
|
+
} = extension;
|
|
4546
4576
|
await openNativeFolder(uri);
|
|
4547
4577
|
return state;
|
|
4548
4578
|
};
|
|
4549
4579
|
|
|
4550
4580
|
const handleClickUninstall = async state => {
|
|
4581
|
+
const {
|
|
4582
|
+
extension
|
|
4583
|
+
} = state;
|
|
4551
4584
|
const {
|
|
4552
4585
|
id
|
|
4553
|
-
} =
|
|
4586
|
+
} = extension;
|
|
4554
4587
|
await uninstallExtension(id);
|
|
4555
4588
|
return state;
|
|
4556
4589
|
};
|
|
4557
4590
|
|
|
4558
4591
|
const handleColorThemeChanged = (state, colorThemeId) => {
|
|
4559
|
-
if (state.currentColorThemeId === colorThemeId) {
|
|
4560
|
-
return state;
|
|
4561
|
-
}
|
|
4562
4592
|
const {
|
|
4593
|
+
currentColorThemeId,
|
|
4563
4594
|
disabled,
|
|
4564
4595
|
extension,
|
|
4565
4596
|
hasColorTheme
|
|
4566
4597
|
} = state;
|
|
4598
|
+
if (currentColorThemeId === colorThemeId) {
|
|
4599
|
+
return state;
|
|
4600
|
+
}
|
|
4567
4601
|
const extensionColorThemeId = getColorThemeId(extension) || '';
|
|
4568
4602
|
const extensionColorThemeLabel = getColorThemeLabel(extension) || '';
|
|
4569
4603
|
const isBuiltin = extension?.isBuiltin || extension?.builtin || false;
|
|
@@ -4672,6 +4706,12 @@ const getExtensionUri = (uri, platform, origin) => {
|
|
|
4672
4706
|
};
|
|
4673
4707
|
|
|
4674
4708
|
const segmentRegex = /^[\w.-]+$/;
|
|
4709
|
+
const removeGitPrefix = value => {
|
|
4710
|
+
return value.startsWith('git+') ? value.slice(4) : value;
|
|
4711
|
+
};
|
|
4712
|
+
const removeGitSuffix = value => {
|
|
4713
|
+
return value.toLowerCase().endsWith('.git') ? value.slice(0, -4) : value;
|
|
4714
|
+
};
|
|
4675
4715
|
const getRepositoryUrl = extension => {
|
|
4676
4716
|
if (!extension || !hasProperty(extension, 'repository')) {
|
|
4677
4717
|
return '';
|
|
@@ -4688,7 +4728,7 @@ const getRepositoryUrl = extension => {
|
|
|
4688
4728
|
return '';
|
|
4689
4729
|
};
|
|
4690
4730
|
const getGithubRepository = extension => {
|
|
4691
|
-
const rawUrl = getRepositoryUrl(extension)
|
|
4731
|
+
const rawUrl = removeGitPrefix(getRepositoryUrl(extension));
|
|
4692
4732
|
try {
|
|
4693
4733
|
const url = new URL(rawUrl);
|
|
4694
4734
|
if (url.protocol !== 'https:' || url.hostname.toLowerCase() !== 'github.com' || url.username || url.password || url.port) {
|
|
@@ -4699,7 +4739,7 @@ const getGithubRepository = extension => {
|
|
|
4699
4739
|
return undefined;
|
|
4700
4740
|
}
|
|
4701
4741
|
const owner = segments[0];
|
|
4702
|
-
const repository = segments[1]
|
|
4742
|
+
const repository = removeGitSuffix(segments[1]);
|
|
4703
4743
|
if (!owner || !repository || !segmentRegex.test(owner) || !segmentRegex.test(repository)) {
|
|
4704
4744
|
return undefined;
|
|
4705
4745
|
}
|
|
@@ -4767,9 +4807,15 @@ const toSyntaxLanguage = value => {
|
|
|
4767
4807
|
if (typeof language.id !== 'string' || typeof language.tokenize !== 'string') {
|
|
4768
4808
|
return undefined;
|
|
4769
4809
|
}
|
|
4810
|
+
const aliases = getStringArray(language.aliases);
|
|
4811
|
+
const extensions = getStringArray(language.extensions);
|
|
4770
4812
|
return {
|
|
4771
|
-
aliases
|
|
4772
|
-
|
|
4813
|
+
...(aliases && {
|
|
4814
|
+
aliases
|
|
4815
|
+
}),
|
|
4816
|
+
...(extensions && {
|
|
4817
|
+
extensions
|
|
4818
|
+
}),
|
|
4773
4819
|
id: language.id,
|
|
4774
4820
|
tokenize: language.tokenize
|
|
4775
4821
|
};
|
|
@@ -5301,13 +5347,20 @@ const getIssuesLink = extension => {
|
|
|
5301
5347
|
const isGitHubRepository = url => {
|
|
5302
5348
|
return url.startsWith('https://github.com/');
|
|
5303
5349
|
};
|
|
5350
|
+
const removeTrailingSlashes = value => {
|
|
5351
|
+
let end = value.length;
|
|
5352
|
+
while (end > 0 && value[end - 1] === '/') {
|
|
5353
|
+
end--;
|
|
5354
|
+
}
|
|
5355
|
+
return value.slice(0, end);
|
|
5356
|
+
};
|
|
5304
5357
|
const getLicenseLink = extension => {
|
|
5305
5358
|
const repositoryLink = getRepositoryLink(extension);
|
|
5306
5359
|
if (!repositoryLink) {
|
|
5307
5360
|
return '#';
|
|
5308
5361
|
}
|
|
5309
5362
|
if (isGitHubRepository(repositoryLink)) {
|
|
5310
|
-
const normalizedLink = repositoryLink
|
|
5363
|
+
const normalizedLink = removeTrailingSlashes(repositoryLink);
|
|
5311
5364
|
return `${normalizedLink}/blob/main/LICENSE`;
|
|
5312
5365
|
}
|
|
5313
5366
|
return '#';
|
|
@@ -5461,6 +5514,7 @@ const loadContentInternal = async (state, platform, savedState, isTest = false)
|
|
|
5461
5514
|
savedState = undefined;
|
|
5462
5515
|
}
|
|
5463
5516
|
const {
|
|
5517
|
+
assetDir,
|
|
5464
5518
|
uri,
|
|
5465
5519
|
width
|
|
5466
5520
|
} = state;
|
|
@@ -5471,7 +5525,7 @@ const loadContentInternal = async (state, platform, savedState, isTest = false)
|
|
|
5471
5525
|
}
|
|
5472
5526
|
const currentColorThemeId = await getCurrentColorTheme();
|
|
5473
5527
|
const commit = await getCommit();
|
|
5474
|
-
const languages = await getSyntaxLanguages(platform,
|
|
5528
|
+
const languages = await getSyntaxLanguages(platform, assetDir);
|
|
5475
5529
|
const headerData = loadHeaderContent(state, platform, extension);
|
|
5476
5530
|
const {
|
|
5477
5531
|
badge,
|
|
@@ -5592,10 +5646,13 @@ const loadContentInternal = async (state, platform, savedState, isTest = false)
|
|
|
5592
5646
|
};
|
|
5593
5647
|
};
|
|
5594
5648
|
const loadContent = async (state, platform, savedState, isTest = false) => {
|
|
5649
|
+
const {
|
|
5650
|
+
uri
|
|
5651
|
+
} = state;
|
|
5595
5652
|
try {
|
|
5596
5653
|
return await loadContentInternal(state, platform, savedState, isTest);
|
|
5597
5654
|
} catch (error) {
|
|
5598
|
-
const extensionId = getExtensionIdFromUri(
|
|
5655
|
+
const extensionId = getExtensionIdFromUri(uri);
|
|
5599
5656
|
const errorMessage = error instanceof ExtensionNotFoundError ? extensionNotAvailable(extensionId) : unableToLoadExtensionWithError(getErrorMessage$1(error));
|
|
5600
5657
|
return {
|
|
5601
5658
|
...state,
|
|
@@ -5689,9 +5746,13 @@ const replaceMarkdownImageWithError = (dom, failedSrc) => {
|
|
|
5689
5746
|
};
|
|
5690
5747
|
|
|
5691
5748
|
const handleMarkdownImageError = (state, failedSrc) => {
|
|
5692
|
-
const
|
|
5693
|
-
|
|
5694
|
-
|
|
5749
|
+
const {
|
|
5750
|
+
changelogVirtualDom: oldChangelogVirtualDom,
|
|
5751
|
+
detailsVirtualDom: oldDetailsVirtualDom
|
|
5752
|
+
} = state;
|
|
5753
|
+
const detailsVirtualDom = replaceMarkdownImageWithError(oldDetailsVirtualDom, failedSrc);
|
|
5754
|
+
const changelogVirtualDom = replaceMarkdownImageWithError(oldChangelogVirtualDom, failedSrc);
|
|
5755
|
+
if (detailsVirtualDom === oldDetailsVirtualDom && changelogVirtualDom === oldChangelogVirtualDom) {
|
|
5695
5756
|
return state;
|
|
5696
5757
|
}
|
|
5697
5758
|
return {
|
|
@@ -5709,7 +5770,10 @@ const disablePreviewColorTheme = async () => {
|
|
|
5709
5770
|
};
|
|
5710
5771
|
|
|
5711
5772
|
const handleMouseEnterEnable = async state => {
|
|
5712
|
-
const
|
|
5773
|
+
const {
|
|
5774
|
+
extension
|
|
5775
|
+
} = state;
|
|
5776
|
+
const colorThemeId = getColorThemeId(extension);
|
|
5713
5777
|
if (!colorThemeId) {
|
|
5714
5778
|
return state;
|
|
5715
5779
|
}
|
|
@@ -5804,8 +5868,11 @@ const handleResourceLinkClick = async (state, href) => {
|
|
|
5804
5868
|
};
|
|
5805
5869
|
|
|
5806
5870
|
const handleScroll = (state, scrollTop, scrollSource = Script) => {
|
|
5871
|
+
const {
|
|
5872
|
+
selectedTab
|
|
5873
|
+
} = state;
|
|
5807
5874
|
const newScrollTop = Math.max(0, scrollTop);
|
|
5808
|
-
if (
|
|
5875
|
+
if (selectedTab === Changelog) {
|
|
5809
5876
|
return {
|
|
5810
5877
|
...state,
|
|
5811
5878
|
changelogScrollTop: newScrollTop,
|
|
@@ -5957,7 +6024,7 @@ const getErrorMessage = async response => {
|
|
|
5957
6024
|
const getHttpError = async response => {
|
|
5958
6025
|
const apiMessage = await getErrorMessage(response);
|
|
5959
6026
|
const rateLimitRemaining = response.headers.get('x-ratelimit-remaining');
|
|
5960
|
-
if (response.status === 429 || response.status === 403 && (rateLimitRemaining === '0' ||
|
|
6027
|
+
if (response.status === 429 || response.status === 403 && (rateLimitRemaining === '0' || apiMessage.toLowerCase().includes('rate limit'))) {
|
|
5961
6028
|
const resetValue = Number(response.headers.get('x-ratelimit-reset'));
|
|
5962
6029
|
const retry = Number.isFinite(resetValue) && resetValue > 0 ? ` Try again after ${new Date(resetValue * 1000).toLocaleString()}.` : ' Please try again later.';
|
|
5963
6030
|
return new GithubReleasesError(`GitHub API rate limit exceeded.${retry}`);
|
|
@@ -6377,7 +6444,10 @@ const initialize = async applicationName => {
|
|
|
6377
6444
|
};
|
|
6378
6445
|
|
|
6379
6446
|
const loadContent2 = async (state, savedState, isTest = false) => {
|
|
6380
|
-
|
|
6447
|
+
const {
|
|
6448
|
+
platform
|
|
6449
|
+
} = state;
|
|
6450
|
+
return loadContent(state, platform, savedState, isTest);
|
|
6381
6451
|
};
|
|
6382
6452
|
|
|
6383
6453
|
const openImageInNewTab = async state => {
|
|
@@ -7210,7 +7280,10 @@ const renderEventListeners = () => {
|
|
|
7210
7280
|
};
|
|
7211
7281
|
|
|
7212
7282
|
const renderTitle = state => {
|
|
7213
|
-
|
|
7283
|
+
const {
|
|
7284
|
+
name
|
|
7285
|
+
} = state;
|
|
7286
|
+
return name;
|
|
7214
7287
|
};
|
|
7215
7288
|
|
|
7216
7289
|
const resize = (state, dimensions) => {
|