diff --git a/package.json b/package.json index cc5b028c4..a45e8ec0b 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,14 @@ "dev": "astro dev", "format": "prettier -w --cache --plugin prettier-plugin-astro .", "format:check": "prettier -c --cache --plugin prettier-plugin-astro .", + "build:compatibility-table": "pnpm --filter compatibility-table run build", "build:references": "pnpm --filter js-api-generator run build", "build:releases": "pnpm --filter releases-generator run build", "build:config": "pnpm --filter config-generator run build", "build:cli": "pnpm --filter cli-generator run build", "build:astro": "astro build", "build:i18n": "pnpm --filter docs-i18n-tracker run build", - "build": "pnpm dev:setup && pnpm build:references && pnpm build:config && pnpm build:cli && pnpm build:releases && pnpm build:astro && pnpm build:i18n", + "build": "pnpm dev:setup && pnpm build:references && pnpm build:config && pnpm build:cli && pnpm build:releases && pnpm build:compatibility-table && pnpm build:astro && pnpm build:i18n", "preview": "astro preview" }, "dependencies": { diff --git a/packages/compatibility-table/build.ts b/packages/compatibility-table/build.ts new file mode 100644 index 000000000..e1256f6a3 --- /dev/null +++ b/packages/compatibility-table/build.ts @@ -0,0 +1,45 @@ +import { readdir, readFile } from 'fs/promises'; +import { writeFileSync } from 'node:fs'; +import TOML from '@iarna/toml'; +import path from 'path'; + +// todo: resolve dir +const baseDir = '../plugins-workspace'; +const pluginDir = '../plugins-workspace/plugins'; + +async function main() { + const plugins = await readdir(pluginDir); + + const workspaceCargo = TOML.parse(await readFile(path.join(baseDir, 'Cargo.toml'), 'utf-8')); + const baseRustVersion = workspaceCargo.workspace.package['rust-version']; + + const tables: Record = {}; + for (const plugin of plugins) { + // using Record but it's not reaaaally safe, might as well use any + const pluginPath = path.join(pluginDir, plugin, 'Cargo.toml'); + try { + const data = TOML.parse(await readFile(pluginPath, 'utf-8')); + const pkg = data.package as Record; + + const hasSpecificRustVersion = pkg['rust-version'] && !pkg['rust-version'].workspace; + const platformsSupport: Record = pkg.metadata.platforms.support; + + // todo: fix platforms case iOS, Windows... + const support = Object.entries(platformsSupport).map(([platform, supportInfo]) => ({ + platform, + ...supportInfo, + })); + + tables[plugin] = { + rustVersion: hasSpecificRustVersion ? pkg['rust-version'] : baseRustVersion, + support, + }; + } catch (error) { + continue; + } + } + + writeFileSync('../../src/components/plugins/_tableContent.json', JSON.stringify(tables, null, 2)); +} + +main(); diff --git a/packages/compatibility-table/package.json b/packages/compatibility-table/package.json new file mode 100644 index 000000000..ddf6e14ed --- /dev/null +++ b/packages/compatibility-table/package.json @@ -0,0 +1,20 @@ +{ + "name": "compatibility-table", + "version": "1.0.0", + "private": "true", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "build": "tsm ./build.ts" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "@iarna/toml": "^2.2.5", + "@types/node": "^20.11.20", + "tsm": "^2.3.0", + "typescript": "^5.3.3" + } +} diff --git a/packages/compatibility-table/tsconfig.json b/packages/compatibility-table/tsconfig.json new file mode 100644 index 000000000..b87e6dfb9 --- /dev/null +++ b/packages/compatibility-table/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e309e854e..7f1ed68d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -89,6 +89,21 @@ importers: specifier: ^5.3.3 version: 5.6.2 + packages/compatibility-table: + dependencies: + '@iarna/toml': + specifier: ^2.2.5 + version: 2.2.5 + '@types/node': + specifier: ^20.11.20 + version: 20.16.10 + tsm: + specifier: ^2.3.0 + version: 2.3.0 + typescript: + specifier: ^5.3.3 + version: 5.6.2 + packages/config-generator: dependencies: '@types/json-schema': @@ -970,6 +985,9 @@ packages: '@feelback/js@0.3.4': resolution: {integrity: sha512-xr7gTqSJcVUYQlELs1TntYovCBjMcYUr/hGKTnDoF64/lig5CbX4bOmqLoF50IImCy5q3oIwg9w+TSFvtBwsIA==} + '@iarna/toml@2.2.5': + resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + '@img/sharp-darwin-arm64@0.33.5': resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4799,6 +4817,8 @@ snapshots: '@feelback/js@0.3.4': {} + '@iarna/toml@2.2.5': {} + '@img/sharp-darwin-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.0.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9310e0c71..6f8ca192c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,3 +5,4 @@ packages: - 'packages/cli-generator' - 'packages/tauri-typedoc-theme' - 'packages/releases-generator' + - 'packages/compatibility-table' diff --git a/public/assets/platforms.svg b/public/assets/platforms.svg new file mode 100644 index 000000000..27fbc60af --- /dev/null +++ b/public/assets/platforms.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/components/list/Directory.astro b/src/components/list/Directory.astro index 98c96a3f0..e250d9d53 100644 --- a/src/components/list/Directory.astro +++ b/src/components/list/Directory.astro @@ -4,9 +4,12 @@ import { stripLeadingAndTrailingSlashes, ensureTrailingSlash, } from 'node_modules/@astrojs/starlight/utils/path'; -import { LinkCard, CardGrid } from '@astrojs/starlight/components'; +import { CardGrid } from '@astrojs/starlight/components'; import { routes, type Route } from 'node_modules/@astrojs/starlight/utils/routing'; +// custom component copied from starlight/components/LinkCard +import CustomLinkCard from '@components/plugins/CustomLinkCard.astro'; + interface Props { /** * Slug relative to /src - e.g "/zh-cn/features" @@ -28,6 +31,11 @@ interface Props { * Use this to ignore sidebar order */ sortAlphabetically?: boolean; + + /* + * specifically to support compatibility footer in CustomLink card + */ + callback?: Function; } function hasSidebarOrder(page: Route): number | undefined { @@ -43,7 +51,12 @@ function compareOrder(a: Route, b: Route): boolean { } let { slug } = Astro.props; -const { filterOutByTitle = [], filterOutByFileName = [], sortAlphabetically = false } = Astro.props; +const { + filterOutByTitle = [], + filterOutByFileName = [], + sortAlphabetically = false, + callback, +} = Astro.props; const defaultLocale = config.defaultLocale.lang || 'en'; const localesList = config.isMultilingual ? Object.keys(config.locales) : [defaultLocale]; @@ -137,22 +150,26 @@ if (!sortAlphabetically) { { - mainList.map((item) => ( - - )) + mainList.map((item) => { + return ( + + ); + }) } { locale !== defaultLocale && fallbackList.map((item) => ( - )) } diff --git a/src/components/list/Features.astro b/src/components/list/Features.astro index a3d148f89..7cfa56010 100644 --- a/src/components/list/Features.astro +++ b/src/components/list/Features.astro @@ -1,5 +1,36 @@ --- import Directory from './Directory.astro'; + +import { type PluginData, getPlatformSupportIcon } from 'src/components/plugins/_helpers'; +import data from 'src/components/plugins/_tableContent.json'; + +const fallBackNames: Record = { + clipboard: 'clipboard-manager', + 'deep-linking': 'deep-link', + dialog: 'dialog', + 'file-system': 'fs', + 'http-client': 'http', + localhost: 'localhost', + logging: 'log', + nfc: 'nfc', + 'os-info': 'os', +}; + +function fetchData(pluginSlug: string) { + // assuming slug is "locale?/plugin/{pluginName}" + const plugin = pluginSlug.split('plugin/')[1]; + let pluginData: PluginData = data[plugin]; + if (!pluginData) { + pluginData = data[fallBackNames[plugin]]; + if (!pluginData) { + console.log( + `[Plugin Support] '${plugin}' data is missing or it's name doesn't match any existing plugin` + ); + return ''; + } + } + return pluginData.support.map((plat) => getPlatformSupportIcon(plat.level, plat.platform)); +} --- - + diff --git a/src/components/plugins/.gitignore b/src/components/plugins/.gitignore new file mode 100644 index 000000000..426c373b8 --- /dev/null +++ b/src/components/plugins/.gitignore @@ -0,0 +1 @@ +_tableContent.json \ No newline at end of file diff --git a/src/components/plugins/Compatibility.astro b/src/components/plugins/Compatibility.astro new file mode 100644 index 000000000..33087c076 --- /dev/null +++ b/src/components/plugins/Compatibility.astro @@ -0,0 +1,66 @@ +--- +import { type PluginData, getSupportIcon, getSupportText } from './_helpers'; +import data from './_tableContent.json'; +import { createMarkdownProcessor } from '@astrojs/markdown-remark'; + +const { plugin } = Astro.props; + +interface Props { + plugin: string; +} +const md = await createMarkdownProcessor(); + +const pluginData: PluginData = data[plugin]; + +const versionText = await md.render( + `_This plugin requires a Rust version of at least **${pluginData.rustVersion}**_` +); +--- + +
+ + + + + + + + + + + { + pluginData.support.map(async (t) => { + const { platform, notes, level } = t; + const parsedNotes = await md.render(notes || ''); + const icon = getSupportIcon(level); + const title = getSupportText(level); + return ( + + + + + + ); + }) + } + +
PlatformLevelNotes
{platform} +
+
+
+
+ + diff --git a/src/components/plugins/CustomLinkCard.astro b/src/components/plugins/CustomLinkCard.astro new file mode 100644 index 000000000..4eee9abae --- /dev/null +++ b/src/components/plugins/CustomLinkCard.astro @@ -0,0 +1,91 @@ +--- +// copied from LinkCard.Astro +// removed icon +// added a footer field to place the supported platform icons + +import type { HTMLAttributes } from 'astro/types'; + +interface Props extends Omit, 'title'> { + title: string; + description?: string; + footer?: string; +} + +const { title, description, footer, ...attributes } = Astro.props; +--- + +