refactor(stage-web,stage-ui): replace warpdrive plugin with unplugin-basemove (#1818)

This commit is contained in:
Doji
2026-05-13 12:03:30 +08:00
committed by GitHub
parent e882ba7dd6
commit 2c432fc1c8
19 changed files with 31 additions and 809 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ Use `To developers` for external developer impact:
Use `To contributors` for internal project work:
- `vishot`, `vite-plugin-warpdrive`, `cap-vite`, CI, dev scripts, repo build/test/lint workflow, docs generation, internal-only packages, release automation, test harnesses, screenshots, evaluation tools.
- `vishot`, `cap-vite`, CI, dev scripts, repo build/test/lint workflow, docs generation, internal-only packages, release automation, test harnesses, screenshots, evaluation tools.
- Include relevant `chore` commits even when changelogithub does not surface them prominently.
## End-User Writing
-2
View File
@@ -34,7 +34,6 @@ Concise but detailed reference for contributors working across the `moeru-ai/air
- **IPC/Eventa**: Always use `@moeru/eventa` for type-safe, framework/runtime-agnostic IPC/RPC. Define contracts centrally (e.g., `apps/stage-tamagotchi/src/shared`) and follow usage patterns in `apps/stage-tamagotchi/src/main/services/electron` for main/renderer integration.
- **Dependency Injection**: Use `injeca` for services/electron modules/plugins/frontend; see `apps/stage-tamagotchi/src/main/index.ts` for composition patterns.
- **Build/CI/Lint**: `.github/workflows` for pipelines; `eslint.config.js` for lint rules.
- **Bundling libs**: Use `tsdown` for new modules (see `packages/vite-plugin-warpdrive`).
- **Styles**: UnoCSS config at `uno.config.ts`; check `apps/stage-web/src/styles` for existing animations; prefer UnoCSS over Tailwind.
## Key Path Index (what lives where)
@@ -60,7 +59,6 @@ Concise but detailed reference for contributors working across the `moeru-ai/air
- Styles: `uno.config.ts` (UnoCSS), `apps/stage-web/src/styles` (animations/reference).
- Build pipeline refs: `.github/workflows`; lint rules in `eslint.config.js`.
- Tailwind/UnoCSS: prefer UnoCSS; if standardizing styles, add shortcuts/rules/plugins in `uno.config.ts`.
- Bundling pattern: `packages/vite-plugin-warpdrive` (tsdown example).
## Commands (pnpm with filters)
-1
View File
@@ -124,7 +124,6 @@
"@proj-airi/lobe-icons": "^1.0.19",
"@proj-airi/unplugin-fetch": "catalog:",
"@proj-airi/unplugin-live2d-sdk": "^0.1.7",
"@proj-airi/vite-plugin-warpdrive": "workspace:*",
"@shikijs/markdown-it": "^4.0.2",
"@types/audioworklet": "catalog:",
"@types/culori": "^4.0.1",
+1 -1
View File
@@ -120,7 +120,6 @@
"@proj-airi/lobe-icons": "^1.0.19",
"@proj-airi/unplugin-fetch": "catalog:",
"@proj-airi/unplugin-live2d-sdk": "^0.1.7",
"@proj-airi/vite-plugin-warpdrive": "workspace:*",
"@shikijs/markdown-it": "^4.0.2",
"@types/audioworklet": "catalog:",
"@types/culori": "^4.0.1",
@@ -136,6 +135,7 @@
"csstype": "^3.2.3",
"hfup": "^1.0.4",
"less": "^4.6.4",
"unplugin-basemove": "0.0.1",
"unplugin-info": "^1.3.2",
"unplugin-yaml": "^4.1.0",
"vite": "catalog:",
+2 -2
View File
@@ -7,6 +7,7 @@ import VueI18n from '@intlify/unplugin-vue-i18n/vite'
import templateCompilerOptions from '@tresjs/core/template-compiler-options'
import Vue from '@vitejs/plugin-vue'
import Unocss from 'unocss/vite'
import Basemove, { createS3Provider } from 'unplugin-basemove/vite'
import Info from 'unplugin-info/vite'
import Yaml from 'unplugin-yaml/vite'
import Mkcert from 'vite-plugin-mkcert'
@@ -18,7 +19,6 @@ import VueRouter from 'vue-router/vite'
import { tryCatch } from '@moeru/std'
import { Download } from '@proj-airi/unplugin-fetch/vite'
import { DownloadLive2DSDK } from '@proj-airi/unplugin-live2d-sdk/vite'
import { createS3Provider, WarpDrivePlugin } from '@proj-airi/vite-plugin-warpdrive'
import { LFS, SpaceCard } from 'hfup/vite'
import { defineConfig } from 'vite'
import { VitePWA } from 'vite-plugin-pwa'
@@ -275,7 +275,7 @@ export default defineConfig({
...((!env.S3_ENDPOINT || !env.S3_ACCESS_KEY_ID || !env.S3_SECRET_ACCESS_KEY)
? []
: [
WarpDrivePlugin({
Basemove({
prefix: env.STAGE_WEB_WARP_DRIVE_PREFIX || 'proj-airi/stage-web/main/',
include: [/\.wasm$/i, /\.ttf$/i, /\.vrm$/i, /\.zip$/i], // in existing assets, wasm, ttf, vrm files are the largest ones
manifest: true,
+1 -1
View File
@@ -32,6 +32,7 @@ words:
- baichuan
- baiducloud
- bailian
- Basemove
- bestmove
- bigserial
- bilibili
@@ -345,7 +346,6 @@ words:
- vueuse
- waapi
- Waifu
- warpdrive
- Warudo
- wavefile
- webgpu
+1 -1
View File
@@ -182,7 +182,6 @@
"@pinia/testing": "catalog:",
"@proj-airi/lobe-icons": "^1.0.19",
"@proj-airi/stream-kit": "workspace:*",
"@proj-airi/vite-plugin-warpdrive": "workspace:*",
"@types/audioworklet": "catalog:",
"@types/culori": "^4.0.1",
"@types/d3": "catalog:",
@@ -197,6 +196,7 @@
"histoire": "catalog:",
"is-network-error": "catalog:",
"unocss": "^66.6.8",
"unplugin-basemove": "0.0.1",
"unplugin-info": "catalog:",
"unplugin-yaml": "^4.1.0",
"vite": "^6.4.2",
+2 -2
View File
@@ -5,10 +5,10 @@ import { env } from 'node:process'
import Vue from '@vitejs/plugin-vue'
import Unocss from 'unocss/vite'
import Basemove, { createS3Provider } from 'unplugin-basemove/vite'
import Yaml from 'unplugin-yaml/vite'
import Inspect from 'vite-plugin-inspect'
import { createS3Provider, WarpDrivePlugin } from '@proj-airi/vite-plugin-warpdrive'
import { defineConfig } from 'vite'
// For Histoire
@@ -61,7 +61,7 @@ export default defineConfig({
...((!env.S3_ENDPOINT || !env.S3_ACCESS_KEY_ID || !env.S3_SECRET_ACCESS_KEY)
? []
: [
WarpDrivePlugin({
Basemove({
prefix: env.STAGE_UI_WARP_DRIVE_PREFIX || 'proj-airi/stage-ui/main/',
include: [/\.wasm$/i, /\.ttf$/i, /\.vrm$/i, /\.zip$/i], // in existing assets, wasm, ttf, vrm files are the largest ones
manifest: true,
-84
View File
@@ -1,84 +0,0 @@
# @proj-airi/vite-plugin-warpdrive
Vite plugin that rewrites selected build assets (large WASM/TTF/VRM, etc.) to remote object storage and uploads them after build. It uses Vite's `renderBuiltUrl` hook so the generated bundles reference the remote URL while keeping the local file for upload.
## Why
- Keep HTML/JS bundles lean while serving heavy assets (WASM, fonts, models) from object storage/CDN.
- Simple provider abstraction; ships with an S3-compatible implementation via [`s3mini`](https://github.com/good-lly/s3mini).
- Emits an optional manifest (`remote-assets.manifest.json`) that maps built filenames to remote URLs plus hostId/hostType for debugging.
## Install
```bash
pnpm add -D @proj-airi/vite-plugin-warpdrive
```
## Usage
```ts
import { createS3Provider, WarpDrivePlugin } from '@proj-airi/vite-plugin-warpdrive'
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
WarpDrivePlugin({
prefix: 'remote-assets', // path prefix in the bucket (default: remote-assets)
include: [/\.wasm$/i, /\.ttf$/i, /\.vrm$/i], // which assets to rewrite/upload (required)
// includeBy: (file, ctx) => ctx.hostId?.includes('duckdb'), // extra predicate with host info
// contentTypeBy: (file) => file.endsWith('.wasm') ? 'application/wasm' : undefined,
manifest: true, // emit remote-assets.manifest.json in dist
delete: true, // delete local uploaded assets (default: true)
clean: true, // clean remote prefix before upload (default: true if provider supports it)
skipNotModified: true, // skip uploads if provider supports it (default: true)
// dryRun: true, // rewrite URLs/manifest only; skip cleaning/uploading
provider: createS3Provider({
endpoint: process.env.S3_ENDPOINT!,
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
region: process.env.S3_REGION,
publicBaseUrl: process.env.WARP_DRIVE_PUBLIC_BASE, // defaults to endpoint
}),
}),
],
})
```
### Options
- `provider` (required): object implementing `UploadProvider` (see below).
- `prefix`: string path prefix for uploaded keys and URLs (default: `remote-assets`; e.g. `remote-assets/assets/foo.wasm`).
- `include`: array of regex or predicate functions to decide which assets to rewrite/upload (empty array means nothing is rewritten).
- `includeBy`: optional `(filename, ctx) => boolean` for finer control (`ctx` has `hostId`, `hostType`).
- `contentTypeBy`: optional `(filename) => string | Promise<string | undefined> | undefined` resolver passed to `provider.upload`.
- `manifest`: when true, emits `remote-assets.manifest.json` describing fileName/key/url/hostId/hostType/size.
- `delete`: when true (default), delete uploaded local assets from disk after upload.
- `clean`: when true (default), call `provider.cleanPrefix(prefix)` before uploading; skipped if no prefix or provider lacks `cleanPrefix`.
- `skipNotModified`: when true (default), skip uploads if `provider.shouldSkipUpload` returns true.
- `dryRun`: when true, rewrite URLs/emit manifest without cleaning or uploading.
#### UploadProvider interface
```ts
interface UploadProvider {
getPublicUrl: (key: string) => string
upload: (localPath: string, key: string, contentType?: string) => Promise<void>
cleanPrefix?: (prefix: string) => Promise<void>
shouldSkipUpload?: (localPath: string, key: string) => Promise<boolean>
}
```
### createS3Provider
Light wrapper around `s3mini`. Required fields:
- `endpoint`: full bucket URL (e.g. `https://s3.example.com/my-bucket`).
- `accessKeyId`, `secretAccessKey`: credentials.
- Optional: `region`, `requestSizeInBytes`, `requestAbortTimeout`, `publicBaseUrl` (override public URL base), `skipNotModified` (default: true; uses ETag/MD5 to skip uploads).
## How it works
1. `renderBuiltUrl` returns the remote URL for matching assets while remembering the key/hostId/hostType.
2. `generateBundle` records assets to upload, emits the optional manifest, and leaves the local files in `dist/`.
3. `closeBundle` optionally cleans the prefix, skips unmodified uploads when supported, uploads assets, and deletes local copies (unless `delete` is false).
@@ -1,40 +0,0 @@
{
"name": "@proj-airi/vite-plugin-warpdrive",
"type": "module",
"version": "0.10.2",
"private": true,
"description": "Vite plugin to rewrite and upload heavy build assets to remote object storage",
"author": {
"name": "Moeru AI Project AIRI Team",
"email": "airi@moeru.ai",
"url": "https://github.com/moeru-ai"
},
"license": "MIT",
"exports": {
".": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
}
},
"main": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"files": [
"README.md",
"dist",
"package.json"
],
"scripts": {
"build": "tsdown",
"typecheck": "tsc --noEmit"
},
"peerDependencies": {
"vite": "^5.0.0 || ^6.0.0"
},
"dependencies": {
"rolldown": "1.0.0-beta.51",
"s3mini": "^0.9.4"
},
"devDependencies": {
"@moeru/std": "catalog:"
}
}
-293
View File
@@ -1,293 +0,0 @@
import type { OutputAsset } from 'rollup'
import type { Plugin, RenderBuiltAssetUrl, ResolvedConfig } from 'vite'
import type { UploadProvider } from './providers/types'
import { Buffer } from 'node:buffer'
import { rm } from 'node:fs/promises'
import { join, resolve } from 'node:path'
import { cwd } from 'node:process'
import { errorCauseFrom, errorMessageFrom, errorNameFrom, errorStackFrom } from '@moeru/std'
export { createS3Provider } from './providers/s3'
export type { S3ProviderOptions } from './providers/s3'
export type { UploadProvider } from './providers/types'
type IncludeMatcher = RegExp | ((filename: string) => boolean)
export interface WarpDrivePluginOptions {
provider: UploadProvider
/**
* Prefix to prepend before the asset filename when uploading and when rewriting URLs.
* e.g. `remote-assets` will produce `remote-assets/assets/duckdb-eh-123.wasm`.
*/
prefix?: string
/**
* Restrict which assets are rewritten/uploaded.
*/
include?: IncludeMatcher[]
/**
* Optional extra predicate that receives filename + host info to decide inclusion.
*/
includeBy?: (filename: string, ctx: { hostId?: string, hostType?: string }) => boolean
/**
* Optional content-type resolver. If omitted, uploads use the provider default.
*/
contentTypeBy?: (filename: string) => Promise<string | undefined> | string | undefined
/**
* Emit a manifest with module id + URL for debugging.
*/
manifest?: boolean
/**
* Delete the uploaded local asset from disk after upload completes. Enabled by default.
*/
delete?: boolean
/**
* Clean the remote prefix before uploading (delete existing objects). Enabled by default.
*/
clean?: boolean
/**
* When enabled, skip cleaning and uploading; emit manifest/rewrite URLs only.
*/
dryRun?: boolean
/**
* Skip uploading assets that are already present and not modified. Enabled by default when supported.
*/
skipNotModified?: boolean
}
export function WarpDrivePlugin(options: WarpDrivePluginOptions): Plugin {
const include = options.include ?? []
const prefix = normalizePrefix(options.prefix ?? 'remote-assets')
const pluginName = 'proj-airi-warpdrive'
const shouldDeleteLocalAsset = options.delete !== false
const shouldCleanRemote = options.clean !== false
const shouldSkipNotModified = options.skipNotModified !== false
const isDryRun = options.dryRun === true
const tracked = new Map<string, { key: string, url: string, hostId?: string, hostType?: string }>()
const manifest: Array<{
fileName: string
url: string
key: string
hostId?: string
hostType?: string
size: number
}> = []
let resolvedConfig: ResolvedConfig | undefined
let cleanedRemote = false
const pendingUploads: Array<{
fileName: string
key: string
localPath: string
contentType?: string
}> = []
const shouldHandle = (filename: string, ctx: { hostId?: string, hostType?: string }) => {
const includeMatch = include.some((matcher) => {
if (matcher instanceof RegExp)
return matcher.test(filename)
return matcher(filename)
})
if (!includeMatch)
return false
if (options.includeBy)
return options.includeBy(filename, ctx)
return true
}
const renderBuiltUrl: RenderBuiltAssetUrl = (filename, ctx) => {
if (!shouldHandle(filename, ctx))
return
if (!options.provider)
return
const key = prefix ? `${prefix}/${filename}` : filename
const url = options.provider.getPublicUrl(key)
tracked.set(filename, {
key,
url,
hostId: ctx.hostId,
hostType: ctx.hostType,
})
return url
}
return {
name: pluginName,
apply: 'build',
enforce: 'post',
config: () => {
return {
experimental: {
renderBuiltUrl,
},
}
},
configResolved(config) {
resolvedConfig = config
},
async generateBundle(_, bundle) {
if (!resolvedConfig) {
console.warn?.(`[${pluginName}] Vite config not resolved, skipping upload step`)
return
}
if (!options.provider) {
resolvedConfig.logger.warn(`[${pluginName}] no upload provider configured, skipping upload step`)
return
}
const root = resolvedConfig.root || cwd()
const outDir = resolve(root, resolvedConfig.build.outDir)
for (const [fileName, output] of Object.entries(bundle)) {
if (output.type !== 'asset')
continue
const trackedMeta = tracked.get(fileName)
if (!trackedMeta)
continue
const key = trackedMeta.key
const url = trackedMeta.url
const localPath = join(outDir, fileName)
const size = getAssetSize(output)
const contentType = await options.contentTypeBy?.(fileName)
manifest.push({
fileName,
url,
key,
hostId: trackedMeta.hostId,
hostType: trackedMeta.hostType,
size,
})
pendingUploads.push({ fileName, key, localPath, contentType })
resolvedConfig.logger.info(`[${pluginName}] scheduled uploading: ${fileName} -> ${key} (${size} bytes)`)
}
if (options.manifest && manifest.length) {
this.emitFile({
type: 'asset',
fileName: 'remote-assets.manifest.json',
source: JSON.stringify({ assets: manifest }, null, 2),
})
}
},
async closeBundle() {
if (!resolvedConfig) {
console.warn?.(`[${pluginName}] Vite config not resolved, skipping upload step`)
return
}
if (!options.provider) {
resolvedConfig.logger.warn(`[${pluginName}] no upload provider configured, skipping upload step`)
return
}
if (!pendingUploads.length)
return
if (isDryRun) {
resolvedConfig.logger.info(
`[${pluginName}] dry run enabled; skipping clean/upload for ${pendingUploads.length} assets`,
)
return
}
if (shouldCleanRemote && !cleanedRemote) {
if (!prefix) {
resolvedConfig.logger.warn(`[${pluginName}] skipping clean step because no prefix provided`)
}
else if (typeof options.provider.cleanPrefix === 'function') {
resolvedConfig.logger.info(`[${pluginName}] cleaning remote prefix: ${prefix}`)
await options.provider.cleanPrefix(prefix)
resolvedConfig.logger.info(`[${pluginName}] cleaned remote prefix: ${prefix}`)
cleanedRemote = true
}
else {
resolvedConfig.logger.warn(
`[${pluginName}] clean is enabled but provider does not support prefix cleaning; skipping`,
)
}
}
resolvedConfig.logger.info(`[${pluginName}] uploading ${pendingUploads.length} assets to remote storage...`)
const uploads: Array<Promise<void>> = []
for (const { fileName, key, localPath, contentType } of pendingUploads) {
uploads.push((async () => {
if (shouldSkipNotModified && typeof options.provider.shouldSkipUpload === 'function') {
try {
const skip = await options.provider.shouldSkipUpload(localPath, key)
if (skip) {
resolvedConfig.logger.info(
`[${pluginName}] skipped upload (not modified): ${fileName} -> ${key}`,
)
if (shouldDeleteLocalAsset) {
try {
await rm(localPath, { force: true })
resolvedConfig.logger.info(`[${pluginName}] deleted local asset: ${fileName}`)
}
catch (error) {
resolvedConfig.logger.warn(`[${pluginName}] failed to delete local asset ${fileName}: ${error}`)
}
}
return
}
}
catch (error) {
resolvedConfig.logger.warn(
`[${pluginName}] could not determine if upload should be skipped for ${fileName}: ${error}`,
)
}
}
try {
await options.provider.upload(localPath, key, contentType)
}
catch (err) {
const error = new Error(errorMessageFrom(err))
error.name = errorNameFrom(err) || 'UploadError'
const stack = errorStackFrom(err)
if (stack)
error.stack = stack
error.cause = errorCauseFrom(err)
resolvedConfig.logger.error(`[${pluginName}] upload failed, file: ${fileName} -> ${key}: ${err}`, { error })
throw err
}
if (shouldDeleteLocalAsset) {
try {
await rm(localPath, { force: true })
resolvedConfig.logger.info(`[${pluginName}] deleted local asset: ${fileName}`)
}
catch (error) {
resolvedConfig.logger.warn(`[${pluginName}] failed to delete local asset ${fileName}: ${error}`)
}
}
})())
}
await Promise.all(uploads)
resolvedConfig.logger.info(`[${pluginName}] upload complete`)
},
}
}
function normalizePrefix(prefix: string) {
return prefix.replace(/^\/*/, '').replace(/\/*$/, '')
}
function getAssetSize(asset: OutputAsset) {
if (typeof asset.source === 'string')
return Buffer.byteLength(asset.source)
return asset.source?.byteLength ?? 0
}
@@ -1,28 +0,0 @@
import { join } from 'node:path'
import { cwd, env } from 'node:process'
import { describe, expect, it } from 'vitest'
import { createS3Provider } from './s3'
describe('s3', (test) => {
if (!env.S3_ENDPOINT || !env.S3_REGION || !env.S3_ACCESS_KEY_ID || !env.S3_SECRET_ACCESS_KEY) {
test.skip('S3_ENDPOINT, S3_REGION, S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY must be set in environment to run this test', () => {})
return
}
// eslint-disable-next-line test/prefer-lowercase-title
describe('S3Provider', () => {
it('should skip upload', async () => {
const s3 = createS3Provider({
endpoint: env.S3_ENDPOINT!,
accessKeyId: env.S3_ACCESS_KEY_ID!,
secretAccessKey: env.S3_SECRET_ACCESS_KEY!,
region: env.S3_REGION,
publicBaseUrl: env.WARP_DRIVE_PUBLIC_BASE ?? env.S3_ENDPOINT,
})
expect(await s3.shouldSkipUpload?.(join(cwd(), 'packages', 'stage-ui', 'src', 'assets', 'live2d', 'models', 'hiyori_free_zh.zip'), '/proj-airi/stage-web/assets/hiyori_free_zh-D9UJNK98.zip')).toBe(true)
})
})
})
@@ -1,102 +0,0 @@
import type { Buffer } from 'node:buffer'
import type { UploadProvider } from './types'
import { createHash } from 'node:crypto'
import { readFile } from 'node:fs/promises'
import { S3mini } from 's3mini'
export interface S3ProviderOptions {
endpoint: string
accessKeyId: string
secretAccessKey: string
region?: string
requestSizeInBytes?: number
requestAbortTimeout?: number
/**
* Skip uploading when the remote object ETag matches the local content hash (MD5). Enabled by default.
*/
skipNotModified?: boolean
/**
* Public base URL used in rewritten assets. Defaults to endpoint.
*/
publicBaseUrl?: string
}
export function createS3Provider(options: S3ProviderOptions): UploadProvider {
const client = new S3mini({
accessKeyId: options.accessKeyId,
secretAccessKey: options.secretAccessKey,
endpoint: options.endpoint,
region: options.region ?? 'auto',
requestAbortTimeout: options.requestAbortTimeout,
requestSizeInBytes: options.requestSizeInBytes,
})
const publicBaseUrl = options.publicBaseUrl ?? options.endpoint
const skipNotModified = options.skipNotModified !== false
return {
async upload(localPath: string, key: string, contentType?: string) {
const data = await readFile(localPath)
await client.putObject(normalizeKey(key), data, contentType ?? 'application/octet-stream')
},
async cleanPrefix(prefix: string) {
const normalizedPrefix = normalizePrefix(prefix)
if (!normalizedPrefix)
return
const objects = await client.listObjects('/', `${normalizedPrefix}/`)
if (!objects?.length)
return
const keys = objects.map(obj => obj.Key)
await client.deleteObjects(keys)
},
async shouldSkipUpload(localPath: string, key: string) {
if (!skipNotModified)
return false
const data = await readFile(localPath)
return isMd5HashMatched(client, key, data)
},
getPublicUrl(key: string) {
return joinUrl(publicBaseUrl, key)
},
}
}
async function isMd5HashMatched(client: S3mini, key: string, data: Buffer) {
try {
const etag = await client.getEtag(normalizeKey(key))
if (!etag)
return false
const normalizedEtag = sanitizeEtag(etag)
if (!normalizedEtag || normalizedEtag.includes('-'))
return false
const localHash = createHash('md5').update(data).digest('hex')
return normalizedEtag.toLowerCase() === localHash.toLowerCase()
}
catch {
return false
}
}
function normalizePrefix(prefix: string) {
return prefix.replace(/^\/*/, '').replace(/\/*$/, '')
}
function normalizeKey(key: string) {
return key.replace(/^\/*/, '')
}
function joinUrl(base: string, path: string) {
return `${base.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`
}
function sanitizeEtag(etag: string) {
return etag.replace(/^"+|"+$/g, '')
}
@@ -1,12 +0,0 @@
export interface UploadProvider {
getPublicUrl: (key: string) => string
upload: (localPath: string, key: string, contentType?: string) => Promise<void>
/**
* Optionally clean a remote prefix before uploading new assets.
*/
cleanPrefix?: (prefix: string) => Promise<void>
/**
* Optionally determine if an upload can be skipped (e.g., hash/etag match).
*/
shouldSkipUpload?: (localPath: string, key: string) => Promise<boolean>
}
@@ -1,18 +0,0 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": [
"ESNext"
],
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
},
"include": [
"src/**/*.ts"
]
}
@@ -1,9 +0,0 @@
import { defineConfig } from 'tsdown'
export default defineConfig({
entry: [
'./src/index.ts',
],
dts: true,
sourcemap: true,
})
@@ -1,14 +0,0 @@
import { join } from 'node:path'
import { cwd } from 'node:process'
import { loadEnv } from 'vite'
import { defineConfig } from 'vitest/config'
export default defineConfig(({ mode }) => {
return ({
test: {
include: ['src/**/*.test.ts'],
env: loadEnv(mode, join(cwd(), 'packages', 'vite-plugin-warpdrive'), ''),
},
})
})
+23 -197
View File
@@ -1063,9 +1063,6 @@ importers:
'@proj-airi/unplugin-live2d-sdk':
specifier: ^0.1.7
version: 0.1.7(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
'@proj-airi/vite-plugin-warpdrive':
specifier: workspace:*
version: link:../../packages/vite-plugin-warpdrive
'@shikijs/markdown-it':
specifier: ^4.0.2
version: 4.0.2
@@ -1950,9 +1947,6 @@ importers:
'@proj-airi/unplugin-live2d-sdk':
specifier: ^0.1.7
version: 0.1.7(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
'@proj-airi/vite-plugin-warpdrive':
specifier: workspace:*
version: link:../../packages/vite-plugin-warpdrive
'@shikijs/markdown-it':
specifier: ^4.0.2
version: 4.0.2
@@ -1998,6 +1992,9 @@ importers:
less:
specifier: ^4.6.4
version: 4.6.4
unplugin-basemove:
specifier: 0.0.1
version: 0.0.1(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
unplugin-info:
specifier: ^1.3.2
version: 1.3.2(esbuild@0.27.2)(rollup@4.60.1)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
@@ -3486,9 +3483,6 @@ importers:
'@proj-airi/stream-kit':
specifier: workspace:*
version: link:../stream-kit
'@proj-airi/vite-plugin-warpdrive':
specifier: workspace:*
version: link:../vite-plugin-warpdrive
'@types/audioworklet':
specifier: 'catalog:'
version: 0.0.97
@@ -3531,6 +3525,9 @@ importers:
unocss:
specifier: ^66.6.8
version: 66.6.8(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
unplugin-basemove:
specifier: 0.0.1
version: 0.0.1(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
unplugin-info:
specifier: 'catalog:'
version: 1.3.2(esbuild@0.27.2)(rollup@4.60.1)(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
@@ -3876,22 +3873,6 @@ importers:
specifier: ^3.2.6
version: 3.2.6(typescript@5.9.3)
packages/vite-plugin-warpdrive:
dependencies:
rolldown:
specifier: 1.0.0-beta.51
version: 1.0.0-beta.51(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)
s3mini:
specifier: ^0.9.4
version: 0.9.4
vite:
specifier: ^5.0.0 || ^6.0.0
version: 6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
devDependencies:
'@moeru/std':
specifier: 'catalog:'
version: 0.1.0-beta.17
plugins/airi-plugin-bilibili-laplace:
dependencies:
'@guiiai/logg':
@@ -7944,9 +7925,6 @@ packages:
'@oxc-project/types@0.126.0':
resolution: {integrity: sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==}
'@oxc-project/types@0.98.0':
resolution: {integrity: sha512-Vzmd6FsqVuz5HQVcRC/hrx7Ujo3WEVeQP7C2UNP5uy1hUY4SQvMB+93jxkI1KRHz9a/6cni3glPOtvteN+zpsw==}
'@oxc-resolver/binding-android-arm-eabi@11.19.1':
resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==}
cpu: [arm]
@@ -8703,12 +8681,6 @@ packages:
'@rive-app/canvas-lite@2.37.2':
resolution: {integrity: sha512-Pp8R/ZpZliwkPm684HFIKZ4N6UurcfbfFQXV74+HV2bxAutpQYsDCr0sOjEgJC/brG5aeSCVyJY3Iq7nNAkmeQ==}
'@rolldown/binding-android-arm64@1.0.0-beta.51':
resolution: {integrity: sha512-Ctn8FUXKWWQI9pWC61P1yumS9WjQtelNS9riHwV7oCkknPGaAry4o7eFx2KgoLMnI2BgFJYpW7Im8/zX3BuONg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@rolldown/binding-android-arm64@1.0.0-rc.15':
resolution: {integrity: sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8721,12 +8693,6 @@ packages:
cpu: [arm64]
os: [android]
'@rolldown/binding-darwin-arm64@1.0.0-beta.51':
resolution: {integrity: sha512-EL1aRW2Oq15ShUEkBPsDtLMO8GTqfb/ktM/dFaVzXKQiEE96Ss6nexMgfgQrg8dGnNpndFyffVDb5IdSibsu1g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@rolldown/binding-darwin-arm64@1.0.0-rc.15':
resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8739,12 +8705,6 @@ packages:
cpu: [arm64]
os: [darwin]
'@rolldown/binding-darwin-x64@1.0.0-beta.51':
resolution: {integrity: sha512-uGtYKlFen9pMIPvkHPWZVDtmYhMQi5g5Ddsndg1gf3atScKYKYgs5aDP4DhHeTwGXQglhfBG7lEaOIZ4UAIWww==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@rolldown/binding-darwin-x64@1.0.0-rc.15':
resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8757,12 +8717,6 @@ packages:
cpu: [x64]
os: [darwin]
'@rolldown/binding-freebsd-x64@1.0.0-beta.51':
resolution: {integrity: sha512-JRoVTQtHYbZj1P07JLiuTuXjiBtIa7ag7/qgKA6CIIXnAcdl4LrOf7nfDuHPJcuRKaP5dzecMgY99itvWfmUFQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@rolldown/binding-freebsd-x64@1.0.0-rc.15':
resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8775,12 +8729,6 @@ packages:
cpu: [x64]
os: [freebsd]
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.51':
resolution: {integrity: sha512-BKATVnpPZ0TYBW9XfDwyd4kPGgvf964HiotIwUgpMrFOFYWqpZ+9ONNzMV4UFAYC7Hb5C2qgYQk/qj2OnAd4RQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15':
resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8793,13 +8741,6 @@ packages:
cpu: [arm]
os: [linux]
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.51':
resolution: {integrity: sha512-xLd7da5jkfbVsBCm1buIRdWtuXY8+hU3+6ESXY/Tk5X5DPHaifrUblhYDgmA34dQt6WyNC2kfXGgrduPEvDI6Q==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15':
resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8814,13 +8755,6 @@ packages:
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.51':
resolution: {integrity: sha512-EQFXTgHxxTzv3t5EmjUP/DfxzFYx9sMndfLsYaAY4DWF6KsK1fXGYsiupif6qPTViPC9eVmRm78q0pZU/kuIPg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.15':
resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8863,13 +8797,6 @@ packages:
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.51':
resolution: {integrity: sha512-p5P6Xpa68w3yFaAdSzIZJbj+AfuDnMDqNSeglBXM7UlJT14Q4zwK+rV+8Mhp9MiUb4XFISZtbI/seBprhkQbiQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.15':
resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8884,13 +8811,6 @@ packages:
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-x64-musl@1.0.0-beta.51':
resolution: {integrity: sha512-sNVVyLa8HB8wkFipdfz1s6i0YWinwpbMWk5hO5S+XAYH2UH67YzUT13gs6wZTKg2x/3gtgXzYnHyF5wMIqoDAw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@rolldown/binding-linux-x64-musl@1.0.0-rc.15':
resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8905,12 +8825,6 @@ packages:
os: [linux]
libc: [musl]
'@rolldown/binding-openharmony-arm64@1.0.0-beta.51':
resolution: {integrity: sha512-e/JMTz9Q8+T3g/deEi8DK44sFWZWGKr9AOCW5e8C8SCVWzAXqYXAG7FXBWBNzWEZK0Rcwo9TQHTQ9Q0gXgdCaA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@rolldown/binding-openharmony-arm64@1.0.0-rc.15':
resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8923,11 +8837,6 @@ packages:
cpu: [arm64]
os: [openharmony]
'@rolldown/binding-wasm32-wasi@1.0.0-beta.51':
resolution: {integrity: sha512-We3LWqSu6J9s5Y0MK+N7fUiiu37aBGPG3Pc347EoaROuAwkCS2u9xJ5dpIyLW4B49CIbS3KaPmn4kTgPb3EyPw==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
'@rolldown/binding-wasm32-wasi@1.0.0-rc.15':
resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==}
engines: {node: '>=14.0.0'}
@@ -8938,12 +8847,6 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [wasm32]
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.51':
resolution: {integrity: sha512-fj56buHRuMM+r/cb6ZYfNjNvO/0xeFybI6cTkTROJatdP4fvmQ1NS8D/Lm10FCSDEOkqIz8hK3TGpbAThbPHsA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15':
resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8956,18 +8859,6 @@ packages:
cpu: [arm64]
os: [win32]
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.51':
resolution: {integrity: sha512-fkqEqaeEx8AySXiDm54b/RdINb3C0VovzJA3osMhZsbn6FoD73H0AOIiaVAtGr6x63hefruVKTX8irAm4Jkt2w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.51':
resolution: {integrity: sha512-CWuLG/HMtrVcjKGa0C4GnuxONrku89g0+CsH8nT0SNhOtREXuzwgjIXNJImpE/A/DMf9JF+1Xkrq/YRr+F/rCg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.15':
resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -8980,9 +8871,6 @@ packages:
cpu: [x64]
os: [win32]
'@rolldown/pluginutils@1.0.0-beta.51':
resolution: {integrity: sha512-51/8cNXMrqWqX3o8DZidhwz1uYq0BhHDDSfVygAND1Skx5s1TDw3APSSxCMcFFedwgqGcx34gRouwY+m404BBQ==}
'@rolldown/pluginutils@1.0.0-rc.13':
resolution: {integrity: sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==}
@@ -16245,11 +16133,6 @@ packages:
vue-tsc:
optional: true
rolldown@1.0.0-beta.51:
resolution: {integrity: sha512-ZRLgPlS91l4JztLYEZnmMcd3Umcla1hkXJgiEiR4HloRJBBoeaX8qogTu5Jfu36rRMVLndzqYv0h+M5gJAkUfg==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
rolldown@1.0.0-rc.15:
resolution: {integrity: sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -17328,6 +17211,11 @@ packages:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
unplugin-basemove@0.0.1:
resolution: {integrity: sha512-U1XlGlzhmppJwNbCLMHZCr9srhRclpCTa70vcOoe8B9CGcmQ5ykqqsNc4p3twHLifsmorWL0mXgjWd71y89VSA==}
peerDependencies:
vite: ^5.0.0 || ^6.0.0
unplugin-combine@2.3.0:
resolution: {integrity: sha512-0aZjv0JqOCPY+yujTatSwlCbsK6bMcBUZDlpMHTlc7KDc2gq8XL5cPgEOeS2GZ767BHAonkEqhC+NlOvzzm5FA==}
engines: {node: '>=20.19.0'}
@@ -22251,8 +22139,6 @@ snapshots:
'@oxc-project/types@0.126.0': {}
'@oxc-project/types@0.98.0': {}
'@oxc-resolver/binding-android-arm-eabi@11.19.1':
optional: true
@@ -22900,63 +22786,42 @@ snapshots:
'@rive-app/canvas-lite@2.37.2': {}
'@rolldown/binding-android-arm64@1.0.0-beta.51':
optional: true
'@rolldown/binding-android-arm64@1.0.0-rc.15':
optional: true
'@rolldown/binding-android-arm64@1.0.0-rc.16':
optional: true
'@rolldown/binding-darwin-arm64@1.0.0-beta.51':
optional: true
'@rolldown/binding-darwin-arm64@1.0.0-rc.15':
optional: true
'@rolldown/binding-darwin-arm64@1.0.0-rc.16':
optional: true
'@rolldown/binding-darwin-x64@1.0.0-beta.51':
optional: true
'@rolldown/binding-darwin-x64@1.0.0-rc.15':
optional: true
'@rolldown/binding-darwin-x64@1.0.0-rc.16':
optional: true
'@rolldown/binding-freebsd-x64@1.0.0-beta.51':
optional: true
'@rolldown/binding-freebsd-x64@1.0.0-rc.15':
optional: true
'@rolldown/binding-freebsd-x64@1.0.0-rc.16':
optional: true
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.51':
optional: true
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15':
optional: true
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.16':
optional: true
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.51':
optional: true
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15':
optional: true
'@rolldown/binding-linux-arm64-gnu@1.0.0-rc.16':
optional: true
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.51':
optional: true
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.15':
optional: true
@@ -22975,41 +22840,24 @@ snapshots:
'@rolldown/binding-linux-s390x-gnu@1.0.0-rc.16':
optional: true
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.51':
optional: true
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.15':
optional: true
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.16':
optional: true
'@rolldown/binding-linux-x64-musl@1.0.0-beta.51':
optional: true
'@rolldown/binding-linux-x64-musl@1.0.0-rc.15':
optional: true
'@rolldown/binding-linux-x64-musl@1.0.0-rc.16':
optional: true
'@rolldown/binding-openharmony-arm64@1.0.0-beta.51':
optional: true
'@rolldown/binding-openharmony-arm64@1.0.0-rc.15':
optional: true
'@rolldown/binding-openharmony-arm64@1.0.0-rc.16':
optional: true
'@rolldown/binding-wasm32-wasi@1.0.0-beta.51(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)':
dependencies:
'@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
optional: true
'@rolldown/binding-wasm32-wasi@1.0.0-rc.15':
dependencies:
'@emnapi/core': 1.9.2
@@ -23024,29 +22872,18 @@ snapshots:
'@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)
optional: true
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.51':
optional: true
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15':
optional: true
'@rolldown/binding-win32-arm64-msvc@1.0.0-rc.16':
optional: true
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.51':
optional: true
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.51':
optional: true
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.15':
optional: true
'@rolldown/binding-win32-x64-msvc@1.0.0-rc.16':
optional: true
'@rolldown/pluginutils@1.0.0-beta.51': {}
'@rolldown/pluginutils@1.0.0-rc.13': {}
'@rolldown/pluginutils@1.0.0-rc.15': {}
@@ -31687,29 +31524,6 @@ snapshots:
transitivePeerDependencies:
- oxc-resolver
rolldown@1.0.0-beta.51(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2):
dependencies:
'@oxc-project/types': 0.98.0
'@rolldown/pluginutils': 1.0.0-beta.51
optionalDependencies:
'@rolldown/binding-android-arm64': 1.0.0-beta.51
'@rolldown/binding-darwin-arm64': 1.0.0-beta.51
'@rolldown/binding-darwin-x64': 1.0.0-beta.51
'@rolldown/binding-freebsd-x64': 1.0.0-beta.51
'@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.51
'@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.51
'@rolldown/binding-linux-arm64-musl': 1.0.0-beta.51
'@rolldown/binding-linux-x64-gnu': 1.0.0-beta.51
'@rolldown/binding-linux-x64-musl': 1.0.0-beta.51
'@rolldown/binding-openharmony-arm64': 1.0.0-beta.51
'@rolldown/binding-wasm32-wasi': 1.0.0-beta.51(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)
'@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.51
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.51
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.51
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
rolldown@1.0.0-rc.15:
dependencies:
'@oxc-project/types': 0.124.0
@@ -33041,6 +32855,18 @@ snapshots:
unpipe@1.0.0: {}
unplugin-basemove@0.0.1(vite@6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
dependencies:
s3mini: 0.9.4
unplugin: 3.0.0
vite: 6.4.2(@types/node@25.6.0)(jiti@2.6.1)(less@4.6.4)(lightningcss@1.32.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
unplugin-basemove@0.0.1(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
dependencies:
s3mini: 0.9.4
unplugin: 3.0.0
vite: 8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
unplugin-combine@2.3.0(esbuild@0.27.2)(rolldown@1.0.0-rc.16)(rollup@2.80.0)(unplugin@2.3.11)(vite@8.0.8(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.6.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)):
optionalDependencies:
esbuild: 0.27.2
-1
View File
@@ -15,7 +15,6 @@ export default defineConfig({
'packages/server-runtime',
'packages/server-sdk',
'packages/stage-shared',
'packages/vite-plugin-warpdrive',
],
},
})