From afc2939089fd908871c2cc87bb0279687f6b6737 Mon Sep 17 00:00:00 2001 From: Qingyu Wang <40660121+colinaaa@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:38:15 +0800 Subject: [PATCH] feat: introduce upgrade-rspeedy (#145) ## Summary Add a simple CLI program for upgrading Rspeedy-related packages. ```bash npx upgrade-rspeedy@latest ``` ## Checklist - [x] **Tests updated** (or not required). - [x] Documentation updated (or not required). See: https://github.com/lynx-family/lynx-website/pull/30 --- .changeset/config.json | 3 +- .changeset/dull-olives-move.md | 2 + .github/workflows/test.yml | 1 + packages/rspeedy/upgrade-rspeedy/README.md | 55 ++++ .../rspeedy/upgrade-rspeedy/__mocks__/fs.cjs | 7 + packages/rspeedy/upgrade-rspeedy/package.json | 55 ++++ .../rspeedy/upgrade-rspeedy/rslib.config.ts | 12 + .../rspeedy/upgrade-rspeedy/src/install.ts | 147 +++++++++++ packages/rspeedy/upgrade-rspeedy/src/main.ts | 34 +++ .../upgrade-rspeedy/src/upgrade-rspeedy.ts | 8 + .../rspeedy/upgrade-rspeedy/src/version.ts | 21 ++ .../upgrade-rspeedy/test/install.test.ts | 237 ++++++++++++++++++ .../rspeedy/upgrade-rspeedy/test/main.test.ts | 36 +++ .../rspeedy/upgrade-rspeedy/tsconfig.json | 15 ++ packages/rspeedy/upgrade-rspeedy/turbo.json | 17 ++ .../rspeedy/upgrade-rspeedy/vitest.config.ts | 12 + pnpm-lock.yaml | 71 ++++++ 17 files changed, 732 insertions(+), 1 deletion(-) create mode 100644 .changeset/dull-olives-move.md create mode 100644 packages/rspeedy/upgrade-rspeedy/README.md create mode 100644 packages/rspeedy/upgrade-rspeedy/__mocks__/fs.cjs create mode 100644 packages/rspeedy/upgrade-rspeedy/package.json create mode 100644 packages/rspeedy/upgrade-rspeedy/rslib.config.ts create mode 100644 packages/rspeedy/upgrade-rspeedy/src/install.ts create mode 100644 packages/rspeedy/upgrade-rspeedy/src/main.ts create mode 100644 packages/rspeedy/upgrade-rspeedy/src/upgrade-rspeedy.ts create mode 100644 packages/rspeedy/upgrade-rspeedy/src/version.ts create mode 100644 packages/rspeedy/upgrade-rspeedy/test/install.test.ts create mode 100644 packages/rspeedy/upgrade-rspeedy/test/main.test.ts create mode 100644 packages/rspeedy/upgrade-rspeedy/tsconfig.json create mode 100644 packages/rspeedy/upgrade-rspeedy/turbo.json create mode 100644 packages/rspeedy/upgrade-rspeedy/vitest.config.ts diff --git a/.changeset/config.json b/.changeset/config.json index 5e0d2c89..930c3a01 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -21,7 +21,8 @@ ], [ "@lynx-js/rspeedy", - "create-rspeedy" + "create-rspeedy", + "upgrade-rspeedy" ] ], "linked": [], diff --git a/.changeset/dull-olives-move.md b/.changeset/dull-olives-move.md new file mode 100644 index 00000000..a845151c --- /dev/null +++ b/.changeset/dull-olives-move.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aafea555..d236997e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,6 +32,7 @@ jobs: sudo apt-get install -y iproute2 && pnpm run test --project rspeedy + --project upgrade-rspeedy --project 'rspeedy/*' --test-timeout=50000 --coverage diff --git a/packages/rspeedy/upgrade-rspeedy/README.md b/packages/rspeedy/upgrade-rspeedy/README.md new file mode 100644 index 00000000..3692a327 --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/README.md @@ -0,0 +1,55 @@ +

+ Rspeedy Logo +

+ +# Upgrade Rspeedy + +

+ + + + + license + +

+ +The easiest way to upgrade Rspeedy-related packages. + +This CLI tool helps to update the `package.json` with corresponding version. Both `latest` and `canary` are supported. + +## Latest version + +To update to the latest `@lynx-js/rspeedy` and its plugins, use the following command in your `@lynx-js/rspeedy` project: + +```bash +npx upgrade-rspeedy@latest +``` + +Then all the Rspeedy-related packages' version would be updated. Run your package manager to install the dependencies: + +```bash +npm install +# Or +yarn install +# Or +pnpm install +``` + +## Canary version + +To update to one of the canary version of `@lynx-js/rspeedy`, use the following command: + +```bash +# Replace the version with your canary version +npx upgrade-rspeedy-canary@0.8.2-canary-20250309-870106fc +``` + +Then all the Rspeedy-related packages' version would be updated with `npm:` alias. Run your package manager to install the dependencies: + +```bash +npm install +# Or +yarn install +# Or +pnpm install +``` diff --git a/packages/rspeedy/upgrade-rspeedy/__mocks__/fs.cjs b/packages/rspeedy/upgrade-rspeedy/__mocks__/fs.cjs new file mode 100644 index 00000000..07097f75 --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/__mocks__/fs.cjs @@ -0,0 +1,7 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. + +const { fs } = require('memfs') + +module.exports = fs diff --git a/packages/rspeedy/upgrade-rspeedy/package.json b/packages/rspeedy/upgrade-rspeedy/package.json new file mode 100644 index 00000000..04da642b --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/package.json @@ -0,0 +1,55 @@ +{ + "name": "upgrade-rspeedy", + "version": "0.8.3", + "description": "Upgrade Rspeedy-related packages", + "keywords": [ + "webpack", + "Rspack", + "Rsbuild", + "Rspeedy", + "Lynx" + ], + "repository": { + "type": "git", + "url": "https://github.com/lynx-family/lynx-stack.git", + "directory": "packages/rspeedy/upgrade-rspeedy" + }, + "license": "Apache-2.0", + "author": { + "name": "Qingyu Wang", + "email": "colinwang.0616@gmail.com" + }, + "type": "module", + "exports": null, + "bin": { + "upgrade-rspeedy": "./dist/upgrade-rspeedy.js" + }, + "files": [ + "dist/upgrade-rspeedy.js", + "CHANGELOG.md", + "README.md" + ], + "scripts": { + "build": "rslib build", + "test": "vitest" + }, + "devDependencies": { + "@lynx-js/qrcode-rsbuild-plugin": "workspace:*", + "@lynx-js/react": "workspace:*", + "@lynx-js/react-rsbuild-plugin": "workspace:*", + "@lynx-js/rspeedy": "workspace:*", + "@lynx-js/types": "^3.2.0", + "@rsbuild/plugin-less": "1.1.1", + "@rsbuild/plugin-sass": "1.2.2", + "commander": "^13.1.0", + "detect-indent": "^7.0.1", + "memfs": "^4.17.0", + "picocolors": "^1.1.1", + "rsbuild-plugin-tailwindcss": "0.2.0", + "rslog": "^1.2.3", + "type-fest": "^4.37.0" + }, + "engines": { + "node": ">=18" + } +} diff --git a/packages/rspeedy/upgrade-rspeedy/rslib.config.ts b/packages/rspeedy/upgrade-rspeedy/rslib.config.ts new file mode 100644 index 00000000..eeb7367a --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/rslib.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from '@rslib/core' + +export default defineConfig({ + lib: [ + { format: 'esm', syntax: 'es2022' }, + ], + source: { + entry: { + 'upgrade-rspeedy': './src/upgrade-rspeedy.ts', + }, + }, +}) diff --git a/packages/rspeedy/upgrade-rspeedy/src/install.ts b/packages/rspeedy/upgrade-rspeedy/src/install.ts new file mode 100644 index 00000000..e5675356 --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/src/install.ts @@ -0,0 +1,147 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import fs from 'node:fs' +import { EOL } from 'node:os' +import path from 'node:path' + +import detectIndent from 'detect-indent' +import color from 'picocolors' +import { logger } from 'rslog' +import type { PackageJson } from 'type-fest' + +import { devDependencies } from './version.js' + +const LYNX_RSPEEDY = '@lynx-js/rspeedy' + +export async function install(cwd: string): Promise { + const packageJSONPath = path.resolve(cwd, 'package.json') + + if (!fs.existsSync(packageJSONPath)) { + const message = `${ + color.underline(color.yellow(packageJSONPath)) + } not found. Please run ${ + color.bold('upgrade-rspeedy') + } in your Rspeedy project.` + logger.error(message) + + throw new Error(message) + } + + try { + const content = await fs.promises.readFile(packageJSONPath, 'utf-8') + const pkg = JSON.parse(content) as PackageJson + + if ( + pkg.dependencies?.[LYNX_RSPEEDY] === undefined + && pkg.devDependencies?.[LYNX_RSPEEDY] === undefined + ) { + throw new Error( + `No ${color.yellow(LYNX_RSPEEDY)} found in ${packageJSONPath}. + +Please run ${color.bold('upgrade-rspeedy')} in your Rspeedy project.`, + ) + } + + const { indent } = detectIndent(content) + + console.info() + const dependenciesUpdated = updateDependencies( + pkg, + packageJSONPath, + 'dependencies', + ) + console.info() + const devDependenciesUpdated = updateDependencies( + pkg, + packageJSONPath, + 'devDependencies', + ) + console.info() + + if (dependenciesUpdated || devDependenciesUpdated) { + await fs.promises.writeFile( + packageJSONPath, + JSON.stringify(pkg, null, indent) + EOL, + 'utf-8', + ) + logger.success(`${color.yellow(packageJSONPath)} has been updated.`) + logger.success( + `Please install the dependencies with your package manager.`, + ) + } + } catch (error) { + logger.error(error) + throw error + } +} + +function updateDependencies( + pkg: PackageJson, + packageJSONPath: string, + name: 'dependencies' | 'devDependencies', +) { + const dependencies = pkg[name] + if (!dependencies) { + logger.info( + `No ${color.yellow(name)} is found in ${ + color.underline(packageJSONPath) + }`, + ) + return false + } + + const updatedDependencies = findDependencies(dependencies) + .filter(([, { original, target }]) => original !== target) + + if (updatedDependencies.length === 0) { + logger.info( + `No ${color.yellow(name)} need to be updated in ${ + color.underline(packageJSONPath) + }`, + ) + return false + } else { + const sep = '\n - ' + logger.info( + `Updated ${color.yellow(name)}:\n${sep}${ + updatedDependencies.map(([name, { original, target }]) => { + return `${color.cyan(name)}: ${color.dim(original)} -> ${ + color.green(target) + }` + }).join(sep) + }`, + ) + } + + updatedDependencies.forEach(([dependency, { target }]) => { + dependencies[dependency] = target + }) + + return true +} + +const targetDependencies = new Map(Object.entries(devDependencies ?? {})) + +function findDependencies( + dependencies: Record, +) { + return Object.entries(dependencies) + .map(([name, original]) => { + if ( + targetDependencies.has(name) + // Avoid install packages like `commander` or `type-fest` + && (name.startsWith('@lynx-js/') || name.includes('rsbuild')) + ) { + return [ + name, + { + original, + target: targetDependencies.get(name)!, + }, + ] as const + } + return null + }) + .filter(i => i !== null) +} diff --git a/packages/rspeedy/upgrade-rspeedy/src/main.ts b/packages/rspeedy/upgrade-rspeedy/src/main.ts new file mode 100644 index 00000000..dab8b213 --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/src/main.ts @@ -0,0 +1,34 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import { Command } from 'commander' +import { logger } from 'rslog' + +import { install } from './install.js' +import { version } from './version.js' + +export async function main( + cwd?: string, + argv?: readonly string[], +): Promise { + const program = new Command('upgrade-rspeedy') + + // If not called through a package manager, + // output a blank line to keep the greet log nice. + const { npm_execpath } = process.env + if ( + !npm_execpath || npm_execpath.includes('npm-cli.js') + || npm_execpath.includes('npx-cli.js') + ) { + console.info() + } + + logger.greet(`Upgrade Rspeedy v${version}\n`) + + program + .helpCommand(false) + .description('Upgrade the Rspeedy-related packages') + .action(() => install(cwd ?? process.cwd())) + + await program.parseAsync(argv) +} diff --git a/packages/rspeedy/upgrade-rspeedy/src/upgrade-rspeedy.ts b/packages/rspeedy/upgrade-rspeedy/src/upgrade-rspeedy.ts new file mode 100644 index 00000000..6d801054 --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/src/upgrade-rspeedy.ts @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import { main } from './main.js' + +await main() diff --git a/packages/rspeedy/upgrade-rspeedy/src/version.ts b/packages/rspeedy/upgrade-rspeedy/src/version.ts new file mode 100644 index 00000000..7eea00e1 --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/src/version.ts @@ -0,0 +1,21 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. + +import { createRequire } from 'node:module' + +import type { PackageJson } from 'type-fest' + +const require = createRequire(import.meta.url) + +// Using `import('../package.json', { with: { type: 'json' } })` will cause NodeJS print a +// experimental warning. +// eslint-disable-next-line import/no-commonjs +const pkg = require( + '../package.json', +) as PackageJson + +const version: PackageJson['version'] = pkg.version +const devDependencies: PackageJson['devDependencies'] = pkg.devDependencies + +export { version, devDependencies } diff --git a/packages/rspeedy/upgrade-rspeedy/test/install.test.ts b/packages/rspeedy/upgrade-rspeedy/test/install.test.ts new file mode 100644 index 00000000..262c28fa --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/test/install.test.ts @@ -0,0 +1,237 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import { fs, vol } from 'memfs' +import { beforeEach, describe, expect, test, vi } from 'vitest' + +import { install } from '../src/install.js' + +vi.mock('node:fs') + +beforeEach(() => { + vol.reset() +}) + +describe('Install', () => { + test('no package.json', async () => { + await expect(() => install('/tmp')).rejects + .toThrowErrorMatchingInlineSnapshot( + `[Error: /tmp/package.json not found. Please run upgrade-rspeedy in your Rspeedy project.]`, + ) + }) + + test('invalid package.json', async () => { + vol.fromJSON( + { + 'package.json': 'This is a invalid JSON', + }, + '/tmp', + ) + + await expect(() => install('/tmp')).rejects.toThrowError('Unexpected token') + }) + + test('empty package.json', async () => { + vol.fromJSON( + { + 'package.json': '{}', + }, + '/tmp', + ) + + await expect(() => install('/tmp')).rejects + .toThrowErrorMatchingInlineSnapshot(` + [Error: No @lynx-js/rspeedy found in /tmp/package.json. + + Please run upgrade-rspeedy in your Rspeedy project.] + `) + }) + + test('empty dependencies', async () => { + vol.fromJSON( + { + 'package.json': JSON.stringify({ + devDependencies: { + '@lynx-js/rspeedy': 'workspace:*', + }, + dependencies: {}, + }), + }, + '/tmp', + ) + + await install('/tmp') + + expect(fs.readFileSync('/tmp/package.json', 'utf-8')).toMatchInlineSnapshot( + `"{"devDependencies":{"@lynx-js/rspeedy":"workspace:*"},"dependencies":{}}"`, + ) + }) + + test('update dependencies', async () => { + vol.fromJSON( + { + 'package.json': JSON.stringify({ + dependencies: { + '@lynx-js/react': '0.20.0', + }, + devDependencies: { + '@lynx-js/rspeedy': 'workspace:*', + }, + }), + }, + '/tmp', + ) + + await install('/tmp') + + expect(fs.readFileSync('/tmp/package.json', 'utf-8')).toMatchInlineSnapshot( + ` + "{"dependencies":{"@lynx-js/react":"workspace:*"},"devDependencies":{"@lynx-js/rspeedy":"workspace:*"}} + " + `, + ) + }) + + test('update devDependencies', async () => { + vol.fromJSON( + { + 'package.json': JSON.stringify({ + devDependencies: { + '@lynx-js/react-rsbuild-plugin': '0.20.0', + '@lynx-js/rspeedy': 'workspace:*', + }, + }), + }, + '/tmp', + ) + + await install('/tmp') + + expect(fs.readFileSync('/tmp/package.json', 'utf-8')).toMatchInlineSnapshot( + ` + "{"devDependencies":{"@lynx-js/react-rsbuild-plugin":"workspace:*","@lynx-js/rspeedy":"workspace:*"}} + " + `, + ) + }) + + test('update dependencies and devDependencies', async () => { + vol.fromJSON( + { + 'package.json': JSON.stringify({ + dependencies: { + '@lynx-js/react': '0.20.0', + }, + devDependencies: { + '@lynx-js/rspeedy': '0.100.0', + }, + }), + }, + '/tmp', + ) + + await install('/tmp') + + expect(fs.readFileSync('/tmp/package.json', 'utf-8')).toMatchInlineSnapshot( + ` + "{"dependencies":{"@lynx-js/react":"workspace:*"},"devDependencies":{"@lynx-js/rspeedy":"workspace:*"}} + " + `, + ) + }) + + test('do not update non-public packages', async () => { + vol.fromJSON( + { + 'package.json': JSON.stringify( + { + devDependencies: { + '@lynx-js/rspeedy': '0.20.0', + 'memfs': '0.100.0', + }, + }, + null, + 2, + ), + }, + '/tmp', + ) + + await install('/tmp') + + expect(fs.readFileSync('/tmp/package.json', 'utf-8')).toMatchInlineSnapshot( + ` + "{ + "devDependencies": { + "@lynx-js/rspeedy": "workspace:*", + "memfs": "0.100.0" + } + } + " + `, + ) + }) + + test('do not update peerDependencies', async () => { + vol.fromJSON( + { + 'package.json': JSON.stringify( + { + devDependencies: { + '@lynx-js/rspeedy': 'workspace:*', + }, + peerDependencies: { + '@lynx-js/rspeedy': '^0.20.0', + }, + }, + null, + 2, + ), + }, + '/tmp', + ) + + await install('/tmp') + + expect(fs.readFileSync('/tmp/package.json', 'utf-8')).toMatchInlineSnapshot( + ` + "{ + "devDependencies": { + "@lynx-js/rspeedy": "workspace:*" + }, + "peerDependencies": { + "@lynx-js/rspeedy": "^0.20.0" + } + }" + `, + ) + }) + + test('update with indent respected', async () => { + vol.fromJSON( + { + 'package.json': JSON.stringify( + { + devDependencies: { + '@lynx-js/rspeedy': '0.20.0', + }, + }, + null, + 4, + ), + }, + '/tmp', + ) + await install('/tmp') + + expect(fs.readFileSync('/tmp/package.json', 'utf-8')) + .toMatchInlineSnapshot(` + "{ + "devDependencies": { + "@lynx-js/rspeedy": "workspace:*" + } + } + " + `) + }) +}) diff --git a/packages/rspeedy/upgrade-rspeedy/test/main.test.ts b/packages/rspeedy/upgrade-rspeedy/test/main.test.ts new file mode 100644 index 00000000..9c3f6b4a --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/test/main.test.ts @@ -0,0 +1,36 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import { fs, vol } from 'memfs' +import { beforeEach, describe, expect, test, vi } from 'vitest' + +import { main } from '../src/main.js' + +vi.mock('node:fs') + +beforeEach(() => { + vol.reset() +}) + +describe('main', () => { + test('install-rspeedy', async () => { + vol.fromJSON( + { + 'package.json': JSON.stringify({ + devDependencies: { + '@lynx-js/rspeedy': '0.0.0', + }, + }), + }, + '/tmp', + ) + await main('/tmp', ['node', 'upgrade-rspeedy']) + + expect(fs.readFileSync('/tmp/package.json', 'utf-8')).toMatchInlineSnapshot( + ` + "{"devDependencies":{"@lynx-js/rspeedy":"workspace:*"}} + " + `, + ) + }) +}) diff --git a/packages/rspeedy/upgrade-rspeedy/tsconfig.json b/packages/rspeedy/upgrade-rspeedy/tsconfig.json new file mode 100644 index 00000000..211bdd51 --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "composite": true, + "outDir": "./lib", + "baseUrl": "./", + "rootDir": "./", + "noEmit": true, + }, + "include": [ + "src", + "test", + "vitest.config.ts", + ], +} diff --git a/packages/rspeedy/upgrade-rspeedy/turbo.json b/packages/rspeedy/upgrade-rspeedy/turbo.json new file mode 100644 index 00000000..a48515f1 --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/turbo.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": [ + "//" + ], + "tasks": { + "build": { + "dependsOn": [], + "inputs": [ + "src" + ], + "outputs": [ + "dist" + ] + } + } +} diff --git a/packages/rspeedy/upgrade-rspeedy/vitest.config.ts b/packages/rspeedy/upgrade-rspeedy/vitest.config.ts new file mode 100644 index 00000000..a5a5beac --- /dev/null +++ b/packages/rspeedy/upgrade-rspeedy/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config' +import type { UserWorkspaceConfig } from 'vitest/config' + +const config: UserWorkspaceConfig = defineProject({ + test: { + env: { + NO_COLOR: 'true', + }, + }, +}) + +export default config diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 787cce59..90a9521a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -435,6 +435,51 @@ importers: specifier: 'catalog:' version: 1.2.16 + packages/rspeedy/upgrade-rspeedy: + devDependencies: + '@lynx-js/qrcode-rsbuild-plugin': + specifier: workspace:* + version: link:../plugin-qrcode + '@lynx-js/react': + specifier: workspace:* + version: link:../../react + '@lynx-js/react-rsbuild-plugin': + specifier: workspace:* + version: link:../plugin-react + '@lynx-js/rspeedy': + specifier: workspace:* + version: link:../core + '@lynx-js/types': + specifier: ^3.2.0 + version: 3.2.0 + '@rsbuild/plugin-less': + specifier: 1.1.1 + version: 1.1.1(@rsbuild/core@1.2.16) + '@rsbuild/plugin-sass': + specifier: 1.2.2 + version: 1.2.2(@rsbuild/core@1.2.16) + commander: + specifier: ^13.1.0 + version: 13.1.0 + detect-indent: + specifier: ^7.0.1 + version: 7.0.1 + memfs: + specifier: ^4.17.0 + version: 4.17.0 + picocolors: + specifier: ^1.1.1 + version: 1.1.1 + rsbuild-plugin-tailwindcss: + specifier: 0.2.0 + version: 0.2.0(@rsbuild/core@1.2.16)(tailwindcss@3.4.17) + rslog: + specifier: ^1.2.3 + version: 1.2.3 + type-fest: + specifier: ^4.37.0 + version: 4.37.0 + packages/rspeedy/websocket: dependencies: eventemitter3: @@ -2109,6 +2154,11 @@ packages: '@rsbuild/core': optional: true + '@rsbuild/plugin-less@1.1.1': + resolution: {integrity: sha512-Gkp73c9p4CQs2dB4BVCmw/cJ6JpIaWbsKcmZqyr+tlsKqZvZn9aYU+Zx4qWSqPR8I5zatiV2Lh15ObL9CCnlXw==} + peerDependencies: + '@rsbuild/core': 1.x + '@rsbuild/plugin-sass@1.2.2': resolution: {integrity: sha512-vznLfxxPXDyFSPYW7JWTYf/6SJMx5DEgKParNd5lXo7FRa1IKsQOrJdf6F3Rm+T7jKoAvnCVXjM2IkxBW2yJSA==} peerDependencies: @@ -5807,6 +5857,15 @@ packages: typescript: optional: true + rsbuild-plugin-tailwindcss@0.2.0: + resolution: {integrity: sha512-JxixXVuUO8F0gr4EX8j8DZG0FJxUGAj1YECg2K+5XRw/EQXKHbynE0EmiVdMbRukUj+etcK/8lo35Lfyhr2MZA==} + peerDependencies: + '@rsbuild/core': ^1.1.0 + tailwindcss: ^3.1.0 + peerDependenciesMeta: + '@rsbuild/core': + optional: true + rslog@1.2.3: resolution: {integrity: sha512-antALPJaKBRPBU1X2q9t085K4htWDOOv/K1qhTUk7h0l1ePU/KbDqKJn19eKP0dk7PqMioeA0+fu3gyPXCsXxQ==} engines: {node: '>=14.17.6'} @@ -8149,6 +8208,12 @@ snapshots: - lightningcss - webpack + '@rsbuild/plugin-less@1.1.1(@rsbuild/core@1.2.16)': + dependencies: + '@rsbuild/core': 1.2.16 + deepmerge: 4.3.1 + reduce-configs: 1.1.0 + '@rsbuild/plugin-sass@1.2.2(@rsbuild/core@1.2.16)': dependencies: '@rsbuild/core': 1.2.16 @@ -12336,6 +12401,12 @@ snapshots: '@microsoft/api-extractor': 7.51.1(@types/node@22.13.5) typescript: 5.7.3 + rsbuild-plugin-tailwindcss@0.2.0(@rsbuild/core@1.2.16)(tailwindcss@3.4.17): + dependencies: + tailwindcss: 3.4.17 + optionalDependencies: + '@rsbuild/core': 1.2.16 + rslog@1.2.3: {} run-applescript@7.0.0: {}