Compare commits

...

6 Commits

Author SHA1 Message Date
ChaosExAnima
698962c185
Migrate from Jest to Vitest 2025-05-06 22:02:02 +02:00
Claire
fbe9728f36
Bump version to v4.3.8 (#34626)
Some checks are pending
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / Libvips tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / Libvips tests (3.2) (push) Blocked by required conditions
Ruby Testing / Libvips tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
2025-05-06 14:17:07 +00:00
Claire
3bbf3e9709
Fix code style issue (#34624) 2025-05-06 13:35:54 +00:00
Claire
79931bf3ae
Merge commit from fork
* Check scheme in account and post links

* Harden media attachments

* Client-side mitigation

* Client-side mitigation for media attachments
2025-05-06 15:02:13 +02:00
Claire
22e2e7f02b
Fix crash when likes or shares collections are not inlined, for real (#34619)
Some checks are pending
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / Libvips tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / Libvips tests (3.2) (push) Blocked by required conditions
Ruby Testing / Libvips tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
2025-05-06 09:51:42 +00:00
Claire
41d00bc28b
Fix libvips being unconditionally required by tasks (#34620) 2025-05-06 09:45:32 +00:00
28 changed files with 2421 additions and 1941 deletions

View File

@ -40,4 +40,4 @@ jobs:
uses: ./.github/actions/setup-javascript
- name: JavaScript testing
run: yarn jest --reporters github-actions summary
run: yarn test:js

View File

@ -2,9 +2,34 @@
All notable changes to this project will be documented in this file.
## [4.3.8] - 2025-05-06
### Security
- Update dependencies
- Check scheme on account, profile, and media URLs ([GHSA-x2rc-v5wx-g3m5](https://github.com/mastodon/mastodon/security/advisories/GHSA-x2rc-v5wx-g3m5))
### Added
- Add warning for REDIS_NAMESPACE deprecation at startup (#34581 by @ClearlyClaire)
- Add built-in context for interaction policies (#34574 by @ClearlyClaire)
### Changed
- Change activity distribution error handling to skip retrying for deleted accounts (#33617 by @ClearlyClaire)
### Removed
- Remove double-query for signed query strings (#34610 by @ClearlyClaire)
### Fixed
- Fix incorrect redirect in response to unauthenticated API requests in limited federation mode (#34549 by @ClearlyClaire)
- Fix sign-up e-mail confirmation page reloading on error or redirect (#34548 by @ClearlyClaire)
## [4.3.7] - 2025-04-02
### Add
### Added
- Add delay to profile updates to debounce them (#34137 by @ClearlyClaire)
- Add support for paginating partial collections in `SynchronizeFollowersService` (#34272 and #34277 by @ClearlyClaire)

View File

@ -66,7 +66,7 @@ Example:
Pull requests that do not pass automated checks on CI may not be reviewed. In
particular, please keep in mind:
- Unit and integration tests (rspec, jest)
- Unit and integration tests (rspec, vitest)
- Code style rules (rubocop, eslint)
- Normalization of locale files (i18n-tasks)
- Relevant accessibility or performance concerns

View File

@ -77,6 +77,17 @@ export function normalizeStatus(status, normalOldStatus) {
normalStatus.contentHtml = emojify(normalStatus.content, emojiMap);
normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(spoilerText), emojiMap);
normalStatus.hidden = expandSpoilers ? false : spoilerText.length > 0 || normalStatus.sensitive;
if (normalStatus.url && !(normalStatus.url.startsWith('http://') || normalStatus.url.startsWith('https://'))) {
normalStatus.url = null;
}
normalStatus.url ||= normalStatus.uri;
normalStatus.media_attachments.forEach(item => {
if (item.remote_url && !(item.remote_url.startsWith('http://') || item.remote_url.startsWith('https://')))
item.remote_url = null;
});
}
if (normalOldStatus) {

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<AutosuggestEmoji /> renders emoji with custom url 1`] = `
exports[`<AutosuggestEmoji /> > renders emoji with custom url 1`] = `
<div
className="autosuggest-emoji"
>
@ -17,7 +17,7 @@ exports[`<AutosuggestEmoji /> renders emoji with custom url 1`] = `
</div>
`;
exports[`<AutosuggestEmoji /> renders native emoji 1`] = `
exports[`<AutosuggestEmoji /> > renders native emoji 1`] = `
<div
className="autosuggest-emoji"
>

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<Avatar /> Autoplay renders a animated avatar 1`] = `
exports[`<Avatar /> > Autoplay > renders a animated avatar 1`] = `
<div
className="account__avatar account__avatar--loading"
onMouseEnter={[Function]}
@ -21,7 +21,7 @@ exports[`<Avatar /> Autoplay renders a animated avatar 1`] = `
</div>
`;
exports[`<Avatar /> Still renders a still avatar 1`] = `
exports[`<Avatar /> > Still > renders a still avatar 1`] = `
<div
className="account__avatar account__avatar--loading"
onMouseEnter={[Function]}

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<AvatarOverlay renders a overlay avatar 1`] = `
exports[`<AvatarOverlay > renders a overlay avatar 1`] = `
<div
className="account__avatar-overlay"
onMouseEnter={[Function]}

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<Button /> adds class "button-secondary" if props.secondary given 1`] = `
exports[`<Button /> > adds class "button-secondary" if props.secondary given 1`] = `
<button
className="button button-secondary"
onClick={[Function]}
@ -8,7 +8,7 @@ exports[`<Button /> adds class "button-secondary" if props.secondary given 1`] =
/>
`;
exports[`<Button /> renders a button element 1`] = `
exports[`<Button /> > renders a button element 1`] = `
<button
className="button"
onClick={[Function]}
@ -16,7 +16,7 @@ exports[`<Button /> renders a button element 1`] = `
/>
`;
exports[`<Button /> renders a disabled attribute if props.disabled given 1`] = `
exports[`<Button /> > renders a disabled attribute if props.disabled given 1`] = `
<button
className="button"
disabled={true}
@ -25,7 +25,7 @@ exports[`<Button /> renders a disabled attribute if props.disabled given 1`] = `
/>
`;
exports[`<Button /> renders class="button--block" if props.block given 1`] = `
exports[`<Button /> > renders class="button--block" if props.block given 1`] = `
<button
className="button button--block"
onClick={[Function]}
@ -33,7 +33,7 @@ exports[`<Button /> renders class="button--block" if props.block given 1`] = `
/>
`;
exports[`<Button /> renders the children 1`] = `
exports[`<Button /> > renders the children 1`] = `
<button
className="button"
onClick={[Function]}
@ -45,7 +45,7 @@ exports[`<Button /> renders the children 1`] = `
</button>
`;
exports[`<Button /> renders the given text 1`] = `
exports[`<Button /> > renders the given text 1`] = `
<button
className="button"
onClick={[Function]}
@ -55,7 +55,7 @@ exports[`<Button /> renders the given text 1`] = `
</button>
`;
exports[`<Button /> renders the props.text instead of children 1`] = `
exports[`<Button /> > renders the props.text instead of children 1`] = `
<button
className="button"
onClick={[Function]}

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<DisplayName /> renders display name + account name 1`] = `
exports[`<DisplayName /> > renders display name + account name 1`] = `
<span
className="display-name"
onMouseEnter={[Function]}

View File

@ -21,7 +21,7 @@ describe('<Button />', () => {
});
it('handles click events using the given handler', () => {
const handler = jest.fn();
const handler = vi.fn();
render(<Button onClick={handler}>button</Button>);
fireEvent.click(screen.getByText('button'));
@ -29,7 +29,7 @@ describe('<Button />', () => {
});
it('does not handle click events if props.disabled given', () => {
const handler = jest.fn();
const handler = vi.fn();
render(<Button onClick={handler} disabled>button</Button>);
fireEvent.click(screen.getByText('button'));

View File

@ -7,7 +7,7 @@ const fakeIcon = () => <span />;
describe('<Column />', () => {
describe('<ColumnHeader /> click handler', () => {
it('runs the scroll animation if the column contains scrollable content', () => {
const scrollToMock = jest.fn();
const scrollToMock = vi.fn();
const { container } = render(
<Column heading='notifications' icon='notifications' iconComponent={fakeIcon}>
<div className='scrollable' />

View File

@ -144,5 +144,10 @@ export function createAccountFromServerJSON(serverJSON: ApiAccountJSON) {
),
note_emojified: emojify(accountJSON.note, emojiMap),
note_plain: unescapeHTML(accountJSON.note),
url:
accountJSON.url.startsWith('http://') ||
accountJSON.url.startsWith('https://')
? accountJSON.url
: accountJSON.uri,
});
}

View File

@ -3,17 +3,17 @@ import { IntlProvider } from 'react-intl';
import { MemoryRouter } from 'react-router';
import type { RenderOptions } from '@testing-library/react';
// eslint-disable-next-line import/no-extraneous-dependencies
import { render as rtlRender } from '@testing-library/react';
import { IdentityContext } from './identity_context';
beforeEach(() => {
global.requestIdleCallback = jest
.fn()
.mockImplementation((fn: () => void) => {
fn();
});
beforeAll(() => {
global.requestIdleCallback = vi.fn((cb: IdleRequestCallback) => {
// @ts-expect-error IdleRequestCallback expects an argument of type IdleDeadline,
// but that doesn't exist in this environment.
cb();
return 0;
});
});
function render(
@ -46,7 +46,6 @@ function render(
}
// re-export everything
// eslint-disable-next-line import/no-extraneous-dependencies
export * from '@testing-library/react';
// override render method

View File

@ -1 +0,0 @@
import '@testing-library/jest-dom';

View File

@ -15,13 +15,15 @@ class ActivityPub::Parser::MediaAttachmentParser
end
def remote_url
Addressable::URI.parse(@json['url'])&.normalize&.to_s
url = Addressable::URI.parse(@json['url'])&.normalize&.to_s
url unless unsupported_uri_scheme?(url)
rescue Addressable::URI::InvalidURIError
nil
end
def thumbnail_remote_url
Addressable::URI.parse(@json['icon'].is_a?(Hash) ? @json['icon']['url'] : @json['icon'])&.normalize&.to_s
url = Addressable::URI.parse(@json['icon'].is_a?(Hash) ? @json['icon']['url'] : @json['icon'])&.normalize&.to_s
url unless unsupported_uri_scheme?(url)
rescue Addressable::URI::InvalidURIError
nil
end

View File

@ -29,7 +29,10 @@ class ActivityPub::Parser::StatusParser
end
def url
url_to_href(@object['url'], 'text/html') if @object['url'].present?
return if @object['url'].blank?
url = url_to_href(@object['url'], 'text/html')
url unless unsupported_uri_scheme?(url)
end
def text
@ -95,11 +98,11 @@ class ActivityPub::Parser::StatusParser
end
def favourites_count
@object.dig('likes', 'totalItems') if @object.is_a?(Hash)
@object['likes']['totalItems'] if @object.is_a?(Hash) && @object['likes'].is_a?(Hash)
end
def reblogs_count
@object.dig('shares', 'totalItems') if @object.is_a?(Hash)
@object['shares']['totalItems'] if @object.is_a?(Hash) && @object['shares'].is_a?(Hash)
end
def quote_policy

View File

@ -4,6 +4,7 @@ require 'singleton'
class ActivityPub::TagManager
include Singleton
include JsonLdHelper
include RoutingHelper
CONTEXT = 'https://www.w3.org/ns/activitystreams'
@ -17,7 +18,7 @@ class ActivityPub::TagManager
end
def url_for(target)
return target.url if target.respond_to?(:local?) && !target.local?
return unsupported_uri_scheme?(target.url) ? nil : target.url if target.respond_to?(:local?) && !target.local?
return unless target.respond_to?(:object_type)

17
config/vite.json Normal file
View File

@ -0,0 +1,17 @@
{
"all": {
"sourceCodeDir": "app/javascript",
"additionalEntrypoints": ["~/{icons,images}/**/*", "~/styles/*.scss"],
"watchAdditionalPaths": []
},
"development": {
"autoBuild": true,
"publicOutputDir": "vite-dev",
"port": 3036
},
"test": {
"autoBuild": true,
"publicOutputDir": "vite-test",
"port": 3037
}
}

View File

@ -59,7 +59,7 @@ services:
web:
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
# build: .
image: ghcr.io/mastodon/mastodon:v4.3.7
image: ghcr.io/mastodon/mastodon:v4.3.8
restart: always
env_file: .env.production
command: bundle exec puma -C config/puma.rb
@ -83,7 +83,7 @@ services:
# build:
# dockerfile: ./streaming/Dockerfile
# context: .
image: ghcr.io/mastodon/mastodon-streaming:v4.3.7
image: ghcr.io/mastodon/mastodon-streaming:v4.3.8
restart: always
env_file: .env.production
command: node ./streaming/index.js
@ -102,7 +102,7 @@ services:
sidekiq:
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
# build: .
image: ghcr.io/mastodon/mastodon:v4.3.7
image: ghcr.io/mastodon/mastodon:v4.3.8
restart: always
env_file: .env.production
command: bundle exec sidekiq

View File

@ -247,6 +247,7 @@ export default tseslint.config([
'config/webpack/**',
'app/javascript/mastodon/performance.js',
'app/javascript/mastodon/test_setup.js',
'app/javascript/mastodon/test_helpers.tsx',
'app/javascript/**/__tests__/**',
],
},
@ -387,9 +388,7 @@ export default tseslint.config([
files: ['**/__tests__/*.js', '**/__tests__/*.jsx'],
languageOptions: {
globals: {
...globals.jest,
},
globals: globals.vitest,
},
},
]);

View File

@ -1,28 +0,0 @@
/** @type {import('jest').Config} */
const config = {
testEnvironment: 'jsdom',
testPathIgnorePatterns: [
'<rootDir>/node_modules/',
'<rootDir>/vendor/',
'<rootDir>/config/',
'<rootDir>/log/',
'<rootDir>/public/',
'<rootDir>/tmp/',
],
setupFilesAfterEnv: ['<rootDir>/app/javascript/mastodon/test_setup.js'],
collectCoverageFrom: [
'app/javascript/mastodon/**/*.{js,jsx,ts,tsx}',
'!app/javascript/mastodon/features/emoji/emoji_compressed.js',
'!app/javascript/mastodon/service_worker/entry.js',
'!app/javascript/mastodon/test_setup.js',
],
// Those packages are ESM, so we need them to be processed by Babel
transformIgnorePatterns: ['/node_modules/(?!(redent|strip-indent)/)'],
coverageDirectory: '<rootDir>/coverage',
moduleDirectories: ['node_modules', '<rootDir>/app/javascript'],
moduleNameMapper: {
'\\.svg\\?react$': '<rootDir>/app/javascript/__mocks__/svg.js',
},
};
module.exports = config;

View File

@ -17,7 +17,7 @@ module Mastodon
end
def default_prerelease
'alpha.4'
'alpha.5'
end
def prerelease

View File

@ -1,7 +1,5 @@
# frozen_string_literal: true
require 'vips'
def gen_border(codepoint, color)
input = Rails.public_path.join('emoji', "#{codepoint}.svg")
dest = Rails.public_path.join('emoji', "#{codepoint}_border.svg")
@ -191,6 +189,8 @@ namespace :emojis do
desc 'Generate a spritesheet of emojis'
task :generate_emoji_sheet do
require 'vips'
src = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_data.json')
sheet = Oj.load(File.read(src))

View File

@ -18,14 +18,14 @@
"format": "prettier --write --log-level warn .",
"format:check": "prettier --check --ignore-unknown .",
"i18n:extract": "formatjs extract 'app/javascript/**/*.{js,jsx,ts,tsx}' --ignore '**/*.d.ts' --out-file app/javascript/mastodon/locales/en.json --format config/formatjs-formatter.js",
"jest": "cross-env NODE_ENV=test jest",
"lint:js": "cd $INIT_CWD && eslint --cache --report-unused-disable-directives",
"lint:css": "stylelint \"**/*.{css,scss}\"",
"lint": "yarn lint:js && yarn lint:css",
"postversion": "git push --tags",
"postinstall": "test -d node_modules/husky && husky || echo \"husky is not installed\"",
"start": "node ./streaming/index.js",
"test": "yarn lint && yarn run typecheck && yarn jest",
"test": "yarn lint && yarn run typecheck && yarn test:js run",
"test:js": "vitest",
"typecheck": "tsc --noEmit"
},
"repository": {
@ -127,6 +127,7 @@
"tiny-queue": "^0.2.1",
"twitter-text": "3.1.0",
"use-debounce": "^10.0.0",
"vite": "^6.2.6",
"webpack": "^4.47.0",
"webpack-assets-manifest": "^4.0.6",
"webpack-bundle-analyzer": "^4.8.0",
@ -152,7 +153,6 @@
"@types/hoist-non-react-statics": "^3.3.1",
"@types/http-link-header": "^1.0.3",
"@types/intl": "^1.2.0",
"@types/jest": "^29.5.2",
"@types/js-yaml": "^4.0.5",
"@types/lodash": "^4.14.195",
"@types/object-assign": "^4.0.30",
@ -173,7 +173,7 @@
"@types/requestidlecallback": "^0.3.5",
"@types/webpack": "^4.41.33",
"@types/webpack-env": "^1.18.4",
"babel-jest": "^29.5.0",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^9.23.0",
"eslint-import-resolver-typescript": "^4.2.5",
"eslint-plugin-formatjs": "^5.3.1",
@ -185,8 +185,6 @@
"eslint-plugin-react-hooks": "^5.2.0",
"globals": "^16.0.0",
"husky": "^9.0.11",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"lint-staged": "^15.0.0",
"prettier": "^3.3.3",
"react-test-renderer": "^18.2.0",
@ -195,6 +193,9 @@
"stylelint-config-standard-scss": "^14.0.0",
"typescript": "~5.7.3",
"typescript-eslint": "^8.28.0",
"vite-plugin-rails": "^0.5.0",
"vite-plugin-svgr": "^4.2.0",
"vitest": "^3.1.1",
"webpack-dev-server": "^3.11.3"
},
"resolutions": {

View File

@ -49,6 +49,24 @@ RSpec.describe ActivityPub::Parser::StatusParser do
)
end
context 'when the likes collection is not inlined' do
let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), 'post1'].join('/'),
type: 'Note',
to: 'https://www.w3.org/ns/activitystreams#Public',
content: 'bleh',
published: 1.hour.ago.utc.iso8601,
updated: 1.hour.ago.utc.iso8601,
likes: 'https://example.com/collections/likes',
}
end
it 'does not raise an error' do
expect { subject.favourites_count }.to_not raise_error
end
end
describe '#quote_policy' do
subject do
described_class

View File

@ -11,16 +11,20 @@
"noUncheckedIndexedAccess": true,
"esModuleInterop": true,
"skipLibCheck": true,
"types": ["vitest/globals", "@types/webpack-env"],
"baseUrl": "./",
"incremental": true,
"tsBuildInfoFile": "tmp/cache/tsconfig.tsbuildinfo",
"paths": {
"@/*": ["app/javascript/*"],
"mastodon": ["app/javascript/mastodon"],
"mastodon/*": ["app/javascript/mastodon/*"],
"@/*": ["app/javascript/*"]
"images/*": ["app/javascript/images/*"],
"styles/*": ["app/javascript/styles/*"]
}
},
"include": [
"vite.config.mts",
"app/javascript/mastodon",
"app/javascript/entrypoints",
"app/javascript/types"

58
vite.config.mts Normal file
View File

@ -0,0 +1,58 @@
/// <reference types="vitest" />
import fs from 'fs';
import path from 'path';
import react from '@vitejs/plugin-react';
import RailsPlugin from 'vite-plugin-rails';
import svgr from 'vite-plugin-svgr';
import { defineConfig, configDefaults } from 'vitest/config';
const sourceCodeDir = 'app/javascript';
const items = fs.readdirSync(sourceCodeDir);
const directories = items.filter((item) =>
fs.lstatSync(path.join(sourceCodeDir, item)).isDirectory(),
);
const aliasesFromJavascriptRoot: Record<string, string> = {};
directories.forEach((directory) => {
aliasesFromJavascriptRoot[directory] = path.resolve(
__dirname,
sourceCodeDir,
directory,
);
});
export default defineConfig({
resolve: {
alias: {
...aliasesFromJavascriptRoot,
},
},
plugins: [
RailsPlugin(),
react({
include: ['**/*.jsx', '**/*.tsx'],
babel: {
plugins: ['formatjs', 'preval', 'transform-react-remove-prop-types'],
},
}),
svgr(),
],
test: {
environment: 'jsdom',
include: [
...configDefaults.include,
'**/__tests__/**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
],
exclude: [
...configDefaults.exclude,
'**/node_modules/**',
'vendor/**',
'config/**',
'log/**',
'public/**',
'tmp/**',
],
globals: true,
},
});

4082
yarn.lock

File diff suppressed because it is too large Load Diff