@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
- return /\s/.test(value);
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
- return trimmed === '' || /^\.*$/.test(trimmed);
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
- if (!/^[./]?[A-Za-z0-9._\-/]+$/.test(value)) {
1236
- return false;
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 !!/[A-Za-z0-9]/.test(value);
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
- await writeText(state.extensionId);
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
- if (state.selectedTab === Changelog) {
4486
- if (state.changelogScrollTop === 0) {
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
- extension
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(state.hasColorTheme, isBuiltin, state.disabled, colorThemeId, colorThemeLabel, colorThemeId);
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
- } = state.extension;
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
- } = state.extension;
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).replace(/^git\+/, '');
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].replace(/\.git$/i, '');
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: getStringArray(language.aliases),
4772
- extensions: getStringArray(language.extensions),
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.replace(/\/+$/, '');
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, state.assetDir);
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(state.uri);
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 detailsVirtualDom = replaceMarkdownImageWithError(state.detailsVirtualDom, failedSrc);
5693
- const changelogVirtualDom = replaceMarkdownImageWithError(state.changelogVirtualDom, failedSrc);
5694
- if (detailsVirtualDom === state.detailsVirtualDom && changelogVirtualDom === state.changelogVirtualDom) {
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 colorThemeId = getColorThemeId(state.extension);
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 (state.selectedTab === Changelog) {
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' || /rate limit/i.test(apiMessage))) {
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
- return loadContent(state, state.platform, savedState, isTest);
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
- return state.name;
7283
+ const {
7284
+ name
7285
+ } = state;
7286
+ return name;
7214
7287
  };
7215
7288
 
7216
7289
  const resize = (state, dimensions) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-detail-view",
3
- "version": "7.20.0",
3
+ "version": "7.21.0",
4
4
  "description": "Extension Detail View Worker",
5
5
  "repository": {
6
6
  "type": "git",