@lvce-editor/extension-detail-view 7.9.0 → 7.11.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.
@@ -20,6 +20,7 @@ const Copy = 'Copy';
20
20
  const CopyImage = 'Copy Image';
21
21
  const CopyImageUrl = 'Copy Image Url';
22
22
  const CopyLink = 'Copy Link';
23
+ const Created = 'Created';
23
24
  const Details$1 = 'Details';
24
25
  const Disable$1 = 'Disable';
25
26
  const Elements = 'Elements';
@@ -214,6 +215,9 @@ const identifier = () => {
214
215
  const version = () => {
215
216
  return i18nString(Version);
216
217
  };
218
+ const created = () => {
219
+ return i18nString(Created);
220
+ };
217
221
  const lastUpdated = () => {
218
222
  return i18nString(LastUpdated);
219
223
  };
@@ -2492,6 +2496,9 @@ const enable2 = (id, platform) => {
2492
2496
  const disable2 = (id, platform) => {
2493
2497
  return invoke$4(`Extensions.disable2`, id, platform);
2494
2498
  };
2499
+ const getLanguages = (platform, assetDir) => {
2500
+ return invoke$4('Extensions.getLanguages', platform, assetDir);
2501
+ };
2495
2502
 
2496
2503
  const {
2497
2504
  invoke: invoke$3,
@@ -3417,6 +3424,7 @@ const create = (uid, uri, x, y, width, height, platform, assetDir) => {
3417
3424
  changelogVirtualDom: [],
3418
3425
  commands: [],
3419
3426
  commit: '',
3427
+ created: null,
3420
3428
  currentColorThemeId: '',
3421
3429
  description: '',
3422
3430
  detailsVirtualDom: [],
@@ -3439,6 +3447,7 @@ const create = (uid, uri, x, y, width, height, platform, assetDir) => {
3439
3447
  initial: true,
3440
3448
  installationEntries: [],
3441
3449
  jsonValidation: [],
3450
+ languages: [],
3442
3451
  lastUpdated: null,
3443
3452
  linkProtectionEnabled: false,
3444
3453
  locationHost: '',
@@ -4029,6 +4038,13 @@ const getExtensionIdFromUri = uri => {
4029
4038
  return id;
4030
4039
  };
4031
4040
 
4041
+ const getExtensionUri = (uri, platform, origin) => {
4042
+ if (platform !== Web || !uri) {
4043
+ return uri;
4044
+ }
4045
+ return new URL(uri, origin).href;
4046
+ };
4047
+
4032
4048
  const getLinkProtectionEnabled = async () => {
4033
4049
  try {
4034
4050
  const setting = await getPreference('application.linkProtectionEnabled');
@@ -4070,6 +4086,42 @@ const getSideBarWidth = width => {
4070
4086
  return Math.max(175 + Math.round(20 * (width / 100)), Math.round(width / 4));
4071
4087
  };
4072
4088
 
4089
+ const getStringArray = value => {
4090
+ if (!Array.isArray(value)) {
4091
+ return undefined;
4092
+ }
4093
+ return value.filter(item => typeof item === 'string');
4094
+ };
4095
+ const toSyntaxLanguage = value => {
4096
+ if (!value || typeof value !== 'object') {
4097
+ return undefined;
4098
+ }
4099
+ const language = value;
4100
+ if (typeof language.id !== 'string' || typeof language.tokenize !== 'string') {
4101
+ return undefined;
4102
+ }
4103
+ return {
4104
+ aliases: getStringArray(language.aliases),
4105
+ extensions: getStringArray(language.extensions),
4106
+ id: language.id,
4107
+ tokenize: language.tokenize
4108
+ };
4109
+ };
4110
+ const getSyntaxLanguages = async (platform, assetDir) => {
4111
+ try {
4112
+ const languages = await getLanguages(platform, assetDir);
4113
+ if (!Array.isArray(languages)) {
4114
+ return [];
4115
+ }
4116
+ return languages.flatMap(language => {
4117
+ const syntaxLanguage = toSyntaxLanguage(language);
4118
+ return syntaxLanguage ? [syntaxLanguage] : [];
4119
+ });
4120
+ } catch {
4121
+ return [];
4122
+ }
4123
+ };
4124
+
4073
4125
  const getTabs = (selectedTab, hasReadme, hasFeatures, hasChangelog) => {
4074
4126
  const tabs = [{
4075
4127
  enabled: hasReadme,
@@ -4141,6 +4193,9 @@ const getIcon = (extension, platform, assetDir) => {
4141
4193
  }
4142
4194
  return `/remote/${extension.path}/${extension.icon}`; // TODO support windows paths
4143
4195
  }
4196
+ if (platform === Web) {
4197
+ return `${extension.path}/${extension.icon}`;
4198
+ }
4144
4199
  return '';
4145
4200
  };
4146
4201
 
@@ -4419,6 +4474,39 @@ const getFolderSize = async uri => {
4419
4474
  }
4420
4475
  };
4421
4476
 
4477
+ const minute = 60 * 1000;
4478
+ const hour = 60 * minute;
4479
+ const day = 24 * hour;
4480
+ const month = 30 * day;
4481
+ const year = 365 * day;
4482
+ const relativeTimeFormat = new Intl.RelativeTimeFormat(undefined, {
4483
+ numeric: 'always'
4484
+ });
4485
+ const getRelativeValue = diff => {
4486
+ const absoluteDiff = Math.abs(diff);
4487
+ if (absoluteDiff >= year) {
4488
+ return [Math.trunc(diff / year), 'year'];
4489
+ }
4490
+ if (absoluteDiff >= month) {
4491
+ return [Math.trunc(diff / month), 'month'];
4492
+ }
4493
+ if (absoluteDiff >= day) {
4494
+ return [Math.trunc(diff / day), 'day'];
4495
+ }
4496
+ if (absoluteDiff >= hour) {
4497
+ return [Math.trunc(diff / hour), 'hour'];
4498
+ }
4499
+ return [Math.trunc(diff / minute), 'minute'];
4500
+ };
4501
+ const formatCreated = (created, now = Date.now()) => {
4502
+ if (created === null || !Number.isFinite(created)) {
4503
+ return 'n/a';
4504
+ }
4505
+ const diff = created - now;
4506
+ const [value, unit] = getRelativeValue(diff);
4507
+ return relativeTimeFormat.format(value, unit);
4508
+ };
4509
+
4422
4510
  const formatLastUpdated = lastUpdated => {
4423
4511
  if (lastUpdated === null) {
4424
4512
  return 'n/a';
@@ -4450,22 +4538,38 @@ const getSizeEntries = (showSizeLink, displaySize, extensionUri) => {
4450
4538
  }];
4451
4539
  };
4452
4540
 
4453
- const getInstallationEntries = (displaySize, extensionId, extensionVersion, extensionUri, showSizeLink, lastUpdated$1) => {
4541
+ const addOddEntries = entries => {
4542
+ return entries.map((entry, index) => {
4543
+ if (index % 2 === 0) {
4544
+ return {
4545
+ ...entry,
4546
+ odd: true
4547
+ };
4548
+ }
4549
+ return entry;
4550
+ });
4551
+ };
4552
+ const getInstallationEntries = (displaySize, extensionId, extensionVersion, extensionUri, showSizeLink, created$1, lastUpdated$1) => {
4454
4553
  const entries = [{
4455
4554
  code: true,
4456
4555
  key: identifier(),
4457
- odd: true,
4458
4556
  value: extensionId
4459
4557
  }, {
4460
4558
  code: true,
4461
4559
  key: version(),
4462
4560
  value: extensionVersion
4463
- }, {
4561
+ }];
4562
+ if (created$1 !== null) {
4563
+ entries.push({
4564
+ key: created(),
4565
+ value: formatCreated(created$1)
4566
+ });
4567
+ }
4568
+ entries.push({
4464
4569
  key: lastUpdated(),
4465
- odd: true,
4466
4570
  value: formatLastUpdated(lastUpdated$1)
4467
- }, ...getSizeEntries(showSizeLink, displaySize, extensionUri)];
4468
- return entries;
4571
+ }, ...getSizeEntries(showSizeLink, displaySize, extensionUri));
4572
+ return addOddEntries(entries);
4469
4573
  };
4470
4574
 
4471
4575
  const getMarketplaceEntries = isBuiltin => {
@@ -4566,10 +4670,10 @@ const getResources = (isBuiltin, extension) => {
4566
4670
  return rawResources.filter(resource => resource.enabled);
4567
4671
  };
4568
4672
 
4569
- const loadSideBarContent = async (extensionId, extensionVersion, extensionUri, isBuiltin, extension, showSizeLink, lastUpdated) => {
4673
+ const loadSideBarContent = async (extensionId, extensionVersion, extensionUri, isBuiltin, extension, showSizeLink, created, lastUpdated) => {
4570
4674
  const folderSize = await getFolderSize(extensionUri);
4571
4675
  const displaySize = getDisplaySize(folderSize);
4572
- const installationEntries = getInstallationEntries(displaySize, extensionId, extensionVersion, extensionUri, showSizeLink, lastUpdated);
4676
+ const installationEntries = getInstallationEntries(displaySize, extensionId, extensionVersion, extensionUri, showSizeLink, created, lastUpdated);
4573
4677
  const marketplaceEntries = getMarketplaceEntries(isBuiltin);
4574
4678
  const categories = getCategories(extension);
4575
4679
  const resources = getResources(isBuiltin, extension);
@@ -4583,6 +4687,23 @@ const loadSideBarContent = async (extensionId, extensionVersion, extensionUri, i
4583
4687
  };
4584
4688
  };
4585
4689
 
4690
+ const parseCreated = extension => {
4691
+ if (!extension || typeof extension !== 'object') {
4692
+ return null;
4693
+ }
4694
+ const {
4695
+ created
4696
+ } = extension;
4697
+ if (typeof created !== 'string' || created === '') {
4698
+ return null;
4699
+ }
4700
+ const timestamp = Date.parse(created);
4701
+ if (!Number.isFinite(timestamp)) {
4702
+ return null;
4703
+ }
4704
+ return timestamp;
4705
+ };
4706
+
4586
4707
  const parseLastUpdated = extension => {
4587
4708
  if (!extension || typeof extension !== 'object') {
4588
4709
  return null;
@@ -4671,19 +4792,21 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4671
4792
  }
4672
4793
  const currentColorThemeId = await getCurrentColorTheme();
4673
4794
  const commit = await getCommit();
4795
+ const languages = await getSyntaxLanguages(platform, state.assetDir);
4674
4796
  const headerData = loadHeaderContent(state, platform, extension);
4675
4797
  const {
4676
4798
  badge,
4677
4799
  description,
4678
4800
  downloadCount,
4679
4801
  extensionId,
4680
- extensionUri,
4802
+ extensionUri: unresolvedExtensionUri,
4681
4803
  extensionVersion,
4682
4804
  hasColorTheme,
4683
4805
  iconSrc,
4684
4806
  name,
4685
4807
  rating
4686
4808
  } = headerData;
4809
+ const extensionUri = getExtensionUri(unresolvedExtensionUri, platform, location.origin);
4687
4810
  const readmeUrl = join(extensionUri, 'README.md');
4688
4811
  const changelogUrl = join(extensionUri, 'CHANGELOG.md');
4689
4812
  const [hasReadme, hasChangelog] = await Promise.all([existsFile(readmeUrl), existsFile(changelogUrl)]);
@@ -4695,13 +4818,14 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4695
4818
  const readmeHtml = await renderMarkdown(readmeContent, {
4696
4819
  baseUrl,
4697
4820
  commit,
4821
+ languages,
4698
4822
  linksExternal: true,
4699
4823
  locationProtocol
4700
4824
  });
4701
4825
  const detailsVirtualDom = await getMarkdownVirtualDom(readmeHtml, {
4702
4826
  scrollToTopEnabled: true
4703
4827
  });
4704
- const isBuiltin = extension?.isBuiltin;
4828
+ const isBuiltin = extension?.isBuiltin || extension?.builtin || false;
4705
4829
  const disabled = extension?.disabled;
4706
4830
  const extensionColorThemeId = getColorThemeId(extension) || '';
4707
4831
  const extensionColorThemeLabel = getColorThemeLabel(extension) || '';
@@ -4719,6 +4843,7 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4719
4843
  const enabledTabs = tabs.filter(isEnabled);
4720
4844
  const sizeValue = getViewletSize(width || 0);
4721
4845
  const showSizeLink = platform !== Web$1;
4846
+ const created = parseCreated(extension);
4722
4847
  const lastUpdated = parseLastUpdated(extension);
4723
4848
  const {
4724
4849
  categories,
@@ -4727,7 +4852,7 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4727
4852
  installationEntries,
4728
4853
  marketplaceEntries,
4729
4854
  resources
4730
- } = await loadSideBarContent(extensionId, extensionVersion, extensionUri, isBuiltin, extension, showSizeLink, lastUpdated);
4855
+ } = await loadSideBarContent(extensionId, extensionVersion, extensionUri, isBuiltin, extension, showSizeLink, created, lastUpdated);
4731
4856
  const padding = getPadding(width);
4732
4857
  const sideBarWidth = getSideBarWidth(width);
4733
4858
  const showSideBar = sideBarWidth > 0;
@@ -4740,6 +4865,7 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4740
4865
  categories,
4741
4866
  changelogScrollTop,
4742
4867
  commit,
4868
+ created,
4743
4869
  currentColorThemeId,
4744
4870
  description,
4745
4871
  detailsVirtualDom,
@@ -4757,6 +4883,7 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4757
4883
  iconSrc,
4758
4884
  initial: false,
4759
4885
  installationEntries,
4886
+ languages,
4760
4887
  lastUpdated,
4761
4888
  linkProtectionEnabled,
4762
4889
  locationHost,
@@ -4979,13 +5106,15 @@ const loadChangelogContent = async path => {
4979
5106
  const selectTabChangelog = async state => {
4980
5107
  const {
4981
5108
  baseUrl,
4982
- extension,
5109
+ extensionUri,
5110
+ languages,
4983
5111
  locationProtocol,
4984
5112
  tabs
4985
5113
  } = state;
4986
- const changelogContent = await loadChangelogContent(extension.path); // TODO use uri
5114
+ const changelogContent = await loadChangelogContent(extensionUri);
4987
5115
  const changelogMarkdownHtml = await renderMarkdown(changelogContent, {
4988
5116
  baseUrl,
5117
+ languages,
4989
5118
  locationProtocol
4990
5119
  });
4991
5120
  const changelogDom = await getMarkdownVirtualDom(changelogMarkdownHtml);
@@ -5010,6 +5139,7 @@ const selectTabDefault = async state => {
5010
5139
  const selectTabDetails = async state => {
5011
5140
  const {
5012
5141
  baseUrl,
5142
+ languages,
5013
5143
  locationProtocol,
5014
5144
  readmeUrl,
5015
5145
  tabs
@@ -5017,6 +5147,7 @@ const selectTabDetails = async state => {
5017
5147
  const readmeContent = await loadReadmeContent(readmeUrl);
5018
5148
  const readmeHtml = await renderMarkdown(readmeContent, {
5019
5149
  baseUrl,
5150
+ languages,
5020
5151
  linksExternal: true,
5021
5152
  locationProtocol
5022
5153
  });
@@ -5102,6 +5233,7 @@ const handleTabsClick = (state, name) => {
5102
5233
 
5103
5234
  const hideSizeLink = state => {
5104
5235
  const {
5236
+ created,
5105
5237
  displaySize,
5106
5238
  extensionId,
5107
5239
  extensionUri,
@@ -5109,7 +5241,7 @@ const hideSizeLink = state => {
5109
5241
  lastUpdated
5110
5242
  } = state;
5111
5243
  const newShowSizeLink = false;
5112
- const installationEntries = getInstallationEntries(displaySize, extensionId, extensionVersion, extensionUri, newShowSizeLink, lastUpdated);
5244
+ const installationEntries = getInstallationEntries(displaySize, extensionId, extensionVersion, extensionUri, newShowSizeLink, created, lastUpdated);
5113
5245
  return {
5114
5246
  ...state,
5115
5247
  installationEntries,
@@ -5338,7 +5470,7 @@ const getExtraProps = (title, onClick) => {
5338
5470
  props.title = title;
5339
5471
  }
5340
5472
  if (onClick) {
5341
- props.style = 'cursor: pointer';
5473
+ props.style = 'color: var(--vscode-textLink-foreground, #3794ff); cursor: pointer; text-decoration: none';
5342
5474
  props.tabIndex = 0;
5343
5475
  }
5344
5476
  return props;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-detail-view",
3
- "version": "7.9.0",
3
+ "version": "7.11.0",
4
4
  "description": "Extension Detail View Worker",
5
5
  "repository": {
6
6
  "type": "git",