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 @@
+
+
+
+
+# Upgrade Rspeedy
+
+
+
+
+
+
+
+
+
+
+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: {}