🤖 feat: migrate static S3 storage to Cloudflare R2 and add multi-locale SSG support (#70)
## Summary - **Cloudflare R2 Migration**: - Migrated `static.ermnvldmr.com` asset storage to Cloudflare R2 bucket `com-ermnvldmr-static` (location `WEUR`). - Added support for `COM_ERMNVLDMR_STATIC_PUBLIC_URL` fallback in `@ermnvldmr/cli` to properly format public asset URLs for non-dotted bucket names. - Relocated public CA cert to `/dev/ssl/certs/ErmnvldmrDevelopmentRootCA.pem` and updated `REMOTE_ROOT_CA_URL` references in `@ermnvldmr/rsbuild-config` and `ensure-dev-certs.mjs`. - Configured R2 CORS policies using wildcards (`https://*.ermnvldmr.com`, `https://ermnvldmr.com`, `https://localhost.ermnvldmr.com*`, `http://localhost*`, `https://direct.yandex.ru`, `https://*.direct.yandex.ru`, `https://localhost.yandex.ru*`). - Enforced minimum TLS 1.2 on zone `ermnvldmr.com`. - Updated encrypted `.env.dev` and GitHub secrets in both `deytenit/ermnvldmr.com` and `deytenit/apex.ermnvldmr.com`. - **Multi-locale SSG Support**: - Added `NormalModuleReplacementPlugin` to SSR runner in `@ermnvldmr/ssg` for automatic `.en.mdx` -> `.${locale}.mdx` substitution during Russian builds. - Added page metadata extraction (`getPageOptions`) in `@ermnvldmr/ssg` for pre-rendered `<title>` and `<meta name="description">` tags. - Added unit test suite for `createPage` and updated `services/www` build scripts (`build:all`, `build:en`, `build:ru`, `dev:en`, `dev:ru`).
This commit is contained in:
1 parent
649d6c3fd0
commit
9200529bf0
16 files changed
+442
-368
No files matched your search
@@ -12,10 +12,11 @@ DOTENV_PUBLIC_KEY_DEV="02a9d0f6522086b04ac7763e008a6ad0273c58258715e613c977fd6c8
|
||||
DOTENV_PUBLIC_KEY="02a9d0f6522086b04ac7763e008a6ad0273c58258715e613c977fd6c82a2030d92"
|
||||
|
||||
# .env
|
||||
COM_ERMNVLDMR_STATIC_S3_BUCKET="encrypted:BL1vJLB9uPSvsUvrJah4UegRU8uPdFjE7sya+Fae3rwOmVzWsK5+TP4z4YzigTAuwit4FANvANvhRV46se+ZgprYplU8Cw1tZ5mHKO4rWAjif2sJCnsGXUKp8GZ2J7PrMH35MY0YrXX4NVqe18b2NEv2B9K7"
|
||||
COM_ERMNVLDMR_STATIC_S3_REGION="encrypted:BAj3iuo7tWWNR2V4yQ+LHnFCB4JcZp7TTfUtvv+2FPntNhwc/fV95IeFWz6S0z6aPRkDG+UQzPXNwdMz7y8ZbTHbduDDrgydHu1fST1NfQd2s1Bbpf+yJTG7dPBSc5RSNKZkkpB4v55qg/UC"
|
||||
COM_ERMNVLDMR_STATIC_S3_ENDPOINT_URL="encrypted:BNkQrgsrxtz544vuJbgwWUh5cPjHG5wbmHNcxTUWrzbFJJsdncaAitviCvIrS7Q41w+FiWkssv3D05Tu8Inn2P62E6G3PU4gNxO2oLdmGEdrzUqB/xvxOvLvos42j54QOZf7lOqMPKH6SL2/rheCAo10gSCicCqkfh4xsCAbYpyL"
|
||||
COM_ERMNVLDMR_STATIC_AWS_ACCESS_KEY_ID="encrypted:BCsp8p4bp3cB+9grxHo634isRUaFGU3MOc1lr8ClSFRYLjqjqukyrbJCTZWV2Xdo8iQ33EylmbzUltbwzTWMQcjJSvIskesVLyV93q60o/Mu9L9jg/apwHuBgHv4zVuHstJ0zkHWgapbNTIlWD3RCm0ujeX/H1gBH3U="
|
||||
COM_ERMNVLDMR_STATIC_AWS_SECRET_ACCESS_KEY="encrypted:BM7aPliOyiPrqFPZMfqpn534Nu+Y0Nbh/YRoxv2KY6XAi2dNO0LSEf97DqSUQYdsnu9iibZmVNktF2K/D6mtHr9+gumF6KsmaLH65KE7c9ly7NdFQHL9I26wxRq1Sr3Zgrfs954J6oURSlBRKqJFdcTsBltuuupGuqJHyLS9+DE0jD+bl0Qg0lA="
|
||||
COM_ERMNVLDMR_STATIC_S3_BUCKET="encrypted:BE65d5I9m1jrHGVNKDmfGL3Cjb7LjhB4tVWyNzSPU1Zu5Y00+R8NXgqSBrzBnXVj3vVinibjihVt3fStegyiqI52GtSycX1NlFSVJlRFWadUJ6SVK+SYfB7sFKSJ2jKGfwRaXKMzaKCdPWY+ni685oPXU9Rp"
|
||||
COM_ERMNVLDMR_STATIC_S3_REGION="encrypted:BPQ2+ms76A+PLFUeKL1Cnz8bdOcsJou03e8AyGwzdhozpcAwhP5yWXSqhTK8ZccAvmfjJcM4NK+x2a2r4g0ALd/UaQDa9xy2eZ6QnXwkoHXu2ce+F86/HuFnzX0qWqYTWi4q+N4="
|
||||
COM_ERMNVLDMR_STATIC_S3_ENDPOINT_URL="encrypted:BCcK2ih1QrABMImpUj31KIQYlbp9zhnafzrXINAwvyCaCjbOst6UGnhhi5M3LtQ+Fhgpx52ZKGjmke1oVxnvU6BBGz/lAbSD5euhHNbJ6EIoSqc25XpcmgucIQGx1cfiJxsL4sDR95FyR3fNaS9KGr005DwQaIRKGg86gALUCPhaLekq/Sd6Nn+TDoqmigLJPozdxp33AFpmWF+EwayYae2u"
|
||||
COM_ERMNVLDMR_STATIC_AWS_ACCESS_KEY_ID="encrypted:BPaBvzNo1eH3Z2ro+NFq4zLi4krZQT48h20r0etBfVFLDNS01gh5Uosy70Ip29rC8sa1JoP4Q8isJ2Xz0pr5Vxxa62vVFOJ9wJ6LkXbYF2bUm+UNyjfsIztJsMyiVZfPEEPEEKcniXZ3faqePwgLwCZSTa/Qry6znNmMV5FshSsP"
|
||||
COM_ERMNVLDMR_STATIC_AWS_SECRET_ACCESS_KEY="encrypted:BFiOxOo/TNvSIMOjyeOswLcl+9AVdqp4axW+I46c1CL0ckSucQS+7CLpO8fNfakmW2bSibqru+xfWUbQT7FDH1YB3CPXUc0qPm1PsG0FiLixDefQuDrC/JHuA0Z3/dOAkn/e94BBuPtyJXxcLRP1v517MijPa0MuNqhI9BS3jFHKjWivqc9AVPs2ybglo14b/nEO1GqlM0TYflPoDhHoWjM="
|
||||
SOPS_AGE_KEY="encrypted:BKiJVxKYhiadu0kNCw8wVLYdaEWZreAVu2PaujxhvcXeCowCGjivEuQD/uhduAy/CwwDWyQkgQJ2FJMEKA47e7QDjS9TMdPCXO19/teR7LThgqTf6AbSM3sebln5zalgyplay4A/7cVytPXuOvVkaYyoh9CgzTVsPJKXRq5yMaDEx/9/91Yo8zUMF3z1vq3/preI5baK4/1xXewR3OwfZqnNGyd7LXkdqyT5"
|
||||
COM_ERMNVLDMR_DEV_ROOT_CA_KEY="encrypted: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"
|
||||
COM_ERMNVLDMR_STATIC_PUBLIC_URL="encrypted:BEZbNy1WbNKhgUWmKO648nvuVNyMNXrMnq64WkjsScTOcE/HFtMX3nQktbIvEYiTSNHvoceUeW10E9i4n+C5ZEHKIBi9VUk3nuqVIcwAr6xTfqKjM1cJlRNKFQzwhHbBTYcImLoxFvM56KU4L/9Ei/XuQ/QRz0KTabhvGMM="
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.STATIC_AWS_ACCESS_KEY_ID || secrets.COM_ERMNVLDMR_STATIC_AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.STATIC_AWS_SECRET_ACCESS_KEY || secrets.COM_ERMNVLDMR_STATIC_AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_DEFAULT_REGION: ${{ secrets.STATIC_AWS_REGION || secrets.COM_ERMNVLDMR_STATIC_S3_REGION || 'ru-central1' }}
|
||||
AWS_DEFAULT_REGION: ${{ secrets.STATIC_AWS_REGION || secrets.COM_ERMNVLDMR_STATIC_S3_REGION || 'auto' }}
|
||||
S3_ENDPOINT: ${{ secrets.STATIC_S3_ENDPOINT_URL || secrets.COM_ERMNVLDMR_STATIC_S3_ENDPOINT_URL }}
|
||||
S3_BUCKET: ${{ secrets.STATIC_S3_BUCKET || secrets.COM_ERMNVLDMR_STATIC_S3_BUCKET }}
|
||||
IMAGE_NAME: ${{ needs.build-image.outputs.image_name }}
|
||||
|
||||
@@ -162,7 +162,7 @@ export function loadDevRootCaKey(workspaceRoot = findWorkspaceRoot()) {
|
||||
* Remote public URL for the Ermnvldmr development root CA certificate.
|
||||
*/
|
||||
export const REMOTE_ROOT_CA_URL =
|
||||
'https://static.ermnvldmr.com/ssl/certs/ErmnvldmrDevelopmentRootCA.pem';
|
||||
'https://static.ermnvldmr.com/dev/ssl/certs/ErmnvldmrDevelopmentRootCA.pem';
|
||||
|
||||
/**
|
||||
* Ensures valid development certificates exist for localhost.ermnvldmr.com.
|
||||
|
||||
@@ -376,4 +376,33 @@ describe('runS3Sync', () => {
|
||||
const content = fs.readFileSync(srcPath, 'utf-8');
|
||||
expect(content).toContain('https://cdn.example.com/www/img.webp');
|
||||
});
|
||||
|
||||
it('should fallback to COM_ERMNVLDMR_STATIC_PUBLIC_URL when publicUrl is not explicitly configured', async () => {
|
||||
process.env.COM_ERMNVLDMR_STATIC_PUBLIC_URL = 'https://static.ermnvldmr.com';
|
||||
|
||||
const staticDir = path.join(tempDir, 'static');
|
||||
fs.mkdirSync(staticDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(staticDir, 'asset.png'), 'png-content');
|
||||
|
||||
const srcDir = path.join(tempDir, 'src');
|
||||
fs.mkdirSync(srcDir, { recursive: true });
|
||||
const srcPath = path.join(srcDir, 'index.ts');
|
||||
fs.writeFileSync(srcPath, 'const img = "/static/asset.png";');
|
||||
|
||||
const cmd: S3SyncCommandConfig = {
|
||||
name: 'sync',
|
||||
description: 'desc',
|
||||
bucket: 'com-ermnvldmr-static',
|
||||
targetPrefix: 'www',
|
||||
sourceDir: './static',
|
||||
type: 's3-sync',
|
||||
};
|
||||
|
||||
await runS3Sync(cmd, {});
|
||||
|
||||
const content = fs.readFileSync(srcPath, 'utf-8');
|
||||
expect(content).toContain('https://static.ermnvldmr.com/www/asset.png');
|
||||
|
||||
delete process.env.COM_ERMNVLDMR_STATIC_PUBLIC_URL;
|
||||
});
|
||||
});
|
||||
@@ -53,6 +53,7 @@ export async function runS3Sync(
|
||||
const bucket = cmd.bucket ?? process.env.S3_BUCKET;
|
||||
const region = cmd.region ?? process.env.AWS_REGION ?? process.env.S3_REGION;
|
||||
const endpoint = cmd.endpoint ?? process.env.S3_ENDPOINT_URL ?? process.env.S3_ENDPOINT;
|
||||
const publicUrl = cmd.publicUrl ?? process.env.COM_ERMNVLDMR_STATIC_PUBLIC_URL ?? process.env.S3_PUBLIC_URL;
|
||||
const accessKey = cmd.accessKeyId ?? process.env.AWS_ACCESS_KEY_ID ?? process.env.S3_ACCESS_KEY_ID;
|
||||
const secretKey = cmd.secretAccessKey ?? process.env.AWS_SECRET_ACCESS_KEY ?? process.env.S3_SECRET_ACCESS_KEY;
|
||||
|
||||
@@ -149,8 +150,8 @@ export async function runS3Sync(
|
||||
*/
|
||||
const getS3Url = (finalName: string): string => {
|
||||
const normalizedKey = normalizeKey(cmd.targetPrefix, finalName);
|
||||
if (cmd.publicUrl) {
|
||||
const cleanPublicUrl = cmd.publicUrl.replace(/\/+$/, '');
|
||||
if (publicUrl) {
|
||||
const cleanPublicUrl = publicUrl.replace(/\/+$/, '');
|
||||
return `${cleanPublicUrl}/${normalizedKey}`;
|
||||
}
|
||||
if (bucket.includes('.')) {
|
||||
|
||||
@@ -214,7 +214,7 @@ export function loadDevRootCaKey(
|
||||
* Remote public URL for the Ermnvldmr development root CA certificate.
|
||||
*/
|
||||
export const REMOTE_ROOT_CA_URL =
|
||||
'https://static.ermnvldmr.com/ssl/certs/ErmnvldmrDevelopmentRootCA.pem';
|
||||
'https://static.ermnvldmr.com/dev/ssl/certs/ErmnvldmrDevelopmentRootCA.pem';
|
||||
|
||||
/**
|
||||
* Ensures that valid TLS development certificates exist for localhost.ermnvldmr.com.
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"build": "tsc",
|
||||
"lint": "eslint src --max-warnings 0",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "vitest run",
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -39,6 +40,8 @@
|
||||
"@rsbuild/core": "^1.7.3",
|
||||
"@rsbuild/plugin-react": "^1.1.1",
|
||||
"@rsbuild/plugin-type-check": "^1.1.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.1",
|
||||
"@types/node": "*",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.2",
|
||||
@@ -46,7 +49,8 @@
|
||||
"fast-glob": "^3.3.3",
|
||||
"jsdom": "^28.0.0",
|
||||
"rsbuild-plugin-dts": "^0.19.5",
|
||||
"typescript": "^5.8.2"
|
||||
"typescript": "^5.8.2",
|
||||
"vitest": "^4.1.11"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.1.0",
|
||||
|
||||
@@ -5,14 +5,36 @@ import path from 'node:path';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { getPageOptions } from '../core/createPage.js';
|
||||
|
||||
import type { RsbuildPlugin } from '@rsbuild/core';
|
||||
|
||||
/**
|
||||
* Escapes HTML special characters for safe injection into markup.
|
||||
*
|
||||
* @param str - The raw string to escape.
|
||||
* @returns The escaped HTML string.
|
||||
* @example
|
||||
* ```ts
|
||||
* escapeHtml('<script>alert("xss")</script>');
|
||||
* ```
|
||||
*/
|
||||
function escapeHtml(str: string): string {
|
||||
return str
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
const SSR_RUNNER_SCRIPT = `
|
||||
import { createRsbuild } from '@rsbuild/core';
|
||||
|
||||
async function main() {
|
||||
const entries = JSON.parse(process.argv[1]);
|
||||
const ssrDistPath = process.argv[2];
|
||||
const locale = process.argv[3] || process.env.LOCALE || 'en';
|
||||
|
||||
const plugins = [];
|
||||
try {
|
||||
@@ -31,10 +53,35 @@ async function main() {
|
||||
// MDX plugins not installed or needed in this service
|
||||
}
|
||||
|
||||
if (locale !== 'en') {
|
||||
plugins.push({
|
||||
name: 'ermnvldmr:ssr-locale-mdx-replacement',
|
||||
setup(api) {
|
||||
api.modifyRspackConfig((config, { rspack }) => {
|
||||
config.plugins = [
|
||||
...(config.plugins ?? []),
|
||||
new rspack.NormalModuleReplacementPlugin(
|
||||
/\\.en\\.mdx$/,
|
||||
(resource) => {
|
||||
resource.request = resource.request.replace(/\\.en\\.mdx$/, '.' + locale + '.mdx');
|
||||
}
|
||||
),
|
||||
];
|
||||
return config;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const ssrBuild = await createRsbuild({
|
||||
rsbuildConfig: {
|
||||
plugins,
|
||||
source: { entry: entries },
|
||||
source: {
|
||||
entry: entries,
|
||||
define: {
|
||||
'process.env.LOCALE': JSON.stringify(locale),
|
||||
},
|
||||
},
|
||||
output: {
|
||||
target: 'node',
|
||||
distPath: { root: ssrDistPath, js: '.' },
|
||||
@@ -119,11 +166,16 @@ export function ssgPlugin(): RsbuildPlugin {
|
||||
);
|
||||
const ssrDistPath = path.join(path.dirname(webDistPath), 'dist-ssr');
|
||||
|
||||
const locale = process.env.LOCALE ?? 'en';
|
||||
|
||||
console.log('[ssg-plugin] Building SSR bundles...');
|
||||
execFileSync(
|
||||
process.execPath,
|
||||
['--input-type=module', '-e', SSR_RUNNER_SCRIPT, JSON.stringify(entries), ssrDistPath],
|
||||
{ stdio: 'inherit' }
|
||||
['--input-type=module', '-e', SSR_RUNNER_SCRIPT, JSON.stringify(entries), ssrDistPath, locale],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
env: { ...process.env, LOCALE: locale },
|
||||
}
|
||||
);
|
||||
console.log('[ssg-plugin] SSR bundles ready.');
|
||||
|
||||
@@ -175,8 +227,10 @@ export function ssgPlugin(): RsbuildPlugin {
|
||||
React.createElement(React.StrictMode, null, React.createElement(Component))
|
||||
);
|
||||
|
||||
const pageOptions = getPageOptions(Component);
|
||||
|
||||
const source = await fs.readFile(webHtmlPath, 'utf8');
|
||||
const injected = source.replace(
|
||||
let injected = source.replace(
|
||||
/<div id="root"[^>]*>\s*<\/div>/,
|
||||
`<div id="root">${renderedHtml}</div>`
|
||||
);
|
||||
@@ -187,9 +241,29 @@ export function ssgPlugin(): RsbuildPlugin {
|
||||
);
|
||||
}
|
||||
|
||||
if (pageOptions?.title) {
|
||||
injected = injected.replace(
|
||||
/<title>[^<]*<\/title>/i,
|
||||
`<title>${escapeHtml(pageOptions.title)}</title>`
|
||||
);
|
||||
}
|
||||
|
||||
if (pageOptions?.description) {
|
||||
if (/<meta\s+[^>]*name=["']description["'][^>]*>/i.test(injected)) {
|
||||
injected = injected.replace(
|
||||
/<meta\s+[^>]*name=["']description["'][^>]*>/i,
|
||||
`<meta name="description" content="${escapeHtml(pageOptions.description)}">`
|
||||
);
|
||||
} else {
|
||||
injected = injected.replace(
|
||||
/<\/head>/i,
|
||||
` <meta name="description" content="${escapeHtml(pageOptions.description)}">\n</head>`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const processed = await critters.process(injected);
|
||||
|
||||
const locale = process.env.LOCALE ?? 'en';
|
||||
const localized = processed.replace(
|
||||
/<html([^>]*)\slang="[^"]*"/,
|
||||
`<html$1 lang="${locale}"`
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import React from 'react';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { createPage, getPageOptions } from './createPage';
|
||||
|
||||
describe('createPage and getPageOptions', () => {
|
||||
beforeEach(() => {
|
||||
document.title = 'Default Title';
|
||||
const existingMeta = document.querySelector('meta[name="description"]');
|
||||
if (existingMeta) {
|
||||
existingMeta.remove();
|
||||
}
|
||||
});
|
||||
|
||||
it('attaches metadata options to component and retrieves them via getPageOptions', () => {
|
||||
function SamplePage(): React.JSX.Element {
|
||||
return <div>Sample</div>;
|
||||
}
|
||||
|
||||
createPage(SamplePage, {
|
||||
title: 'Sample Title',
|
||||
description: 'Sample Description',
|
||||
});
|
||||
|
||||
const options = getPageOptions(SamplePage);
|
||||
expect(options).toEqual({
|
||||
title: 'Sample Title',
|
||||
description: 'Sample Description',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns undefined for entities without metadata options', () => {
|
||||
function PlainComponent(): React.JSX.Element {
|
||||
return <div>Plain</div>;
|
||||
}
|
||||
|
||||
expect(getPageOptions(PlainComponent)).toBeUndefined();
|
||||
expect(getPageOptions(null)).toBeUndefined();
|
||||
expect(getPageOptions(undefined)).toBeUndefined();
|
||||
expect(getPageOptions('string')).toBeUndefined();
|
||||
expect(getPageOptions(123)).toBeUndefined();
|
||||
expect(getPageOptions({})).toBeUndefined();
|
||||
});
|
||||
|
||||
it('updates document.title and creates meta description in DOM', () => {
|
||||
function MetaPage(): React.JSX.Element {
|
||||
return <div>Meta</div>;
|
||||
}
|
||||
|
||||
createPage(MetaPage, {
|
||||
title: 'Custom Title',
|
||||
description: 'Custom Description',
|
||||
});
|
||||
|
||||
expect(document.title).toBe('Custom Title');
|
||||
const meta = document.querySelector('meta[name="description"]');
|
||||
expect(meta).not.toBeNull();
|
||||
expect(meta?.getAttribute('content')).toBe('Custom Description');
|
||||
});
|
||||
|
||||
it('updates existing meta description if already present in DOM', () => {
|
||||
const existingMeta = document.createElement('meta');
|
||||
existingMeta.setAttribute('name', 'description');
|
||||
existingMeta.setAttribute('content', 'Old Description');
|
||||
document.head.appendChild(existingMeta);
|
||||
|
||||
function AnotherMetaPage(): React.JSX.Element {
|
||||
return <div>Another Meta</div>;
|
||||
}
|
||||
|
||||
createPage(AnotherMetaPage, {
|
||||
description: 'Updated Description',
|
||||
});
|
||||
|
||||
const meta = document.querySelector('meta[name="description"]');
|
||||
expect(meta?.getAttribute('content')).toBe('Updated Description');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,121 @@
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Options for page creation.
|
||||
*/
|
||||
export interface PageOptions {
|
||||
/** Document title to set on mount. */
|
||||
title?: string;
|
||||
/** Content of the meta description tag. */
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal interface representing a component with attached page options.
|
||||
*/
|
||||
interface HasPageOptions {
|
||||
/** The attached page options. */
|
||||
__pageOptions?: PageOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type predicate checking if a value is an object or function with attached page options.
|
||||
*
|
||||
* @param value - The value to inspect.
|
||||
* @returns True if value has __pageOptions.
|
||||
* @example
|
||||
* ```ts
|
||||
* if (hasPageOptions(Component)) {
|
||||
* console.log(Component.__pageOptions);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
function hasPageOptions(value: unknown): value is HasPageOptions {
|
||||
return (
|
||||
(typeof value === 'function' || (typeof value === 'object' && value !== null)) &&
|
||||
'__pageOptions' in value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the page metadata options attached to a component via createPage.
|
||||
*
|
||||
* @param component - The component to inspect.
|
||||
* @returns The associated PageOptions, or undefined if none are set.
|
||||
* @example
|
||||
* ```ts
|
||||
* const options = getPageOptions(MyPageComponent);
|
||||
* ```
|
||||
*/
|
||||
export function getPageOptions(component: unknown): PageOptions | undefined {
|
||||
if (hasPageOptions(component)) {
|
||||
return component.__pageOptions;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts or hydrates a React component into the `#root` element.
|
||||
*
|
||||
* Attaches metadata options for SSG extraction. Skips DOM mounting during the SSG
|
||||
* server-side render pass (`typeof window === 'undefined'`). On the client, hydrates
|
||||
* asynchronously during idle time to unblock First Contentful Paint.
|
||||
*
|
||||
* @param Component - The React component to render.
|
||||
* @param options - Optional page metadata (title, description).
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* createPage(App, { title: 'My Page' });
|
||||
* ```
|
||||
*/
|
||||
export function createPage(Component: React.ComponentType, options: PageOptions = {}): void {
|
||||
Object.assign(Component, { __pageOptions: options });
|
||||
|
||||
if (typeof window === 'undefined') return; // SSG build context: skip DOM mounting
|
||||
const rootElement = document.getElementById('root');
|
||||
|
||||
if (options.title && document.title !== options.title) {
|
||||
document.title = options.title;
|
||||
}
|
||||
|
||||
if (options.description) {
|
||||
let metaDescription = document.querySelector('meta[name="description"]');
|
||||
if (!metaDescription) {
|
||||
metaDescription = document.createElement('meta');
|
||||
metaDescription.setAttribute('name', 'description');
|
||||
document.head.appendChild(metaDescription);
|
||||
}
|
||||
if (metaDescription.getAttribute('content') !== options.description) {
|
||||
metaDescription.setAttribute('content', options.description);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rootElement) return;
|
||||
|
||||
const mountOrHydrate = () => {
|
||||
void import('react-dom/client')
|
||||
.then(({ createRoot, hydrateRoot }) => {
|
||||
const node = React.createElement(
|
||||
React.StrictMode,
|
||||
null,
|
||||
React.createElement(Component)
|
||||
);
|
||||
|
||||
if (rootElement.hasChildNodes()) {
|
||||
hydrateRoot(rootElement, node);
|
||||
} else {
|
||||
createRoot(rootElement).render(node);
|
||||
}
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
console.error('[createPage] Client hydration failed:', err);
|
||||
});
|
||||
};
|
||||
|
||||
if ('requestIdleCallback' in window) {
|
||||
window.requestIdleCallback(mountOrHydrate);
|
||||
} else {
|
||||
setTimeout(mountOrHydrate, 1);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Options for page creation.
|
||||
*/
|
||||
export interface PageOptions {
|
||||
/** Document title to set on mount. */
|
||||
title?: string;
|
||||
/** Content of the meta description tag. */
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mounts or hydrates a React component into the `#root` element.
|
||||
*
|
||||
* Skips DOM mounting during the SSG server-side render pass
|
||||
* (`typeof window === 'undefined'`). On the client, hydrates asynchronously
|
||||
* during idle time to unblock First Contentful Paint.
|
||||
*
|
||||
* @param Component - The React component to render.
|
||||
* @param options - Optional page metadata (title, description).
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* createPage(App, { title: 'My Page' });
|
||||
* ```
|
||||
*/
|
||||
export function createPage(Component: React.ComponentType, options: PageOptions = {}): void {
|
||||
if (typeof window === 'undefined') return; // SSG build context: skip DOM mounting
|
||||
const rootElement = document.getElementById('root');
|
||||
|
||||
if (options.title) {
|
||||
document.title = options.title;
|
||||
}
|
||||
|
||||
if (options.description) {
|
||||
let metaDescription = document.querySelector('meta[name="description"]');
|
||||
if (!metaDescription) {
|
||||
metaDescription = document.createElement('meta');
|
||||
metaDescription.setAttribute('name', 'description');
|
||||
document.head.appendChild(metaDescription);
|
||||
}
|
||||
metaDescription.setAttribute('content', options.description);
|
||||
}
|
||||
|
||||
if (!rootElement) return;
|
||||
|
||||
const mountOrHydrate = () => {
|
||||
void import('react-dom/client')
|
||||
.then(({ createRoot, hydrateRoot }) => {
|
||||
const node = (
|
||||
<React.StrictMode>
|
||||
<Component />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
if (rootElement.hasChildNodes()) {
|
||||
hydrateRoot(rootElement, node);
|
||||
} else {
|
||||
createRoot(rootElement).render(node);
|
||||
}
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
console.error('[createPage] Client hydration failed:', err);
|
||||
});
|
||||
};
|
||||
|
||||
if ('requestIdleCallback' in window) {
|
||||
window.requestIdleCallback(mountOrHydrate);
|
||||
} else {
|
||||
setTimeout(mountOrHydrate, 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { baseVitestConfig } from '@ermnvldmr/rsbuild-config/dev';
|
||||
import { mergeConfig } from 'vitest/config';
|
||||
|
||||
export default mergeConfig(baseVitestConfig, {
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
exclude: ['dist/**', 'node_modules/**'],
|
||||
},
|
||||
});
|
||||
Generated
+104
-278
@@ -69,7 +69,7 @@ importers:
|
||||
version: 5.8.3
|
||||
vitest:
|
||||
specifier: ^4.1.11
|
||||
version: 4.1.11(@types/node@22.20.0)(jsdom@28.0.0)(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
version: 4.1.11(@types/node@22.20.0)(@vitest/coverage-v8@4.0.18)(jsdom@28.0.0)(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
|
||||
packages/eslint-config:
|
||||
dependencies:
|
||||
@@ -176,7 +176,7 @@ importers:
|
||||
version: 8.6.15(storybook@8.6.17(prettier@3.9.10))
|
||||
'@storybook/addon-coverage':
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(vite@8.1.6(@types/node@22.20.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
version: 3.0.0(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
'@storybook/addon-essentials':
|
||||
specifier: ^8.6.15
|
||||
version: 8.6.15(@types/react@19.2.9)(storybook@8.6.17(prettier@3.9.10))
|
||||
@@ -236,13 +236,13 @@ importers:
|
||||
version: 8.6.17(prettier@3.9.10)
|
||||
storybook-react-rsbuild:
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12))
|
||||
version: 1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7))
|
||||
typescript:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
vitest:
|
||||
specifier: ^4.1.11
|
||||
version: 4.1.11(@types/node@22.20.0)(@vitest/coverage-v8@4.0.18)(jsdom@28.0.0)(vite@8.1.6(@types/node@22.20.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
version: 4.1.11(@types/node@22.20.0)(@vitest/coverage-v8@4.0.18)(jsdom@28.0.0)(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
wait-on:
|
||||
specifier: ^8.0.3
|
||||
version: 8.0.5
|
||||
@@ -300,7 +300,7 @@ importers:
|
||||
dependencies:
|
||||
'@rsbuild/plugin-mdx':
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1(@rsbuild/core@1.7.3)(webpack@5.105.1)
|
||||
version: 1.1.1(@rsbuild/core@1.7.3)(webpack@5.105.1(esbuild@0.27.7))
|
||||
react:
|
||||
specifier: ^19.1.0
|
||||
version: 19.2.3
|
||||
@@ -329,6 +329,12 @@ importers:
|
||||
'@rsbuild/plugin-type-check':
|
||||
specifier: ^1.1.1
|
||||
version: 1.3.3(@rsbuild/core@1.7.3)(@rspack/core@1.7.6(@swc/helpers@0.5.18))(tslib@2.8.1)(typescript@5.8.3)
|
||||
'@testing-library/jest-dom':
|
||||
specifier: ^6.9.1
|
||||
version: 6.9.1
|
||||
'@testing-library/react':
|
||||
specifier: ^16.3.1
|
||||
version: 16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@types/node':
|
||||
specifier: '*'
|
||||
version: 22.20.0
|
||||
@@ -353,6 +359,9 @@ importers:
|
||||
typescript:
|
||||
specifier: ^5.8.2
|
||||
version: 5.8.3
|
||||
vitest:
|
||||
specifier: ^4.1.11
|
||||
version: 4.1.11(@types/node@22.20.0)(@vitest/coverage-v8@4.0.18)(jsdom@28.0.0)(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
|
||||
packages/stl:
|
||||
dependencies:
|
||||
@@ -444,7 +453,7 @@ importers:
|
||||
version: 7.0.1
|
||||
storybook-react-rsbuild:
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(esbuild@0.27.7))
|
||||
version: 1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(esbuild@0.27.7))
|
||||
typescript:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
@@ -523,7 +532,7 @@ importers:
|
||||
version: 8.6.15(storybook@8.6.17(prettier@3.9.10))
|
||||
'@storybook/addon-coverage':
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(vite@8.1.6(@types/node@25.6.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
version: 3.0.0(vite@8.1.6(@types/node@22.20.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
'@storybook/addon-essentials':
|
||||
specifier: ^8.6.15
|
||||
version: 8.6.15(@types/react@19.2.9)(storybook@8.6.17(prettier@3.9.10))
|
||||
@@ -541,7 +550,7 @@ importers:
|
||||
version: 8.6.15(storybook@8.6.17(prettier@3.9.10))
|
||||
'@storybook/test-runner':
|
||||
specifier: ^0.19.1
|
||||
version: 0.19.1(@swc/helpers@0.5.18)(@types/node@25.6.2)(storybook@8.6.17(prettier@3.9.10))(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
version: 0.19.1(@swc/helpers@0.5.18)(@types/node@22.20.0)(storybook@8.6.17(prettier@3.9.10))(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@22.20.0)(typescript@5.8.3))
|
||||
'@tailwindcss/postcss':
|
||||
specifier: ^4.1.18
|
||||
version: 4.1.18
|
||||
@@ -589,13 +598,13 @@ importers:
|
||||
version: 8.6.17(prettier@3.9.10)
|
||||
storybook-react-rsbuild:
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(postcss@8.5.31))
|
||||
version: 1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31))
|
||||
typescript:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
vitest:
|
||||
specifier: ^4.1.11
|
||||
version: 4.1.11(@types/node@25.6.2)(@vitest/coverage-v8@4.0.18)(jsdom@28.0.0)(vite@8.1.6(@types/node@25.6.2)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
version: 4.1.11(@types/node@22.20.0)(@vitest/coverage-v8@4.0.18)(jsdom@28.0.0)(vite@8.1.6(@types/node@22.20.0)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
wait-on:
|
||||
specifier: ^8.0.3
|
||||
version: 8.0.5
|
||||
@@ -10259,41 +10268,6 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
'@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))':
|
||||
dependencies:
|
||||
'@jest/console': 29.7.0
|
||||
'@jest/reporters': 29.7.0
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 22.20.0
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.9.0
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-changed-files: 29.7.0
|
||||
jest-config: 29.7.0(@types/node@22.20.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
jest-haste-map: 29.7.0
|
||||
jest-message-util: 29.7.0
|
||||
jest-regex-util: 29.6.3
|
||||
jest-resolve: 29.7.0
|
||||
jest-resolve-dependencies: 29.7.0
|
||||
jest-runner: 29.7.0
|
||||
jest-runtime: 29.7.0
|
||||
jest-snapshot: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
jest-watcher: 29.7.0
|
||||
micromatch: 4.0.8
|
||||
pretty-format: 29.7.0
|
||||
slash: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
transitivePeerDependencies:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
'@jest/create-cache-key-function@30.2.0':
|
||||
dependencies:
|
||||
'@jest/types': 30.2.0
|
||||
@@ -10628,12 +10602,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@mdx-js/loader@3.1.1(webpack@5.105.1)':
|
||||
'@mdx-js/loader@3.1.1(webpack@5.105.1(esbuild@0.27.7))':
|
||||
dependencies:
|
||||
'@mdx-js/mdx': 3.1.1
|
||||
source-map: 0.7.6
|
||||
optionalDependencies:
|
||||
webpack: 5.105.1
|
||||
webpack: 5.105.1(esbuild@0.27.7)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -12563,9 +12537,9 @@ snapshots:
|
||||
- supports-color
|
||||
- webpack
|
||||
|
||||
'@rsbuild/plugin-mdx@1.1.1(@rsbuild/core@1.7.3)(webpack@5.105.1)':
|
||||
'@rsbuild/plugin-mdx@1.1.1(@rsbuild/core@1.7.3)(webpack@5.105.1(esbuild@0.27.7))':
|
||||
dependencies:
|
||||
'@mdx-js/loader': 3.1.1(webpack@5.105.1)
|
||||
'@mdx-js/loader': 3.1.1(webpack@5.105.1(esbuild@0.27.7))
|
||||
optionalDependencies:
|
||||
'@rsbuild/core': 1.7.3
|
||||
transitivePeerDependencies:
|
||||
@@ -13083,6 +13057,20 @@ snapshots:
|
||||
- supports-color
|
||||
- vite
|
||||
|
||||
'@storybook/addon-coverage@3.0.0(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@istanbuljs/load-nyc-config': 1.1.0
|
||||
'@jsdevtools/coverage-istanbul-loader': 3.0.5
|
||||
'@types/istanbul-lib-coverage': 2.0.6
|
||||
convert-source-map: 2.0.0
|
||||
espree: 9.6.1
|
||||
istanbul-lib-instrument: 6.0.3
|
||||
test-exclude: 6.0.0
|
||||
vite-plugin-istanbul: 6.0.2(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- vite
|
||||
|
||||
'@storybook/addon-coverage@3.0.0(vite@8.1.6(@types/node@25.0.10)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))':
|
||||
dependencies:
|
||||
'@istanbuljs/load-nyc-config': 1.1.0
|
||||
@@ -13408,7 +13396,7 @@ snapshots:
|
||||
dependencies:
|
||||
storybook: 8.6.17(prettier@3.9.10)
|
||||
|
||||
'@storybook/react-docgen-typescript-plugin@1.0.1(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12))':
|
||||
'@storybook/react-docgen-typescript-plugin@1.0.1(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31))':
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
endent: 2.1.0
|
||||
@@ -13418,7 +13406,7 @@ snapshots:
|
||||
react-docgen-typescript: 2.4.0(typescript@5.8.3)
|
||||
tslib: 2.8.1
|
||||
typescript: 5.8.3
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -13436,6 +13424,20 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@storybook/react-docgen-typescript-plugin@1.0.1(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7))':
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
endent: 2.1.0
|
||||
find-cache-dir: 3.3.2
|
||||
flat-cache: 3.2.0
|
||||
micromatch: 4.0.8
|
||||
react-docgen-typescript: 2.4.0(typescript@5.8.3)
|
||||
tslib: 2.8.1
|
||||
typescript: 5.8.3
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@storybook/react-docgen-typescript-plugin@1.0.1(typescript@5.8.3)(webpack@5.105.1(esbuild@0.27.7))':
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
@@ -13604,40 +13606,6 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
'@storybook/test-runner@0.19.1(@swc/helpers@0.5.18)(@types/node@25.6.2)(storybook@8.6.17(prettier@3.9.10))(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@babel/generator': 7.28.6
|
||||
'@babel/template': 7.28.6
|
||||
'@babel/types': 7.28.6
|
||||
'@jest/types': 29.6.3
|
||||
'@storybook/core-common': 8.6.14(storybook@8.6.17(prettier@3.9.10))
|
||||
'@storybook/csf': 0.1.13
|
||||
'@storybook/csf-tools': 8.6.14(storybook@8.6.17(prettier@3.9.10))
|
||||
'@storybook/preview-api': 8.6.15(storybook@8.6.17(prettier@3.9.10))
|
||||
'@swc/core': 1.15.10(@swc/helpers@0.5.18)
|
||||
'@swc/jest': 0.2.39(@swc/core@1.15.10(@swc/helpers@0.5.18))
|
||||
expect-playwright: 0.8.0
|
||||
jest: 29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
jest-circus: 29.7.0
|
||||
jest-environment-node: 29.7.0
|
||||
jest-junit: 16.0.0
|
||||
jest-playwright-preset: 4.0.0(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)))
|
||||
jest-runner: 29.7.0
|
||||
jest-serializer-html: 7.1.0
|
||||
jest-watch-typeahead: 2.2.2(jest@29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)))
|
||||
nyc: 15.1.0
|
||||
playwright: 1.58.0
|
||||
transitivePeerDependencies:
|
||||
- '@swc/helpers'
|
||||
- '@types/node'
|
||||
- babel-plugin-macros
|
||||
- debug
|
||||
- node-notifier
|
||||
- storybook
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
'@storybook/test@8.6.15(storybook@8.6.17(prettier@3.5.3))':
|
||||
dependencies:
|
||||
'@storybook/global': 5.0.0
|
||||
@@ -14972,21 +14940,6 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
create-jest@29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
chalk: 4.1.2
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-config: 29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
jest-util: 29.7.0
|
||||
prompts: 2.4.2
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
create-require@1.1.1: {}
|
||||
|
||||
critters@0.0.25:
|
||||
@@ -16629,25 +16582,6 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
jest-cli@29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
chalk: 4.1.2
|
||||
create-jest: 29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
exit: 0.1.2
|
||||
import-local: 3.2.0
|
||||
jest-config: 29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
yargs: 17.7.2
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
jest-config@29.7.0(@types/node@22.20.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@22.20.0)(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
@@ -16710,37 +16644,6 @@ snapshots:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
|
||||
jest-config@29.7.0(@types/node@22.20.0)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@jest/test-sequencer': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
babel-jest: 29.7.0(@babel/core@7.28.6)
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.9.0
|
||||
deepmerge: 4.3.1
|
||||
glob: 7.2.3
|
||||
graceful-fs: 4.2.11
|
||||
jest-circus: 29.7.0
|
||||
jest-environment-node: 29.7.0
|
||||
jest-get-type: 29.6.3
|
||||
jest-regex-util: 29.6.3
|
||||
jest-resolve: 29.7.0
|
||||
jest-runner: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
micromatch: 4.0.8
|
||||
parse-json: 5.2.0
|
||||
pretty-format: 29.7.0
|
||||
slash: 3.0.0
|
||||
strip-json-comments: 3.1.1
|
||||
optionalDependencies:
|
||||
'@types/node': 22.20.0
|
||||
ts-node: 10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)
|
||||
transitivePeerDependencies:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
|
||||
jest-config@29.7.0(@types/node@25.0.10)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.0.10)(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
@@ -16772,37 +16675,6 @@ snapshots:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
|
||||
jest-config@29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@jest/test-sequencer': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
babel-jest: 29.7.0(@babel/core@7.28.6)
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.9.0
|
||||
deepmerge: 4.3.1
|
||||
glob: 7.2.3
|
||||
graceful-fs: 4.2.11
|
||||
jest-circus: 29.7.0
|
||||
jest-environment-node: 29.7.0
|
||||
jest-get-type: 29.6.3
|
||||
jest-regex-util: 29.6.3
|
||||
jest-resolve: 29.7.0
|
||||
jest-runner: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
micromatch: 4.0.8
|
||||
parse-json: 5.2.0
|
||||
pretty-format: 29.7.0
|
||||
slash: 3.0.0
|
||||
strip-json-comments: 3.1.1
|
||||
optionalDependencies:
|
||||
'@types/node': 25.6.2
|
||||
ts-node: 10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)
|
||||
transitivePeerDependencies:
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
|
||||
jest-diff@29.7.0:
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
@@ -16918,22 +16790,6 @@ snapshots:
|
||||
- debug
|
||||
- supports-color
|
||||
|
||||
jest-playwright-preset@4.0.0(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))):
|
||||
dependencies:
|
||||
expect-playwright: 0.8.0
|
||||
jest: 29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
jest-circus: 29.7.0
|
||||
jest-environment-node: 29.7.0
|
||||
jest-process-manager: 0.4.0
|
||||
jest-runner: 29.7.0
|
||||
nyc: 15.1.0
|
||||
playwright-core: 1.58.0
|
||||
rimraf: 3.0.2
|
||||
uuid: 8.3.2
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
- supports-color
|
||||
|
||||
jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
|
||||
optionalDependencies:
|
||||
jest-resolve: 29.7.0
|
||||
@@ -17099,17 +16955,6 @@ snapshots:
|
||||
string-length: 5.0.1
|
||||
strip-ansi: 7.1.2
|
||||
|
||||
jest-watch-typeahead@2.2.2(jest@29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))):
|
||||
dependencies:
|
||||
ansi-escapes: 6.2.1
|
||||
chalk: 5.6.2
|
||||
jest: 29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
jest-regex-util: 29.6.3
|
||||
jest-watcher: 29.7.0
|
||||
slash: 5.1.0
|
||||
string-length: 5.0.1
|
||||
strip-ansi: 7.1.2
|
||||
|
||||
jest-watcher@29.7.0:
|
||||
dependencies:
|
||||
'@jest/test-result': 29.7.0
|
||||
@@ -17158,18 +17003,6 @@ snapshots:
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
jest@29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3)):
|
||||
dependencies:
|
||||
'@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
'@jest/types': 29.6.3
|
||||
import-local: 3.2.0
|
||||
jest-cli: 29.7.0(@types/node@25.6.2)(ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3))
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- babel-plugin-macros
|
||||
- supports-color
|
||||
- ts-node
|
||||
|
||||
jiti@2.6.1: {}
|
||||
|
||||
jju@1.4.0:
|
||||
@@ -18765,14 +18598,14 @@ snapshots:
|
||||
ajv: 6.12.6
|
||||
ajv-keywords: 3.5.2(ajv@6.12.6)
|
||||
|
||||
schema-utils@4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)):
|
||||
schema-utils@4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31)):
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
ajv: 8.20.0
|
||||
ajv-formats: 3.0.1(ajv@8.20.0)
|
||||
ajv-keywords: 5.1.0(ajv@8.20.0)
|
||||
optionalDependencies:
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31)
|
||||
|
||||
schema-utils@4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(postcss@8.5.31)):
|
||||
dependencies:
|
||||
@@ -18783,6 +18616,15 @@ snapshots:
|
||||
optionalDependencies:
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(postcss@8.5.31)
|
||||
|
||||
schema-utils@4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)):
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
ajv: 8.20.0
|
||||
ajv-formats: 3.0.1(ajv@8.20.0)
|
||||
ajv-keywords: 5.1.0(ajv@8.20.0)
|
||||
optionalDependencies:
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)
|
||||
|
||||
schema-utils@4.8.1(webpack@5.105.1(esbuild@0.27.7)):
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
@@ -18792,16 +18634,6 @@ snapshots:
|
||||
optionalDependencies:
|
||||
webpack: 5.105.1(esbuild@0.27.7)
|
||||
|
||||
schema-utils@4.8.1(webpack@5.105.1):
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
ajv: 8.20.0
|
||||
ajv-formats: 3.0.1(ajv@8.20.0)
|
||||
ajv-keywords: 5.1.0(ajv@8.20.0)
|
||||
optionalDependencies:
|
||||
webpack: 5.105.1
|
||||
optional: true
|
||||
|
||||
secure-compare@3.0.1: {}
|
||||
|
||||
semver@6.3.1: {}
|
||||
@@ -19120,12 +18952,12 @@ snapshots:
|
||||
- tslib
|
||||
- webpack
|
||||
|
||||
storybook-react-rsbuild@1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)):
|
||||
storybook-react-rsbuild@1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.60.1)
|
||||
'@rsbuild/core': 1.7.3
|
||||
'@storybook/react': 8.6.15(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)
|
||||
'@storybook/react-docgen-typescript-plugin': 1.0.1(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12))
|
||||
'@storybook/react-docgen-typescript-plugin': 1.0.1(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31))
|
||||
'@types/node': 18.19.130
|
||||
find-up: 5.0.0
|
||||
magic-string: 0.30.21
|
||||
@@ -19148,12 +18980,12 @@ snapshots:
|
||||
- tslib
|
||||
- webpack
|
||||
|
||||
storybook-react-rsbuild@1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(postcss@8.5.31)):
|
||||
storybook-react-rsbuild@1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.60.1)
|
||||
'@rsbuild/core': 1.7.3
|
||||
'@storybook/react': 8.6.15(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)
|
||||
'@storybook/react-docgen-typescript-plugin': 1.0.1(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(postcss@8.5.31))
|
||||
'@storybook/react-docgen-typescript-plugin': 1.0.1(typescript@5.8.3)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7))
|
||||
'@types/node': 18.19.130
|
||||
find-up: 5.0.0
|
||||
magic-string: 0.30.21
|
||||
@@ -19176,7 +19008,7 @@ snapshots:
|
||||
- tslib
|
||||
- webpack
|
||||
|
||||
storybook-react-rsbuild@1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(esbuild@0.27.7)):
|
||||
storybook-react-rsbuild@1.0.3(@rsbuild/core@1.7.3)(@storybook/test@8.6.15(storybook@8.6.17(prettier@3.9.10)))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.60.1)(storybook@8.6.17(prettier@3.9.10))(typescript@5.8.3)(webpack@5.105.1(esbuild@0.27.7)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.60.1)
|
||||
'@rsbuild/core': 1.7.3
|
||||
@@ -19373,16 +19205,17 @@ snapshots:
|
||||
|
||||
tapable@2.3.3: {}
|
||||
|
||||
terser-webpack-plugin@5.6.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)):
|
||||
terser-webpack-plugin@5.6.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31)):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
jest-worker: 27.5.1
|
||||
schema-utils: 4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12))
|
||||
schema-utils: 4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31))
|
||||
terser: 5.51.2
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31)
|
||||
optionalDependencies:
|
||||
'@swc/core': 1.15.10(@swc/helpers@0.5.18)
|
||||
esbuild: 0.25.12
|
||||
postcss: 8.5.31
|
||||
|
||||
terser-webpack-plugin@5.6.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(postcss@8.5.31)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(postcss@8.5.31)):
|
||||
dependencies:
|
||||
@@ -19396,6 +19229,17 @@ snapshots:
|
||||
esbuild: 0.27.7
|
||||
postcss: 8.5.31
|
||||
|
||||
terser-webpack-plugin@5.6.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
jest-worker: 27.5.1
|
||||
schema-utils: 4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7))
|
||||
terser: 5.51.2
|
||||
webpack: 5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)
|
||||
optionalDependencies:
|
||||
'@swc/core': 1.15.10(@swc/helpers@0.5.18)
|
||||
esbuild: 0.27.7
|
||||
|
||||
terser-webpack-plugin@5.6.1(esbuild@0.27.7)(webpack@5.105.1(esbuild@0.27.7)):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
@@ -19406,15 +19250,6 @@ snapshots:
|
||||
optionalDependencies:
|
||||
esbuild: 0.27.7
|
||||
|
||||
terser-webpack-plugin@5.6.1(webpack@5.105.1):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
jest-worker: 27.5.1
|
||||
schema-utils: 4.8.1(webpack@5.105.1)
|
||||
terser: 5.51.2
|
||||
webpack: 5.105.1
|
||||
optional: true
|
||||
|
||||
terser@5.46.0:
|
||||
dependencies:
|
||||
'@jridgewell/source-map': 0.3.11
|
||||
@@ -19574,27 +19409,6 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@swc/core': 1.15.10(@swc/helpers@0.5.18)
|
||||
|
||||
ts-node@10.9.2(@swc/core@1.15.10(@swc/helpers@0.5.18))(@types/node@25.6.2)(typescript@5.8.3):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.12
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 25.6.2
|
||||
acorn: 8.15.0
|
||||
acorn-walk: 8.3.4
|
||||
arg: 4.1.3
|
||||
create-require: 1.1.1
|
||||
diff: 4.0.4
|
||||
make-error: 1.3.6
|
||||
typescript: 5.8.3
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
optionalDependencies:
|
||||
'@swc/core': 1.15.10(@swc/helpers@0.5.18)
|
||||
optional: true
|
||||
|
||||
tsconfck@3.1.6(typescript@5.8.3):
|
||||
optionalDependencies:
|
||||
typescript: 5.8.3
|
||||
@@ -19849,6 +19663,18 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-istanbul@6.0.2(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@istanbuljs/load-nyc-config': 1.1.0
|
||||
espree: 10.4.0
|
||||
istanbul-lib-instrument: 6.0.3
|
||||
picocolors: 1.1.1
|
||||
source-map: 0.7.6
|
||||
test-exclude: 6.0.0
|
||||
vite: 8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-istanbul@6.0.2(vite@8.1.6(@types/node@25.0.10)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@istanbuljs/load-nyc-config': 1.1.0
|
||||
@@ -19972,7 +19798,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- msw
|
||||
|
||||
vitest@4.1.11(@types/node@22.20.0)(jsdom@28.0.0)(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2)):
|
||||
vitest@4.1.11(@types/node@22.20.0)(@vitest/coverage-v8@4.0.18)(jsdom@28.0.0)(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
'@vitest/expect': 4.1.11
|
||||
'@vitest/mocker': 4.1.11(vite@8.1.6(@types/node@22.20.0)(esbuild@0.27.7)(jiti@2.6.1)(terser@5.51.2)(yaml@2.8.2))
|
||||
@@ -19996,6 +19822,7 @@ snapshots:
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/node': 22.20.0
|
||||
'@vitest/coverage-v8': 4.0.18(vitest@4.1.11)
|
||||
jsdom: 28.0.0
|
||||
transitivePeerDependencies:
|
||||
- msw
|
||||
@@ -20104,7 +19931,7 @@ snapshots:
|
||||
|
||||
webpack-virtual-modules@0.6.2: {}
|
||||
|
||||
webpack@5.105.1:
|
||||
webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31):
|
||||
dependencies:
|
||||
'@types/eslint-scope': 3.7.7
|
||||
'@types/estree': 1.0.9
|
||||
@@ -20126,9 +19953,9 @@ snapshots:
|
||||
loader-runner: 4.3.2
|
||||
mime-types: 2.1.35
|
||||
neo-async: 2.6.2
|
||||
schema-utils: 4.8.1(webpack@5.105.1)
|
||||
schema-utils: 4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31))
|
||||
tapable: 2.3.3
|
||||
terser-webpack-plugin: 5.6.1(webpack@5.105.1)
|
||||
terser-webpack-plugin: 5.6.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(postcss@8.5.31))
|
||||
watchpack: 2.6.3
|
||||
webpack-sources: 3.6.0
|
||||
transitivePeerDependencies:
|
||||
@@ -20144,9 +19971,8 @@ snapshots:
|
||||
- lightningcss
|
||||
- postcss
|
||||
- uglify-js
|
||||
optional: true
|
||||
|
||||
webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12):
|
||||
webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7):
|
||||
dependencies:
|
||||
'@types/eslint-scope': 3.7.7
|
||||
'@types/estree': 1.0.9
|
||||
@@ -20168,9 +19994,9 @@ snapshots:
|
||||
loader-runner: 4.3.2
|
||||
mime-types: 2.1.35
|
||||
neo-async: 2.6.2
|
||||
schema-utils: 4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12))
|
||||
schema-utils: 4.8.1(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7))
|
||||
tapable: 2.3.3
|
||||
terser-webpack-plugin: 5.6.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.25.12))
|
||||
terser-webpack-plugin: 5.6.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7)(webpack@5.105.1(@swc/core@1.15.10(@swc/helpers@0.5.18))(esbuild@0.27.7))
|
||||
watchpack: 2.6.3
|
||||
webpack-sources: 3.6.0
|
||||
transitivePeerDependencies:
|
||||
|
||||
@@ -10,6 +10,7 @@ export default defineCli({
|
||||
sourceFilesPattern: 'content/**/*.{md,html}',
|
||||
urlPrefixes: ['/static/', '/images/'],
|
||||
bucket: env('COM_ERMNVLDMR_STATIC_S3_BUCKET'),
|
||||
publicUrl: env('COM_ERMNVLDMR_STATIC_PUBLIC_URL', 'https://static.ermnvldmr.com'),
|
||||
region: env('COM_ERMNVLDMR_STATIC_S3_REGION'),
|
||||
endpoint: env('COM_ERMNVLDMR_STATIC_S3_ENDPOINT_URL'),
|
||||
accessKeyId: env('COM_ERMNVLDMR_STATIC_AWS_ACCESS_KEY_ID'),
|
||||
|
||||
@@ -7,6 +7,7 @@ export default defineCli({
|
||||
description: 'Sync static assets to S3',
|
||||
targetPrefix: 'www',
|
||||
bucket: env('COM_ERMNVLDMR_STATIC_S3_BUCKET'),
|
||||
publicUrl: env('COM_ERMNVLDMR_STATIC_PUBLIC_URL', 'https://static.ermnvldmr.com'),
|
||||
region: env('COM_ERMNVLDMR_STATIC_S3_REGION'),
|
||||
endpoint: env('COM_ERMNVLDMR_STATIC_S3_ENDPOINT_URL'),
|
||||
accessKeyId: env('COM_ERMNVLDMR_STATIC_AWS_ACCESS_KEY_ID'),
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"cli": "ermnvldmr-cli",
|
||||
"sync:static": "pnpm cli sync:static",
|
||||
"dev": "rsbuild dev",
|
||||
"build": "rsbuild build",
|
||||
"dev:en": "LOCALE=en rsbuild dev",
|
||||
"dev:ru": "LOCALE=ru rsbuild dev",
|
||||
"build": "pnpm run build:all",
|
||||
"build:en": "LOCALE=en rsbuild build",
|
||||
"build:ru": "LOCALE=ru rsbuild build",
|
||||
"build:all": "pnpm run build:en && pnpm run build:ru",
|
||||
|
||||
Reference in new issue
Block a user