diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d8241e65..801f12a8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,51 @@ jobs: - name: Perform linting run: pnpm lint + cypress: + name: Cypress + runs-on: macos-14 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup System and Rust + uses: ./.github/actions/setup-system + with: + token: ${{ secrets.GITHUB_TOKEN }} + target: aarch64-apple-darwin + + - name: Setup Node.js, pnpm and dependencies + uses: ./.github/actions/setup-pnpm + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Cypress + uses: cypress-io/github-action@v6 + with: + runTests: false + working-directory: . + + - name: E2E test + uses: cypress-io/github-action@v6 + with: + install: false + command: pnpm test:e2e + working-directory: apps/web + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: cypress-screenshots + path: apps/web/cypress/screenshots + if-no-files-found: ignore + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: cypress-videos + path: apps/web/cypress/videos + if-no-files-found: ignore + rustfmt: name: Rust Formatting runs-on: ubuntu-latest diff --git a/.nvmrc b/.nvmrc index edf176c67..3f430af82 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18.17 +v18 diff --git a/Cargo.lock b/Cargo.lock index d119260fd..5c0bd3710 100644 Binary files a/Cargo.lock and b/Cargo.lock differ diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 7c5fe567a..d815a0594 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -14,7 +14,7 @@ "dependencies": { "@oscartbeaumont-sd/rspc-client": "=0.0.0-main-dc31e5b2", "@oscartbeaumont-sd/rspc-tauri": "=0.0.0-main-dc31e5b2", - "@remix-run/router": "^1.13.1", + "@remix-run/router": "=1.13.1", "@sd/client": "workspace:*", "@sd/interface": "workspace:*", "@sd/ui": "workspace:*", @@ -25,18 +25,18 @@ "immer": "^10.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router-dom": "^6.20.1", + "react-router-dom": "=6.20.1", "sonner": "^1.0.3" }, "devDependencies": { "@sd/config": "workspace:*", - "@sentry/vite-plugin": "^2.14.2", - "@tauri-apps/cli": "^1.5.10", - "@types/react": "^18.2.61", - "@types/react-dom": "^18.2.19", - "sass": "^1.71.1", - "typescript": "^5.3.3", - "vite": "^5.1.4", - "vite-tsconfig-paths": "^4.3.1" + "@sentry/vite-plugin": "^2.16.0", + "@tauri-apps/cli": "^1.5.11", + "@types/react": "^18.2.67", + "@types/react-dom": "^18.2.22", + "sass": "^1.72.0", + "typescript": "^5.4.2", + "vite": "^5.1.6", + "vite-tsconfig-paths": "^4.3.2" } } diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 461c3d583..845b597cb 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -74,13 +74,13 @@ "zod": "~3.22.4" }, "devDependencies": { - "@babel/core": "^7.23.9", + "@babel/core": "^7.24.0", "@rnx-kit/metro-config": "^1.3.15", "@sd/config": "workspace:*", - "@types/react": "^18.2.61", + "@types/react": "^18.2.67", "babel-plugin-module-resolver": "^5.0.0", "eslint-plugin-react-native": "^4.1.0", "react-native-svg-transformer": "^1.3.0", - "typescript": "^5.3.3" + "typescript": "^5.4.2" } } diff --git a/apps/server/Cargo.toml b/apps/server/Cargo.toml index 836defb71..1b8cf75c0 100644 --- a/apps/server/Cargo.toml +++ b/apps/server/Cargo.toml @@ -22,5 +22,7 @@ rspc = { workspace = true, features = ["axum"] } tokio = { workspace = true, features = ["sync", "rt-multi-thread", "signal"] } tracing = { workspace = true } +tempfile = "3.10.1" + include_dir = "0.7.3" mime_guess = "2.0.4" diff --git a/apps/server/src/main.rs b/apps/server/src/main.rs index 8d80008b2..5aa3939bf 100644 --- a/apps/server/src/main.rs +++ b/apps/server/src/main.rs @@ -21,7 +21,13 @@ async fn main() { } #[cfg(debug_assertions)] { - Path::new(env!("CARGO_MANIFEST_DIR")).join("sdserver_data") + if env::var("E2E_TEST").is_ok() { + let temp_dir = + tempfile::tempdir().expect("Tempdir for e2e test must be created!"); + temp_dir.into_path() + } else { + Path::new(env!("CARGO_MANIFEST_DIR")).join("sdserver_data") + } } } }; diff --git a/apps/storybook/.storybook/main.ts b/apps/storybook/.storybook/main.ts index 04a92eb81..8a6dd6c7e 100644 --- a/apps/storybook/.storybook/main.ts +++ b/apps/storybook/.storybook/main.ts @@ -14,13 +14,11 @@ const config: StorybookConfig = { } ], addons: [ - '@storybook/addon-links', - '@storybook/addon-essentials', - '@storybook/addon-interactions', - { - name: '@storybook/addon-styling' - } - ], + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/addon-interactions', + '@storybook/addon-styling-webpack' + ], framework: { name: '@storybook/react-vite', options: {} diff --git a/apps/storybook/package.json b/apps/storybook/package.json index aae4748fc..589d2987f 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -6,13 +6,13 @@ "build-storybook": "storybook build" }, "dependencies": { - "@storybook/addon-essentials": "^7.6.17", - "@storybook/addon-interactions": "^7.6.17", - "@storybook/addon-links": "^7.6.17", - "@storybook/addon-styling": "^1.3.7", - "@storybook/blocks": "^7.6.17", - "@storybook/react": "^7.6.17", - "@storybook/react-vite": "^7.6.17", + "@storybook/addon-essentials": "^8.0.1", + "@storybook/addon-interactions": "^8.0.1", + "@storybook/addon-links": "^8.0.1", + "@storybook/addon-styling-webpack": "^1.0.0", + "@storybook/blocks": "^8.0.1", + "@storybook/react": "^8.0.1", + "@storybook/react-vite": "^8.0.1", "@storybook/testing-library": "^0.2.2", "react": "^18.2.0", "react-dom": "^18.2.0" @@ -20,16 +20,16 @@ "devDependencies": { "@sd/config": "workspace:*", "@sd/ui": "workspace:*", - "@types/react": "^18.2.61", - "@types/react-dom": "^18.2.19", - "autoprefixer": "^10.4.17", - "postcss": "^8.4.35", + "@types/react": "^18.2.67", + "@types/react-dom": "^18.2.22", + "autoprefixer": "^10.4.18", + "postcss": "^8.4.36", "postcss-pseudo-companion-classes": "^0.1.1", "prop-types": "^15.8.1", "rollup-plugin-node-builtins": "^2.1.2", - "storybook": "^7.6.17", + "storybook": "^8.0.1", "tailwindcss": "^3.4.1", - "typescript": "^5.3.3", - "vite": "^5.1.4" + "typescript": "^5.4.2", + "vite": "^5.1.6" } } diff --git a/apps/web/.eslintrc.cjs b/apps/web/.eslintrc.cjs index a746deaf8..c5817f957 100644 --- a/apps/web/.eslintrc.cjs +++ b/apps/web/.eslintrc.cjs @@ -4,5 +4,5 @@ module.exports = { tsconfigRootDir: __dirname, project: './tsconfig.json' }, - ignorePatterns: ['playwright.config.ts', 'tests/**/*'] + ignorePatterns: ['playwright.config.ts', 'tests/**/*', 'cypress/**/*'] }; diff --git a/apps/web/cypress.config.ts b/apps/web/cypress.config.ts new file mode 100644 index 000000000..6f92aa001 --- /dev/null +++ b/apps/web/cypress.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'cypress'; + +export default defineConfig({ + e2e: { + baseUrl: 'http://localhost:8002', + setupNodeEvents(on, config) { + // implement node event listeners here + } + }, + video: true +}); diff --git a/apps/web/cypress/.eslintrc.cjs b/apps/web/cypress/.eslintrc.cjs new file mode 100644 index 000000000..26e23b653 --- /dev/null +++ b/apps/web/cypress/.eslintrc.cjs @@ -0,0 +1,8 @@ +module.exports = { + extends: [require.resolve('@sd/config/eslint/web.js')], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + }, + plugins: ['cypress'] +}; diff --git a/apps/web/cypress/.gitignore b/apps/web/cypress/.gitignore new file mode 100644 index 000000000..c93c16037 --- /dev/null +++ b/apps/web/cypress/.gitignore @@ -0,0 +1,2 @@ +screenshots +videos diff --git a/apps/web/cypress/e2e/onboarding.spec.cy.ts b/apps/web/cypress/e2e/onboarding.spec.cy.ts new file mode 100644 index 000000000..77c331932 --- /dev/null +++ b/apps/web/cypress/e2e/onboarding.spec.cy.ts @@ -0,0 +1,177 @@ +import { discord, libraryName } from '../fixtures/onboarding.json'; + +describe('Onboarding', () => { + // TODO: Create debug flag to bypass auto language detection + it('Alpha onboarding', () => { + cy.visit('/', { + onBeforeLoad(win) { + cy.stub(win, 'open').as('winOpen'); + } + }); + + // Check redirect to initial alpha onboarding screen + cy.url().should('contain', '/onboarding/alpha'); + + // Check application name is present + cy.get('h1').should('contain', 'Spacedrive'); + + // Check logo image exists and loaded correctly + cy.get('img[alt="Spacedrive"]') + .should('be.visible') + .and('have.prop', 'naturalWidth') + .should('be.greaterThan', 0); + + // Check we are in the alpha release screen + cy.get('h1').should('contain', 'Alpha Release'); + + // Check Join Discord button exists and point to a valid discord invite + cy.get('button').contains('Join Discord').click(); + cy.get('@winOpen').should('be.calledWith', discord); + + // Check we have a button to continue to the Library creation + cy.get('a') + .contains('Continue') + .should('have.attr', 'href', '/onboarding/new-library') + .click(); + + // Check we were redirect to Library creation screen + cy.url().should('contain', '/onboarding/new-library'); + + // Check create library screen title + cy.get('h2').should('contain', 'Create a Library'); + + // Check we have a button to create a new library + cy.get('button').contains('New library').as('newLibraryButton'); + + // Check we have an input to set the library name + cy.get('input[placeholder="e.g. \\"James\' Library\\""]').as('libraryNameInput'); + + // Check newLibraryButton is disabled + cy.get('@newLibraryButton').should('be.disabled'); + + // Get input with placeholder 'e.g. "James' Library"' + cy.get('@libraryNameInput').type(libraryName); + + // Check newLibraryButton is enabled + cy.get('@newLibraryButton').should('be.enabled'); + + // Check we can clear the input and the button is disabled again + cy.get('@libraryNameInput').clear(); + cy.get('@newLibraryButton').should('be.disabled'); + cy.get('@libraryNameInput').type(libraryName); + + // Check we have a button to continue to the add default locations screen + cy.get('button').contains('New library').click(); + + // Check redirect to add default locations + cy.url().should('contain', '/onboarding/locations'); + + // Check we have a Toggle All button + cy.get('#toggle-all').as('toggleAllButton'); + + cy.get('[data-locations]').then((locationsElem) => { + const locations = locationsElem.data('locations'); + if (locations == null || typeof locations !== 'object') + throw new Error('Invalid locations data'); + + // Check that default location checkboxes work + for (const state of ['unchecked', 'checked']) { + if (state === 'checked') { + // Check if @toggleAllButton has data-state == checked + cy.get('@toggleAllButton').should('have.attr', 'data-state', 'checked'); + // Uncheck all locations + cy.get('@toggleAllButton').click(); + } + + // Check we have all the default locations available + for (const [location, locationName] of Object.entries(locations)) { + if (typeof locationName !== 'string') throw new Error('Invalid location name'); + + let newState: typeof state; + if (state === 'unchecked') { + cy.get('label').contains(locationName).click(); + newState = 'checked'; + } else { + newState = 'unchecked'; + } + cy.get(`button[id="locations.${location}"]`).should( + 'have.attr', + 'data-state', + newState + ); + } + } + }); + + // Check we have a button to continue to the privacy screen + cy.get('button').contains('Continue').click(); + + // Check redirect to privacy screen + cy.url().should('contain', '/onboarding/privacy'); + + // Check privacy screen title + cy.get('h2').should('contain', 'Your Privacy'); + + // Check we have all privacy options + cy.get('label').contains('Share the bare minimum').click(); + cy.get('#radiominimal-telemetry').should('have.attr', 'data-state', 'checked'); + cy.get('#radioshare-telemetry').should('have.attr', 'data-state', 'unchecked'); + cy.get('label').contains('Share anonymous usage').click(); + cy.get('#radioshare-telemetry').should('have.attr', 'data-state', 'checked'); + cy.get('#radiominimal-telemetry').should('have.attr', 'data-state', 'unchecked'); + + // Check More info button exists and point to the valid pravacy policy + cy.get('button').contains('More info').click(); + cy.get('@winOpen').should( + 'be.calledWith', + 'https://www.spacedrive.com/docs/product/resources/privacy' + ); + + // Check we have a button to finish onboarding + cy.get('button[type="submit"]').contains('Continue').click(); + + // Check redirect to privacy screen + cy.url().should('contain', '/onboarding/creating-library'); + + // FIX-ME: This fails a lot, due to the creating library screen only being show for a short time + // Check creating library screen title + // cy.get('h2').should('contain', 'Creating your library'); + + // Check redirect to Library + cy.url().should((url) => { + expect(/\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\//.test(url)).to + .be.true; + }); + + // Click on the library submenu + cy.get('button[aria-haspopup="menu"]').contains(libraryName).click(); + cy.get('a').contains('Manage Library').click(); + + // Check redirect to Library settings + cy.url().should('contain', '/settings/library/general'); + + // Check Library seetings screen title + cy.get('h1').should('contain', 'Library Settings'); + + // Check Library name is correct + cy.get('label') + .contains('Name') + .parent() + .find('input') + .should((input) => { + expect(input.val()).to.eq(libraryName); + }); + + // Delete Library + cy.get('button').contains('Delete').click(); + + // Check confirmation modal for deleting appears + cy.get('body > div[role="dialog"]').as('deleteModal'); + + // Check modal title + cy.get('@deleteModal').find('h2').should('contain', 'Delete Library'); + + // Confirm delete + cy.get('@deleteModal').find('button').contains('Delete').click(); + }); +}); diff --git a/apps/web/cypress/fixtures/onboarding.json b/apps/web/cypress/fixtures/onboarding.json new file mode 100644 index 000000000..3b34c1884 --- /dev/null +++ b/apps/web/cypress/fixtures/onboarding.json @@ -0,0 +1,4 @@ +{ + "discord": "https://discord.gg/ukRnWSnAbG", + "libraryName": "Test Library" +} diff --git a/apps/web/cypress/support/commands.ts b/apps/web/cypress/support/commands.ts new file mode 100644 index 000000000..95857aea4 --- /dev/null +++ b/apps/web/cypress/support/commands.ts @@ -0,0 +1,37 @@ +/// +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) +// +// declare global { +// namespace Cypress { +// interface Chainable { +// login(email: string, password: string): Chainable +// drag(subject: string, options?: Partial): Chainable +// dismiss(subject: string, options?: Partial): Chainable +// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable +// } +// } +// } diff --git a/apps/web/cypress/support/e2e.ts b/apps/web/cypress/support/e2e.ts new file mode 100644 index 000000000..598ab5f0d --- /dev/null +++ b/apps/web/cypress/support/e2e.ts @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands'; + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/apps/web/cypress/tsconfig.json b/apps/web/cypress/tsconfig.json new file mode 100644 index 000000000..fb4800d97 --- /dev/null +++ b/apps/web/cypress/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["es5", "dom"], + "types": ["cypress", "node"], + "resolveJsonModule": true, + }, + "include": ["**/*.ts"] +} diff --git a/apps/web/package.json b/apps/web/package.json index 6fb9ed388..9f6501193 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -3,10 +3,15 @@ "private": true, "type": "module", "scripts": { + "dev:api": "env E2E_TEST=1 cargo run -p sd-server", "dev": "vite", "build": "vite build", "preview": "vite preview", "test": "VITE_SD_DEMO_MODE=true playwright test", + "test:e2e": "env WAIT_ON_TIMEOUT=1800000 start-test dev:api http://localhost:8080 dev http://localhost:8002 cy:run", + "test:interactive": "env WAIT_ON_TIMEOUT=1800000 start-test dev:api http://localhost:8080 dev http://localhost:8002 cy:open", + "cy:run": "env ELECTRON_EXTRA_LAUNCH_ARGS=--lang=en cypress run", + "cy:open": "env ELECTRON_EXTRA_LAUNCH_ARGS=--lang=en cypress open --e2e", "typecheck": "tsc -b", "lint": "eslint src --cache" }, @@ -19,19 +24,22 @@ "html2canvas": "^1.4.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router-dom": "^6.20.1" + "react-router-dom": "=6.20.1" }, "devDependencies": { - "@playwright/test": "^1.42.0", + "@playwright/test": "^1.42.1", "@sd/config": "workspace:*", "@sd/ui": "workspace:*", - "@types/react": "^18.2.61", - "@types/react-dom": "^18.2.19", - "autoprefixer": "^10.4.17", - "postcss": "^8.4.35", + "@types/react": "^18.2.67", + "@types/react-dom": "^18.2.22", + "autoprefixer": "^10.4.18", + "cypress": "^13.7.0", + "eslint-plugin-cypress": "^2.15.1", + "postcss": "^8.4.36", "rollup-plugin-visualizer": "^5.12.0", - "typescript": "^5.3.3", - "vite": "^5.1.4", - "vite-tsconfig-paths": "^4.3.1" + "start-server-and-test": "^2.0.3", + "typescript": "^5.4.2", + "vite": "^5.1.6", + "vite-tsconfig-paths": "^4.3.2" } } diff --git a/crates/sync/example/web/package.json b/crates/sync/example/web/package.json index 8d05e109e..33a5b18d2 100644 --- a/crates/sync/example/web/package.json +++ b/crates/sync/example/web/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@tanstack/react-query": "^4.36.1", - "typescript": "^5.3.3", + "typescript": "^5.4.2", "vite": "^5.0.10", "tailwindcss": "^3.3.3" } diff --git a/interface/app/onboarding/locations.tsx b/interface/app/onboarding/locations.tsx index 28c540ce6..f68111b14 100644 --- a/interface/app/onboarding/locations.tsx +++ b/interface/app/onboarding/locations.tsx @@ -69,6 +69,7 @@ export default function OnboardingLocations() { }), {} as Record ); + return Object.keys(locations).length > 0 ? locations : null; }, [data]); @@ -131,7 +132,10 @@ export default function OnboardingLocations() { }} /> -
+
{(Object.keys(systemLocations) as SystemLocation[]).map((location) => ( 18.x", + "@types/react": "^18.2.67", + "@types/react-dom": "^18.2.22", "@types/uuid": "^9.0.8", "tailwindcss": "^3.4.1", - "type-fest": "^4.10.3", - "typescript": "^5.3.3", - "vite": "^5.1.4", + "type-fest": "^4.12.0", + "typescript": "^5.4.2", + "vite": "^5.1.6", "vite-plugin-svgr": "^3.3.0" } } diff --git a/package.json b/package.json index d421e81bc..e7b1b2d3d 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "typecheck": "pnpm -r typecheck", "lint": "turbo run lint", "lint:fix": "turbo run lint -- --fix", - "clean": "git clean -qfX ." + "clean": "cargo clean; git clean -qfX ." }, "pnpm": { "patchedDependencies": { @@ -37,32 +37,32 @@ "@contentlayer/cli@0.3.4": "patches/@contentlayer__cli@0.3.4.patch" }, "overrides": { - "@types/node": "~18.19.21", + "@types/node": ">18.x", "react-router": "=6.20.1", "react-router-dom": "=6.20.1", "@remix-run/router": "=1.13.1", "@contentlayer/cli": "=0.3.4", - "@typescript-eslint/parser": "^7.1.0" + "@typescript-eslint/parser": "^7.1.1" } }, "devDependencies": { "@babel/plugin-syntax-import-assertions": "^7.23.3", "@cspell/dict-rust": "^4.0.2", "@cspell/dict-typescript": "^3.1.2", - "@ianvs/prettier-plugin-sort-imports": "^4.1.1", - "cspell": "^8.4.1", + "@ianvs/prettier-plugin-sort-imports": "^4.2.1", + "cspell": "^8.6.0", "prettier": "^3.2.5", - "prettier-plugin-tailwindcss": "^0.5.11", - "turbo": "^1.12.4", - "turbo-ignore": "^1.12.4", - "typescript": "^5.3.3", - "vite": "^5.1.4" + "prettier-plugin-tailwindcss": "^0.5.12", + "turbo": "^1.12.5", + "turbo-ignore": "^1.12.5", + "typescript": "^5.4.2", + "vite": "^5.1.6" }, "engines": { "pnpm": ">=8.0.0", "npm": "pnpm", "yarn": "pnpm", - "node": ">=18.17 <19 || >=20.1" + "node": ">=18.18 <19 || >=20.1" }, "eslintConfig": { "root": true diff --git a/packages/client/package.json b/packages/client/package.json index 100ebcf59..5942f9461 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -27,8 +27,8 @@ }, "devDependencies": { "@sd/config": "workspace:*", - "@types/react": "^18.2.61", - "typescript": "^5.3.3" + "@types/react": "^18.2.67", + "typescript": "^5.4.2" }, "peerDependencies": { "react": "^18.2" diff --git a/packages/config/package.json b/packages/config/package.json index 8d649e157..c3d5ad111 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -11,24 +11,24 @@ "lint": "eslint . --cache" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^7.1.0", - "@typescript-eslint/parser": "^7.1.0", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", "@vitejs/plugin-react-swc": "^3.6.0", "eslint": "^8.57.0", - "eslint-config-next": "^14.1.0", + "eslint-config-next": "^14.1.3", "eslint-config-prettier": "^9.1.0", - "eslint-config-turbo": "^1.12.4", + "eslint-config-turbo": "^1.12.5", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react": "^7.34.1", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-solid": "^0.13.1", - "eslint-plugin-tailwindcss": "^3.14.3", + "eslint-plugin-tailwindcss": "^3.15.1", "eslint-utils": "^3.0.0", "regexpp": "^3.2.0", "vite-plugin-html": "^3.2.2", "vite-plugin-i18next-loader": "^2.0.12", "vite-plugin-inspect": "^0.8.3", - "vite-plugin-solid": "^2.10.1", + "vite-plugin-solid": "^2.10.2", "vite-plugin-svgr": "^3.3.0" }, "dependencies": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 5873540a4..b955f477f 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -40,27 +40,27 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-loading-icons": "^1.1.0", - "react-router-dom": "^6.20.1", + "react-router-dom": "=6.20.1", "sonner": "^1.0.3", "use-debounce": "^9.0.4", "zod": "~3.22.4" }, "devDependencies": { - "@babel/core": "^7.23.9", + "@babel/core": "^7.24.0", "@headlessui/tailwindcss": "^0.2.0", "@sd/config": "workspace:*", - "@storybook/types": "^7.6.17", + "@storybook/types": "^8.0.1", "@tailwindcss/forms": "^0.5.7", "@tailwindcss/typography": "^0.5.10", - "@types/node": "~18.17.19", - "@types/react": "^18.2.61", - "@types/react-dom": "^18.2.19", - "autoprefixer": "^10.4.17", - "postcss": "^8.4.35", - "sass": "^1.71.1", + "@types/node": ">18.x", + "@types/react": "^18.2.67", + "@types/react-dom": "^18.2.22", + "autoprefixer": "^10.4.18", + "postcss": "^8.4.36", + "sass": "^1.72.0", "tailwindcss": "^3.4.1", "tailwindcss-animate": "^1.0.7", "tailwindcss-radix": "^2.8.0", - "typescript": "^5.3.3" + "typescript": "^5.4.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e05c6d62..92589e6f7 100644 Binary files a/pnpm-lock.yaml and b/pnpm-lock.yaml differ diff --git a/scripts/package.json b/scripts/package.json index c37dfc1ac..d0f4a0d15 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -22,21 +22,21 @@ "archive-wasm": "^1.6.1", "mustache": "^4.2.0", "semver": "^7.6.0", - "undici": "^6.6.2" + "undici": "^6.9.0" }, "devDependencies": { - "@babel/core": "^7.23.9", + "@babel/core": "^7.24.0", "@babel/eslint-parser": "^7.23.10", "@babel/eslint-plugin": "^7.23.5", "@types/mustache": "^4.2.5", - "@types/node": "~18.17.19", - "@typescript-eslint/eslint-plugin": "^7.1.0", - "@typescript-eslint/parser": "^7.1.0", + "@types/node": ">18.x", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-config-standard": "^17.1.0", - "eslint-plugin-jsdoc": "^48.2.0", + "eslint-plugin-jsdoc": "^48.2.1", "eslint-plugin-prettier": "^5.1.3", - "typescript": "^5.3.3" + "typescript": "^5.4.2" } }