feat(plugin-detail): show Markdown plugin details on bundle and market entry pages
Plugins bundle pages and Discover entry pages show the plugin's long description first, as Markdown with images, in a height-limited region without its own heading. The document is the file locale meta.detail names, otherwise the package README, otherwise (market entries only) the declared repository's README. The new dsh-plugin-detail library selects documents and reads local package directories and npm file CDNs without state. plugin-manager reads installed and offered bundles through readBundleDetail; plugin-market reads market entries through readEntryDetail, single-file APIs, and a size-limited partial clone cache serialized across processes. Raw HTML is omitted, relative links stay text, and relative images load from Host routes with a sandbox CSP.
This commit is contained in:
1 parent
82a5ae1744
commit
9c8522bb64
111 files changed
+5057
-141
No files matched your search
@@ -6,11 +6,11 @@
|
||||
en: 962b4398c9052959
|
||||
zh: 14471c340a9f6e60
|
||||
/profile-management/management-records:
|
||||
en: 56c269c5f6dc107c
|
||||
zh: 535fe725b924b1e6
|
||||
en: 2def418f04e9fc10
|
||||
zh: af0bd1610bdc2f2b
|
||||
/profile-management/market-records:
|
||||
en: a28421bc6481b0ed
|
||||
zh: 73142d6163a20f50
|
||||
en: 3dfc62d837d61b9b
|
||||
zh: ec223be315f3dc62
|
||||
/profile-management/profile-reconciliation:
|
||||
en: 42a093314af774d4
|
||||
zh: 7c1784a3af02b31c
|
||||
@@ -14,6 +14,8 @@ The [boot package group](../../packages/boot/README.md) owns launcher-provided p
|
||||
|
||||
`InstallBundleOptions.saveExact` passes `--save-exact` to the shared package installer. `InstallBundleOptions.enabled` defaults to true. False installs without selecting the bundle layer. `approvedBuilds` grants persistent script permission to the supplied pending package names before installation. `registry` names the registry asked first; absent, the configured one.
|
||||
|
||||
`BundleDetail` is a profile bundle's long description: `{ status: 'found' }` with its `origin` (`locale` or `readme`), its `path` inside the package, and its `markdown`, or `{ status: 'none' }`; [`readBundleDetail`](../../packages/boot/plugin-manager/README.md#bundle-detail-documents) documents the order and the image route. `NpmFileSource` names a public npm file CDN, `jsdelivr`, `unpkg`, or `npmmirror`; a read's `npmFileSources` lists the ones to ask first.
|
||||
|
||||
`PluginRegistries` carries the configured first registry, `null` for the one pnpm's own configuration names, the fallbacks asked after it, and `resolved`, the URL pnpm's own configuration names or `null` while unread. `InspectOptions.registry` names the registry a lookup asks first.
|
||||
|
||||
`ChangeResult.changed` reports a disk edit independently of `application`: `applied`, `restart-required`, `overridden` or `failed`. Optional `error` carries a localizable code and external diagnostic. `packageResult` records the pnpm exit code, bounded output, truncation flag and complete diagnostic log path, plus `timedOut` when the manager terminated a run that stopped printing. A terminated run is classified `timeout` whatever exit status the signal left behind, so installation and removal report failure instead of success and no further registry is asked. `pendingBuilds` lists undecided packages across the profile; `approvedBuilds` records the names granted permission by this operation; `registries` lists the registries an installation asked, in order; `bundle` and `version` name the package a finished installation added and its manifest version; `failedAt` says whether the last failed run could not reach the registry it asked or the host a git or tarball spec is fetched from.
|
||||
@@ -26,6 +28,8 @@ The [boot package group](../../packages/boot/README.md) owns launcher-provided p
|
||||
|
||||
`MarketQuery` selects one page of an index: fuzzy `text`, a `category`, `labels` that must all be present, a `MarketSort`, `offset`, `limit` up to 100, `refresh` to fetch again instead of using a cached document, and `fetchedAt` to continue the pages of one document. `MarketSearchResult` carries the index URL, `title`, optional `description`, market `metadata`, the document's `fetchedAt`, the page's `entries`, the `total` number of matches, and the `nextOffset`. Each `MarketListingEntry` adds `defaultVersion`, the version installed by default, and `installation`, the profile's status for the package name; each of its `versions` adds `install`, the exact spec and optional first registry for `installBundle`, and `compatibility`, the evaluation of its `engines.dsh` including a version exemption.
|
||||
|
||||
`PluginDetail` is a market entry's long description: `{ status: 'found' }` with its `origin` (`locale`, `readme`, or `repository`), its `markdown`, and a `document` id whose images `GET /api/plugin-market/detail-file` serves, or `{ status: 'none' }`. The [plugin market documents the order](../../packages/boot/plugin-market/README.md#plugin-detail-documents) its sources are read in.
|
||||
|
||||
## Profile reconciliation
|
||||
|
||||
<a id="profile-reconciliation"></a>
|
||||
@@ -151,6 +155,20 @@ Source: [`packages/boot/hmr/src/index.ts`](../../packages/boot/hmr/src/index.ts)
|
||||
Manage profile files and apply their declared reload lifecycle.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Read a bundle's long description: the Markdown file its locale `meta.detail` names in `language`, otherwise its
|
||||
* README. An installed bundle is read from its directory without network access; an official bundle the installation
|
||||
* offers before it is installed is read from the npm file CDNs at its offered version. Nothing is cached.
|
||||
* @param name - the bundle's package name, as `listBundles()` lists it.
|
||||
* @param language - the display language, such as `zh-CN`; documents fall back through its prefixes to English.
|
||||
* @param options - `npmFileSources` names npm file CDNs to ask first for an offered bundle, in order, such as the one
|
||||
* a Client measured as fastest; configured CDNs it omits follow, and CDNs that are not configured are not asked.
|
||||
* @returns the document with its origin and path, or `none`.
|
||||
* @throws {RemoteError} `plugin-manager/unknown-bundle`, `plugin-manager/invalid-language`, or
|
||||
* `plugin-manager/detail-unavailable`.
|
||||
*/
|
||||
@Remote async readBundleDetail(name: string, language: string, options?: { npmFileSources?: NpmFileSource[] }): Promise<BundleDetail>
|
||||
|
||||
/** Read exact plugin-version exemptions saved in this profile.
|
||||
* @returns Accepted package-name@version keys with the runtime versions they may run on, and any
|
||||
* record or file problem the reader rejected, which the caller reports instead of failing.
|
||||
@@ -312,6 +330,25 @@ Fetches, validates, and caches configured market indexes; annotates entries with
|
||||
* or `plugin-market/invalid-index`.
|
||||
*/
|
||||
async entry(url: string, name: string): Promise<MarketListingEntry | undefined>
|
||||
|
||||
/**
|
||||
* Read the long description of one listed version of a plugin market entry, from the version's source: the npm file
|
||||
* CDNs for a public npm version, or its pinned Git commit. The Markdown file the package's locale `meta.detail` names
|
||||
* in `language` comes first, then the package's README, then the README of the entry's `repository`, or for an npm
|
||||
* version without one, of its `package.json` `repository`, at the default branch. An npm version from another
|
||||
* registry has no readable package files, so only the entry's `repository` is read.
|
||||
* @param url - a configured index URL.
|
||||
* @param name - the plugin's package name.
|
||||
* @param version - one listed version.
|
||||
* @param language - the display language, such as `zh-CN`; documents fall back through its prefixes to English.
|
||||
* @param options - `refresh` reads again instead of reusing a result cached for `cacheTtlMs`; `npmFileSources` names
|
||||
* npm file CDNs to ask first for an npm version, in order; configured CDNs it omits follow, and CDNs that are not
|
||||
* configured are not asked.
|
||||
* @returns the document with its origin and image document id, or `none`.
|
||||
* @throws {RemoteError} the failures of `search`, `plugin-market/unknown-plugin` for an unlisted plugin or version,
|
||||
* `plugin-market/invalid-query`, or `plugin-market/detail-unavailable`.
|
||||
*/
|
||||
@Remote async readEntryDetail( url: string, name: string, version: string, language: string, options?: { refresh?: boolean; npmFileSources?: NpmFileSource[] }, ): Promise<PluginDetail>
|
||||
```
|
||||
|
||||
Source: [`packages/boot/plugin-market/src/index.ts`](../../packages/boot/plugin-market/src/index.ts)
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
`InstallBundleOptions.saveExact` 向共享包安装器传入 `--save-exact`。`InstallBundleOptions.enabled` 默认为 true,false 表示安装但不选择组合包层。`approvedBuilds` 在安装前向指定的待审批包名授予持久脚本权限。`registry` 指定首先询问的注册表;缺省为配置的那个。
|
||||
|
||||
`BundleDetail` 是 profile 中组合包的详细介绍:`{ status: 'found' }` 携带其 `origin`(`locale` 或 `readme`)、在包内的 `path` 和 `markdown`;否则为 `{ status: 'none' }`。[`readBundleDetail`](../../packages/boot/plugin-manager/README.zh.md#bundle-detail-documents) 说明读取顺序和图片路由。`NpmFileSource` 指定一个公共 npm 文件 CDN:`jsdelivr`、`unpkg` 或 `npmmirror`;一次读取的 `npmFileSources` 列出先请求的 CDN。
|
||||
|
||||
`PluginRegistries` 携带配置的第一个注册表(`null` 即 pnpm 自身配置指定的那个)、随后依次询问的备选注册表,以及 `resolved`——pnpm 自身配置指向的 URL,未读到时为 `null`。`InspectOptions.registry` 指定一次查询首先询问的注册表。
|
||||
|
||||
`ChangeResult.changed` 报告磁盘修改,独立于 `application`:`applied`、`restart-required`、`overridden` 或 `failed`。可选的 `error` 包含可本地化的错误码和外部诊断。`packageResult` 记录 pnpm 退出码、有界输出、截断标志及完整诊断日志路径;当管理器终止了一个停止打印的运行,还记录 `timedOut`。被终止的运行不论信号留下什么退出状态都归类为 `timeout`,因此安装与删除都报告失败而非成功,也不会再询问下一个注册表。`pendingBuilds` 列出整个 profile 尚未决定的包;`approvedBuilds` 记录本次操作授予权限的包名;`registries` 按顺序列出一次安装问过的注册表;`bundle` 与 `version` 给出完成的安装新增的包及其清单版本;`failedAt` 说明最后一次失败的运行连不上的是所问的注册表,还是 git 或 tarball spec 自身拉取的主机。
|
||||
@@ -26,6 +28,8 @@
|
||||
|
||||
`MarketQuery` 选择索引的一页:模糊匹配的 `text`、一个 `category`、必须全部具备的 `labels`、一个 `MarketSort`、`offset`、不超过 100 的 `limit`、表示重新获取而不使用缓存文档的 `refresh`,以及用于继续读取同一文档后续页的 `fetchedAt`。`MarketSearchResult` 携带索引 URL、`title`、可选的 `description`、市场 `metadata`、该文档的 `fetchedAt`、本页的 `entries`、匹配总数 `total` 和 `nextOffset`。每个 `MarketListingEntry` 额外携带 `defaultVersion`,即默认安装的版本,以及 `installation`,即该包名在当前 profile 中的状态;其 `versions` 中的每个版本额外携带 `install`,即交给 `installBundle` 的精确 spec 和可选的首选 registry,以及 `compatibility`,即包含版本豁免在内的 `engines.dsh` 评估结果。
|
||||
|
||||
`PluginDetail` 是市场条目的详细介绍:`{ status: 'found' }` 携带其 `origin`(`locale`、`readme` 或 `repository`)、`markdown`,以及一个 `document` id,该文档中的图片由 `GET /api/plugin-market/detail-file` 提供;否则为 `{ status: 'none' }`。读取其来源的顺序见[插件市场的说明](../../packages/boot/plugin-market/README.zh.md#plugin-detail-documents)。
|
||||
|
||||
## Profile 重新组合
|
||||
|
||||
<a id="profile-reconciliation"></a>
|
||||
@@ -151,6 +155,20 @@ Source: [`packages/boot/hmr/src/index.ts`](../../packages/boot/hmr/src/index.ts)
|
||||
Manage profile files and apply their declared reload lifecycle.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Read a bundle's long description: the Markdown file its locale `meta.detail` names in `language`, otherwise its
|
||||
* README. An installed bundle is read from its directory without network access; an official bundle the installation
|
||||
* offers before it is installed is read from the npm file CDNs at its offered version. Nothing is cached.
|
||||
* @param name - the bundle's package name, as `listBundles()` lists it.
|
||||
* @param language - the display language, such as `zh-CN`; documents fall back through its prefixes to English.
|
||||
* @param options - `npmFileSources` names npm file CDNs to ask first for an offered bundle, in order, such as the one
|
||||
* a Client measured as fastest; configured CDNs it omits follow, and CDNs that are not configured are not asked.
|
||||
* @returns the document with its origin and path, or `none`.
|
||||
* @throws {RemoteError} `plugin-manager/unknown-bundle`, `plugin-manager/invalid-language`, or
|
||||
* `plugin-manager/detail-unavailable`.
|
||||
*/
|
||||
@Remote async readBundleDetail(name: string, language: string, options?: { npmFileSources?: NpmFileSource[] }): Promise<BundleDetail>
|
||||
|
||||
/** Read exact plugin-version exemptions saved in this profile.
|
||||
* @returns Accepted package-name@version keys with the runtime versions they may run on, and any
|
||||
* record or file problem the reader rejected, which the caller reports instead of failing.
|
||||
@@ -312,6 +330,25 @@ Fetches, validates, and caches configured market indexes; annotates entries with
|
||||
* or `plugin-market/invalid-index`.
|
||||
*/
|
||||
async entry(url: string, name: string): Promise<MarketListingEntry | undefined>
|
||||
|
||||
/**
|
||||
* Read the long description of one listed version of a plugin market entry, from the version's source: the npm file
|
||||
* CDNs for a public npm version, or its pinned Git commit. The Markdown file the package's locale `meta.detail` names
|
||||
* in `language` comes first, then the package's README, then the README of the entry's `repository`, or for an npm
|
||||
* version without one, of its `package.json` `repository`, at the default branch. An npm version from another
|
||||
* registry has no readable package files, so only the entry's `repository` is read.
|
||||
* @param url - a configured index URL.
|
||||
* @param name - the plugin's package name.
|
||||
* @param version - one listed version.
|
||||
* @param language - the display language, such as `zh-CN`; documents fall back through its prefixes to English.
|
||||
* @param options - `refresh` reads again instead of reusing a result cached for `cacheTtlMs`; `npmFileSources` names
|
||||
* npm file CDNs to ask first for an npm version, in order; configured CDNs it omits follow, and CDNs that are not
|
||||
* configured are not asked.
|
||||
* @returns the document with its origin and image document id, or `none`.
|
||||
* @throws {RemoteError} the failures of `search`, `plugin-market/unknown-plugin` for an unlisted plugin or version,
|
||||
* `plugin-market/invalid-query`, or `plugin-market/detail-unavailable`.
|
||||
*/
|
||||
@Remote async readEntryDetail( url: string, name: string, version: string, language: string, options?: { refresh?: boolean; npmFileSources?: NpmFileSource[] }, ): Promise<PluginDetail>
|
||||
```
|
||||
|
||||
Source: [`packages/boot/plugin-market/src/index.ts`](../../packages/boot/plugin-market/src/index.ts)
|
||||
|
||||
Reference in new issue
Block a user