mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-09 06:03:01 -05:00
Frontend plugins Support [2/10]: Plugin service worker (#5784)
* Plugin service worker
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -26,6 +26,8 @@ packages/desktop-electron/build
|
||||
packages/desktop-electron/.electron-symbols
|
||||
packages/desktop-electron/dist
|
||||
packages/desktop-electron/loot-core
|
||||
packages/desktop-client/service-worker
|
||||
packages/plugins-service/dist
|
||||
bundle.desktop.js
|
||||
bundle.desktop.js.map
|
||||
bundle.mobile.js
|
||||
|
||||
@@ -16,6 +16,7 @@ packages/desktop-client/bin/remove-untranslated-languages
|
||||
|
||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
yarn workspace plugins-service build
|
||||
yarn workspace loot-core build:browser
|
||||
yarn workspace @actual-app/web build:browser
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ packages/desktop-client/bin/remove-untranslated-languages
|
||||
|
||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||
|
||||
yarn workspace plugins-service build
|
||||
yarn workspace loot-core build:node
|
||||
yarn workspace @actual-app/web build --mode=desktop # electron specific build
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ export default pluginTypescript.config(
|
||||
'packages/component-library/src/icons/**/*',
|
||||
'packages/desktop-client/bundle.browser.js',
|
||||
'packages/desktop-client/build/',
|
||||
'packages/desktop-client/service-worker/*',
|
||||
'packages/desktop-client/build-electron/',
|
||||
'packages/desktop-client/build-stats/',
|
||||
'packages/desktop-client/public/kcab/',
|
||||
@@ -98,6 +99,7 @@ export default pluginTypescript.config(
|
||||
'packages/loot-core/**/lib-dist/*',
|
||||
'packages/loot-core/**/proto/*',
|
||||
'packages/sync-server/build/',
|
||||
'packages/plugins-service/dist/',
|
||||
'.yarn/*',
|
||||
'.github/*',
|
||||
],
|
||||
|
||||
@@ -23,18 +23,20 @@
|
||||
"start:server-monitor": "yarn workspace @actual-app/sync-server start-monitor",
|
||||
"start:server-dev": "NODE_ENV=development BROWSER_OPEN=localhost:5006 yarn npm-run-all --parallel 'start:server-monitor' 'start'",
|
||||
"start:desktop": "yarn desktop-dependencies && npm-run-all --parallel 'start:desktop-*'",
|
||||
"desktop-dependencies": "npm-run-all --parallel rebuild-electron build:browser-backend",
|
||||
"desktop-dependencies": "npm-run-all --parallel rebuild-electron build:browser-backend build:plugins-service",
|
||||
"start:desktop-node": "yarn workspace loot-core watch:node",
|
||||
"start:desktop-client": "yarn workspace @actual-app/web watch",
|
||||
"start:desktop-server-client": "yarn workspace @actual-app/web build:browser",
|
||||
"start:desktop-electron": "yarn workspace desktop-electron watch",
|
||||
"start:browser": "npm-run-all --parallel 'start:browser-*'",
|
||||
"start:browser": "yarn workspace plugins-service build-dev && npm-run-all --parallel 'start:browser-*'",
|
||||
"start:service-plugins": "yarn workspace plugins-service watch",
|
||||
"start:browser-backend": "yarn workspace loot-core watch:browser",
|
||||
"start:browser-frontend": "yarn workspace @actual-app/web start:browser",
|
||||
"build:browser-backend": "yarn workspace loot-core build:browser",
|
||||
"build:server": "yarn build:browser && yarn workspace @actual-app/sync-server build",
|
||||
"build:browser": "./bin/package-browser",
|
||||
"build:desktop": "./bin/package-electron",
|
||||
"build:plugins-service": "yarn workspace plugins-service build",
|
||||
"build:api": "yarn workspace @actual-app/api build",
|
||||
"generate:i18n": "yarn workspace @actual-app/web generate:i18n",
|
||||
"generate:release-notes": "ts-node ./bin/release-note-generator.ts",
|
||||
|
||||
3
packages/desktop-client/.gitignore
vendored
3
packages/desktop-client/.gitignore
vendored
@@ -14,6 +14,9 @@ build-electron
|
||||
build-stats
|
||||
stats.json
|
||||
|
||||
# generated service worker
|
||||
service-worker/
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env
|
||||
|
||||
@@ -9,6 +9,7 @@ rm -fr build
|
||||
|
||||
export IS_GENERIC_BROWSER=1
|
||||
export REACT_APP_BACKEND_WORKER_HASH=`ls "$ROOT"/../public/kcab/kcab.worker.*.js | sed 's/.*kcab\.worker\.\(.*\)\.js/\1/'`
|
||||
export REACT_APP_PLUGIN_SERVICE_WORKER_HASH=`ls "$ROOT"/../service-worker/plugin-sw.*.js | sed 's/.*plugin-sw\.\(.*\)\.js/\1/'`
|
||||
|
||||
yarn build
|
||||
|
||||
|
||||
@@ -6,5 +6,6 @@ cd "$ROOT/.."
|
||||
export IS_GENERIC_BROWSER=1
|
||||
export PORT=3001
|
||||
export REACT_APP_BACKEND_WORKER_HASH="dev"
|
||||
export REACT_APP_PLUGIN_SERVICE_WORKER_HASH="dev"
|
||||
|
||||
yarn start
|
||||
|
||||
18
packages/desktop-client/tsconfig.service-worker.json
Normal file
18
packages/desktop-client/tsconfig.service-worker.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false,
|
||||
"outDir": "./service-worker",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022", "WebWorker", "DOM", "DOM.Iterable"],
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"types": ["vite/client"]
|
||||
},
|
||||
"include": ["src/plugin-service-worker.ts"],
|
||||
"exclude": ["**/*.test.ts", "**/*.spec.ts"]
|
||||
}
|
||||
@@ -26,6 +26,15 @@ const addWatchers = (): Plugin => ({
|
||||
},
|
||||
});
|
||||
|
||||
// Get service worker filename from environment variable
|
||||
function getServiceWorkerFilename(): string {
|
||||
const hash = process.env.REACT_APP_PLUGIN_SERVICE_WORKER_HASH;
|
||||
if (hash) {
|
||||
return `plugin-sw.${hash}.js`;
|
||||
}
|
||||
return 'plugin-sw.js'; // fallback
|
||||
}
|
||||
|
||||
// Inject build shims using the inject plugin
|
||||
const injectShims = (): Plugin[] => {
|
||||
const buildShims = path.resolve('./src/build-shims.js');
|
||||
@@ -159,18 +168,41 @@ export default defineConfig(async ({ mode }) => {
|
||||
? undefined
|
||||
: VitePWA({
|
||||
registerType: 'prompt',
|
||||
strategies: 'injectManifest',
|
||||
srcDir: 'service-worker',
|
||||
filename: getServiceWorkerFilename(),
|
||||
manifest: {
|
||||
name: 'Actual',
|
||||
short_name: 'Actual',
|
||||
description: 'A local-first personal finance tool',
|
||||
theme_color: '#8812E1',
|
||||
background_color: '#8812E1',
|
||||
display: 'standalone',
|
||||
start_url: './',
|
||||
},
|
||||
injectManifest: {
|
||||
maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // 10MB
|
||||
swSrc: `service-worker/${getServiceWorkerFilename()}`,
|
||||
},
|
||||
devOptions: {
|
||||
enabled: true, // We need service worker in dev mode to work with plugins
|
||||
type: 'module',
|
||||
},
|
||||
workbox: {
|
||||
globPatterns: [
|
||||
'**/*.{js,css,html,txt,wasm,sql,sqlite,ico,png,woff2,webmanifest}',
|
||||
],
|
||||
ignoreURLParametersMatching: [/^v$/],
|
||||
navigateFallback: '/index.html',
|
||||
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB
|
||||
maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // 10MB
|
||||
navigateFallbackDenylist: [
|
||||
/^\/account\/.*$/,
|
||||
/^\/admin\/.*$/,
|
||||
/^\/secret\/.*$/,
|
||||
/^\/openid\/.*$/,
|
||||
/^\/plugins\/.*$/,
|
||||
/^\/kcab\/.*$/,
|
||||
/^\/plugin-data\/.*$/,
|
||||
],
|
||||
},
|
||||
}),
|
||||
|
||||
28
packages/plugins-service/bin/build-service-worker
Executable file
28
packages/plugins-service/bin/build-service-worker
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
cd `dirname "$0"`
|
||||
ROOT=`pwd -P`
|
||||
VITE_ARGS=""
|
||||
|
||||
DESKTOP_DIR="$ROOT"/../../desktop-client
|
||||
SERVICE_WORKER_DIR="$DESKTOP_DIR"/service-worker
|
||||
mkdir -p "$SERVICE_WORKER_DIR"
|
||||
|
||||
# Clean out previous build files
|
||||
rm -f ../dist/*
|
||||
rm -rf "$DESKTOP_DIR"/service-worker/*
|
||||
|
||||
if [ $NODE_ENV == 'development' ]; then
|
||||
if [ "$OSTYPE" == "msys" ]; then
|
||||
# Ensure symlinks are created as native Windows symlinks.
|
||||
export MSYS=winsymlinks:nativestrict
|
||||
fi
|
||||
ln -snf "$ROOT"/../dist "$DESKTOP_DIR"/service-worker
|
||||
fi
|
||||
|
||||
yarn vite build --config ../vite.config.ts --mode $NODE_ENV $VITE_ARGS
|
||||
|
||||
if [ $NODE_ENV == 'production' ]; then
|
||||
# In production, just copy the built files
|
||||
cp -r ../dist/* "$DESKTOP_DIR"/service-worker
|
||||
fi
|
||||
22
packages/plugins-service/package.json
Normal file
22
packages/plugins-service/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "plugins-service",
|
||||
"version": "0.0.1",
|
||||
"description": "Plugin service worker for Actual",
|
||||
"main": "plugin-sw.js",
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_ENV=production ./bin/build-service-worker",
|
||||
"build-dev": "cross-env NODE_ENV=development ./bin/build-service-worker",
|
||||
"watch": "cross-env NODE_ENV=development ./bin/build-service-worker --watch"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"workbox-precaching": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.17.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"typescript": "^5.9.2",
|
||||
"vite": "^6.3.6"
|
||||
}
|
||||
}
|
||||
159
packages/plugins-service/src/plugin-service-worker.ts
Normal file
159
packages/plugins-service/src/plugin-service-worker.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
/// <reference lib="WebWorker" />
|
||||
import { precacheAndRoute } from 'workbox-precaching';
|
||||
|
||||
// Service Worker Global Types
|
||||
declare const self: ServiceWorkerGlobalScope & {
|
||||
__WB_DISABLE_DEV_LOGS: boolean;
|
||||
};
|
||||
|
||||
type PluginFile = {
|
||||
name: string;
|
||||
content: string;
|
||||
};
|
||||
|
||||
type PluginMessage = {
|
||||
type: string;
|
||||
eventData?: {
|
||||
pluginUrl: string;
|
||||
};
|
||||
};
|
||||
|
||||
self.__WB_DISABLE_DEV_LOGS = true;
|
||||
|
||||
// Injected by VitePWA
|
||||
precacheAndRoute(self.__WB_MANIFEST);
|
||||
|
||||
const fileList = new Map<string, string>();
|
||||
|
||||
// Log installation event
|
||||
self.addEventListener('install', (_event: ExtendableEvent) => {
|
||||
console.log('Plugins Worker installing...');
|
||||
self.skipWaiting(); // Forces activation immediately
|
||||
});
|
||||
|
||||
// Log activation event
|
||||
self.addEventListener('activate', (_event: ExtendableEvent) => {
|
||||
self.clients.claim();
|
||||
|
||||
self.clients.matchAll().then(clients => {
|
||||
clients.forEach(client => {
|
||||
client.postMessage({
|
||||
type: 'service-worker-ready',
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
self.addEventListener('message', (event: ExtendableMessageEvent) => {
|
||||
if (event.data && (event.data as PluginMessage).type === 'SKIP_WAITING') {
|
||||
self.skipWaiting();
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', (event: FetchEvent) => {
|
||||
const url = new URL(event.request.url);
|
||||
const pathSegments = url.pathname.split('/').filter(Boolean); // Split and remove empty segments
|
||||
|
||||
const pluginsIndex = pathSegments.indexOf('plugin-data');
|
||||
const slugIndex = pluginsIndex + 1;
|
||||
if (pluginsIndex !== -1 && pathSegments[slugIndex]) {
|
||||
const slug = pathSegments[slugIndex];
|
||||
const fileName =
|
||||
pathSegments.length > slugIndex + 1
|
||||
? pathSegments[slugIndex + 1].split('?')[0]
|
||||
: '';
|
||||
event.respondWith(handlePlugin(slug, fileName.replace('?import', '')));
|
||||
}
|
||||
});
|
||||
|
||||
async function handlePlugin(slug: string, fileName: string): Promise<Response> {
|
||||
for (const key of fileList.keys()) {
|
||||
if (key.startsWith(`${slug}/`)) {
|
||||
if (key.endsWith(`/${fileName}`)) {
|
||||
const content = fileList.get(key);
|
||||
const contentType = getContentType(fileName);
|
||||
return new Response(content, {
|
||||
headers: { 'Content-Type': contentType },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const clientsList = await self.clients.matchAll();
|
||||
if (clientsList.length === 0) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: 'No active clients to process' }),
|
||||
{
|
||||
status: 404,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const client = clientsList[0];
|
||||
return new Promise<Response>(resolve => {
|
||||
const channel = new MessageChannel();
|
||||
channel.port1.onmessage = (messageEvent: MessageEvent<PluginFile[]>) => {
|
||||
const responseData = messageEvent.data as PluginFile[];
|
||||
|
||||
if (responseData && Array.isArray(responseData)) {
|
||||
responseData.forEach(({ name, content }) => {
|
||||
fileList.set(`${slug}/${encodeURIComponent(name)}`, content);
|
||||
});
|
||||
}
|
||||
|
||||
const fileToCheck = fileName.length > 0 ? fileName : 'mf-manifest.json';
|
||||
|
||||
if (fileList.has(`${slug}/${fileToCheck}`)) {
|
||||
let content = fileList.get(`${slug}/${fileToCheck}`)!;
|
||||
const contentType = getContentType(fileToCheck);
|
||||
const headers: Record<string, string> = { 'Content-Type': contentType };
|
||||
|
||||
if (fileToCheck === 'mf-manifest.json') {
|
||||
try {
|
||||
const manifest = JSON.parse(content);
|
||||
if (manifest.metaData?.publicPath) {
|
||||
manifest.metaData.publicPath = `/plugin-data/${slug}/`;
|
||||
content = JSON.stringify(manifest);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'Failed to parse manifest for publicPath rewrite:',
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
headers['Cache-Control'] = 'no-cache, no-store, must-revalidate';
|
||||
headers['Pragma'] = 'no-cache';
|
||||
headers['Expires'] = '0';
|
||||
}
|
||||
|
||||
resolve(new Response(content, { headers }));
|
||||
} else {
|
||||
resolve(new Response('File not found', { status: 404 }));
|
||||
}
|
||||
};
|
||||
|
||||
client.postMessage(
|
||||
{ type: 'plugin-files', eventData: { pluginUrl: slug } },
|
||||
[channel.port2],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getContentType(fileName: string): string {
|
||||
const extension = fileName.split('.').pop()?.toLowerCase() || '';
|
||||
const mimeTypes: Record<string, string> = {
|
||||
html: 'text/html',
|
||||
css: 'text/css',
|
||||
js: 'application/javascript',
|
||||
json: 'application/json',
|
||||
png: 'image/png',
|
||||
jpg: 'image/jpeg',
|
||||
jpeg: 'image/jpeg',
|
||||
gif: 'image/gif',
|
||||
svg: 'image/svg+xml',
|
||||
};
|
||||
return mimeTypes[extension] || 'application/octet-stream';
|
||||
}
|
||||
17
packages/plugins-service/tsconfig.json
Normal file
17
packages/plugins-service/tsconfig.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022", "WebWorker", "DOM", "DOM.Iterable"],
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"types": ["vite/client"],
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
40
packages/plugins-service/vite.config.ts
Normal file
40
packages/plugins-service/vite.config.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
// @ts-strict-ignore
|
||||
import path from 'path';
|
||||
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default defineConfig(({ mode }) => {
|
||||
const isDev = mode === 'development';
|
||||
const outDir = path.resolve(__dirname, 'dist');
|
||||
|
||||
return {
|
||||
mode,
|
||||
build: {
|
||||
target: 'es2020',
|
||||
outDir,
|
||||
emptyOutDir: true,
|
||||
lib: {
|
||||
entry: path.resolve(__dirname, 'src/plugin-service-worker.ts'),
|
||||
name: 'plugin_sw',
|
||||
formats: ['iife'],
|
||||
fileName: () => (isDev ? 'plugin-sw.dev.js' : 'plugin-sw.[hash].js'),
|
||||
},
|
||||
sourcemap: true,
|
||||
minify: isDev ? false : 'terser',
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_debugger: false,
|
||||
},
|
||||
mangle: false,
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.ts', '.json'],
|
||||
},
|
||||
define: {
|
||||
'process.env': '{}',
|
||||
'process.env.IS_DEV': JSON.stringify(isDev),
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -16,6 +16,7 @@ COPY packages/desktop-electron/package.json packages/desktop-electron/package.js
|
||||
COPY packages/eslint-plugin-actual/package.json packages/eslint-plugin-actual/package.json
|
||||
COPY packages/loot-core/package.json packages/loot-core/package.json
|
||||
COPY packages/sync-server/package.json packages/sync-server/package.json
|
||||
COPY packages/plugins-service/package.json packages/plugins-service/package.json
|
||||
|
||||
# Avoiding memory issues with ARMv7
|
||||
RUN if [ "$(uname -m)" = "armv7l" ]; then yarn config set taskPoolConcurrency 2; yarn config set networkConcurrency 5; fi
|
||||
|
||||
@@ -16,6 +16,7 @@ COPY packages/desktop-electron/package.json packages/desktop-electron/package.js
|
||||
COPY packages/eslint-plugin-actual/package.json packages/eslint-plugin-actual/package.json
|
||||
COPY packages/loot-core/package.json packages/loot-core/package.json
|
||||
COPY packages/sync-server/package.json packages/sync-server/package.json
|
||||
COPY packages/plugins-service/package.json packages/plugins-service/package.json
|
||||
|
||||
# Avoiding memory issues with ARMv7
|
||||
RUN if [ "$(uname -m)" = "armv7l" ]; then yarn config set taskPoolConcurrency 2; yarn config set networkConcurrency 5; fi
|
||||
|
||||
@@ -16,6 +16,7 @@ COPY packages/desktop-electron/package.json packages/desktop-electron/package.js
|
||||
COPY packages/eslint-plugin-actual/package.json packages/eslint-plugin-actual/package.json
|
||||
COPY packages/loot-core/package.json packages/loot-core/package.json
|
||||
COPY packages/sync-server/package.json packages/sync-server/package.json
|
||||
COPY packages/plugins-service/package.json packages/plugins-service/package.json
|
||||
|
||||
COPY ./bin/package-browser ./bin/package-browser
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@
|
||||
"**/dist/*",
|
||||
"**/lib-dist/*",
|
||||
"**/test-results/*",
|
||||
"**/playwright-report/*"
|
||||
"**/playwright-report/*",
|
||||
"**/service-worker/*"
|
||||
],
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
|
||||
7
upcoming-release-notes/5784.md
Normal file
7
upcoming-release-notes/5784.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
category: Features
|
||||
authors: [lelemm]
|
||||
---
|
||||
|
||||
Introduce a Workbox-based service worker for enhanced plugin support and caching functionality.
|
||||
|
||||
91
yarn.lock
91
yarn.lock
@@ -6717,7 +6717,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^22.18.8":
|
||||
"@types/node@npm:^22.17.0, @types/node@npm:^22.18.8":
|
||||
version: 22.18.8
|
||||
resolution: "@types/node@npm:22.18.8"
|
||||
dependencies:
|
||||
@@ -9479,6 +9479,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-env@npm:^7.0.3":
|
||||
version: 7.0.3
|
||||
resolution: "cross-env@npm:7.0.3"
|
||||
dependencies:
|
||||
cross-spawn: "npm:^7.0.1"
|
||||
bin:
|
||||
cross-env: src/bin/cross-env.js
|
||||
cross-env-shell: src/bin/cross-env-shell.js
|
||||
checksum: 10/e99911f0d31c20e990fd92d6fd001f4b01668a303221227cc5cb42ed155f086351b1b3bd2699b200e527ab13011b032801f8ce638e6f09f854bdf744095e604c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-spawn@npm:^6.0.5":
|
||||
version: 6.0.5
|
||||
resolution: "cross-spawn@npm:6.0.5"
|
||||
@@ -16670,6 +16682,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"plugins-service@workspace:packages/plugins-service":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "plugins-service@workspace:packages/plugins-service"
|
||||
dependencies:
|
||||
"@types/node": "npm:^22.17.0"
|
||||
cross-env: "npm:^7.0.3"
|
||||
typescript: "npm:^5.9.2"
|
||||
vite: "npm:^6.3.6"
|
||||
workbox-precaching: "npm:^7.0.0"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"possible-typed-array-names@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "possible-typed-array-names@npm:1.0.0"
|
||||
@@ -16677,7 +16701,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"postcss@npm:^8.5.5, postcss@npm:^8.5.6":
|
||||
"postcss@npm:^8.5.3, postcss@npm:^8.5.5, postcss@npm:^8.5.6":
|
||||
version: 8.5.6
|
||||
resolution: "postcss@npm:8.5.6"
|
||||
dependencies:
|
||||
@@ -19661,7 +19685,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15":
|
||||
"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.13, tinyglobby@npm:^0.2.15":
|
||||
version: 0.2.15
|
||||
resolution: "tinyglobby@npm:0.2.15"
|
||||
dependencies:
|
||||
@@ -20144,7 +20168,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:^5.9.3":
|
||||
"typescript@npm:^5.9.2, typescript@npm:^5.9.3":
|
||||
version: 5.9.3
|
||||
resolution: "typescript@npm:5.9.3"
|
||||
bin:
|
||||
@@ -20174,7 +20198,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@npm%3A^5.9.3#optional!builtin<compat/typescript>":
|
||||
"typescript@patch:typescript@npm%3A^5.9.2#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.9.3#optional!builtin<compat/typescript>":
|
||||
version: 5.9.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"
|
||||
bin:
|
||||
@@ -20940,6 +20964,61 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite@npm:^6.3.6":
|
||||
version: 6.3.6
|
||||
resolution: "vite@npm:6.3.6"
|
||||
dependencies:
|
||||
esbuild: "npm:^0.25.0"
|
||||
fdir: "npm:^6.4.4"
|
||||
fsevents: "npm:~2.3.3"
|
||||
picomatch: "npm:^4.0.2"
|
||||
postcss: "npm:^8.5.3"
|
||||
rollup: "npm:^4.34.9"
|
||||
tinyglobby: "npm:^0.2.13"
|
||||
peerDependencies:
|
||||
"@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0
|
||||
jiti: ">=1.21.0"
|
||||
less: "*"
|
||||
lightningcss: ^1.21.0
|
||||
sass: "*"
|
||||
sass-embedded: "*"
|
||||
stylus: "*"
|
||||
sugarss: "*"
|
||||
terser: ^5.16.0
|
||||
tsx: ^4.8.1
|
||||
yaml: ^2.4.2
|
||||
dependenciesMeta:
|
||||
fsevents:
|
||||
optional: true
|
||||
peerDependenciesMeta:
|
||||
"@types/node":
|
||||
optional: true
|
||||
jiti:
|
||||
optional: true
|
||||
less:
|
||||
optional: true
|
||||
lightningcss:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
sass-embedded:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
sugarss:
|
||||
optional: true
|
||||
terser:
|
||||
optional: true
|
||||
tsx:
|
||||
optional: true
|
||||
yaml:
|
||||
optional: true
|
||||
bin:
|
||||
vite: bin/vite.js
|
||||
checksum: 10/8b8b6fe12318ca457396bf2053df7056cf4810f1d4a43b36b6afe59860e32b749c0685a290fe8a973b0d3da179ceec4c30cebbd3c91d0c47fbcf6436b17bdeef
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite@npm:^7.1.9":
|
||||
version: 7.1.9
|
||||
resolution: "vite@npm:7.1.9"
|
||||
@@ -21460,7 +21539,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-precaching@npm:7.3.0":
|
||||
"workbox-precaching@npm:7.3.0, workbox-precaching@npm:^7.0.0":
|
||||
version: 7.3.0
|
||||
resolution: "workbox-precaching@npm:7.3.0"
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user