diff --git a/.env.local.secret b/.env.local.secret index 631a10d..382c1fb 100644 Binary files a/.env.local.secret and b/.env.local.secret differ diff --git a/.env.playwright.secret b/.env.playwright.secret index c1fb9d3..1a7f545 100644 Binary files a/.env.playwright.secret and b/.env.playwright.secret differ diff --git a/.env.template b/.env.template index c51a544..21ea857 100644 --- a/.env.template +++ b/.env.template @@ -16,10 +16,6 @@ PUBLIC_SENTRY_PROJECT_ID= PROJECT_NAME=code-snippet-sharing -VITE_DEV_HOST=localhost -VITE_DEV_PORT=3000 -VITE_PREVIEW_PORT=3000 - POSTGRES_DATA_VOLUME_NAME=postgres-data-development ## Development and production diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 82dfe40..01f0886 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -3,53 +3,56 @@ module.exports = { parser: '@typescript-eslint/parser', parserOptions: { sourceType: 'module', - ecmaVersion: 2020, + ecmaVersion: 'latest', project: './tsconfig.json', extraFileExtensions: ['.svelte'], }, - plugins: [ - '@typescript-eslint', - 'import-no-duplicates-prefix-resolved-path', - 'prettier', - ], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - ], env: { browser: true, es2017: true, node: true, }, - settings: { - 'import/parsers': { - '@typescript-eslint/parser': ['.cjs', '.js', '.ts'], - }, - 'import/resolver': { - typescript: { - alwaysTryTypes: true, - }, - }, - }, + plugins: ['simple-import-sort', '@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/strict-type-checked', + 'plugin:@typescript-eslint/stylistic-type-checked', + 'prettier', + ], rules: { - 'prettier/prettier': 'error', 'no-unused-vars': 'off', // Useful for triggering Svelte reactivity 'no-self-assign': 'off', - '@typescript-eslint/no-unused-vars': [ - 'error', - { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }, - ], - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-floating-promises': 'error', + /* eslint-plugin-simple-import-sort */ + 'simple-import-sort/imports': 'error', + 'simple-import-sort/exports': 'error', + /* @typescript-eslint/eslint-plugin */ '@typescript-eslint/ban-ts-comment': 'off', - '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/consistent-indexed-object-style': 'off', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/no-confusing-void-expression': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-extraneous-class': 'off', + '@typescript-eslint/no-floating-promises': 'error', '@typescript-eslint/no-namespace': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-throw-literal': 'off', + '@typescript-eslint/no-unnecessary-condition': 'off', + '@typescript-eslint/no-unnecessary-type-arguments': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }, + ], + '@typescript-eslint/prefer-nullish-coalescing': 'off', + '@typescript-eslint/prefer-reduce-type-parameter': 'off', + '@typescript-eslint/unbound-method': 'off', }, overrides: [ { @@ -62,20 +65,48 @@ module.exports = { rules: {}, }, { - files: ['**/*.cjs'], + files: ['./scripts/testing/load/tests/**/*.js'], + rules: { + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + }, + }, + { + files: ['**/*.cjs', '**/*.js'], rules: { '@typescript-eslint/no-var-requires': 'off', }, }, { - // No `.spec.{js,ts}` files, because those are for server unit tests - files: ['src/**/*.{test,browser-test}.{js,ts}'], + files: ['src/**/*.{node-test,dom-test}.ts'], + rules: { + '@typescript-eslint/require-await': 'off', + }, + }, + { + files: ['src/**/*.node-test.{js,ts}'], + extends: ['plugin:jest-dom/recommended'], + rules: { + 'jest-dom/prefer-in-document': 'off', + }, + }, + { + files: ['src/**/*.dom-test.{js,ts}'], plugins: ['testing-library'], extends: ['plugin:testing-library/dom', 'plugin:jest-dom/recommended'], rules: { 'jest-dom/prefer-in-document': 'off', + 'testing-library/prefer-presence-queries': 'off', 'testing-library/prefer-screen-queries': 'off', }, }, + { + files: ['tests/playwright/**/*.{api-test,e2e-test}.{js,ts}'], + extends: ['plugin:playwright/recommended'], + rules: { + 'playwright/expect-expect': 'off', + }, + }, ], }; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a565cfb..39f5f2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -190,13 +190,13 @@ jobs: ref: ${{ github.head_ref }} - name: Setup todos CLI command run: | - curl -sSLo slsa-verifier https://github.com/slsa-framework/slsa-verifier/releases/download/v2.3.0/slsa-verifier-linux-amd64 \ - && echo "ea687149d658efecda64d69da999efb84bb695a3212f29548d4897994027172d slsa-verifier" | sha256sum -c - \ + curl -sSLo slsa-verifier https://github.com/slsa-framework/slsa-verifier/releases/download/v2.4.1/slsa-verifier-linux-amd64 \ + && echo "e81900c9f11a44276e1552afb7c1f6ea7b13ad9c6efdb920d97f23a76659e25f slsa-verifier" | sha256sum -c - \ && chmod +x slsa-verifier - curl -sSLo todos https://github.com/ianlewis/todos/releases/download/v0.5.0/todos-linux-amd64 \ - && curl -sSLo todos.intoto.jsonl https://github.com/ianlewis/todos/releases/download/v0.5.0/todos-linux-amd64.intoto.jsonl \ - && ./slsa-verifier verify-artifact todos --provenance-path todos.intoto.jsonl --source-uri github.com/ianlewis/todos --source-tag v0.5.0 \ + curl -sSLo todos https://github.com/ianlewis/todos/releases/download/v0.8.0/todos-linux-amd64 \ + && curl -sSLo todos.intoto.jsonl https://github.com/ianlewis/todos/releases/download/v0.8.0/todos-linux-amd64.intoto.jsonl \ + && ./slsa-verifier verify-artifact todos --provenance-path todos.intoto.jsonl --source-uri github.com/ianlewis/todos --source-tag v0.8.0 \ && chmod +x todos \ && sudo cp todos /usr/local/bin - name: Run todos CLI command diff --git a/.gitsecret/paths/mapping.cfg b/.gitsecret/paths/mapping.cfg index 2fc52c3..f2c5f45 100644 --- a/.gitsecret/paths/mapping.cfg +++ b/.gitsecret/paths/mapping.cfg @@ -1,2 +1,2 @@ -.env.local:ae055e688bd77cea8f52cea6ab36a0038b6374d2425526996d398c797f703d14 -.env.playwright:ae1afa4ec916e6c9ce9476856be19236d9f664512aba3d24e2df0ea14e210cbd +.env.local:abbe9da718d9249cfa0b265678517b558b7fbe9f67c38ad714e2f0d9da51c63e +.env.playwright:cc88f3266a590b9cd526fc40bb2dfd415fa65fc19ebaa7396a342dd10a137567 diff --git a/.vscode/extensions.template.json b/.vscode/extensions.template.json index dddae26..27f94b9 100644 --- a/.vscode/extensions.template.json +++ b/.vscode/extensions.template.json @@ -24,6 +24,7 @@ "stordahl.sveltekit-snippets", "proverbialninja.svelte-extractor", "vunguyentuan.vscode-postcss", - "wix.vscode-import-cost" + "wix.vscode-import-cost", + "vitest.explorer" ] } diff --git a/.vscode/settings.template.json b/.vscode/settings.template.json index dcf174a..6449ff3 100644 --- a/.vscode/settings.template.json +++ b/.vscode/settings.template.json @@ -1,5 +1,8 @@ { "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll": "explicit" + }, "files.watcherExclude": { "**/.git/objects/**": true, "**/.git/subtree-cache/**": true, @@ -18,6 +21,8 @@ "debug.javascript.terminalOptions": { "skipFiles": ["/**"] }, + "javascript.updateImportsOnFileMove.enabled": "always", + "typescript.updateImportsOnFileMove.enabled": "always", "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" // Identation settings -> .editorconfig @@ -50,9 +55,21 @@ "editor.defaultFormatter": "redhat.vscode-yaml" // Identation settings -> .editorconfig }, + "[markdown]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + // Identation settings -> .editorconfig + }, /* TypeScript */ "typescript.tsdk": "./node_modules/typescript/lib", "typescript.preferences.importModuleSpecifier": "shortest", + "typescript.inlayHints.parameterNames.enabled": "all", + // "typescript.inlayHints.variableTypes.enabled": true, + // "typescript.inlayHints.propertyDeclarationTypes.enabled": true, + "typescript.inlayHints.functionLikeReturnTypes.enabled": true, + // "typescript.inlayHints.parameterTypes.enabled": true, + "typescript.inlayHints.enumMemberValues.enabled": true, + "typescript.referencesCodeLens.enabled": true, + "typescript.implementationsCodeLens.enabled": true, /* GitHub Copilot */ "github.copilot.enable": { "*": true, @@ -75,11 +92,11 @@ /* Wallaby.js */ "wallaby.startAutomatically": false, /* ESLint */ - // "eslint.enable": true, - // "eslint.format.enable": true, + "eslint.enable": true, + "eslint.format.enable": true, "eslint.validate": ["javascript", "typescript", "svelte"], /* Prettier */ - // "prettier.enable": true, + "prettier.enable": true, /* Stylelint */ "stylelint.validate": ["postcss", "svelte"], /* cSpell */ diff --git a/nodemon.json b/nodemon.json deleted file mode 100644 index f2c1559..0000000 --- a/nodemon.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "verbose": true, - "ignore": [ - "node_modules", - "dist", - "build", - ".stryker-tmp", - ".nyc_output", - "coverage", - "target", - "reports", - ".svelte-kit" - ], - "ext": "json,js,cjs,mjs,ts,svelte" -} diff --git a/package-lock.json b/package-lock.json index c286930..093fcac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,16 +57,13 @@ "dotenv": "16.3.1", "eslint": "8.53.0", "eslint-config-prettier": "9.0.0", - "eslint-import-resolver-typescript": "3.6.1", - "eslint-plugin-import": "2.29.0", - "eslint-plugin-import-no-duplicates-prefix-resolved-path": "2.0.0", "eslint-plugin-jest-dom": "5.1.0", - "eslint-plugin-prettier": "5.0.1", + "eslint-plugin-playwright": "1.5.4", + "eslint-plugin-simple-import-sort": "12.0.0", "eslint-plugin-svelte": "2.34.1", "eslint-plugin-testing-library": "6.1.0", "ignore": "5.3.0", "jsdom": "23.0.1", - "nodemon": "3.0.1", "npm-check-updates": "16.14.6", "playwright": "1.39.0", "postcss": "8.4.31", @@ -2456,56 +2453,6 @@ "node": ">=14" } }, - "node_modules/@pkgr/utils": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", - "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "fast-glob": "^3.3.0", - "is-glob": "^4.0.3", - "open": "^9.1.0", - "picocolors": "^1.0.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 ||>=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@pkgr/utils/node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@pkgr/utils/node_modules/open": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", - "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", - "dev": true, - "dependencies": { - "default-browser": "^4.0.0", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@playwright/test": { "version": "1.39.0", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", @@ -3812,12 +3759,6 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, "node_modules/@types/lodash": { "version": "4.14.200", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.200.tgz", @@ -4801,25 +4742,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -4829,81 +4751,6 @@ "node": ">=8" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -5030,15 +4877,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -5189,18 +5027,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.44" - }, - "engines": { - "node": ">= 5.10.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -5301,21 +5127,6 @@ "semver": "^7.0.0" } }, - "node_modules/bundle-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", - "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", - "dev": true, - "dependencies": { - "run-applescript": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -6318,40 +6129,6 @@ "node": ">=0.10.0" } }, - "node_modules/default-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", - "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", - "dev": true, - "dependencies": { - "bundle-name": "^3.0.0", - "default-browser-id": "^3.0.0", - "execa": "^7.1.1", - "titleize": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -6651,19 +6428,6 @@ "node": ">=10.0.0" } }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -6700,59 +6464,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-get-iterator": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", @@ -6773,46 +6484,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -7275,198 +6946,58 @@ "eslint": ">=7.0.0" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", - "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "node_modules/eslint-plugin-jest-dom": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.1.0.tgz", + "integrity": "sha512-JIXZp+E/h/aGlP/rQc4tuOejiHlZXg65qw8JAJMIJA5VsdjOkss/SYcRSqBrQuEOytEM8JvngUjcz31d1RrCrA==", "dev": true, "dependencies": { - "debug": "^4.3.4", - "enhanced-resolve": "^5.12.0", - "eslint-module-utils": "^2.7.4", - "fast-glob": "^3.3.1", - "get-tsconfig": "^4.5.0", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3" + "@babel/runtime": "^7.16.3", + "requireindex": "^1.2.0" }, "engines": { - "node": "^14.18.0 ||>=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + "node": "^12.22.0 || ^14.17.0 ||>=16.0.0", + "npm": ">=6", + "yarn": ">=1" }, "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" + "@testing-library/dom": "^8.0.0 || ^9.0.0", + "eslint": "^6.8.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { - "eslint": { + "@testing-library/dom": { "optional": true } } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", - "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "node_modules/eslint-plugin-playwright": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.5.4.tgz", + "integrity": "sha512-J38Wy3Vc2f9y73J+KRmgXgbYI8TZ3zbz6qBbTj3PhpFndUS572jZ7kqQ3rJ9si5BaMHT7lmZzraO+3UjwIDV4Q==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" + "globals": "^13.23.0" }, "engines": { - "node": ">=4" + "node": ">=16.6.0" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": ">=8.40.0", + "eslint-plugin-jest": ">=25" + }, + "peerDependenciesMeta": { + "eslint-plugin-jest": { + "optional": true + } } }, - "node_modules/eslint-plugin-import-no-duplicates-prefix-resolved-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-no-duplicates-prefix-resolved-path/-/eslint-plugin-import-no-duplicates-prefix-resolved-path-2.0.0.tgz", - "integrity": "sha512-FRtQxcuUV+0W9KXfo2a2ZeAy6mXti8k6Nk/51zPTMyxOnTcPwbnNfcA3DVkG0g9z8Vk2UftSmQY1LGUz3darnA==", + "node_modules/eslint-plugin-simple-import-sort": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.0.0.tgz", + "integrity": "sha512-8o0dVEdAkYap0Cn5kNeklaKcT1nUsa3LITWEuFk3nJifOoD+5JQGoyDUW2W/iPWwBsNBJpyJS9y4je/BgxLcyQ==", "dev": true, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jest-dom": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.1.0.tgz", - "integrity": "sha512-JIXZp+E/h/aGlP/rQc4tuOejiHlZXg65qw8JAJMIJA5VsdjOkss/SYcRSqBrQuEOytEM8JvngUjcz31d1RrCrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.3", - "requireindex": "^1.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 ||>=16.0.0", - "npm": ">=6", - "yarn": ">=1" - }, - "peerDependencies": { - "@testing-library/dom": "^8.0.0 || ^9.0.0", - "eslint": "^6.8.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@testing-library/dom": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", - "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.5" - }, - "engines": { - "node": "^14.18.0 ||>=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } + "eslint": ">=5.0.0" } }, "node_modules/eslint-plugin-svelte": { @@ -7729,29 +7260,6 @@ "node": ">=6" } }, - "node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 ||>=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, "node_modules/exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -7790,12 +7298,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -8105,24 +7607,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -8216,22 +7700,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-tsconfig": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", @@ -8373,21 +7841,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/globalyzer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", @@ -8692,15 +8145,6 @@ "node": ">= 6" } }, - "node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, - "engines": { - "node": ">=14.18.0" - } - }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -8731,12 +8175,6 @@ "node": ">= 4" } }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true - }, "node_modules/ignore-walk": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.3.tgz", @@ -9372,39 +8810,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-inside-container/node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 ||>=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -9457,18 +8862,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-npm": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", @@ -9663,18 +9056,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-weakset": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", @@ -9932,18 +9313,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", @@ -11137,79 +10506,6 @@ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, - "node_modules/nodemon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", - "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -11684,79 +10980,33 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "dependencies": { "define-lazy-prop": "^2.0.0", @@ -13136,18 +12386,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/prettier-plugin-svelte": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.0.3.tgz", @@ -13366,12 +12604,6 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -14119,110 +13351,6 @@ "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", "dev": true }, - "node_modules/run-applescript": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", - "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/run-applescript/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/run-applescript/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/run-applescript/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/run-applescript/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-applescript/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -14304,24 +13432,6 @@ "node": ">=6" } }, - "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -14342,20 +13452,6 @@ } ] }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/safe-stable-stringify": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", @@ -14676,18 +13772,6 @@ "node": "^14.17.0 || ^16.13.0 ||>=18.0.0" } }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/sirv": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", @@ -14981,51 +14065,6 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -15051,15 +14090,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -15623,22 +14653,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/synckit": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", - "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", - "dev": true, - "dependencies": { - "@pkgr/utils": "^2.3.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": "^14.18.0 ||>=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -15727,15 +14741,6 @@ "node": ">=4" } }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/tar": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", @@ -15889,18 +14894,6 @@ "node": ">=14.0.0" } }, - "node_modules/titleize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", - "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -15940,18 +14933,6 @@ "node": ">=6" } }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, "node_modules/tough-cookie": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", @@ -16015,18 +14996,6 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -16131,71 +15100,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -16224,27 +15128,6 @@ "integrity": "sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==", "dev": true }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, "node_modules/undici": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", diff --git a/package.json b/package.json index f6e8406..16f501e 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "test:unit:dom:coverage": "npm run test:unit:dom -- --coverage", "test:unit:dom:debug": "npm run test:unit:dom -- --single-thread", "test:unit:browser": "vitest run --config vitest.browser.config.ts", - "test:unit:browser:learning": "vitest run --config vitest.browser.learning.config.ts", "test:api:only": "playwright test --config playwright.api.config.ts", "test:api:ui:only": "npm run test:api:only -- --ui", "test:e2e:only": "playwright test --config playwright.e2e.config.ts", @@ -35,8 +34,8 @@ "test:e2e:codegen:only": "playwright codegen", "test:playwright:report:show": "playwright show-report", "test:playwright:trace:show": "playwright show-trace", - "lint": "npm run lint:base && npm run lint:prettier && npm run lint:eslint && npm run lint:stylelint", - "lint:fix": "npm run lint:base && npm run lint:prettier:fix && npm run lint:eslint:fix && npm run lint:stylelint:fix", + "lint": "npm run lint:base && npm run lint:eslint && npm run lint:prettier && npm run lint:stylelint", + "lint:fix": "npm run lint:base && npm run lint:eslint:fix && npm run lint:prettier:fix && npm run lint:stylelint:fix", "lint:base": "npm run lint:types && npm run lint:svelte", "lint:types": "tsc --project ./tsconfig.json", "lint:svelte": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", @@ -105,16 +104,13 @@ "dotenv": "16.3.1", "eslint": "8.53.0", "eslint-config-prettier": "9.0.0", - "eslint-import-resolver-typescript": "3.6.1", - "eslint-plugin-import": "2.29.0", - "eslint-plugin-import-no-duplicates-prefix-resolved-path": "2.0.0", "eslint-plugin-jest-dom": "5.1.0", - "eslint-plugin-prettier": "5.0.1", + "eslint-plugin-playwright": "1.5.4", + "eslint-plugin-simple-import-sort": "12.0.0", "eslint-plugin-svelte": "2.34.1", "eslint-plugin-testing-library": "6.1.0", "ignore": "5.3.0", "jsdom": "23.0.1", - "nodemon": "3.0.1", "npm-check-updates": "16.14.6", "playwright": "1.39.0", "postcss": "8.4.31", diff --git a/playwright.api.config.ts b/playwright.api.config.ts index 4268629..4e90df3 100644 --- a/playwright.api.config.ts +++ b/playwright.api.config.ts @@ -1,10 +1,11 @@ import { defineConfig, devices } from '@playwright/test'; -import commonConfig from './playwright.common.config.ts'; import path from 'path'; + +import commonConfig from './playwright.common.config.ts'; import { - COMMON_SAVED_STATES_FOLDER, API_REPORTS_FOLDER, API_TESTS_FOLDER, + COMMON_SAVED_STATES_FOLDER, } from './tests/playwright/common/lib/constants.ts'; /** diff --git a/playwright.e2e.config.ts b/playwright.e2e.config.ts index 5f9f204..fdc6444 100644 --- a/playwright.e2e.config.ts +++ b/playwright.e2e.config.ts @@ -1,6 +1,7 @@ import { defineConfig, devices } from '@playwright/test'; -import commonConfig from './playwright.common.config.ts'; import path from 'path'; + +import commonConfig from './playwright.common.config.ts'; import { COMMON_SAVED_STATES_FOLDER, E2E_REPORTS_FOLDER, diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..ee97425 --- /dev/null +++ b/renovate.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + "schedule": ["before 5am on the first day of the month"], + "prConcurrentLimit": 1, + "separateMajorMinor": false, + "internalChecksFilter": "strict", + "minimumReleaseAge": "3", + "packageRules": [ + { + "matchUpdateTypes": ["major", "minor", "patch"], + "groupName": "all dependencies", + "groupSlug": "update-all-dependencies" + } + ] +} diff --git a/scripts/app/lib/lucia/client.js b/scripts/app/lib/lucia/client.js index ab1fbcf..55fc85f 100644 --- a/scripts/app/lib/lucia/client.js +++ b/scripts/app/lib/lucia/client.js @@ -1,8 +1,10 @@ // Polyfill the Web Crypto API, required only for Node.js runtime <= version 18 import 'lucia/polyfill/node'; + +import { prisma as prismaAdapter } from '@lucia-auth/adapter-prisma'; import { lucia } from 'lucia'; import { node as nodeMiddleware } from 'lucia/middleware'; -import { prisma as prismaAdapter } from '@lucia-auth/adapter-prisma'; + import { prisma as prismaClient } from '../prisma/client.js'; export const auth = lucia({ diff --git a/scripts/app/seeds/enumeration/seedCodeSnippets.js b/scripts/app/seeds/enumeration/seedCodeSnippets.js index 682e122..2ca1cee 100644 --- a/scripts/app/seeds/enumeration/seedCodeSnippets.js +++ b/scripts/app/seeds/enumeration/seedCodeSnippets.js @@ -1,6 +1,7 @@ -import { prisma } from '../../lib/prisma/client.js'; import { faker } from '@faker-js/faker'; +import { prisma } from '../../lib/prisma/client.js'; + const POSTGRES_CODE_SNIPPETS_SEQUENCE_NAME = 'code_snippets_id_seq'; const SEEDED_USER_ID = 'uop6wpmo6m20i6p'; const OTHER_SEEDED_USER_ID = 'zop6wpmo6m20i6p'; diff --git a/scripts/app/seeds/groups/development.js b/scripts/app/seeds/groups/development.js index d5adea9..143c6af 100644 --- a/scripts/app/seeds/groups/development.js +++ b/scripts/app/seeds/groups/development.js @@ -1,7 +1,8 @@ import { fileURLToPath } from 'url'; -import { seedUsersAndSessions } from '../enumeration/seedUsersAndSessions.js'; + import { logAndIgnoreError } from '../../lib/utils/errors.js'; import { seedCodeSnippets } from '../enumeration/seedCodeSnippets.js'; +import { seedUsersAndSessions } from '../enumeration/seedUsersAndSessions.js'; const filepath = fileURLToPath(import.meta.url); const filename = filepath.split('/').pop()?.split('.')[0]; diff --git a/scripts/app/seeds/groups/playwright.js b/scripts/app/seeds/groups/playwright.js index 6b91fcf..1169209 100644 --- a/scripts/app/seeds/groups/playwright.js +++ b/scripts/app/seeds/groups/playwright.js @@ -1,7 +1,8 @@ import { fileURLToPath } from 'url'; -import { seedUsersAndSessions } from '../enumeration/seedUsersAndSessions.js'; + import { deleteAll } from '../enumeration/deleteAll.js'; import { seedCodeSnippets } from '../enumeration/seedCodeSnippets.js'; +import { seedUsersAndSessions } from '../enumeration/seedUsersAndSessions.js'; const filepath = fileURLToPath(import.meta.url); const filename = filepath.split('/').pop()?.split('.')[0]; diff --git a/scripts/stack/_lib/actions.js b/scripts/stack/_lib/actions.js index bd27945..784ffc7 100644 --- a/scripts/stack/_lib/actions.js +++ b/scripts/stack/_lib/actions.js @@ -1,4 +1,5 @@ import { execSync, spawn } from 'child_process'; + import { displayDockerContainerLogs, startDockerizedStack, @@ -136,9 +137,7 @@ export async function startLocalApp() { await sleep(5000); try { - await waitUntilServiceIsAvailable( - `http://localhost:${process.env['VITE_DEV_PORT']}`, - ); + await waitUntilServiceIsAvailable('http://localhost:3000'); } catch (error) { console.error(error); console.error(`app (local): failed`); @@ -332,7 +331,7 @@ export function stopLocalApp() { try { console.log('app (local): stopping'); const appPid = execSync( - `ss -lnp | grep :${process.env['VITE_DEV_PORT']} | sed 's/.*pid=\\(.*\\),.*/\1円/g'`, + `ss -lnp | grep :3000 | sed 's/.*pid=\\(.*\\),.*/\1円/g'`, { env: process.env }, ) .toString() diff --git a/scripts/stack/_lib/utils/docker.js b/scripts/stack/_lib/utils/docker.js index 40f0db0..79b2e31 100644 --- a/scripts/stack/_lib/utils/docker.js +++ b/scripts/stack/_lib/utils/docker.js @@ -1,4 +1,5 @@ import { execSync } from 'child_process'; + import { sleep } from './misc.js'; /** @@ -39,8 +40,9 @@ export function getDockerContainerHealthStatus(containerName) { .trim() ); } catch (e) { + const error = /** @type {Error} */ (e); throw new Error( - `Failed to get health status of ${containerName} container: ${e}`, + `Failed to get health status of ${containerName} container: ${error.message}`, ); } diff --git a/scripts/stack/local/all/api/down.js b/scripts/stack/local/all/api/down.js index e213c4d..8222733 100755 --- a/scripts/stack/local/all/api/down.js +++ b/scripts/stack/local/all/api/down.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { stopDockerizedApi } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { stopDockerizedApi } from '../../../_lib/actions.js'; -import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/stack/local/all/api/headless.js b/scripts/stack/local/all/api/headless.js index ef43c1d..ee24780 100755 --- a/scripts/stack/local/all/api/headless.js +++ b/scripts/stack/local/all/api/headless.js @@ -1,11 +1,12 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; + +import { startDockerizedApi } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { startDockerizedApi } from '../../../_lib/actions.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; -import { execSync } from 'child_process'; import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; main().catch((e) => { diff --git a/scripts/stack/local/all/e2e/down.js b/scripts/stack/local/all/e2e/down.js index 87f6ff3..b64b028 100755 --- a/scripts/stack/local/all/e2e/down.js +++ b/scripts/stack/local/all/e2e/down.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { stopDockerizedE2E } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { stopDockerizedE2E } from '../../../_lib/actions.js'; -import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/stack/local/all/e2e/headless.js b/scripts/stack/local/all/e2e/headless.js index 9dde0db..ec26b08 100755 --- a/scripts/stack/local/all/e2e/headless.js +++ b/scripts/stack/local/all/e2e/headless.js @@ -1,11 +1,12 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; + +import { startDockerizedE2E } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { startDockerizedE2E } from '../../../_lib/actions.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; -import { execSync } from 'child_process'; import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; main().catch((e) => { diff --git a/scripts/stack/local/infra-app/playwright/api/headless.js b/scripts/stack/local/infra-app/playwright/api/headless.js index 7172323..be35f9d 100755 --- a/scripts/stack/local/infra-app/playwright/api/headless.js +++ b/scripts/stack/local/infra-app/playwright/api/headless.js @@ -1,15 +1,16 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { runLocalHeadlessApi, startDockerizedInfraApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { MANDATORY_ENV_VARS } from '../../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra-app/playwright/api/ui.js b/scripts/stack/local/infra-app/playwright/api/ui.js index da78c59..3e43b7b 100755 --- a/scripts/stack/local/infra-app/playwright/api/ui.js +++ b/scripts/stack/local/infra-app/playwright/api/ui.js @@ -1,15 +1,16 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { runLocalUiApi, startDockerizedInfraApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { MANDATORY_ENV_VARS } from '../../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra-app/playwright/down.js b/scripts/stack/local/infra-app/playwright/down.js index 92b0a0d..3714683 100755 --- a/scripts/stack/local/infra-app/playwright/down.js +++ b/scripts/stack/local/infra-app/playwright/down.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { stopDockerizedInfraApp } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { stopDockerizedInfraApp } from '../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from './_lib/constants.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/stack/local/infra-app/playwright/e2e/codegen.js b/scripts/stack/local/infra-app/playwright/e2e/codegen.js index a5949d9..581fed8 100755 --- a/scripts/stack/local/infra-app/playwright/e2e/codegen.js +++ b/scripts/stack/local/infra-app/playwright/e2e/codegen.js @@ -1,15 +1,16 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { runLocalCodegenE2E, startDockerizedInfraApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { MANDATORY_ENV_VARS } from '../../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra-app/playwright/e2e/headed.js b/scripts/stack/local/infra-app/playwright/e2e/headed.js index 3233dbf..628a639 100755 --- a/scripts/stack/local/infra-app/playwright/e2e/headed.js +++ b/scripts/stack/local/infra-app/playwright/e2e/headed.js @@ -1,15 +1,16 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { runLocalHeadedE2E, startDockerizedInfraApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { MANDATORY_ENV_VARS } from '../../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra-app/playwright/e2e/headless.js b/scripts/stack/local/infra-app/playwright/e2e/headless.js index d4a2582..532cbc3 100755 --- a/scripts/stack/local/infra-app/playwright/e2e/headless.js +++ b/scripts/stack/local/infra-app/playwright/e2e/headless.js @@ -1,15 +1,16 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { runLocalHeadlessE2E, startDockerizedInfraApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { MANDATORY_ENV_VARS } from '../../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra-app/playwright/e2e/ui.js b/scripts/stack/local/infra-app/playwright/e2e/ui.js index e6bc5d4..b25dcce 100755 --- a/scripts/stack/local/infra-app/playwright/e2e/ui.js +++ b/scripts/stack/local/infra-app/playwright/e2e/ui.js @@ -1,15 +1,16 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { runLocalUiE2E, startDockerizedInfraApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { MANDATORY_ENV_VARS } from '../../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra-app/stack-only/down.js b/scripts/stack/local/infra-app/stack-only/down.js index 30c5bdb..65cedb9 100755 --- a/scripts/stack/local/infra-app/stack-only/down.js +++ b/scripts/stack/local/infra-app/stack-only/down.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { stopDockerizedInfraApp } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { stopDockerizedInfraApp } from '../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from './_lib/constants.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/stack/local/infra-app/stack-only/infra-app-seed.js b/scripts/stack/local/infra-app/stack-only/infra-app-seed.js index eacf24a..55fa52e 100755 --- a/scripts/stack/local/infra-app/stack-only/infra-app-seed.js +++ b/scripts/stack/local/infra-app/stack-only/infra-app-seed.js @@ -1,14 +1,15 @@ #!/usr/bin/env node import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; -import { getPaths } from '../../../_lib/utils/paths.js'; + import { performLocalSeeding, startDockerizedInfraApp, } from '../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from './_lib/constants.js'; +import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; +import { getPaths } from '../../../_lib/utils/paths.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra-app/stack-only/infra-app.js b/scripts/stack/local/infra-app/stack-only/infra-app.js index 0b5302f..eb16c92 100755 --- a/scripts/stack/local/infra-app/stack-only/infra-app.js +++ b/scripts/stack/local/infra-app/stack-only/infra-app.js @@ -1,11 +1,12 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { startDockerizedInfraApp } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { startDockerizedInfraApp } from '../../../_lib/actions.js'; -import { ENV_FILE, DOCKER_COMPOSE_FILES } from './_lib/constants.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { DOCKER_COMPOSE_FILES, ENV_FILE } from './_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/_lib/constants.js b/scripts/stack/local/infra/_lib/constants.js index 1926469..20ed754 100644 --- a/scripts/stack/local/infra/_lib/constants.js +++ b/scripts/stack/local/infra/_lib/constants.js @@ -2,6 +2,5 @@ export const MANDATORY_ENV_VARS = [ 'PROJECT_NAME', 'POSTGRES_DATA_VOLUME_NAME', 'DATABASE_URL', - 'VITE_DEV_PORT', ]; export const DOCKER_COMPOSE_FILES = ['docker-compose.local.infra-only.yml']; diff --git a/scripts/stack/local/infra/playwright/api/headless.js b/scripts/stack/local/infra/playwright/api/headless.js index a100a87..80df916 100755 --- a/scripts/stack/local/infra/playwright/api/headless.js +++ b/scripts/stack/local/infra/playwright/api/headless.js @@ -1,20 +1,21 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { performLocalMigration, runLocalHeadlessApi, startDockerizedInfra, startLocalApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS, } from '../../_lib/constants.js'; +import { ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/playwright/api/ui.js b/scripts/stack/local/infra/playwright/api/ui.js index 29793e1..3f2fc70 100755 --- a/scripts/stack/local/infra/playwright/api/ui.js +++ b/scripts/stack/local/infra/playwright/api/ui.js @@ -1,20 +1,21 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { performLocalMigration, runLocalUiApi, startDockerizedInfra, startLocalApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS, } from '../../_lib/constants.js'; +import { ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/playwright/down.js b/scripts/stack/local/infra/playwright/down.js index 0160922..6816485 100755 --- a/scripts/stack/local/infra/playwright/down.js +++ b/scripts/stack/local/infra/playwright/down.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { stopDockerizedInfra, stopLocalApp } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { stopDockerizedInfra, stopLocalApp } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/stack/local/infra/playwright/e2e/codegen.js b/scripts/stack/local/infra/playwright/e2e/codegen.js index a21f7e3..ef69457 100755 --- a/scripts/stack/local/infra/playwright/e2e/codegen.js +++ b/scripts/stack/local/infra/playwright/e2e/codegen.js @@ -1,20 +1,21 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { performLocalMigration, runLocalCodegenE2E, startDockerizedInfra, startLocalApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS, } from '../../_lib/constants.js'; +import { ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/playwright/e2e/headed.js b/scripts/stack/local/infra/playwright/e2e/headed.js index ca15ebe..ba99819 100755 --- a/scripts/stack/local/infra/playwright/e2e/headed.js +++ b/scripts/stack/local/infra/playwright/e2e/headed.js @@ -1,20 +1,21 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { performLocalMigration, runLocalHeadedE2E, startDockerizedInfra, startLocalApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS, } from '../../_lib/constants.js'; +import { ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/playwright/e2e/headless.js b/scripts/stack/local/infra/playwright/e2e/headless.js index b5b2fe2..5b0969d 100755 --- a/scripts/stack/local/infra/playwright/e2e/headless.js +++ b/scripts/stack/local/infra/playwright/e2e/headless.js @@ -1,20 +1,21 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { performLocalMigration, runLocalHeadlessE2E, startDockerizedInfra, startLocalApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS, } from '../../_lib/constants.js'; +import { ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/playwright/e2e/ui.js b/scripts/stack/local/infra/playwright/e2e/ui.js index f7feba8..a0419e8 100755 --- a/scripts/stack/local/infra/playwright/e2e/ui.js +++ b/scripts/stack/local/infra/playwright/e2e/ui.js @@ -1,20 +1,21 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; -import { getPaths } from '../../../../_lib/utils/paths.js'; + import { performLocalMigration, runLocalUiE2E, startDockerizedInfra, startLocalApp, } from '../../../../_lib/actions.js'; -import { ENV_FILE } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { loadAndCheckEnvVars } from '../../../../_lib/utils/env.js'; +import { getPaths } from '../../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS, } from '../../_lib/constants.js'; +import { ENV_FILE } from '../_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/playwright/infra-app.js b/scripts/stack/local/infra/playwright/infra-app.js index 057a0e9..a36166d 100755 --- a/scripts/stack/local/infra/playwright/infra-app.js +++ b/scripts/stack/local/infra/playwright/infra-app.js @@ -1,15 +1,16 @@ #!/usr/bin/env node import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; -import { getPaths } from '../../../_lib/utils/paths.js'; + import { performLocalMigration, startDockerizedInfra, startLocalApp, } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; +import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; +import { getPaths } from '../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { ENV_FILE } from './_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/stack-only/app.js b/scripts/stack/local/infra/stack-only/app.js index 3622bd4..9b1eccc 100755 --- a/scripts/stack/local/infra/stack-only/app.js +++ b/scripts/stack/local/infra/stack-only/app.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { runLocalApp } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { runLocalApp } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/stack/local/infra/stack-only/down.js b/scripts/stack/local/infra/stack-only/down.js index 826b61a..b7b8404 100755 --- a/scripts/stack/local/infra/stack-only/down.js +++ b/scripts/stack/local/infra/stack-only/down.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { stopDockerizedInfra, stopLocalApp } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { stopDockerizedInfra, stopLocalApp } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/stack/local/infra/stack-only/infra-app.js b/scripts/stack/local/infra/stack-only/infra-app.js index 531ff88..fedb610 100755 --- a/scripts/stack/local/infra/stack-only/infra-app.js +++ b/scripts/stack/local/infra/stack-only/infra-app.js @@ -1,16 +1,17 @@ #!/usr/bin/env node +import { execSync } from 'child_process'; import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; -import { getPaths } from '../../../_lib/utils/paths.js'; + import { performLocalMigration, runLocalApp, startDockerizedInfra, } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; +import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; +import { getPaths } from '../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS } from '../_lib/constants.js'; -import { execSync } from 'child_process'; +import { ENV_FILE } from './_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/stack-only/infra-migrate.js b/scripts/stack/local/infra/stack-only/infra-migrate.js index 23705c5..05c633b 100755 --- a/scripts/stack/local/infra/stack-only/infra-migrate.js +++ b/scripts/stack/local/infra/stack-only/infra-migrate.js @@ -1,14 +1,15 @@ #!/usr/bin/env node import { program } from 'commander'; -import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; -import { getPaths } from '../../../_lib/utils/paths.js'; + import { performLocalMigration, startDockerizedInfra, } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; +import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; +import { getPaths } from '../../../_lib/utils/paths.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { ENV_FILE } from './_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/stack-only/infra.js b/scripts/stack/local/infra/stack-only/infra.js index 8ec598a..549f24b 100755 --- a/scripts/stack/local/infra/stack-only/infra.js +++ b/scripts/stack/local/infra/stack-only/infra.js @@ -1,11 +1,12 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { startDockerizedInfra } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { startDockerizedInfra } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; import { DOCKER_COMPOSE_FILES, MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { ENV_FILE } from './_lib/constants.js'; main().catch((e) => { console.error(e); diff --git a/scripts/stack/local/infra/stack-only/migrate.js b/scripts/stack/local/infra/stack-only/migrate.js index 0111d17..2a86d6e 100755 --- a/scripts/stack/local/infra/stack-only/migrate.js +++ b/scripts/stack/local/infra/stack-only/migrate.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { performLocalMigration } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { performLocalMigration } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/stack/local/infra/stack-only/seed.js b/scripts/stack/local/infra/stack-only/seed.js index 7fa6d76..7a0c904 100755 --- a/scripts/stack/local/infra/stack-only/seed.js +++ b/scripts/stack/local/infra/stack-only/seed.js @@ -1,18 +1,21 @@ #!/usr/bin/env node import { program } from 'commander'; + +import { performLocalSeeding } from '../../../_lib/actions.js'; import { loadAndCheckEnvVars } from '../../../_lib/utils/env.js'; import { getPaths } from '../../../_lib/utils/paths.js'; -import { performLocalSeeding } from '../../../_lib/actions.js'; -import { ENV_FILE } from './_lib/constants.js'; import { MANDATORY_ENV_VARS } from '../_lib/constants.js'; +import { ENV_FILE } from './_lib/constants.js'; -main().catch((e) => { +try { + main(); +} catch (e) { console.error(e); process.exit(1); -}); +} -async function main() { +function main() { const scriptPath = /** @type {string} */ (process.argv[1]); const paths = getPaths(scriptPath, ENV_FILE); diff --git a/scripts/testing/load/commands/run-sh.sh b/scripts/testing/load/commands/run-sh.sh new file mode 100755 index 0000000..3de0ce8 --- /dev/null +++ b/scripts/testing/load/commands/run-sh.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -eu + +docker container run \ + --name "graphana-k6" \ + --interactive \ + --tty \ + --rm \ + --user "k6" \ + --workdir "/home/k6" \ + --volume "${PWD}:/home/k6" \ + --entrypoint "/bin/sh" \ + "grafana/k6:0.49.0" diff --git a/scripts/testing/load/commands/run.sh b/scripts/testing/load/commands/run.sh new file mode 100755 index 0000000..2596284 --- /dev/null +++ b/scripts/testing/load/commands/run.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -eu + +docker container run \ + --name "graphana-k6" \ + --interactive \ + --tty \ + --rm \ + --user "root" \ + --workdir "/home/k6" \ + --volume "${PWD}:/home/k6" \ + "grafana/k6:0.49.0" \ + $@ diff --git a/scripts/testing/load/tests/_template.load-test.js b/scripts/testing/load/tests/_template.load-test.js new file mode 100644 index 0000000..251bc28 --- /dev/null +++ b/scripts/testing/load/tests/_template.load-test.js @@ -0,0 +1,63 @@ +// @ts-expect-error +import { sleep } from 'k6'; +// @ts-expect-error +import http from 'k6/http'; + +export const options = { + // A number specifying the number of VUs to run concurrently. + vus: 10, + // A string specifying the total duration of the test run. + duration: '30s', + + // The following section contains configuration options for execution of this + // test script in Grafana Cloud. + // + // See https://grafana.com/docs/grafana-cloud/k6/get-started/run-cloud-tests-from-the-cli/ + // to learn about authoring and running k6 test scripts in Grafana k6 Cloud. + // + // ext: { + // loadimpact: { + // // The ID of the project to which the test is assigned in the k6 Cloud UI. + // // By default tests are executed in default project. + // projectID: "", + // // The name of the test in the k6 Cloud UI. + // // Test runs with the same name will be grouped. + // name: "script.js" + // } + // }, + + // Uncomment this section to enable the use of Browser API in your tests. + // + // See https://grafana.com/docs/k6/latest/using-k6-browser/running-browser-tests/ to learn more + // about using Browser API in your test scripts. + // + // scenarios: { + // // The scenario name appears in the result summary, tags, and so on. + // // You can give the scenario any name, as long as each name in the script is unique. + // ui: { + // // Executor is a mandatory parameter for browser-based tests. + // // Shared iterations in this case tells k6 to reuse VUs to execute iterations. + // // + // // See https://grafana.com/docs/k6/latest/using-k6/scenarios/executors/ for other executor types. + // executor: 'shared-iterations', + // options: { + // browser: { + // // This is a mandatory parameter that instructs k6 to launch and + // // connect to a chromium-based browser, and use it to run UI-based + // // tests. + // type: 'chromium', + // }, + // }, + // }, + // } +}; + +// The function that defines VU logic. +// +// See https://grafana.com/docs/k6/latest/examples/get-started-with-k6/ to learn more +// about authoring k6 scripts. +// +export default function () { + http.get('https://test.k6.io'); + sleep(1); +} diff --git a/scripts/testing/load/tests/load-1.load-test.js b/scripts/testing/load/tests/load-1.load-test.js new file mode 100644 index 0000000..40470b0 --- /dev/null +++ b/scripts/testing/load/tests/load-1.load-test.js @@ -0,0 +1,47 @@ +// @ts-expect-error +import { htmlReport } from 'https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js'; +// @ts-expect-error +import { check, sleep } from 'k6'; +// @ts-expect-error +import http from 'k6/http'; +// @ts-expect-error +import { Rate } from 'k6/metrics'; + +// Define the failure rate +let failureRate = new Rate('failed_requests'); + +export let options = { + stages: [ + { duration: '10s', target: 10 }, // ramp up to 5 requests per second over 10 seconds + { duration: '10s', target: 10 }, // stay at 5 requests per second for 10 seconds + { duration: '10s', target: 1 }, // ramp down to 1 request per second over 10 seconds + ], + thresholds: { + 'http_req_duration{scenario:default}': ['p(95)<5000'], // Test fails if 95th percentile of request durations is higher than 5 seconds + failed_requests: ['rate<0.01'], // Fail if more than 1% of requests fail + }, +}; + +export default function () { + let response = http.get('http://staging-code-snippet-sharing.nodeexx.com'); + + // Check each response for a 200 status code + const checkRes = check(response, { + // @ts-expect-error + 'status is 200': (r) => r.status === 200, + }); + + // Track the failed requests + failureRate.add(!checkRes); + + // Since the test doesn't precisely control the request rate to exactly match the target, + // sleeping for a short duration helps to regulate the execution pace. + sleep(1); +} + +// @ts-expect-error +export function handleSummary(data) { + return { + 'summary.html': htmlReport(data), + }; +} diff --git a/src/app.d.ts b/src/app.d.ts index 5969186..8a461d2 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -7,11 +7,11 @@ declare global { type Auth = import('$lib/server/lucia/types').Auth; // Database user = AuthUserSchema // Properties of the auth user schema that Lucia can be aware of - type DatabaseUserAttributes = { + interface DatabaseUserAttributes { email: string; email_verified: boolean; created_at?: Date; - }; + } type DatabaseSessionAttributes = Record; } @@ -27,7 +27,6 @@ declare global { interface PageData { flash?: GlobalMessage; authUser: import('$lib/shared/lucia/types').AuthUser | null; - doesRequireAuth?: boolean; } // interface Platform {} diff --git a/src/hooks.client.ts b/src/hooks.client.ts index 7c49cda..078c120 100644 --- a/src/hooks.client.ts +++ b/src/hooks.client.ts @@ -1,13 +1,14 @@ -import { dev } from '$app/environment'; import type { HandleClientError } from '@sveltejs/kit'; + +import { dev } from '$app/environment'; import { config } from '$lib/client/core/config'; -import { handleErrorWithSentry, setupSentryClient } from '$lib/shared/sentry'; +import { logger } from '$lib/client/logging'; import { setupBrowserPosthogClient } from '$lib/client/posthog'; import { getClientSentryIntegrations, setClientPosthogSessionId, } from '$lib/client/sentry/utils'; -import { logger } from '$lib/client/logging'; +import { handleErrorWithSentry, setupSentryClient } from '$lib/shared/sentry'; setupBrowserPosthogClient(config.posthog.projectApiKey, config.posthog.apiHost); setupSentryClient({ @@ -24,9 +25,9 @@ setupSentryClient({ }); setClientPosthogSessionId(); -logger.debug('Client app started'); +logger.info('Starting the app client...'); -export const handleError = handleErrorWithSentry((async ({ error }) => { +export const handleError = handleErrorWithSentry((({ error }) => { const message = 'Internal Client Error'; if (dev) { console.error(message, error); diff --git a/src/hooks.server.ts b/src/hooks.server.ts index a38e44a..8d298c7 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,21 +1,22 @@ +import type { Handle, HandleServerError } from '@sveltejs/kit'; +import { sequence } from '@sveltejs/kit/hooks'; + +import { config } from '$lib/server/core/config'; import { checkMandatoryPrivateEnvVarsHandle, maintenanceModeHandle, } from '$lib/server/core/hooks'; import { addAuthDataToLocalHandle } from '$lib/server/lucia/hooks'; -import { sequence } from '@sveltejs/kit/hooks'; -import { config } from '$lib/server/core/config'; -import type { Handle, HandleServerError } from '@sveltejs/kit'; +import { posthog, setupNodePosthogClient } from '$lib/server/posthog'; +import { roarr } from '$lib/server/roarr'; +import { httpLogHandle } from '$lib/server/roarr/hooks'; +import { setSentryUserIdentity } from '$lib/server/sentry/hooks'; +import { getServerSentryIntegrations } from '$lib/server/sentry/utils'; import { handleErrorWithSentry, sentry, setupSentryClient, } from '$lib/shared/sentry'; -import { setSentryUserIdentity } from '$lib/server/sentry/hooks'; -import { posthog, setupNodePosthogClient } from '$lib/server/posthog'; -import { getServerSentryIntegrations } from '$lib/server/sentry/utils'; -import { roarr } from '$lib/server/roarr'; -import { httpLogHandle } from '$lib/server/roarr/hooks'; setupNodePosthogClient(config.posthog.projectApiKey, config.posthog.apiHost); setupSentryClient({ @@ -53,7 +54,7 @@ export const handle = (async (input) => { return sequence(...nonMaintenanceModeHandles)(input); }) satisfies Handle; -export const handleError = handleErrorWithSentry((async ({ error }) => { +export const handleError = handleErrorWithSentry((({ error }) => { const message = 'Internal Server Error'; console.error(message, error); @@ -63,6 +64,7 @@ export const handleError = handleErrorWithSentry((async ({ error }) => { }; }) satisfies HandleServerError); +// eslint-disable-next-line @typescript-eslint/no-misused-promises process.on('SIGINT', async () => { console.info( 'Got SIGINT (e.g. `Ctrl+C`). Graceful shutdown ', @@ -70,6 +72,7 @@ process.on('SIGINT', async () => { ); await shutdownGracefully(); }); +// eslint-disable-next-line @typescript-eslint/no-misused-promises process.on('SIGTERM', async () => { console.info( 'Got SIGTERM (e.g. `docker container stop`). Graceful shutdown ', diff --git a/src/index.browser-test.ts b/src/index.browser-test.ts deleted file mode 100644 index 964d287..0000000 --- a/src/index.browser-test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { describe, it, expect } from 'vitest'; - -describe('sum test', () => { - it('adds 1 + 2 to equal 3', () => { - expect(1 + 2).toBe(3); - }); -}); diff --git a/src/index.dom-test.ts b/src/index.dom-test.ts deleted file mode 100644 index 964d287..0000000 --- a/src/index.dom-test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { describe, it, expect } from 'vitest'; - -describe('sum test', () => { - it('adds 1 + 2 to equal 3', () => { - expect(1 + 2).toBe(3); - }); -}); diff --git a/src/index.node-test.ts b/src/index.node-test.ts deleted file mode 100644 index 964d287..0000000 --- a/src/index.node-test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { describe, it, expect } from 'vitest'; - -describe('sum test', () => { - it('adds 1 + 2 to equal 3', () => { - expect(1 + 2).toBe(3); - }); -}); diff --git a/src/lib/client/components/app-shell/AppBar.svelte b/src/lib/client/components/app-shell/AppBar.svelte index 4fab452..f58fb9d 100644 --- a/src/lib/client/components/app-shell/AppBar.svelte +++ b/src/lib/client/components/app-shell/AppBar.svelte @@ -1,5 +1,6 @@ diff --git a/src/lib/client/components/app-shell/AppBar.svelte.dom-test.ts b/src/lib/client/components/app-shell/AppBar.svelte.dom-test.ts index 2c0d8c3..d7e7454 100644 --- a/src/lib/client/components/app-shell/AppBar.svelte.dom-test.ts +++ b/src/lib/client/components/app-shell/AppBar.svelte.dom-test.ts @@ -1,5 +1,6 @@ -import { describe, it, expect, afterEach } from 'vitest'; -import { render, cleanup } from '@testing-library/svelte'; +import { cleanup, render } from '@testing-library/svelte'; +import { afterEach, describe, expect, it } from 'vitest'; + import Component from './AppBar.svelte'; describe(Component.name, () => { diff --git a/src/lib/client/components/app-shell/AppMenuButton.svelte b/src/lib/client/components/app-shell/AppMenuButton.svelte index e12233b..766a930 100644 --- a/src/lib/client/components/app-shell/AppMenuButton.svelte +++ b/src/lib/client/components/app-shell/AppMenuButton.svelte @@ -2,8 +2,8 @@ import IconUser from '~icons/fa6-solid/user'; import { page } from '$app/stores'; import { - ORIGINAL_PATH_URL_QUERY_PARAM_NAME, encodeOriginalPath, + ORIGINAL_PATH_URL_QUERY_PARAM_NAME, } from '$lib/shared/core/utils'; $: signInPath = getSignInPath($page.url); diff --git a/src/lib/client/components/app-shell/AppMenuButton.svelte.dom-test.ts b/src/lib/client/components/app-shell/AppMenuButton.svelte.dom-test.ts index 16d4471..67326f1 100644 --- a/src/lib/client/components/app-shell/AppMenuButton.svelte.dom-test.ts +++ b/src/lib/client/components/app-shell/AppMenuButton.svelte.dom-test.ts @@ -1,14 +1,16 @@ -import { describe, it, expect, vi, afterEach } from 'vitest'; -import { render, cleanup } from '@testing-library/svelte'; -import Component from './AppMenuButton.svelte'; +import type { Page } from '@sveltejs/kit'; +import { cleanup, render } from '@testing-library/svelte'; +import { readable } from 'svelte/store'; +import { afterEach, describe, expect, it, vi } from 'vitest'; + +import * as appStores from '$app/stores'; +import type { AuthUser } from '$lib/shared/lucia/types'; import { - SveltekitDefaultMocks, defaultMockAppStoresPageValue, + SveltekitDefaultMocks, } from '$lib/shared/sveltekit/testing'; -import type { AuthUser } from '$lib/shared/lucia/types'; -import * as appStores from '$app/stores'; -import { readable } from 'svelte/store'; -import type { Page } from '@sveltejs/kit'; + +import Component from './AppMenuButton.svelte'; describe(Component.name, () => { afterEach(() => { diff --git a/src/lib/client/components/app-shell/AppShell.svelte b/src/lib/client/components/app-shell/AppShell.svelte index 19f59de..2702f85 100644 --- a/src/lib/client/components/app-shell/AppShell.svelte +++ b/src/lib/client/components/app-shell/AppShell.svelte @@ -1,5 +1,6 @@ diff --git a/src/lib/client/core/config/index.ts b/src/lib/client/core/config/index.ts index a216636..bf10dfb 100644 --- a/src/lib/client/core/config/index.ts +++ b/src/lib/client/core/config/index.ts @@ -1,8 +1,8 @@ import { - PUBLIC_POSTHOG_PROJECT_API_KEY, PUBLIC_POSTHOG_API_HOST, - PUBLIC_SENTRY_ENVIRONMENT, + PUBLIC_POSTHOG_PROJECT_API_KEY, PUBLIC_SENTRY_DSN, + PUBLIC_SENTRY_ENVIRONMENT, PUBLIC_SENTRY_ORGANIZATION, PUBLIC_SENTRY_PROJECT_ID, } from '$env/static/public'; diff --git a/src/lib/client/core/stores/previous-app-page.store.dom-test.ts b/src/lib/client/core/stores/previous-app-page.store.dom-test.ts index 43bd66f..2c68405 100644 --- a/src/lib/client/core/stores/previous-app-page.store.dom-test.ts +++ b/src/lib/client/core/stores/previous-app-page.store.dom-test.ts @@ -1,16 +1,18 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { _createPreviousAppPageStore } from './previous-app-page.store'; -import * as appStoresModule from '$app/stores'; import type { Navigation, NavigationTarget } from '@sveltejs/kit'; import { - writable, - type Unsubscriber, - type Writable, type Readable, type Subscriber, + type Unsubscriber, + type Writable, + writable, } from 'svelte/store'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import * as appStoresModule from '$app/stores'; import { mockAppStoresNavigatingValue } from '$lib/shared/sveltekit/testing'; +import { _createPreviousAppPageStore } from './previous-app-page.store'; + describe(_createPreviousAppPageStore.name, () => { const defaultPreviousAppPageSubscriber: Subscriber< NavigationTarget | undefined diff --git a/src/lib/client/core/stores/previous-app-page.store.ts b/src/lib/client/core/stores/previous-app-page.store.ts index 73b142b..9f9f64d 100644 --- a/src/lib/client/core/stores/previous-app-page.store.ts +++ b/src/lib/client/core/stores/previous-app-page.store.ts @@ -1,12 +1,13 @@ -import { navigating } from '$app/stores'; import type { NavigationTarget } from '@sveltejs/kit'; import { - writable, - type Unsubscriber, - type Subscriber, type Invalidator, + type Subscriber, + type Unsubscriber, + writable, } from 'svelte/store'; +import { navigating } from '$app/stores'; + export function _createPreviousAppPageStore() { const previousAppPage = writable(); diff --git a/src/lib/client/core/utils/index.ts b/src/lib/client/core/utils/index.ts index 375131f..c147feb 100644 --- a/src/lib/client/core/utils/index.ts +++ b/src/lib/client/core/utils/index.ts @@ -1,2 +1,2 @@ -export * from './navigation.utils'; export * from './linting.utils'; +export * from './navigation.utils'; diff --git a/src/lib/client/core/utils/navigation.utils.dom-test.ts b/src/lib/client/core/utils/navigation.utils.dom-test.ts index 7f02018..036919d 100644 --- a/src/lib/client/core/utils/navigation.utils.dom-test.ts +++ b/src/lib/client/core/utils/navigation.utils.dom-test.ts @@ -1,20 +1,22 @@ +import type { NavigationTarget, Page } from '@sveltejs/kit'; +import { type Writable, writable } from 'svelte/store'; import { + afterEach, + beforeEach, describe, - it, expect, - beforeEach, - afterEach, - vi, + it, type MockInstance, + vi, } from 'vitest'; + import * as appNavigationModule from '$app/navigation'; -import { goBack } from './navigation.utils'; -import { writable, type Writable } from 'svelte/store'; -import type { NavigationTarget, Page } from '@sveltejs/kit'; -import { defaultMockAppStoresPageValue } from '$lib/shared/sveltekit/testing'; import * as appStoresModule from '$app/stores'; import * as previousAppPageStoreModule from '$lib/client/core/stores/previous-app-page.store'; +import { defaultMockAppStoresPageValue } from '$lib/shared/sveltekit/testing'; + import { mockPreviousAppPageValue } from '../stores/testing'; +import { goBack } from './navigation.utils'; describe(goBack.name, () => { let previousAppPageStore: Writable; diff --git a/src/lib/client/core/utils/navigation.utils.ts b/src/lib/client/core/utils/navigation.utils.ts index cbbefb3..18693e0 100644 --- a/src/lib/client/core/utils/navigation.utils.ts +++ b/src/lib/client/core/utils/navigation.utils.ts @@ -1,6 +1,8 @@ +import { get } from 'svelte/store'; + import { goto } from '$app/navigation'; import { page } from '$app/stores'; -import { get } from 'svelte/store'; + import { previousAppPage } from '../stores/previous-app-page.store'; export async function goBack() { diff --git a/src/lib/client/global-messages/utils/index.dom-test.ts b/src/lib/client/global-messages/utils/index.dom-test.ts index 1ffe0be..499b9b1 100644 --- a/src/lib/client/global-messages/utils/index.dom-test.ts +++ b/src/lib/client/global-messages/utils/index.dom-test.ts @@ -1,15 +1,17 @@ +import type { ToastStore } from '@skeletonlabs/skeleton'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { z } from 'zod'; + +import * as appEnvironmentModule from '$app/environment'; +import type { SuperformsOnErrorResult } from '$lib/client/superforms/types'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + import { createFlashToastSubscriber, showToast, showToastIfFormMessagePresent, showToastOnInternetDisconnect, } from '.'; -import type { ToastStore } from '@skeletonlabs/skeleton'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; -import * as appEnvironmentModule from '$app/environment'; -import { z } from 'zod'; -import type { SuperformsOnErrorResult } from '$lib/client/superforms/types'; describe(showToast.name, () => { let mockToastStore: ToastStore; diff --git a/src/lib/client/global-messages/utils/index.ts b/src/lib/client/global-messages/utils/index.ts index f3fdf0e..512c02a 100644 --- a/src/lib/client/global-messages/utils/index.ts +++ b/src/lib/client/global-messages/utils/index.ts @@ -9,6 +9,7 @@ import type { ZodValidation, } from 'sveltekit-superforms'; import type { AnyZodObject } from 'zod'; + import { browser } from '$app/environment'; import type { SuperformsOnErrorResult } from '$lib/client/superforms/types'; diff --git a/src/lib/client/logging/client.ts b/src/lib/client/logging/client.ts index 27dd1c1..beb1be4 100644 --- a/src/lib/client/logging/client.ts +++ b/src/lib/client/logging/client.ts @@ -4,6 +4,7 @@ import { enrichContextWithDebugInfo, enrichLoggerContextWithSentryTraceId, } from '$lib/shared/logging/utils'; + import type { LogLevelName } from './types'; import { enrichLoggerContextWithPosthogSessionId, @@ -14,11 +15,7 @@ import { export const logger = (function () { const createLogger = (methodName: LogLevelName) => { - return ( - message: string, - context: LoggerContext = {}, - stackLevel: number = 3, - ) => { + return (message: string, context: LoggerContext = {}, stackLevel = 3) => { if (!shouldBeLogged(methodName)) { return; } diff --git a/src/lib/client/logging/utils/index.ts b/src/lib/client/logging/utils/index.ts index e053e0b..6ba5fc4 100644 --- a/src/lib/client/logging/utils/index.ts +++ b/src/lib/client/logging/utils/index.ts @@ -1,6 +1,7 @@ import { posthog } from '$lib/client/posthog'; import { getSessionId } from '$lib/client/posthog/utils'; import type { LoggerContext } from '$lib/shared/logging/types'; + import type { LogLevelName } from '../types'; export const logLevels = { @@ -11,6 +12,9 @@ export const logLevels = { error: 50, } as const; +/* + * Colors copied from https://github.com/gajus/roarr-browser-log-writer + */ export const logLevelColors = { debug: { backgroundColor: '#666', @@ -36,6 +40,9 @@ export const logLevelColors = { [key in LogLevelName]: { backgroundColor: string; color: string }; }; +/* + * Colors copied from https://github.com/gajus/roarr-browser-log-writer + */ export const logTimestampColors = { debug: { color: '#999', diff --git a/src/lib/client/posthog/client.ts b/src/lib/client/posthog/client.ts index ec94872..b7dff83 100644 --- a/src/lib/client/posthog/client.ts +++ b/src/lib/client/posthog/client.ts @@ -1,5 +1,6 @@ -import _posthog from 'posthog-js'; import type { PostHog } from 'posthog-js'; +import _posthog from 'posthog-js'; + import { _setupPosthogClientBase } from '$lib/shared/posthog/utils'; export let posthog: PostHog | undefined; diff --git a/src/lib/client/posthog/posthog-default-page-events-capture.configurator.dom-test.ts b/src/lib/client/posthog/posthog-default-page-events-capture.configurator.dom-test.ts index f80b7da..b814f9a 100644 --- a/src/lib/client/posthog/posthog-default-page-events-capture.configurator.dom-test.ts +++ b/src/lib/client/posthog/posthog-default-page-events-capture.configurator.dom-test.ts @@ -1,25 +1,27 @@ +import type { Navigation } from '@sveltejs/kit'; +import type { PostHog } from 'posthog-js'; +import { type Writable, writable } from 'svelte/store'; import { + afterEach, + beforeEach, describe, - it, expect, - beforeEach, - afterEach, - vi, + it, type Mock, type MockInstance, + vi, } from 'vitest'; -import type { PostHog } from 'posthog-js'; + +import * as appStoresModule from '$app/stores'; +import { getMockWithType } from '$lib/shared/core/testing'; +import * as libSharedPosthogUtilsModule from '$lib/shared/posthog/utils'; +import { mockAppStoresNavigatingValue } from '$lib/shared/sveltekit/testing'; + +import * as posthogClientModule from './client'; import { _PageEventTrigger, _PosthogDefaultPageEventsCaptureConfigurator, } from './posthog-default-page-events-capture.configurator'; -import * as posthogClientModule from './client'; -import { writable, type Writable } from 'svelte/store'; -import type { Navigation } from '@sveltejs/kit'; -import * as appStoresModule from '$app/stores'; -import { mockAppStoresNavigatingValue } from '$lib/shared/sveltekit/testing'; -import { getMockWithType } from '$lib/shared/core/testing'; -import * as libSharedPosthogUtilsModule from '$lib/shared/posthog/utils'; describe(_PosthogDefaultPageEventsCaptureConfigurator.name, () => { let configurator: _PosthogDefaultPageEventsCaptureConfigurator; diff --git a/src/lib/client/posthog/posthog-default-page-events-capture.configurator.ts b/src/lib/client/posthog/posthog-default-page-events-capture.configurator.ts index 2620e37..e0bce87 100644 --- a/src/lib/client/posthog/posthog-default-page-events-capture.configurator.ts +++ b/src/lib/client/posthog/posthog-default-page-events-capture.configurator.ts @@ -1,12 +1,14 @@ +import type { Unsubscriber } from 'svelte/store'; + import { navigating } from '$app/stores'; import { POSTHOG_PAGE_LEAVE_EVENT_NAME, POSTHOG_PAGE_VIEW_EVENT_NAME, } from '$lib/shared/posthog/constants'; -import type { Unsubscriber } from 'svelte/store'; -import { posthog } from './client'; import { checkIfPosthogClientConfigured } from '$lib/shared/posthog/utils'; +import { posthog } from './client'; + export enum _PageEventTrigger { VISIBILITY_VISIBLE = 'visibility-visible', VISIBILITY_HIDDEN = 'visibility-hidden', @@ -78,7 +80,7 @@ export class _PosthogDefaultPageEventsCaptureConfigurator { // WARN: Navigation after `popstate` event happens before this runs, so // page leave event is captured for the destination page, not the source // one. No solution for now (`beforeNavigate` also did not help). - if ($navigating && $navigating.willUnload === false) { + if ($navigating && !$navigating.willUnload) { this.capturePageLeaveEvent(_PageEventTrigger.BEFORE_NAVIGATE); return; } diff --git a/src/lib/client/posthog/posthog-user-identity.configurator.dom-test.ts b/src/lib/client/posthog/posthog-user-identity.configurator.dom-test.ts index bef7dff..aa087f0 100644 --- a/src/lib/client/posthog/posthog-user-identity.configurator.dom-test.ts +++ b/src/lib/client/posthog/posthog-user-identity.configurator.dom-test.ts @@ -1,22 +1,24 @@ +import type { Page } from '@sveltejs/kit'; +import type { PostHog } from 'posthog-js'; +import { type Writable, writable } from 'svelte/store'; import { + afterEach, + beforeEach, describe, - it, expect, - beforeEach, - afterEach, - vi, + it, type Mock, + vi, } from 'vitest'; -import type { PostHog } from 'posthog-js'; -import { _PosthogUserIdentityConfigurator } from './posthog-user-identity.configurator'; -import * as posthogClientModule from './client'; -import { writable, type Writable } from 'svelte/store'; + import * as appStoresModule from '$app/stores'; -import type { Page } from '@sveltejs/kit'; -import { defaultMockAppStoresPageValue } from '$lib/shared/sveltekit/testing'; -import { getMockAuthUser } from '$lib/shared/lucia/testing'; import { getMockWithType } from '$lib/shared/core/testing'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; import * as libSharedPosthogUtilsModule from '$lib/shared/posthog/utils'; +import { defaultMockAppStoresPageValue } from '$lib/shared/sveltekit/testing'; + +import * as posthogClientModule from './client'; +import { _PosthogUserIdentityConfigurator } from './posthog-user-identity.configurator'; describe(_PosthogUserIdentityConfigurator.name, () => { let configurator: _PosthogUserIdentityConfigurator; diff --git a/src/lib/client/posthog/posthog-user-identity.configurator.ts b/src/lib/client/posthog/posthog-user-identity.configurator.ts index 6b058d5..8cc7381 100644 --- a/src/lib/client/posthog/posthog-user-identity.configurator.ts +++ b/src/lib/client/posthog/posthog-user-identity.configurator.ts @@ -1,9 +1,11 @@ -import { page } from '$app/stores'; +import isEqual from 'lodash/isEqual'; import type { Unsubscriber } from 'svelte/store'; -import { posthog } from './client'; -import { checkIfPosthogClientConfigured } from '$lib/shared/posthog/utils'; + +import { page } from '$app/stores'; import type { AuthUser } from '$lib/shared/lucia/types'; -import isEqual from 'lodash/isEqual'; +import { checkIfPosthogClientConfigured } from '$lib/shared/posthog/utils'; + +import { posthog } from './client'; // NOTE: It does not make sense to use Svelte custom store, because there is // no value to subscribe to. Reactivity is also not needed. Therefor class is diff --git a/src/lib/client/sentry/sentry-user-identity.configurator.dom-test.ts b/src/lib/client/sentry/sentry-user-identity.configurator.dom-test.ts index a417d6a..65256f4 100644 --- a/src/lib/client/sentry/sentry-user-identity.configurator.dom-test.ts +++ b/src/lib/client/sentry/sentry-user-identity.configurator.dom-test.ts @@ -1,20 +1,22 @@ +import type { Page } from '@sveltejs/kit'; +import { type Writable, writable } from 'svelte/store'; import { + afterEach, + beforeEach, describe, - it, expect, - beforeEach, - afterEach, - vi, + it, type Mock, + vi, } from 'vitest'; -import { _SentryUserIdentityConfigurator } from './sentry-user-identity.configurator'; -import * as libSharedSentryModule from '$lib/shared/sentry'; -import { writable, type Writable } from 'svelte/store'; + import * as appStoresModule from '$app/stores'; -import type { Page } from '@sveltejs/kit'; -import { defaultMockAppStoresPageValue } from '$lib/shared/sveltekit/testing'; -import { getMockAuthUser } from '$lib/shared/lucia/testing'; import { getMockWithType } from '$lib/shared/core/testing'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import * as libSharedSentryModule from '$lib/shared/sentry'; +import { defaultMockAppStoresPageValue } from '$lib/shared/sveltekit/testing'; + +import { _SentryUserIdentityConfigurator } from './sentry-user-identity.configurator'; describe(_SentryUserIdentityConfigurator.name, () => { let configurator: _SentryUserIdentityConfigurator; diff --git a/src/lib/client/sentry/sentry-user-identity.configurator.ts b/src/lib/client/sentry/sentry-user-identity.configurator.ts index d1deb4a..09a775e 100644 --- a/src/lib/client/sentry/sentry-user-identity.configurator.ts +++ b/src/lib/client/sentry/sentry-user-identity.configurator.ts @@ -1,8 +1,9 @@ -import { page } from '$app/stores'; +import isEqual from 'lodash/isEqual'; import type { Unsubscriber } from 'svelte/store'; -import { sentry, checkIfSentryClientConfigured } from '$lib/shared/sentry'; + +import { page } from '$app/stores'; import type { AuthUser } from '$lib/shared/lucia/types'; -import isEqual from 'lodash/isEqual'; +import { checkIfSentryClientConfigured, sentry } from '$lib/shared/sentry'; // NOTE: It does not make sense to use Svelte custom store, because there is // no value to subscribe to. Reactivity is also not needed. Therefor class is diff --git a/src/lib/client/sentry/utils/index.ts b/src/lib/client/sentry/utils/index.ts index 34159e5..f9b5f20 100644 --- a/src/lib/client/sentry/utils/index.ts +++ b/src/lib/client/sentry/utils/index.ts @@ -1,7 +1,8 @@ +import type { Integration } from '@sentry/types'; + import { posthog } from '$lib/client/posthog'; import { getSessionId } from '$lib/client/posthog/utils'; import { sentry } from '$lib/shared/sentry'; -import type { Integration } from '@sentry/types'; const POSTHOG_SESSION_ID_TAG = 'posthog_session_id'; @@ -18,6 +19,6 @@ export function getClientSentryIntegrations( export function setClientPosthogSessionId(): void { if (posthog) { - sentry?.setTag(POSTHOG_SESSION_ID_TAG, getSessionId() as string); + sentry?.setTag(POSTHOG_SESSION_ID_TAG, getSessionId()); } } diff --git a/src/lib/client/skeleton/utils/setup.utils.ts b/src/lib/client/skeleton/utils/setup.utils.ts index 199ad6f..6af9a30 100644 --- a/src/lib/client/skeleton/utils/setup.utils.ts +++ b/src/lib/client/skeleton/utils/setup.utils.ts @@ -1,16 +1,16 @@ // Skeleton Popup required middleware import { - computePosition, + arrow, autoUpdate, - offset, - shift, + computePosition, flip, - arrow, type Middleware, + offset, + shift, } from '@floating-ui/dom'; // Skeleton Popup optional middleware -import { size, autoPlacement, hide, inline } from '@floating-ui/dom'; -import { storePopup, initializeStores } from '@skeletonlabs/skeleton'; +import { autoPlacement, hide, inline, size } from '@floating-ui/dom'; +import { initializeStores, storePopup } from '@skeletonlabs/skeleton'; type SkeletonPopupMiddlewareFactory = () => Middleware; @@ -23,7 +23,7 @@ export function setupSkeletonPopup() { computePosition, autoUpdate, offset, - // @ts-ignore + // @ts-expect-error shift, flip, arrow, diff --git a/src/lib/server/code-snippets/form-actions/code-snippets.form-actions.node-test.ts b/src/lib/server/code-snippets/form-actions/code-snippets.form-actions.node-test.ts index e7e7b85..783f707 100644 --- a/src/lib/server/code-snippets/form-actions/code-snippets.form-actions.node-test.ts +++ b/src/lib/server/code-snippets/form-actions/code-snippets.form-actions.node-test.ts @@ -1,27 +1,29 @@ -import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import type { CodeSnippet } from '@prisma/client'; +import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; +import { error, fail } from '@sveltejs/kit'; +import type { PostHog } from 'posthog-node'; +import type { SuperValidated, ZodValidation } from 'sveltekit-superforms'; import { afterEach, beforeEach, describe, expect, it, - vi, type Mock, + vi, } from 'vitest'; -import { fail, error } from '@sveltejs/kit'; +import { type AnyZodObject, z } from 'zod'; + import * as libServerCodeSnippetsModule from '$lib/server/code-snippets'; import type { CodeSnippetsService } from '$lib/server/code-snippets/services'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; +import * as libServerPosthogModule from '$lib/server/posthog'; import { getMockCodeSnippet } from '$lib/shared/code-snippets/testing'; -import type { CodeSnippet } from '@prisma/client'; -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; +import { getMockWithType } from '$lib/shared/core/testing'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; import type { AuthUser } from '$lib/shared/lucia/types'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + import { deleteCodeSnippetFormAction } from './code-snippets.form-actions'; -import { z, type AnyZodObject } from 'zod'; -import type { SuperValidated, ZodValidation } from 'sveltekit-superforms'; -import * as libServerPosthogModule from '$lib/server/posthog'; -import type { PostHog } from 'posthog-node'; -import { getMockWithType } from '$lib/shared/core/testing'; describe('actions', () => { describe(deleteCodeSnippetFormAction.name, () => { diff --git a/src/lib/server/code-snippets/form-actions/code-snippets.form-actions.ts b/src/lib/server/code-snippets/form-actions/code-snippets.form-actions.ts index 31b31db..9d2ed3e 100644 --- a/src/lib/server/code-snippets/form-actions/code-snippets.form-actions.ts +++ b/src/lib/server/code-snippets/form-actions/code-snippets.form-actions.ts @@ -1,18 +1,20 @@ -import type { AuthUser } from '$lib/shared/lucia/types'; import type { CodeSnippet } from '@prisma/client'; +import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; +import type { HttpError } from '@sveltejs/kit'; import type { SuperValidated, ZodValidation } from 'sveltekit-superforms'; import { message } from 'sveltekit-superforms/server'; import type { AnyZodObject } from 'zod'; + import { codeSnippetsService } from '$lib/server/code-snippets'; +import { posthog } from '$lib/server/posthog'; +import type { AuthUser } from '$lib/shared/lucia/types'; +import { POSTHOG_CODE_SNIPPET_DELETED_EVENT_NAME } from '$lib/shared/posthog/constants'; +import { sentry } from '$lib/shared/sentry'; + import { throwCodeSnippetDeletionUnauthorizedError, throwCodeSnippetNotFoundError, } from '../utils/errors'; -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; -import type { HttpError } from '@sveltejs/kit'; -import { posthog } from '$lib/server/posthog'; -import { POSTHOG_CODE_SNIPPET_DELETED_EVENT_NAME } from '$lib/shared/posthog/constants'; -import { sentry } from '$lib/shared/sentry'; export async function deleteCodeSnippetFormAction< T extends ZodValidation, diff --git a/src/lib/server/code-snippets/services/code-snippets.service.node-test.ts b/src/lib/server/code-snippets/services/code-snippets.service.node-test.ts index f80ca48..78a7017 100644 --- a/src/lib/server/code-snippets/services/code-snippets.service.node-test.ts +++ b/src/lib/server/code-snippets/services/code-snippets.service.node-test.ts @@ -1,16 +1,18 @@ +import type { CodeSnippet } from '@prisma/client'; +import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; import { afterEach, beforeEach, describe, - it, expect, - vi, + it, type Mock, + vi, } from 'vitest'; + import * as libServerPrismaModule from '$lib/server/prisma'; + import { CodeSnippetsService } from './code-snippets.service'; -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; -import type { CodeSnippet } from '@prisma/client'; type PrismaClient = typeof libServerPrismaModule.prisma; type CodeSnippetDelegate = PrismaClient['codeSnippet']; diff --git a/src/lib/server/code-snippets/services/code-snippets.service.ts b/src/lib/server/code-snippets/services/code-snippets.service.ts index 4de9ac1..9369540 100644 --- a/src/lib/server/code-snippets/services/code-snippets.service.ts +++ b/src/lib/server/code-snippets/services/code-snippets.service.ts @@ -1,6 +1,7 @@ +import type { CodeSnippet } from '@prisma/client'; + import { prisma } from '$lib/server/prisma'; import type { FindCodeSnippetsQuery } from '$lib/shared/code-snippets/dtos'; -import type { CodeSnippet } from '@prisma/client'; export class CodeSnippetsService { async getAll(): Promise { @@ -31,7 +32,7 @@ export class CodeSnippetsService { where: { is_deleted: false, ...(query?.filterBy === 'author' && - query?.filterValue && { user_id: query?.filterValue }), + query.filterValue && { user_id: query.filterValue }), }, }); @@ -43,7 +44,7 @@ export class CodeSnippetsService { ): Promise { const itemCount = await this.getTotalItemCountByQuery(query); let pageCount = 1; - if (query?.count != null && query?.count> 0) { + if (query?.count != null && query.count> 0) { pageCount = Math.ceil(itemCount / query.count); } @@ -52,26 +53,26 @@ export class CodeSnippetsService { async findManyByQuery(query?: FindCodeSnippetsQuery): Promise { let skip: number | undefined; - if (query?.page != null && query?.page> 1 && query?.count != null) { + if (query?.page != null && query.page> 1 && query.count != null) { skip = (query.page - 1) * query.count; } let take: number | undefined; if (query?.count != null) { - take = query?.count; + take = query.count; } const codeSnippets = await prisma.codeSnippet.findMany({ where: { is_deleted: false, ...(query?.filterBy === 'author' && - query?.filterValue && { user_id: query?.filterValue }), + query.filterValue && { user_id: query.filterValue }), }, ...(skip && { skip }), ...(take && { take }), ...(query?.sortBy && { orderBy: { - [query?.sortBy]: query?.sortOrder || 'asc', + [query.sortBy]: query.sortOrder || 'asc', }, }), }); diff --git a/src/lib/server/code-snippets/utils/errors.node-test.ts b/src/lib/server/code-snippets/utils/errors.node-test.ts index 1d4dd98..a08c288 100644 --- a/src/lib/server/code-snippets/utils/errors.node-test.ts +++ b/src/lib/server/code-snippets/utils/errors.node-test.ts @@ -1,6 +1,7 @@ -import { describe, it, expect, vi } from 'vitest'; -import { throwCodeSnippetNotFoundError } from './errors'; import * as sveltejsKitModule from '@sveltejs/kit'; +import { describe, expect, it, vi } from 'vitest'; + +import { throwCodeSnippetNotFoundError } from './errors'; describe(throwCodeSnippetNotFoundError.name, () => { it('should throw a 404 error', () => { diff --git a/src/lib/server/core/config/index.ts b/src/lib/server/core/config/index.ts index b62d357..7b827a5 100644 --- a/src/lib/server/core/config/index.ts +++ b/src/lib/server/core/config/index.ts @@ -1,8 +1,9 @@ -import { env as privateEnv } from '$env/dynamic/private'; -import { env as publicEnv } from '$env/dynamic/public'; import path from 'path'; import url from 'url'; +import { env as privateEnv } from '$env/dynamic/private'; +import { env as publicEnv } from '$env/dynamic/public'; + export const config = { get origin(): string { return privateEnv.ORIGIN; diff --git a/src/lib/server/core/hooks/check-mandatory-private-env-vars.handle.node-test.ts b/src/lib/server/core/hooks/check-mandatory-private-env-vars.handle.node-test.ts index 304ec4b..3ca4557 100644 --- a/src/lib/server/core/hooks/check-mandatory-private-env-vars.handle.node-test.ts +++ b/src/lib/server/core/hooks/check-mandatory-private-env-vars.handle.node-test.ts @@ -1,4 +1,5 @@ -import { describe, expect, it, vi, afterEach } from 'vitest'; +import { afterEach, describe, expect, it, vi } from 'vitest'; + import * as utilsModule from '../utils'; import { checkMandatoryPrivateEnvVarsHandle } from './check-mandatory-private-env-vars.handle'; diff --git a/src/lib/server/core/hooks/check-mandatory-private-env-vars.handle.ts b/src/lib/server/core/hooks/check-mandatory-private-env-vars.handle.ts index 4890886..5be7550 100644 --- a/src/lib/server/core/hooks/check-mandatory-private-env-vars.handle.ts +++ b/src/lib/server/core/hooks/check-mandatory-private-env-vars.handle.ts @@ -1,6 +1,7 @@ -import { exitIfEnvVarsNotSet } from '$lib/server/core/utils'; import type { Handle } from '@sveltejs/kit'; +import { exitIfEnvVarsNotSet } from '$lib/server/core/utils'; + export const checkMandatoryPrivateEnvVarsHandle = (async ({ event, resolve, diff --git a/src/lib/server/core/hooks/maintenance-mode.handle.node-test.ts b/src/lib/server/core/hooks/maintenance-mode.handle.node-test.ts index 996f002..7282466 100644 --- a/src/lib/server/core/hooks/maintenance-mode.handle.node-test.ts +++ b/src/lib/server/core/hooks/maintenance-mode.handle.node-test.ts @@ -1,7 +1,9 @@ -import { describe, expect, it, vi, afterEach } from 'vitest'; +import * as sveltejsKitModule from '@sveltejs/kit'; +import { afterEach, describe, expect, it, vi } from 'vitest'; + import * as libServerCoreConfigModule from '$lib/server/core/config'; + import { maintenanceModeHandle } from './maintenance-mode.handle'; -import * as sveltejsKitModule from '@sveltejs/kit'; describe(maintenanceModeHandle.name, () => { afterEach(async () => { diff --git a/src/lib/server/core/hooks/maintenance-mode.handle.ts b/src/lib/server/core/hooks/maintenance-mode.handle.ts index 363fe55..583074f 100644 --- a/src/lib/server/core/hooks/maintenance-mode.handle.ts +++ b/src/lib/server/core/hooks/maintenance-mode.handle.ts @@ -1,8 +1,9 @@ +import { type Handle, redirect } from '@sveltejs/kit'; + import { config } from '$lib/server/core/config'; -import { redirect, type Handle } from '@sveltejs/kit'; import { - ORIGINAL_PATH_URL_QUERY_PARAM_NAME, encodeOriginalPath, + ORIGINAL_PATH_URL_QUERY_PARAM_NAME, } from '$lib/shared/core/utils'; const NON_REDIRECTED_ROUTES = [ diff --git a/src/lib/server/core/utils/env.utils.node-test.ts b/src/lib/server/core/utils/env.utils.node-test.ts index 5173d09..c92af87 100644 --- a/src/lib/server/core/utils/env.utils.node-test.ts +++ b/src/lib/server/core/utils/env.utils.node-test.ts @@ -1,16 +1,18 @@ import { + afterEach, + beforeEach, describe, - it, expect, - vi, - beforeEach, - afterEach, + it, type MockInstance, + vi, } from 'vitest'; -import { exitIfEnvVarsNotSet, throwIfEnvVarsNotSet } from './env.utils'; + import * as envDynamicPrivate from '$env/dynamic/private'; import * as envDynamicPublic from '$env/dynamic/public'; +import { exitIfEnvVarsNotSet, throwIfEnvVarsNotSet } from './env.utils'; + beforeEach(() => { vi.spyOn(envDynamicPrivate, 'env', 'get').mockReturnValue({} as any); vi.spyOn(envDynamicPublic, 'env', 'get').mockReturnValue({} as any); diff --git a/src/lib/server/core/utils/url.utils.node-test.ts b/src/lib/server/core/utils/url.utils.node-test.ts index fb5432b..62bc9d5 100644 --- a/src/lib/server/core/utils/url.utils.node-test.ts +++ b/src/lib/server/core/utils/url.utils.node-test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect } from 'vitest'; +import { describe, expect, it } from 'vitest'; + import { getRefererHeaderUrl } from './url.utils'; describe(getRefererHeaderUrl.name, () => { diff --git a/src/lib/server/lucia/client.ts b/src/lib/server/lucia/client.ts index 34c2c38..5b87bed 100644 --- a/src/lib/server/lucia/client.ts +++ b/src/lib/server/lucia/client.ts @@ -1,9 +1,11 @@ -import { lucia } from 'lucia'; -import { sveltekit as sveltekitMiddleware } from 'lucia/middleware'; -import { dev } from '$app/environment'; // Polyfill the Web Crypto API, required only for Node.js runtime <= version 18 import 'lucia/polyfill/node'; + import { prisma as prismaAdapter } from '@lucia-auth/adapter-prisma'; +import { lucia } from 'lucia'; +import { sveltekit as sveltekitMiddleware } from 'lucia/middleware'; + +import { dev } from '$app/environment'; import { prisma as prismaClient } from '$lib/server/prisma'; export const auth = lucia({ diff --git a/src/lib/server/lucia/guards/auth-user.guard.node-test.ts b/src/lib/server/lucia/guards/auth-user.guard.node-test.ts index 1fcaa74..f5962fc 100644 --- a/src/lib/server/lucia/guards/auth-user.guard.node-test.ts +++ b/src/lib/server/lucia/guards/auth-user.guard.node-test.ts @@ -1,16 +1,18 @@ +import * as sveltejsKitModule from '@sveltejs/kit'; import { + afterEach, + beforeEach, describe, expect, it, - vi, - beforeEach, - afterEach, type MockInstance, + vi, } from 'vitest'; -import { guardAuthUser } from './auth-user.guard'; -import * as sveltejsKitModule from '@sveltejs/kit'; + import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import { guardAuthUser } from './auth-user.guard'; + describe(guardAuthUser.name, () => { let redirectSpy: MockInstance; @@ -32,7 +34,6 @@ describe(guardAuthUser.name, () => { expect(result).toEqual({ authUser: locals.authUser, - doesRequireAuth: true, }); expect(redirectSpy).toHaveBeenCalledTimes(0); }); diff --git a/src/lib/server/lucia/guards/auth-user.guard.ts b/src/lib/server/lucia/guards/auth-user.guard.ts index bc5ff93..72dcd0a 100644 --- a/src/lib/server/lucia/guards/auth-user.guard.ts +++ b/src/lib/server/lucia/guards/auth-user.guard.ts @@ -1,14 +1,14 @@ +import { redirect } from '@sveltejs/kit'; + import { - ORIGINAL_PATH_URL_QUERY_PARAM_NAME, encodeOriginalPath, + ORIGINAL_PATH_URL_QUERY_PARAM_NAME, } from '$lib/shared/core/utils'; -import { redirect } from '@sveltejs/kit'; export function guardAuthUser(locals: App.Locals, url: URL): App.PageData { if (locals.authUser) { return { authUser: locals.authUser, - doesRequireAuth: true, }; } diff --git a/src/lib/server/lucia/hooks/add-auth-data-to-local.handle.node-test.ts b/src/lib/server/lucia/hooks/add-auth-data-to-local.handle.node-test.ts index 76c0342..5f9e4fd 100644 --- a/src/lib/server/lucia/hooks/add-auth-data-to-local.handle.node-test.ts +++ b/src/lib/server/lucia/hooks/add-auth-data-to-local.handle.node-test.ts @@ -1,9 +1,11 @@ -import { describe, expect, it, vi, afterEach } from 'vitest'; +import { afterEach, describe, expect, it, vi } from 'vitest'; + import type * as clientModule from '../client'; import type * as utilsModule from '../utils'; import { addAuthDataToLocalHandle } from './add-auth-data-to-local.handle'; vi.mock('../client', async () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const actual = (await vi.importActual('../client')) as typeof clientModule; return { ...actual, @@ -14,6 +16,7 @@ vi.mock('../client', async () => { }); vi.mock('../utils', async () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const actual = (await vi.importActual('../utils')) as typeof utilsModule; return { ...actual, diff --git a/src/lib/server/lucia/hooks/add-auth-data-to-local.handle.ts b/src/lib/server/lucia/hooks/add-auth-data-to-local.handle.ts index f4b9709..8a8d70a 100644 --- a/src/lib/server/lucia/hooks/add-auth-data-to-local.handle.ts +++ b/src/lib/server/lucia/hooks/add-auth-data-to-local.handle.ts @@ -1,4 +1,5 @@ import type { Handle } from '@sveltejs/kit'; + import { auth } from '../client'; import { getCurrentAuthSession, getCurrentAuthUserFromSession } from '../utils'; diff --git a/src/lib/server/lucia/oauth/google/constants.ts b/src/lib/server/lucia/oauth/google/constants.ts index 29309ba..7921643 100644 --- a/src/lib/server/lucia/oauth/google/constants.ts +++ b/src/lib/server/lucia/oauth/google/constants.ts @@ -1,7 +1,7 @@ // See `state` parameter: // https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow#redirecting -export const GOOGLE_OAUTH_STATE_COOKIE_NAME: string = 'google_oauth_state'; -export const GOOGLE_OAUTH_STATE_SEPARATOR: string = '-----'; -export const GOOGLE_OAUTH_STATE_QUERY_PARAM_NAME: string = 'state'; -export const GOOGLE_OAUTH_CODE_QUERY_PARAM_NAME: string = 'code'; -export const GOOGLE_OAUTH_TYPE_QUERY_PARAM_VALUE: string = 'google'; +export const GOOGLE_OAUTH_STATE_COOKIE_NAME = 'google_oauth_state'; +export const GOOGLE_OAUTH_STATE_SEPARATOR = '-----'; +export const GOOGLE_OAUTH_STATE_QUERY_PARAM_NAME = 'state'; +export const GOOGLE_OAUTH_CODE_QUERY_PARAM_NAME = 'code'; +export const GOOGLE_OAUTH_TYPE_QUERY_PARAM_VALUE = 'google'; diff --git a/src/lib/server/lucia/oauth/google/provider.ts b/src/lib/server/lucia/oauth/google/provider.ts index 1638943..af3a860 100644 --- a/src/lib/server/lucia/oauth/google/provider.ts +++ b/src/lib/server/lucia/oauth/google/provider.ts @@ -1,5 +1,7 @@ -import { config } from '$lib/server/core/config'; import { google as googleProvider } from '@lucia-auth/oauth/providers'; + +import { config } from '$lib/server/core/config'; + import { auth } from '../../client'; export const googleAuth = googleProvider(auth, { diff --git a/src/lib/server/lucia/oauth/google/utils/sign-in.utils.node-test.ts b/src/lib/server/lucia/oauth/google/utils/sign-in.utils.node-test.ts index 093f5b3..aa874a5 100644 --- a/src/lib/server/lucia/oauth/google/utils/sign-in.utils.node-test.ts +++ b/src/lib/server/lucia/oauth/google/utils/sign-in.utils.node-test.ts @@ -1,29 +1,31 @@ +import { OAuthRequestError } from '@lucia-auth/oauth'; +import type { GoogleUser, GoogleUserAuth } from '@lucia-auth/oauth/providers'; +import { type Cookies, error, redirect } from '@sveltejs/kit'; +import type { PostHog } from 'posthog-node'; import { afterEach, + beforeEach, describe, expect, it, - vi, type Mock, - beforeEach, + vi, } from 'vitest'; -import { signInWithGoogle } from './sign-in.utils'; -import { redirect, type Cookies, error } from '@sveltejs/kit'; + +import * as libServerLuciaModule from '$lib/server/lucia'; +import * as libServerLuciaOauthGoogleModule from '$lib/server/lucia/oauth/google'; +import * as libServerPosthogModule from '$lib/server/posthog'; +import { prisma } from '$lib/server/prisma'; +import type { DatabaseUser } from '$lib/server/prisma/types'; +import { getMockWithType } from '$lib/shared/core/testing'; import { getMockAuthRequest, getMockAuthSession, getMockAuthUser, } from '$lib/shared/lucia/testing'; -import * as libServerLuciaModule from '$lib/server/lucia'; -import * as libServerLuciaOauthGoogleModule from '$lib/server/lucia/oauth/google'; -import { OAuthRequestError } from '@lucia-auth/oauth'; -import type { GoogleUser, GoogleUserAuth } from '@lucia-auth/oauth/providers'; import type { AuthSession, AuthUser } from '$lib/shared/lucia/types'; -import { prisma } from '$lib/server/prisma'; -import type { DatabaseUser } from '$lib/server/prisma/types'; -import * as libServerPosthogModule from '$lib/server/posthog'; -import type { PostHog } from 'posthog-node'; -import { getMockWithType } from '$lib/shared/core/testing'; + +import { signInWithGoogle } from './sign-in.utils'; interface SignInArgumentsObject { url: URL; diff --git a/src/lib/server/lucia/oauth/google/utils/sign-in.utils.ts b/src/lib/server/lucia/oauth/google/utils/sign-in.utils.ts index d3b7c4c..1aaebfb 100644 --- a/src/lib/server/lucia/oauth/google/utils/sign-in.utils.ts +++ b/src/lib/server/lucia/oauth/google/utils/sign-in.utils.ts @@ -1,3 +1,8 @@ +import { OAuthRequestError } from '@lucia-auth/oauth'; +import type { GoogleAuth } from '@lucia-auth/oauth/providers'; +import type { User as PrismaUser } from '@prisma/client'; +import { type Cookies, error, type HttpError, redirect } from '@sveltejs/kit'; + import { auth } from '$lib/server/lucia'; import { GOOGLE_OAUTH_CODE_QUERY_PARAM_NAME, @@ -6,18 +11,14 @@ import { GOOGLE_OAUTH_STATE_SEPARATOR, googleAuth, } from '$lib/server/lucia/oauth/google'; -import { OAuthRequestError } from '@lucia-auth/oauth'; -import type { GoogleAuth } from '@lucia-auth/oauth/providers'; +import { getCurrentAuthUserFromSession } from '$lib/server/lucia/utils'; +import { posthog } from '$lib/server/posthog'; import { prisma } from '$lib/server/prisma'; -import type { User as PrismaUser } from '@prisma/client'; import type { AuthSession, AuthUser } from '$lib/shared/lucia/types'; -import { error, redirect, type HttpError, type Cookies } from '@sveltejs/kit'; -import { posthog } from '$lib/server/posthog'; import { POSTHOG_USER_SIGN_IN_EVENT_NAME, POSTHOG_USER_SIGN_UP_EVENT_NAME, } from '$lib/shared/posthog/constants'; -import { getCurrentAuthUserFromSession } from '$lib/server/lucia/utils'; export async function signInWithGoogle( url: URL, @@ -189,7 +190,7 @@ async function performOAuthAccountLinking( } async function verifyEmail(databaseUser: PrismaUser): Promise { - if (databaseUser.email_verified === true) { + if (databaseUser.email_verified) { return; } diff --git a/src/lib/server/lucia/utils/index.node-test.ts b/src/lib/server/lucia/utils/index.node-test.ts index 22f83b8..c78f5f6 100644 --- a/src/lib/server/lucia/utils/index.node-test.ts +++ b/src/lib/server/lucia/utils/index.node-test.ts @@ -1,13 +1,15 @@ import { describe, expect, it } from 'vitest'; + +import { + getMockAuthRequest, + getMockAuthSession, +} from '$lib/shared/lucia/testing'; + import { getCurrentAuthSession, getCurrentAuthUserFromRequest, getCurrentAuthUserFromSession, } from './index'; -import { - getMockAuthRequest, - getMockAuthSession, -} from '$lib/shared/lucia/testing'; describe(getCurrentAuthSession.name, () => { it('should return null if request contains invalid, expired, or no session ID', async () => { diff --git a/src/lib/server/lucia/utils/index.ts b/src/lib/server/lucia/utils/index.ts index 77f40e8..98adfa8 100644 --- a/src/lib/server/lucia/utils/index.ts +++ b/src/lib/server/lucia/utils/index.ts @@ -1,4 +1,5 @@ import type { AuthRequest } from 'lucia'; + import type { AuthSession, AuthUser } from '$lib/shared/lucia/types'; /** diff --git a/src/lib/server/pagination/utils/index.node-test.ts b/src/lib/server/pagination/utils/index.node-test.ts index 89c7788..ad66a32 100644 --- a/src/lib/server/pagination/utils/index.node-test.ts +++ b/src/lib/server/pagination/utils/index.node-test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + import { generatePreviousAndNextPageUrlPaths } from '.'; describe(generatePreviousAndNextPageUrlPaths.name, () => { diff --git a/src/lib/server/pagination/utils/index.ts b/src/lib/server/pagination/utils/index.ts index 16f4a38..7f73f39 100644 --- a/src/lib/server/pagination/utils/index.ts +++ b/src/lib/server/pagination/utils/index.ts @@ -1,4 +1,5 @@ import { getUrlPathAndQueryParams } from '$lib/shared/core/utils'; + import type { PaginationQuery } from '../types'; export function generatePreviousAndNextPageUrlPaths( diff --git a/src/lib/server/posthog/client.ts b/src/lib/server/posthog/client.ts index 2f13c9f..92c4f5a 100644 --- a/src/lib/server/posthog/client.ts +++ b/src/lib/server/posthog/client.ts @@ -1,4 +1,5 @@ import { PostHog } from 'posthog-node'; + import { _setupPosthogClientBase } from '$lib/shared/posthog/utils'; export { PostHogSentryIntegration } from 'posthog-node'; @@ -20,7 +21,7 @@ export function setupNodePosthogClient( } function getNodePosthogClient(projectApiKey: string, apiHost: string): PostHog { - return new PostHog(projectApiKey!, { - host: apiHost!, + return new PostHog(projectApiKey, { + host: apiHost, }); } diff --git a/src/lib/server/roarr/client.ts b/src/lib/server/roarr/client.ts index 2ca7999..489b00a 100644 --- a/src/lib/server/roarr/client.ts +++ b/src/lib/server/roarr/client.ts @@ -1,24 +1,26 @@ -import { Roarr, logLevels, type LogLevelName } from 'roarr'; +import { type LogLevelName, logLevels, Roarr } from 'roarr'; +import { serializeError } from 'serialize-error'; + import { config } from '$lib/server/core/config'; +import { + enrichContextWithDebugInfo, + enrichLoggerContextWithSentryTraceId, +} from '$lib/shared/logging/utils'; +import { sentry } from '$lib/shared/sentry'; +import type { SeverityLevel } from '$lib/shared/sentry/types'; + import type { ServerLoggerContext, ServerLoggerContextWithError, ServerLoggerLoggingMethodName, } from './types'; -import { serializeError } from 'serialize-error'; -import { sentry } from '$lib/shared/sentry'; -import type { SeverityLevel } from '$lib/shared/sentry/types'; -import { - enrichContextWithDebugInfo, - enrichLoggerContextWithSentryTraceId, -} from '$lib/shared/logging/utils'; export const roarr = (function () { const createLogger = (methodName: ServerLoggerLoggingMethodName) => { return ( message: string, context: ServerLoggerContextWithError = {}, - stackLevel: number = 3, + stackLevel = 3, ) => { if (!shouldBeLogged(methodName)) { return; diff --git a/src/lib/server/roarr/hooks/http-log.handle.ts b/src/lib/server/roarr/hooks/http-log.handle.ts index a6b8e9b..e8fc900 100644 --- a/src/lib/server/roarr/hooks/http-log.handle.ts +++ b/src/lib/server/roarr/hooks/http-log.handle.ts @@ -1,6 +1,7 @@ import type { Handle } from '@sveltejs/kit'; -import { roarr } from '$lib/server/roarr'; + import { config } from '$lib/server/core/config'; +import { roarr } from '$lib/server/roarr'; export const httpLogHandle = (async ({ event, resolve }) => { if (!config.roarr.isAccessLoggingEnabled) { diff --git a/src/lib/server/roarr/types/index.ts b/src/lib/server/roarr/types/index.ts index 2a95688..2075d57 100644 --- a/src/lib/server/roarr/types/index.ts +++ b/src/lib/server/roarr/types/index.ts @@ -3,16 +3,17 @@ * Don't import from `node_modules/roarr/src/types.ts` directly to avoid type errors. */ -import type { LoggerContext } from '$lib/shared/logging/types'; import type { LogLevelName } from 'roarr'; +import type { LoggerContext } from '$lib/shared/logging/types'; + export type ServerLoggerLoggingMethodName = | ServerLoggerLoggingMethodNameNoOnce | ServerLoggerLoggingMethodNameOnce; -export type JsonObject = { +export interface JsonObject { [k: string]: JsonValue; -}; +} export type JsonValue = | JsonObject | JsonValue[] diff --git a/src/lib/server/roarr/utils/index.ts b/src/lib/server/roarr/utils/index.ts index b75a10a..5d3e8e7 100644 --- a/src/lib/server/roarr/utils/index.ts +++ b/src/lib/server/roarr/utils/index.ts @@ -1,5 +1,7 @@ -import { sentry } from '$lib/shared/sentry'; import type { SeverityLevel } from '@sentry/sveltekit'; + +import { sentry } from '$lib/shared/sentry'; + import { roarr } from '../client'; export function logError(error: Error, level: SeverityLevel = 'error'): void { diff --git a/src/lib/server/sentry/hooks/set-sentry-user-identity.handle.node-test.ts b/src/lib/server/sentry/hooks/set-sentry-user-identity.handle.node-test.ts index 914d542..95780ee 100644 --- a/src/lib/server/sentry/hooks/set-sentry-user-identity.handle.node-test.ts +++ b/src/lib/server/sentry/hooks/set-sentry-user-identity.handle.node-test.ts @@ -1,17 +1,19 @@ +import type { RequestEvent } from '@sveltejs/kit'; import { + afterEach, + beforeEach, describe, - it, expect, - beforeEach, - afterEach, - vi, + it, type Mock, + vi, } from 'vitest'; -import { setSentryUserIdentity } from './set-sentry-user-identity.handle'; -import * as libSharedSentryModule from '$lib/shared/sentry'; -import { getMockAuthUser } from '$lib/shared/lucia/testing'; -import type { RequestEvent } from '@sveltejs/kit'; + import { getMockWithType } from '$lib/shared/core/testing'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import * as libSharedSentryModule from '$lib/shared/sentry'; + +import { setSentryUserIdentity } from './set-sentry-user-identity.handle'; describe(setSentryUserIdentity.name, () => { let mockSetUser: Mock; diff --git a/src/lib/server/sentry/hooks/set-sentry-user-identity.handle.ts b/src/lib/server/sentry/hooks/set-sentry-user-identity.handle.ts index d4fc6e6..d31a5de 100644 --- a/src/lib/server/sentry/hooks/set-sentry-user-identity.handle.ts +++ b/src/lib/server/sentry/hooks/set-sentry-user-identity.handle.ts @@ -1,6 +1,7 @@ -import { sentry } from '$lib/shared/sentry'; import type { Handle } from '@sveltejs/kit'; + import { posthog, PostHogSentryIntegration } from '$lib/server/posthog'; +import { sentry } from '$lib/shared/sentry'; export const setSentryUserIdentity = (async ({ event, resolve }) => { if (!sentry) { diff --git a/src/lib/server/sentry/utils/index.ts b/src/lib/server/sentry/utils/index.ts index 395430c..8754aa1 100644 --- a/src/lib/server/sentry/utils/index.ts +++ b/src/lib/server/sentry/utils/index.ts @@ -1,12 +1,21 @@ -import { posthog, PostHogSentryIntegration } from '$lib/server/posthog'; +import * as Sentry from '@sentry/sveltekit'; import type { Integration } from '@sentry/types'; +import { posthog, PostHogSentryIntegration } from '$lib/server/posthog'; +import { prisma } from '$lib/server/prisma'; + export function getServerSentryIntegrations( organization: string | undefined, ): Integration[] { + const integrations: Integration[] = [ + new Sentry.Integrations.Prisma({ client: prisma }), + ]; + if (posthog && organization) { - return [new PostHogSentryIntegration(posthog, undefined, organization)]; + integrations.unshift( + new PostHogSentryIntegration(posthog, undefined, organization), + ); } - return []; + return integrations; } diff --git a/src/lib/server/superforms/testing/index.ts b/src/lib/server/superforms/testing/index.ts index a2620c9..67c7c81 100644 --- a/src/lib/server/superforms/testing/index.ts +++ b/src/lib/server/superforms/testing/index.ts @@ -6,7 +6,7 @@ export function getMockFormData( Object.entries(data).forEach(([key, value]) => { formData.append(key, value); }); - const formDataFn = async () => formData; + const formDataFn = () => Promise.resolve(formData); return formDataFn; } diff --git a/src/lib/shared/code-snippets/dtos/create-edit-code-snippet.dto.node-test.ts b/src/lib/shared/code-snippets/dtos/create-edit-code-snippet.dto.node-test.ts index 6fcd13a..58d9dee 100644 --- a/src/lib/shared/code-snippets/dtos/create-edit-code-snippet.dto.node-test.ts +++ b/src/lib/shared/code-snippets/dtos/create-edit-code-snippet.dto.node-test.ts @@ -1,7 +1,9 @@ -import { describe, it, expect } from 'vitest'; -import { createEditCodeSnippetFormSchema } from './create-edit-code-snippet.dto'; +import { describe, expect, it } from 'vitest'; + import { expectZodErrorMessages } from '$lib/shared/zod/testing'; +import { createEditCodeSnippetFormSchema } from './create-edit-code-snippet.dto'; + const formSchema = Object.keys({ createEditCodeSnippetFormSchema, })[0]!; diff --git a/src/lib/shared/code-snippets/dtos/create-edit-code-snippet.dto.ts b/src/lib/shared/code-snippets/dtos/create-edit-code-snippet.dto.ts index 85f6e35..03edbe9 100644 --- a/src/lib/shared/code-snippets/dtos/create-edit-code-snippet.dto.ts +++ b/src/lib/shared/code-snippets/dtos/create-edit-code-snippet.dto.ts @@ -1,6 +1,7 @@ -import { getRequiredErrorMessage } from '$lib/shared/zod/utils'; import { z } from 'zod'; +import { getRequiredErrorMessage } from '$lib/shared/zod/utils'; + const nameErrorMessage = getRequiredErrorMessage('Name'); const codeErrorMessage = getRequiredErrorMessage('Code'); export const createEditCodeSnippetFormSchema = z diff --git a/src/lib/shared/code-snippets/dtos/delete-code-snippet.dto.node-test.ts b/src/lib/shared/code-snippets/dtos/delete-code-snippet.dto.node-test.ts index 6338a3a..f42a304 100644 --- a/src/lib/shared/code-snippets/dtos/delete-code-snippet.dto.node-test.ts +++ b/src/lib/shared/code-snippets/dtos/delete-code-snippet.dto.node-test.ts @@ -1,7 +1,9 @@ -import { describe, it, expect } from 'vitest'; -import { deleteCodeSnippetFormSchema } from './delete-code-snippet.dto'; +import { describe, expect, it } from 'vitest'; + import { expectZodErrorMessages } from '$lib/shared/zod/testing'; +import { deleteCodeSnippetFormSchema } from './delete-code-snippet.dto'; + const formSchema = Object.keys({ deleteCodeSnippetFormSchema, })[0]!; diff --git a/src/lib/shared/code-snippets/dtos/delete-code-snippet.dto.ts b/src/lib/shared/code-snippets/dtos/delete-code-snippet.dto.ts index 8bc3fe2..f24a620 100644 --- a/src/lib/shared/code-snippets/dtos/delete-code-snippet.dto.ts +++ b/src/lib/shared/code-snippets/dtos/delete-code-snippet.dto.ts @@ -1,6 +1,7 @@ -import { getRequiredErrorMessage } from '$lib/shared/zod/utils'; import { z } from 'zod'; +import { getRequiredErrorMessage } from '$lib/shared/zod/utils'; + export const deleteCodeSnippetFormSchema = z .object({ id: z.number({ required_error: getRequiredErrorMessage('ID') }), diff --git a/src/lib/shared/code-snippets/dtos/find-code-snippets.dto.node-test.ts b/src/lib/shared/code-snippets/dtos/find-code-snippets.dto.node-test.ts index c179fc2..f24132e 100644 --- a/src/lib/shared/code-snippets/dtos/find-code-snippets.dto.node-test.ts +++ b/src/lib/shared/code-snippets/dtos/find-code-snippets.dto.node-test.ts @@ -1,9 +1,11 @@ -import { describe, it, expect } from 'vitest'; +import { describe, expect, it } from 'vitest'; + +import { expectZodErrorMessages } from '$lib/shared/zod/testing'; + import { findCodeSnippetsDto, type FindCodeSnippetsQuery, } from './find-code-snippets.dto'; -import { expectZodErrorMessages } from '$lib/shared/zod/testing'; const formSchema = Object.keys({ findCodeSnippetsDto, diff --git a/src/lib/shared/code-snippets/testing/index.ts b/src/lib/shared/code-snippets/testing/index.ts index ecb14fa..cfea7ab 100644 --- a/src/lib/shared/code-snippets/testing/index.ts +++ b/src/lib/shared/code-snippets/testing/index.ts @@ -1,5 +1,6 @@ import type { CodeSnippet } from '@prisma/client'; import type { SuperValidated } from 'sveltekit-superforms'; + import type { CreateEditCodeSnippetFormSchema } from '../dtos'; export function getMockCodeSnippet( diff --git a/src/lib/shared/core/utils/datetime.utils.node-test.ts b/src/lib/shared/core/utils/datetime.utils.node-test.ts index 9e4390f..4f4f95b 100644 --- a/src/lib/shared/core/utils/datetime.utils.node-test.ts +++ b/src/lib/shared/core/utils/datetime.utils.node-test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect } from 'vitest'; +import { describe, expect, it } from 'vitest'; + import { formatUtcDateTime } from './datetime.utils'; describe(formatUtcDateTime.name, () => { diff --git a/src/lib/shared/core/utils/index.ts b/src/lib/shared/core/utils/index.ts index a435395..6247c58 100644 --- a/src/lib/shared/core/utils/index.ts +++ b/src/lib/shared/core/utils/index.ts @@ -1,3 +1,3 @@ -export * from './url.utils'; export * from './datetime.utils'; export * from './parsing.utils'; +export * from './url.utils'; diff --git a/src/lib/shared/core/utils/parsing.utils.node-test.ts b/src/lib/shared/core/utils/parsing.utils.node-test.ts index bbabd28..0539a13 100644 --- a/src/lib/shared/core/utils/parsing.utils.node-test.ts +++ b/src/lib/shared/core/utils/parsing.utils.node-test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect } from 'vitest'; +import { describe, expect, it } from 'vitest'; + import { attemptToParseAsNumber, isStringParsableAsNumber, diff --git a/src/lib/shared/core/utils/url.utils.node-test.ts b/src/lib/shared/core/utils/url.utils.node-test.ts index 3198bd5..45c26c7 100644 --- a/src/lib/shared/core/utils/url.utils.node-test.ts +++ b/src/lib/shared/core/utils/url.utils.node-test.ts @@ -1,9 +1,10 @@ -import { describe, it, expect } from 'vitest'; +import { describe, expect, it } from 'vitest'; + import { - ORIGINAL_PATH_URL_QUERY_PARAM_NAME, decodeOriginalPath, encodeOriginalPath, getUrlPathAndQueryParams, + ORIGINAL_PATH_URL_QUERY_PARAM_NAME, } from './url.utils'; describe(getUrlPathAndQueryParams.name, () => { diff --git a/src/lib/shared/logging/utils/index.ts b/src/lib/shared/logging/utils/index.ts index 78a5fe6..657b843 100644 --- a/src/lib/shared/logging/utils/index.ts +++ b/src/lib/shared/logging/utils/index.ts @@ -1,6 +1,8 @@ +import callsites from 'callsites'; + import { sentry } from '$lib/shared/sentry'; import { getTraceId } from '$lib/shared/sentry/utils'; -import callsites from 'callsites'; + import type { LoggerContext } from '../types'; export function enrichLoggerContextWithSentryTraceId( @@ -24,7 +26,7 @@ export function enrichLoggerContextWithSentryTraceId( export function enrichContextWithDebugInfo( context: LoggerContext = {}, rootFolder = '', - stackLevel: number = 3, + stackLevel = 3, ): LoggerContext { return { ...context, @@ -33,7 +35,7 @@ export function enrichContextWithDebugInfo( }; } -function getCallName(stackLevel: number = 3): string { +function getCallName(stackLevel = 3): string { const typeName = callsites()[stackLevel]?.getTypeName() ?? ''; const functionName = callsites()[3]?.getFunctionName() ?? @@ -47,7 +49,7 @@ function getCallName(stackLevel: number = 3): string { return functionName; } -function getFileName(rootFolder = '', stackLevel: number = 3): string { +function getFileName(rootFolder = '', stackLevel = 3): string { const fileName = callsites()[stackLevel]?.getFileName() ?? callsites()[stackLevel]?.getEvalOrigin() ?? diff --git a/src/lib/shared/lucia/testing/index.ts b/src/lib/shared/lucia/testing/index.ts index 43adfd5..23297ca 100644 --- a/src/lib/shared/lucia/testing/index.ts +++ b/src/lib/shared/lucia/testing/index.ts @@ -1,8 +1,9 @@ -import type { AuthSession, AuthUser } from '$lib/shared/lucia/types'; import dayjs from 'dayjs'; import type { AuthRequest } from 'lucia'; import { vi } from 'vitest'; +import type { AuthSession, AuthUser } from '$lib/shared/lucia/types'; + export function getMockAuthRequest( authSession: AuthSession | null = null, ): AuthRequest { diff --git a/src/lib/shared/posthog/utils/index.node-test.ts b/src/lib/shared/posthog/utils/index.node-test.ts index f23637c..3372aa2 100644 --- a/src/lib/shared/posthog/utils/index.node-test.ts +++ b/src/lib/shared/posthog/utils/index.node-test.ts @@ -1,12 +1,13 @@ import { + afterEach, + beforeEach, describe, - it, expect, - beforeEach, - afterEach, - vi, + it, type Mock, + vi, } from 'vitest'; + import { _arePosthogClientConfigurationInputsValid, _setupPosthogClientBase, diff --git a/src/lib/shared/sentry/client.node-test.ts b/src/lib/shared/sentry/client.node-test.ts index 571e334..499983a 100644 --- a/src/lib/shared/sentry/client.node-test.ts +++ b/src/lib/shared/sentry/client.node-test.ts @@ -1,20 +1,21 @@ +import * as sentrySveltekitModule from '@sentry/sveltekit'; import { + afterEach, + beforeEach, describe, - it, expect, - beforeEach, - afterEach, - vi, + it, type MockInstance, + vi, } from 'vitest'; + import { - setupSentryClient, - sentry, - _resetSentryClient, _areSentryClientConfigurationInputsValid, + _resetSentryClient, checkIfSentryClientConfigured, + sentry, + setupSentryClient, } from './client'; -import * as sentrySveltekitModule from '@sentry/sveltekit'; // To avoid "TypeError: Cannot redefine property" error vi.mock('@sentry/sveltekit'); @@ -36,7 +37,7 @@ describe(setupSentryClient.name, () => { }); it('should configure the client', async () => { - await setupSentryClient({ + setupSentryClient({ dsn: 'mock-dsn', environment: 'localhost', origin: 'http://localhost:3000', @@ -53,7 +54,7 @@ describe(setupSentryClient.name, () => { }); it('should not configure the client if its already configured', async () => { - await setupSentryClient({ + setupSentryClient({ dsn: 'mock-dsn', environment: 'localhost', origin: 'http://localhost:3000', @@ -61,7 +62,7 @@ describe(setupSentryClient.name, () => { // Reset the spy to check if it's called again vi.clearAllMocks(); - await setupSentryClient({ + setupSentryClient({ dsn: 'mock-dsn', environment: 'localhost', origin: 'http://localhost:3000', @@ -71,7 +72,7 @@ describe(setupSentryClient.name, () => { }); it('should fail configuration of the client if configuration inputs are invalid', async () => { - await setupSentryClient({ + setupSentryClient({ dsn: undefined, environment: undefined, origin: 'http://localhost:3000', @@ -89,7 +90,7 @@ describe(checkIfSentryClientConfigured.name, () => { }); it('should not throw an error if client is configured', async () => { - await setupSentryClient({ + setupSentryClient({ dsn: 'mock-dsn', environment: 'localhost', origin: 'http://localhost:3000', diff --git a/src/lib/shared/sentry/client.ts b/src/lib/shared/sentry/client.ts index 3f7bc3f..6e43fb3 100644 --- a/src/lib/shared/sentry/client.ts +++ b/src/lib/shared/sentry/client.ts @@ -1,7 +1,8 @@ -import { dev } from '$app/environment'; import * as Sentry from '@sentry/sveltekit'; import type { Integration } from '@sentry/types'; +import { dev } from '$app/environment'; + type SentryClient = typeof Sentry; export const handleErrorWithSentry = Sentry.handleErrorWithSentry; diff --git a/src/lib/shared/sentry/utils/index.ts b/src/lib/shared/sentry/utils/index.ts index 31ed1fb..c66da69 100644 --- a/src/lib/shared/sentry/utils/index.ts +++ b/src/lib/shared/sentry/utils/index.ts @@ -1,6 +1,7 @@ -import { sentry } from '../client'; import type { SpanContextData } from '@sentry/types'; +import { sentry } from '../client'; + export function getTraceSpanId(): string | undefined { const { traceId, spanId } = getSpanContextData() || {}; if (!traceId || !spanId) { diff --git a/src/lib/shared/sveltekit/testing/test-helpers.ts b/src/lib/shared/sveltekit/testing/test-helpers.ts index a8b5bba..9720440 100644 --- a/src/lib/shared/sveltekit/testing/test-helpers.ts +++ b/src/lib/shared/sveltekit/testing/test-helpers.ts @@ -1,11 +1,12 @@ +import type { Navigation, Page } from '@sveltejs/kit'; +import { readable } from 'svelte/store'; import { vi } from 'vitest'; + import type * as appEnvironmentModule from '$app/environment'; import type * as appNavigationModule from '$app/navigation'; import type * as appStoresModule from '$app/stores'; import type * as envDynamicPrivateModule from '$env/dynamic/private'; import type * as envDynamicPublicModule from '$env/dynamic/public'; -import type { Navigation, Page } from '@sveltejs/kit'; -import { readable } from 'svelte/store'; export const defaultMockAppEnvironment: typeof appEnvironmentModule = { browser: false, @@ -100,7 +101,7 @@ export class SveltekitDefaultMocks { const updated = { subscribe: readable(false).subscribe, - check: async () => false, + check: () => Promise.resolve(false), }; return { navigating, page, updated }; @@ -122,7 +123,7 @@ export class SveltekitDefaultMocks { subscribe(fn) { return getStores().updated.subscribe(fn); }, - check: async () => false, + check: () => Promise.resolve(false), }; return { diff --git a/src/lib/shared/zod/utils/errors.node-test.ts b/src/lib/shared/zod/utils/errors.node-test.ts index 99624ac..087aeb2 100644 --- a/src/lib/shared/zod/utils/errors.node-test.ts +++ b/src/lib/shared/zod/utils/errors.node-test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect } from 'vitest'; +import { describe, expect, it } from 'vitest'; + import { getRequiredErrorMessage } from './errors'; describe(getRequiredErrorMessage.name, () => { diff --git a/src/lib/shared/zod/utils/extract.node-test.ts b/src/lib/shared/zod/utils/extract.node-test.ts index 1180c31..e96ceb9 100644 --- a/src/lib/shared/zod/utils/extract.node-test.ts +++ b/src/lib/shared/zod/utils/extract.node-test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest'; +import { z, ZodError } from 'zod'; + import { extractZodErrorPaths } from './extract'; -import { ZodError, z } from 'zod'; describe(extractZodErrorPaths.name, () => { it('should return error path if error is thrown', () => { diff --git a/src/routes/(app)/(card-layout)/code-snippets/[id]/+page.server.ts b/src/routes/(app)/(card-layout)/code-snippets/[id]/+page.server.ts index f9fb742..4c47927 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/[id]/+page.server.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/[id]/+page.server.ts @@ -1,13 +1,15 @@ -import { codeSnippetsService } from '$lib/server/code-snippets'; import type { CodeSnippet } from '@prisma/client'; -import type { Actions, PageServerLoad } from './$types'; import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; -import { throwCodeSnippetNotFoundError } from '$lib/server/code-snippets/utils'; +import type { ActionFailure } from '@sveltejs/kit'; +import { redirect as redirectWithFlash } from 'sveltekit-flash-message/server'; import { superValidate } from 'sveltekit-superforms/server'; import { z } from 'zod'; -import { redirect as redirectWithFlash } from 'sveltekit-flash-message/server'; + +import { codeSnippetsService } from '$lib/server/code-snippets'; import { deleteCodeSnippetFormAction } from '$lib/server/code-snippets/form-actions'; -import type { ActionFailure } from '@sveltejs/kit'; +import { throwCodeSnippetNotFoundError } from '$lib/server/code-snippets/utils'; + +import type { Actions, PageServerLoad } from './$types'; const formSchema = z.object({}).strict(); export type FormSchema = typeof formSchema; @@ -51,7 +53,8 @@ export const actions = { authUser, form, ); - if ((result as unknown as ActionFailure)?.status>= 400) { + const possibleActionFailure = result as unknown as ActionFailure; + if (possibleActionFailure.status && possibleActionFailure.status>= 400) { return result; } diff --git a/src/routes/(app)/(card-layout)/code-snippets/[id]/+page.svelte b/src/routes/(app)/(card-layout)/code-snippets/[id]/+page.svelte index 925c68a..3c2567e 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/[id]/+page.svelte +++ b/src/routes/(app)/(card-layout)/code-snippets/[id]/+page.svelte @@ -1,15 +1,16 @@ lang="ts"> -import { Alert, Card } from '$lib/client/components/common'; import { CodeBlock, getToastStore } from '@skeletonlabs/skeleton'; +import { superForm } from 'sveltekit-superforms/client'; + import IconPenToSquare from '~icons/fa6-solid/pen-to-square'; import IconTrash from '~icons/fa6-solid/trash'; -import { superForm } from 'sveltekit-superforms/client'; +import { Alert, Card } from '$lib/client/components/common'; +import { config } from '$lib/client/core/config'; import { showToastIfFormMessagePresent, showToastOnInternetDisconnect, } from '$lib/client/global-messages/utils'; import { formatUtcDateTime } from '$lib/shared/core/utils'; -import { config } from '$lib/client/core/config'; export let data; diff --git a/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/+page.server.ts b/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/+page.server.ts index b8a2109..5d561e0 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/+page.server.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/+page.server.ts @@ -1,16 +1,18 @@ -import { guardAuthUser } from '$lib/server/lucia/guards'; -import { type HttpError, error, fail } from '@sveltejs/kit'; -import type { Actions, PageServerLoad } from './$types'; -import { codeSnippetsService } from '$lib/server/code-snippets'; -import { message, superValidate } from 'sveltekit-superforms/server'; -import { createEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import type { CodeSnippet } from '@prisma/client'; import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; +import { error, fail, type HttpError } from '@sveltejs/kit'; +import { message, superValidate } from 'sveltekit-superforms/server'; + +import { codeSnippetsService } from '$lib/server/code-snippets'; import { throwCodeSnippetNotFoundError } from '$lib/server/code-snippets/utils'; +import { guardAuthUser } from '$lib/server/lucia/guards'; import { posthog } from '$lib/server/posthog'; +import { createEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import { POSTHOG_CODE_SNIPPET_UPDATED_EVENT_NAME } from '$lib/shared/posthog/constants'; import { sentry } from '$lib/shared/sentry'; +import type { Actions, PageServerLoad } from './$types'; + export const load = (async ({ locals, url, params }) => { const authPageData = guardAuthUser(locals, url); diff --git a/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/+page.svelte b/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/+page.svelte index 473e3b7..f2a7eac 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/+page.svelte +++ b/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/+page.svelte @@ -1,10 +1,11 @@ lang="ts"> -import { Card } from '$lib/client/components/common'; +import { onMount } from 'svelte'; + import { CodeSnippetCreateEditForm } from '$lib/client/components/code-snippets'; -import { goBack } from '$lib/client/core/utils'; +import { Card } from '$lib/client/components/common'; import { config } from '$lib/client/core/config'; -import { onMount } from 'svelte'; import { previousAppPage } from '$lib/client/core/stores'; +import { goBack } from '$lib/client/core/utils'; export let data; diff --git a/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/page.server.node-test.ts b/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/page.server.node-test.ts index aaedd10..5b20968 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/page.server.node-test.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/page.server.node-test.ts @@ -1,37 +1,39 @@ -import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import type { CodeSnippet } from '@prisma/client'; +import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; +import { type Cookies, error, fail } from '@sveltejs/kit'; +import type { PostHog } from 'posthog-node'; +import * as sveltekitSuperformsServerModule from 'sveltekit-superforms/server'; import { afterEach, beforeEach, describe, expect, it, - vi, type Mock, + vi, } from 'vitest'; -import { actions, load } from './+page.server'; -import type { PageServerLoadEvent, RequestEvent } from './$types'; -import { fail, type Cookies, error } from '@sveltejs/kit'; + import * as libServerCodeSnippetsModule from '$lib/server/code-snippets'; import type { CodeSnippetsService } from '$lib/server/code-snippets/services'; -import { getMockFormData } from '$lib/server/superforms/testing'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; -import { getMockCreateCodeSnippetFormConstraints } from '$lib/shared/code-snippets/testing'; -import type { CreateEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import * as libServerLuciaGuardsModule from '$lib/server/lucia/guards'; -import * as sveltekitSuperformsServerModule from 'sveltekit-superforms/server'; -import type { CodeSnippet } from '@prisma/client'; -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; -import type { AuthUser } from '$lib/shared/lucia/types'; +import * as libServerPosthogModule from '$lib/server/posthog'; +import { getMockFormData } from '$lib/server/superforms/testing'; import { getMockCookies, - getMockRequestEvent, getMockLocals, - getMockRequest, getMockPageServerLoadEvent, + getMockRequest, + getMockRequestEvent, } from '$lib/server/sveltekit/testing'; -import * as libServerPosthogModule from '$lib/server/posthog'; -import type { PostHog } from 'posthog-node'; +import type { CreateEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; +import { getMockCreateCodeSnippetFormConstraints } from '$lib/shared/code-snippets/testing'; import { getMockWithType } from '$lib/shared/core/testing'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import type { AuthUser } from '$lib/shared/lucia/types'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import { actions, load } from './+page.server'; +import type { PageServerLoadEvent, RequestEvent } from './$types'; describe(load.name, () => { let mockAuthUser: AuthUser; @@ -62,7 +64,6 @@ describe(load.name, () => { } as CodeSnippet); vi.spyOn(libServerLuciaGuardsModule, 'guardAuthUser').mockReturnValue({ authUser: mockAuthUser, - doesRequireAuth: true, }); vi.spyOn( libServerCodeSnippetsModule, diff --git a/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/page.svelte.dom-test.ts b/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/page.svelte.dom-test.ts index 0753e1c..54067be 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/page.svelte.dom-test.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/[id]/edit/page.svelte.dom-test.ts @@ -1,11 +1,13 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; -import { render, cleanup } from '@testing-library/svelte'; -import Component from './+page.svelte'; -import type { CreateEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; -import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; import type { ToastStore } from '@skeletonlabs/skeleton'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; +import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; +import { cleanup, render } from '@testing-library/svelte'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import type { CreateEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import { getMockCreateCodeSnippetFormConstraints } from '$lib/shared/code-snippets/testing'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import Component from './+page.svelte'; describe(Component.name, () => { beforeEach(() => { diff --git a/src/routes/(app)/(card-layout)/code-snippets/[id]/page.server.node-test.ts b/src/routes/(app)/(card-layout)/code-snippets/[id]/page.server.node-test.ts index fc6dd9f..9cb220c 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/[id]/page.server.node-test.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/[id]/page.server.node-test.ts @@ -1,35 +1,37 @@ -import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import type { CodeSnippet } from '@prisma/client'; +import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; +import { type Cookies, error, fail } from '@sveltejs/kit'; +import * as sveltekitFlashMessageServerModule from 'sveltekit-flash-message/server'; +import * as sveltekitSuperformsServerModule from 'sveltekit-superforms/server'; import { afterEach, beforeEach, describe, expect, it, - vi, type Mock, type MockInstance, + vi, } from 'vitest'; -import { actions, load, type FormSchema } from './+page.server'; -import type { PageServerLoadEvent, RequestEvent } from './$types'; -import { fail, type Cookies, error } from '@sveltejs/kit'; + import * as libServerCodeSnippetsModule from '$lib/server/code-snippets'; +import * as libServerCodeSnippetsFormActionsModule from '$lib/server/code-snippets/form-actions'; import type { CodeSnippetsService } from '$lib/server/code-snippets/services'; import { getMockFormData } from '$lib/server/superforms/testing'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; -import { getMockCodeSnippet } from '$lib/shared/code-snippets/testing'; -import * as sveltekitSuperformsServerModule from 'sveltekit-superforms/server'; -import type { CodeSnippet } from '@prisma/client'; -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; -import type { AuthUser } from '$lib/shared/lucia/types'; import { getMockCookies, - getMockRequestEvent, getMockLocals, - getMockRequest, getMockPageServerLoadEvent, + getMockRequest, + getMockRequestEvent, } from '$lib/server/sveltekit/testing'; -import * as sveltekitFlashMessageServerModule from 'sveltekit-flash-message/server'; -import * as libServerCodeSnippetsFormActionsModule from '$lib/server/code-snippets/form-actions'; +import { getMockCodeSnippet } from '$lib/shared/code-snippets/testing'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import type { AuthUser } from '$lib/shared/lucia/types'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import { actions, type FormSchema, load } from './+page.server'; +import type { PageServerLoadEvent, RequestEvent } from './$types'; describe(load.name, () => { let mockAuthUser: AuthUser; diff --git a/src/routes/(app)/(card-layout)/code-snippets/[id]/page.svelte.dom-test.ts b/src/routes/(app)/(card-layout)/code-snippets/[id]/page.svelte.dom-test.ts index 6fa0e61..dc1292f 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/[id]/page.svelte.dom-test.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/[id]/page.svelte.dom-test.ts @@ -1,12 +1,14 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; -import { render, cleanup } from '@testing-library/svelte'; -import Component from './+page.svelte'; -import type { FormSchema } from './+page.server'; -import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; -import type { ToastStore } from '@skeletonlabs/skeleton'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; import type { CodeSnippet } from '@prisma/client'; +import type { ToastStore } from '@skeletonlabs/skeleton'; +import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; +import { cleanup, render } from '@testing-library/svelte'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + import { getMockCodeSnippet } from '$lib/shared/code-snippets/testing'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import type { FormSchema } from './+page.server'; +import Component from './+page.svelte'; describe(Component.name, () => { let mockCodeSnippet: CodeSnippet; diff --git a/src/routes/(app)/(card-layout)/code-snippets/create/+page.server.ts b/src/routes/(app)/(card-layout)/code-snippets/create/+page.server.ts index 30e8943..21b9e3d 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/create/+page.server.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/create/+page.server.ts @@ -1,15 +1,17 @@ -import { guardAuthUser } from '$lib/server/lucia/guards'; +import type { CodeSnippet } from '@prisma/client'; import { fail } from '@sveltejs/kit'; import { redirect as redirectWithFlash } from 'sveltekit-flash-message/server'; -import type { Actions, PageServerLoad } from './$types'; -import { codeSnippetsService } from '$lib/server/code-snippets'; import { message, superValidate } from 'sveltekit-superforms/server'; -import { createEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; + +import { codeSnippetsService } from '$lib/server/code-snippets'; +import { guardAuthUser } from '$lib/server/lucia/guards'; import { posthog } from '$lib/server/posthog'; +import { createEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import { POSTHOG_CODE_SNIPPET_CREATED_EVENT_NAME } from '$lib/shared/posthog/constants'; -import type { CodeSnippet } from '@prisma/client'; import { sentry } from '$lib/shared/sentry'; +import type { Actions, PageServerLoad } from './$types'; + export const load = (async ({ locals, url }) => { const authPageData = guardAuthUser(locals, url); const form = await superValidate(createEditCodeSnippetFormSchema); diff --git a/src/routes/(app)/(card-layout)/code-snippets/create/+page.svelte b/src/routes/(app)/(card-layout)/code-snippets/create/+page.svelte index ed7eeb8..a25eb92 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/create/+page.svelte +++ b/src/routes/(app)/(card-layout)/code-snippets/create/+page.svelte @@ -1,6 +1,6 @@ lang="ts"> -import { Card } from '$lib/client/components/common'; import { CodeSnippetCreateEditForm } from '$lib/client/components/code-snippets'; +import { Card } from '$lib/client/components/common'; import { config } from '$lib/client/core/config'; export let data; diff --git a/src/routes/(app)/(card-layout)/code-snippets/create/page.server.node-test.ts b/src/routes/(app)/(card-layout)/code-snippets/create/page.server.node-test.ts index d4a8dfc..1420dcf 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/create/page.server.node-test.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/create/page.server.node-test.ts @@ -1,23 +1,25 @@ -import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import { type Cookies, fail } from '@sveltejs/kit'; +import type { PostHog } from 'posthog-node'; +import * as sveltekitFlashMessageServerModule from 'sveltekit-flash-message/server'; +import * as sveltekitSuperformsServerModule from 'sveltekit-superforms/server'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { actions, load } from './+page.server'; -import type { PageServerLoadEvent, RequestEvent } from './$types'; -import { fail, type Cookies } from '@sveltejs/kit'; + import * as libServerCodeSnippetsModule from '$lib/server/code-snippets'; import type { CodeSnippetsService } from '$lib/server/code-snippets/services'; -import * as sveltekitFlashMessageServerModule from 'sveltekit-flash-message/server'; +import * as libServerLuciaGuardsModule from '$lib/server/lucia/guards'; +import * as libServerPosthogModule from '$lib/server/posthog'; import { getMockFormData } from '$lib/server/superforms/testing'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; +import type { CreateEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import { getMockCodeSnippet, getMockCreateCodeSnippetFormConstraints, } from '$lib/shared/code-snippets/testing'; -import type { CreateEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; -import * as libServerLuciaGuardsModule from '$lib/server/lucia/guards'; -import * as sveltekitSuperformsServerModule from 'sveltekit-superforms/server'; -import * as libServerPosthogModule from '$lib/server/posthog'; -import type { PostHog } from 'posthog-node'; import { getMockWithType } from '$lib/shared/core/testing'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import { actions, load } from './+page.server'; +import type { PageServerLoadEvent, RequestEvent } from './$types'; describe(load.name, () => { afterEach(async () => { diff --git a/src/routes/(app)/(card-layout)/code-snippets/create/page.svelte.dom-test.ts b/src/routes/(app)/(card-layout)/code-snippets/create/page.svelte.dom-test.ts index 0753e1c..54067be 100644 --- a/src/routes/(app)/(card-layout)/code-snippets/create/page.svelte.dom-test.ts +++ b/src/routes/(app)/(card-layout)/code-snippets/create/page.svelte.dom-test.ts @@ -1,11 +1,13 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; -import { render, cleanup } from '@testing-library/svelte'; -import Component from './+page.svelte'; -import type { CreateEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; -import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; import type { ToastStore } from '@skeletonlabs/skeleton'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; +import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; +import { cleanup, render } from '@testing-library/svelte'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import type { CreateEditCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import { getMockCreateCodeSnippetFormConstraints } from '$lib/shared/code-snippets/testing'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import Component from './+page.svelte'; describe(Component.name, () => { beforeEach(() => { diff --git a/src/routes/(app)/(card-layout)/layout.svelte.dom-test.ts b/src/routes/(app)/(card-layout)/layout.svelte.dom-test.ts index bfd2ce8..780fab6 100644 --- a/src/routes/(app)/(card-layout)/layout.svelte.dom-test.ts +++ b/src/routes/(app)/(card-layout)/layout.svelte.dom-test.ts @@ -1,8 +1,10 @@ -import { describe, it, expect, afterEach } from 'vitest'; -import Component from './+layout.svelte'; -import { render, cleanup } from '@testing-library/svelte'; +import { cleanup, render } from '@testing-library/svelte'; +import { afterEach, describe, expect, it } from 'vitest'; + import { SlotTest } from '$lib/client/components/testing'; +import Component from './+layout.svelte'; + describe(Component.name, () => { afterEach(() => { cleanup(); @@ -17,7 +19,7 @@ describe(Component.name, () => { it('should render slot content', () => { const renderResult = render(SlotTest, { props: { component: Component } }); - expect(renderResult.getByTestId('slot-content').textContent).toBe( + expect(renderResult.getByTestId('slot-content')).toHaveTextContent( 'mock-slot-text', ); }); diff --git a/src/routes/(app)/(card-layout)/profile/+page.server.ts b/src/routes/(app)/(card-layout)/profile/+page.server.ts index 15bb121..84ec5f6 100644 --- a/src/routes/(app)/(card-layout)/profile/+page.server.ts +++ b/src/routes/(app)/(card-layout)/profile/+page.server.ts @@ -1,20 +1,22 @@ +import { redirect } from '@sveltejs/kit'; +import type { AuthRequest } from 'lucia'; +import { message, superValidate } from 'sveltekit-superforms/server'; +import { z } from 'zod'; + import { auth } from '$lib/server/lucia'; import { guardAuthUser } from '$lib/server/lucia/guards'; import { getCurrentAuthSession, getCurrentAuthUserFromSession, } from '$lib/server/lucia/utils'; -import type { PageServerLoad } from './$types'; -import { redirect } from '@sveltejs/kit'; -import type { Actions } from './$types'; +import { posthog } from '$lib/server/posthog'; import type { AuthSession } from '$lib/shared/lucia/types'; -import { message, superValidate } from 'sveltekit-superforms/server'; -import { z } from 'zod'; import { POSTHOG_USER_SIGN_OUT_EVENT_NAME } from '$lib/shared/posthog/constants'; -import type { AuthRequest } from 'lucia'; -import { posthog } from '$lib/server/posthog'; import { sentry } from '$lib/shared/sentry'; +import type { PageServerLoad } from './$types'; +import type { Actions } from './$types'; + const formSchema = z.object({}).strict(); export type FormSchema = typeof formSchema; diff --git a/src/routes/(app)/(card-layout)/profile/+page.svelte b/src/routes/(app)/(card-layout)/profile/+page.svelte index b44caee..e1e745a 100644 --- a/src/routes/(app)/(card-layout)/profile/+page.svelte +++ b/src/routes/(app)/(card-layout)/profile/+page.svelte @@ -1,12 +1,13 @@ lang="ts"> -import { Alert, Card } from '$lib/client/components/common'; import { getToastStore } from '@skeletonlabs/skeleton'; import { superForm } from 'sveltekit-superforms/client'; + +import { Alert, Card } from '$lib/client/components/common'; +import { config } from '$lib/client/core/config'; import { showToastIfFormMessagePresent, showToastOnInternetDisconnect, } from '$lib/client/global-messages/utils'; -import { config } from '$lib/client/core/config'; export let data; diff --git a/src/routes/(app)/(card-layout)/profile/page.server.node-test.ts b/src/routes/(app)/(card-layout)/profile/page.server.node-test.ts index 7b9933c..11a23f2 100644 --- a/src/routes/(app)/(card-layout)/profile/page.server.node-test.ts +++ b/src/routes/(app)/(card-layout)/profile/page.server.node-test.ts @@ -1,21 +1,23 @@ -import { - getMockAuthRequest, - getMockAuthSession, - getMockAuthUser, -} from '$lib/shared/lucia/testing'; -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { actions, load, type FormSchema } from './+page.server'; -import type { PageServerLoadEvent, RequestEvent } from './$types'; import { fail, redirect } from '@sveltejs/kit'; +import type { PostHog } from 'posthog-node'; +import * as sveltekitSuperformsServerModule from 'sveltekit-superforms/server'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + import { auth } from '$lib/server/lucia'; -import { getMockFormData } from '$lib/server/superforms/testing'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; import * as libServerLuciaModule from '$lib/server/lucia'; import * as libServerLuciaGuardsModule from '$lib/server/lucia/guards'; -import * as sveltekitSuperformsServerModule from 'sveltekit-superforms/server'; import * as libServerPosthogModule from '$lib/server/posthog'; -import type { PostHog } from 'posthog-node'; +import { getMockFormData } from '$lib/server/superforms/testing'; import { getMockWithType } from '$lib/shared/core/testing'; +import { + getMockAuthRequest, + getMockAuthSession, + getMockAuthUser, +} from '$lib/shared/lucia/testing'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import { actions, type FormSchema, load } from './+page.server'; +import type { PageServerLoadEvent, RequestEvent } from './$types'; describe(load.name, () => { afterEach(async () => { diff --git a/src/routes/(app)/(card-layout)/profile/page.svelte.dom-test.ts b/src/routes/(app)/(card-layout)/profile/page.svelte.dom-test.ts index a2bb3de..779762c 100644 --- a/src/routes/(app)/(card-layout)/profile/page.svelte.dom-test.ts +++ b/src/routes/(app)/(card-layout)/profile/page.svelte.dom-test.ts @@ -1,17 +1,19 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import type { ToastStore } from '@skeletonlabs/skeleton'; +import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; import { - render, cleanup, - type RenderResult, queries, + render, + type RenderResult, } from '@testing-library/svelte'; -import Component from './+page.svelte'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + import type { AuthUser } from '$lib/shared/lucia/types'; -import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; -import type { ToastStore } from '@skeletonlabs/skeleton'; -import type { FormSchema } from './+page.server'; import { getMockFormValue } from '$lib/shared/superforms/testing'; +import type { FormSchema } from './+page.server'; +import Component from './+page.svelte'; + describe(Component.name, () => { let renderResult: RenderResult; diff --git a/src/routes/(app)/+page.server.ts b/src/routes/(app)/+page.server.ts index c0d22f2..7b25f34 100644 --- a/src/routes/(app)/+page.server.ts +++ b/src/routes/(app)/+page.server.ts @@ -1,10 +1,12 @@ -import { codeSnippetsService } from '$lib/server/code-snippets'; +import { type ActionFailure, redirect } from '@sveltejs/kit'; import { message, superValidate } from 'sveltekit-superforms/server'; -import type { Actions, PageServerLoad } from './$types'; -import { redirect, type ActionFailure } from '@sveltejs/kit'; + +import { codeSnippetsService } from '$lib/server/code-snippets'; import { deleteCodeSnippetFormAction } from '$lib/server/code-snippets/form-actions'; -import { deleteCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import { generatePreviousAndNextPageUrlPaths } from '$lib/server/pagination/utils'; +import { deleteCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; + +import type { Actions, PageServerLoad } from './$types'; import { cleanSearchParamsAndGenerateQuery } from './page.server.module'; export const load = (async ({ url, locals }) => { @@ -52,7 +54,8 @@ export const actions = { authUser, form, ); - if ((result as unknown as ActionFailure)?.status>= 400) { + const possibleActionFailure = result as unknown as ActionFailure; + if (possibleActionFailure.status && possibleActionFailure.status>= 400) { return result; } diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte index e452bd9..59a45de 100644 --- a/src/routes/(app)/+page.svelte +++ b/src/routes/(app)/+page.svelte @@ -1,4 +1,8 @@ lang="ts"> +import { getToastStore } from '@skeletonlabs/skeleton'; +import { superForm } from 'sveltekit-superforms/client'; + +import IconPlus from '~icons/fa6-solid/plus'; import { goto, invalidateAll } from '$app/navigation'; import { CodeSnippetCard } from '$lib/client/components/code-snippets'; import CodeSnippetFindForm from '$lib/client/components/code-snippets/CodeSnippetFindForm.svelte'; @@ -10,9 +14,6 @@ import { showToastOnInternetDisconnect, } from '$lib/client/global-messages/utils'; import type { FindCodeSnippetsQuery } from '$lib/shared/code-snippets/dtos'; -import { getToastStore } from '@skeletonlabs/skeleton'; -import { superForm } from 'sveltekit-superforms/client'; -import IconPlus from '~icons/fa6-solid/plus'; export let data; diff --git a/src/routes/(app)/layout.svelte.dom-test.ts b/src/routes/(app)/layout.svelte.dom-test.ts index bfd2ce8..780fab6 100644 --- a/src/routes/(app)/layout.svelte.dom-test.ts +++ b/src/routes/(app)/layout.svelte.dom-test.ts @@ -1,8 +1,10 @@ -import { describe, it, expect, afterEach } from 'vitest'; -import Component from './+layout.svelte'; -import { render, cleanup } from '@testing-library/svelte'; +import { cleanup, render } from '@testing-library/svelte'; +import { afterEach, describe, expect, it } from 'vitest'; + import { SlotTest } from '$lib/client/components/testing'; +import Component from './+layout.svelte'; + describe(Component.name, () => { afterEach(() => { cleanup(); @@ -17,7 +19,7 @@ describe(Component.name, () => { it('should render slot content', () => { const renderResult = render(SlotTest, { props: { component: Component } }); - expect(renderResult.getByTestId('slot-content').textContent).toBe( + expect(renderResult.getByTestId('slot-content')).toHaveTextContent( 'mock-slot-text', ); }); diff --git a/src/routes/(app)/page.CodeSnippetCard.mock.svelte b/src/routes/(app)/page.CodeSnippetCard.mock.svelte index 4042347..e1c62aa 100644 --- a/src/routes/(app)/page.CodeSnippetCard.mock.svelte +++ b/src/routes/(app)/page.CodeSnippetCard.mock.svelte @@ -1,10 +1,11 @@ lang="ts"> +import type { CodeSnippet } from '@prisma/client'; +import type { SuperForm } from 'sveltekit-superforms/client'; + import { ignoreUnusedExportLetLintErrors } from '$lib/client/core/utils'; import type { GlobalMessage } from '$lib/client/global-messages/types'; import type { DeleteCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import type { AuthUser } from '$lib/shared/lucia/types'; -import type { CodeSnippet } from '@prisma/client'; -import type { SuperForm } from 'sveltekit-superforms/client'; export let codeSnippet: CodeSnippet; export let codeSnippetDeletionSuperForm: SuperForm< diff --git a/src/routes/(app)/page.server.module.node-test.ts b/src/routes/(app)/page.server.module.node-test.ts index cdc528d..78095d4 100644 --- a/src/routes/(app)/page.server.module.node-test.ts +++ b/src/routes/(app)/page.server.module.node-test.ts @@ -1,9 +1,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { cleanSearchParamsAndGenerateQuery } from './page.server.module'; + import type { FindCodeSnippetsQuery } from '$lib/shared/code-snippets/dtos'; import { getMockAuthUser } from '$lib/shared/lucia/testing'; import type { AuthUser } from '$lib/shared/lucia/types'; +import { cleanSearchParamsAndGenerateQuery } from './page.server.module'; + describe(cleanSearchParamsAndGenerateQuery.name, () => { let mockAuthUser: AuthUser; diff --git a/src/routes/(app)/page.server.module.ts b/src/routes/(app)/page.server.module.ts index 7fe6f90..a856651 100644 --- a/src/routes/(app)/page.server.module.ts +++ b/src/routes/(app)/page.server.module.ts @@ -46,7 +46,7 @@ export function cleanSearchParamsAndGenerateQuery( const sortOrder = (searchParams.get('sortOrder') as | FindCodeSnippetsQuery['sortOrder'] - | null) || 'asc'; + | null) ?? 'asc'; // Set query const findCodeSnippetsQuery = { @@ -55,7 +55,7 @@ export function cleanSearchParamsAndGenerateQuery( ...(filterBy != null && { filterBy }), ...(filterValue != null && { filterValue }), sortBy, - ...(sortOrder != null && { sortOrder }), + sortOrder, }; // Validate query @@ -67,23 +67,23 @@ export function cleanSearchParamsAndGenerateQuery( const path = String(errorPath[0]); if (['page', 'count'].includes(path)) { - delete findCodeSnippetsQuery['page']; + delete findCodeSnippetsQuery.page; cleanedSearchParams.delete('page'); - findCodeSnippetsQuery['count'] = DEFAULT_CODE_SNIPPET_COUNT; + findCodeSnippetsQuery.count = DEFAULT_CODE_SNIPPET_COUNT; cleanedSearchParams.delete('count'); } if (['filterBy'].includes(path)) { - delete findCodeSnippetsQuery['filterBy']; + delete findCodeSnippetsQuery.filterBy; cleanedSearchParams.delete('filterBy'); - delete findCodeSnippetsQuery['filterValue']; + delete findCodeSnippetsQuery.filterValue; cleanedSearchParams.delete('filterValue'); } if (['sortOrder'].includes(path)) { - findCodeSnippetsQuery['sortOrder'] = 'asc'; + findCodeSnippetsQuery.sortOrder = 'asc'; cleanedSearchParams.delete('sortOrder'); } }); diff --git a/src/routes/(app)/page.server.node-test.ts b/src/routes/(app)/page.server.node-test.ts index 7f13b51..b035348 100644 --- a/src/routes/(app)/page.server.node-test.ts +++ b/src/routes/(app)/page.server.node-test.ts @@ -1,30 +1,32 @@ +import { fail } from '@sveltejs/kit'; +import * as sveltejsKitModule from '@sveltejs/kit'; import { afterEach, + beforeEach, describe, expect, it, - vi, type MockInstance, - beforeEach, + vi, } from 'vitest'; -import { actions, load } from './+page.server'; + import { codeSnippetsService } from '$lib/server/code-snippets'; -import type { AuthUser } from '$lib/shared/lucia/types'; -import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import * as libServerCodeSnippetsFormActionsModule from '$lib/server/code-snippets/form-actions'; +import { getMockFormData } from '$lib/server/superforms/testing'; import { getMockLocals, getMockPageServerLoadEvent, getMockRequest, getMockRequestEvent, } from '$lib/server/sveltekit/testing'; -import { getMockFormData } from '$lib/server/superforms/testing'; -import * as libServerCodeSnippetsFormActionsModule from '$lib/server/code-snippets/form-actions'; +import type { DeleteCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; import { getMockCodeSnippet } from '$lib/shared/code-snippets/testing'; -import type { PageServerLoadEvent, RequestEvent } from './$types'; -import { fail } from '@sveltejs/kit'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import type { AuthUser } from '$lib/shared/lucia/types'; import { getMockFormValue } from '$lib/shared/superforms/testing'; -import type { DeleteCodeSnippetFormSchema } from '$lib/shared/code-snippets/dtos'; -import * as sveltejsKitModule from '@sveltejs/kit'; + +import { actions, load } from './+page.server'; +import type { PageServerLoadEvent, RequestEvent } from './$types'; describe(load.name, () => { let mockLocals: App.Locals; diff --git a/src/routes/(app)/page.svelte.dom-test.ts b/src/routes/(app)/page.svelte.dom-test.ts index 8ccb8d7..3ef4ddf 100644 --- a/src/routes/(app)/page.svelte.dom-test.ts +++ b/src/routes/(app)/page.svelte.dom-test.ts @@ -1,16 +1,18 @@ -import { describe, it, expect, afterEach, beforeEach, vi } from 'vitest'; -import { render, cleanup } from '@testing-library/svelte'; -import Component from './+page.svelte'; -import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; +import type { CodeSnippet } from '@prisma/client'; import type { ToastStore } from '@skeletonlabs/skeleton'; -import * as sveltekitSuperformsClientModule from 'sveltekit-superforms/client'; +import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; +import { cleanup, render } from '@testing-library/svelte'; import { writable } from 'svelte/store'; -import type { SuperForm } from 'sveltekit-superforms/client'; import type { UnwrapEffects, ZodValidation } from 'sveltekit-superforms'; +import type { SuperForm } from 'sveltekit-superforms/client'; +import * as sveltekitSuperformsClientModule from 'sveltekit-superforms/client'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import type { AnyZodObject } from 'zod'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; + import { getMockCodeSnippet } from '$lib/shared/code-snippets/testing'; -import type { CodeSnippet } from '@prisma/client'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import Component from './+page.svelte'; type SuperFormReturnType = SuperForm< UnwrapEffects>, diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index e4aca68..29e898f 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1,6 +1,6 @@ import { loadFlash } from 'sveltekit-flash-message/server'; -export const load = loadFlash(async ({ locals }) => { +export const load = loadFlash(({ locals }) => { // NOTE: Used only for the sibling `+error.svelte` that calls // `invalidateAll`. ALWAYS add this auth block to each nested page that // is accessible to unauthenticated users, but may conditionally display diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index e37e5fd..9f9e44f 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,22 +1,24 @@ lang="ts"> import '../app.postcss'; -import { - setupSkeletonModalToastDrawer, - setupSkeletonPopup, -} from '$lib/client/skeleton/utils'; + import { Toast } from '@skeletonlabs/skeleton'; +import { getToastStore } from '@skeletonlabs/skeleton'; +import { onDestroy, onMount } from 'svelte'; import { getFlash } from 'sveltekit-flash-message'; + import { page } from '$app/stores'; -import { getToastStore } from '@skeletonlabs/skeleton'; import { PageMessage } from '$lib/client/components/app-shell'; import { createFlashToastSubscriber } from '$lib/client/global-messages/utils'; -import { onDestroy, onMount } from 'svelte'; import { posthog, posthogDefaultPageEventsCaptureConfigurator, posthogUserIdentityConfigurator, } from '$lib/client/posthog'; import { sentryUserIdentityConfigurator } from '$lib/client/sentry'; +import { + setupSkeletonModalToastDrawer, + setupSkeletonPopup, +} from '$lib/client/skeleton/utils'; import { sentry } from '$lib/shared/sentry'; setupSkeletonPopup(); diff --git a/src/routes/api/healthcheck/+server.ts b/src/routes/api/healthcheck/+server.ts index fad0f71..051c4ad 100644 --- a/src/routes/api/healthcheck/+server.ts +++ b/src/routes/api/healthcheck/+server.ts @@ -1,8 +1,10 @@ import { json } from '@sveltejs/kit'; -import type { RequestHandler } from './$types'; + import { config } from '$lib/server/core/config'; -export const GET = (async () => { +import type { RequestHandler } from './$types'; + +export const GET = (() => { let status = 'OK'; if (config.isMaintenanceMode) { status = 'maintenance'; diff --git a/src/routes/api/healthcheck/server.node-test.ts b/src/routes/api/healthcheck/server.node-test.ts index e868199..f906341 100644 --- a/src/routes/api/healthcheck/server.node-test.ts +++ b/src/routes/api/healthcheck/server.node-test.ts @@ -1,7 +1,9 @@ import { afterEach, describe, expect, it, vi } from 'vitest'; -import { GET } from './+server'; + import * as libServerCoreConfigModule from '$lib/server/core/config'; +import { GET } from './+server'; + describe(GET.name, () => { afterEach(async () => { vi.restoreAllMocks(); @@ -14,7 +16,7 @@ describe(GET.name, () => { typeof libServerCoreConfigModule.config > as typeof libServerCoreConfigModule.config); - const response = await GET(); + const response = GET(); expect(await response.json()).toEqual({ status: 'OK', @@ -28,7 +30,7 @@ describe(GET.name, () => { typeof libServerCoreConfigModule.config > as typeof libServerCoreConfigModule.config); - const response = await GET(); + const response = GET(); expect(await response.json()).toEqual({ status: 'maintenance', diff --git a/src/routes/error.svelte.dom-test.ts b/src/routes/error.svelte.dom-test.ts index b301869..0a6a8fa 100644 --- a/src/routes/error.svelte.dom-test.ts +++ b/src/routes/error.svelte.dom-test.ts @@ -1,11 +1,13 @@ -import { describe, it, expect, afterEach, vi } from 'vitest'; -import Component from './+error.svelte'; -import { render, cleanup } from '@testing-library/svelte'; -import * as appStores from '$app/stores'; -import { readable } from 'svelte/store'; import type { Page } from '@sveltejs/kit'; +import { cleanup, render } from '@testing-library/svelte'; +import { readable } from 'svelte/store'; +import { afterEach, describe, expect, it, vi } from 'vitest'; + +import * as appStores from '$app/stores'; import { defaultMockAppStoresPageValue } from '$lib/shared/sveltekit/testing'; +import Component from './+error.svelte'; + describe(Component.name, () => { afterEach(() => { cleanup(); diff --git a/src/routes/layout.server.node-test.ts b/src/routes/layout.server.node-test.ts index 1ca45aa..d7b3f5e 100644 --- a/src/routes/layout.server.node-test.ts +++ b/src/routes/layout.server.node-test.ts @@ -1,9 +1,11 @@ -import { getMockAuthSession } from '$lib/shared/lucia/testing'; +import type { Cookies } from '@sveltejs/kit'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { auth } from '$lib/server/lucia'; +import { getMockAuthSession } from '$lib/shared/lucia/testing'; + import { load } from './+layout.server'; import type { LayoutServerLoadEvent } from './$types'; -import { auth } from '$lib/server/lucia'; -import type { Cookies } from '@sveltejs/kit'; describe(load.name, () => { beforeEach(async () => { diff --git a/src/routes/layout.svelte.dom-test.ts b/src/routes/layout.svelte.dom-test.ts index c7f21aa..3eb0302 100644 --- a/src/routes/layout.svelte.dom-test.ts +++ b/src/routes/layout.svelte.dom-test.ts @@ -1,25 +1,27 @@ +import { cleanup, render } from '@testing-library/svelte'; +import type { PostHog } from 'posthog-js'; import { + afterEach, + beforeEach, describe, - it, expect, - beforeEach, - afterEach, - vi, + it, type MockInstance, + vi, } from 'vitest'; -import Component from './+layout.svelte'; -import { render, cleanup } from '@testing-library/svelte'; + import { SlotTest } from '$lib/client/components/testing'; -import { getMockWithType } from '$lib/shared/core/testing'; -import * as libClientPosthogModule from '$lib/client/posthog'; -import * as libClientSentryModule from '$lib/client/sentry'; -import * as libSharedSentryModule from '$lib/shared/sentry'; import type { _PosthogDefaultPageEventsCaptureConfigurator, _PosthogUserIdentityConfigurator, } from '$lib/client/posthog'; +import * as libClientPosthogModule from '$lib/client/posthog'; import type { _SentryUserIdentityConfigurator } from '$lib/client/sentry'; -import type { PostHog } from 'posthog-js'; +import * as libClientSentryModule from '$lib/client/sentry'; +import { getMockWithType } from '$lib/shared/core/testing'; +import * as libSharedSentryModule from '$lib/shared/sentry'; + +import Component from './+layout.svelte'; describe(Component.name, () => { beforeEach(() => { @@ -43,7 +45,7 @@ describe(Component.name, () => { it('should render slot content', () => { const renderResult = render(SlotTest, { props: { component: Component } }); - expect(renderResult.getByTestId('slot-content').textContent).toBe( + expect(renderResult.getByTestId('slot-content')).toHaveTextContent( 'mock-slot-text', ); }); diff --git a/src/routes/maintenance/+page.server.ts b/src/routes/maintenance/+page.server.ts index 65171c6..0e61fcf 100644 --- a/src/routes/maintenance/+page.server.ts +++ b/src/routes/maintenance/+page.server.ts @@ -1,9 +1,11 @@ import { error, redirect } from '@sveltejs/kit'; + import { config } from '$lib/server/core/config'; import { decodeOriginalPath } from '$lib/shared/core/utils'; + import type { PageServerLoad } from './$types'; -export const load = (async ({ url, setHeaders }) => { +export const load = (({ url, setHeaders }) => { if (config.isMaintenanceMode) { setHeaders({ 'Retry-After': '600', diff --git a/src/routes/maintenance/page.server.node-test.ts b/src/routes/maintenance/page.server.node-test.ts index 4340388..aeca3c0 100644 --- a/src/routes/maintenance/page.server.node-test.ts +++ b/src/routes/maintenance/page.server.node-test.ts @@ -1,10 +1,12 @@ +import * as sveltejsKitModule from '@sveltejs/kit'; import { afterEach, describe, expect, it, vi } from 'vitest'; -import { load } from './+page.server'; -import type { PageServerLoadEvent } from './$types'; + import * as libServerCoreConfigModule from '$lib/server/core/config'; -import * as sveltejsKitModule from '@sveltejs/kit'; import { ORIGINAL_PATH_URL_QUERY_PARAM_NAME } from '$lib/shared/core/utils'; +import { load } from './+page.server'; +import type { PageServerLoadEvent } from './$types'; + describe(load.name, () => { afterEach(async () => { vi.restoreAllMocks(); @@ -21,7 +23,7 @@ describe(load.name, () => { url: new URL('http://localhost/maintenance'), setHeaders, } as Partial as PageServerLoadEvent; - await expect(load(event)).rejects.toThrow(); + expect(() => load(event)).toThrow(); expect(setHeaders).toHaveBeenCalledTimes(1); expect(setHeaders).toHaveBeenCalledWith({ @@ -44,7 +46,7 @@ describe(load.name, () => { ), setHeaders, } as Partial as PageServerLoadEvent; - await expect(load(event)).rejects.toThrow(); + expect(() => load(event)).toThrow(); expect(redirectSpy).toHaveBeenCalledTimes(1); expect(redirectSpy).toHaveBeenCalledWith(307, '/auth'); @@ -61,7 +63,7 @@ describe(load.name, () => { url: new URL('http://localhost/maintenance'), setHeaders, } as Partial as PageServerLoadEvent; - await expect(load(event)).rejects.toThrow(); + expect(() => load(event)).toThrow(); expect(redirectSpy).toHaveBeenCalledTimes(1); expect(redirectSpy).toHaveBeenCalledWith(307, '/'); diff --git a/src/routes/sign-in/+page.server.ts b/src/routes/sign-in/+page.server.ts index 684d0e6..d87b4a7 100644 --- a/src/routes/sign-in/+page.server.ts +++ b/src/routes/sign-in/+page.server.ts @@ -1,10 +1,17 @@ import { - ORIGINAL_PATH_URL_QUERY_PARAM_NAME, - decodeOriginalPath, -} from '$lib/shared/core/utils'; + type Cookies, + type HttpError, + type Redirect, + redirect, +} from '@sveltejs/kit'; +import { message, superValidate } from 'sveltekit-superforms/server'; +import { z } from 'zod'; + +import { dev } from '$app/environment'; +import { getRefererHeaderUrl } from '$lib/server/core/utils'; import { - OAUTH_TYPE_QUERY_PARAM_NAME, OAUTH_STATE_COOKIE_MAX_AGE_IN_SECONDS, + OAUTH_TYPE_QUERY_PARAM_NAME, } from '$lib/server/lucia/oauth'; import { GOOGLE_OAUTH_STATE_COOKIE_NAME, @@ -14,20 +21,15 @@ import { } from '$lib/server/lucia/oauth/google'; import { signInWithGoogle } from '$lib/server/lucia/oauth/google/utils'; import { - redirect, - type HttpError, - type Redirect, - type Cookies, -} from '@sveltejs/kit'; -import type { PageServerLoad } from './$types'; -import type { Actions } from './$types'; -import { getRefererHeaderUrl } from '$lib/server/core/utils'; + decodeOriginalPath, + ORIGINAL_PATH_URL_QUERY_PARAM_NAME, +} from '$lib/shared/core/utils'; import { encodeOriginalPath } from '$lib/shared/core/utils'; -import { dev } from '$app/environment'; -import { message, superValidate } from 'sveltekit-superforms/server'; -import { z } from 'zod'; import { sentry } from '$lib/shared/sentry'; +import type { PageServerLoad } from './$types'; +import type { Actions } from './$types'; + const formSchema = z.object({}).strict(); export type FormSchema = typeof formSchema; diff --git a/src/routes/sign-in/+page.svelte b/src/routes/sign-in/+page.svelte index c9bce52..bd40764 100644 --- a/src/routes/sign-in/+page.svelte +++ b/src/routes/sign-in/+page.svelte @@ -1,18 +1,19 @@ lang="ts"> +import { getToastStore } from '@skeletonlabs/skeleton'; +import { superForm } from 'sveltekit-superforms/client'; + +import IconGoogle from '~icons/fa6-brands/google'; import { AppShell } from '$lib/client/components/app-shell'; import { Alert, Card, SingleCardPageContainer, } from '$lib/client/components/common'; -import IconGoogle from '~icons/fa6-brands/google'; -import { getToastStore } from '@skeletonlabs/skeleton'; -import { superForm } from 'sveltekit-superforms/client'; +import { config } from '$lib/client/core/config'; import { showToastIfFormMessagePresent, showToastOnInternetDisconnect, } from '$lib/client/global-messages/utils'; -import { config } from '$lib/client/core/config'; export let data; diff --git a/src/routes/sign-in/page.server.node-test.ts b/src/routes/sign-in/page.server.node-test.ts index 4b970e4..acaece6 100644 --- a/src/routes/sign-in/page.server.node-test.ts +++ b/src/routes/sign-in/page.server.node-test.ts @@ -1,26 +1,28 @@ -import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import type { Cookies } from '@sveltejs/kit'; +import * as sveltejsKitModule from '@sveltejs/kit'; +import { error } from '@sveltejs/kit'; import { afterEach, beforeEach, describe, expect, it, - vi, type MockInstance, + vi, } from 'vitest'; -import { load, type FormSchema } from './+page.server'; -import type { PageServerLoadEvent, RequestEvent } from './$types'; -import * as sveltejsKitModule from '@sveltejs/kit'; -import { ORIGINAL_PATH_URL_QUERY_PARAM_NAME } from '$lib/shared/core/utils'; + import * as libServerLuciaOauthGoogleModule from '$lib/server/lucia/oauth/google'; import * as libServerLuciaOauthGoogleUtilsModule from '$lib/server/lucia/oauth/google/utils'; -import { error } from '@sveltejs/kit'; -import { actions } from './+page.server'; -import type { Cookies } from '@sveltejs/kit'; import { getMockFormData } from '$lib/server/superforms/testing'; -import { getMockFormValue } from '$lib/shared/superforms/testing'; -import * as libSharedSentryModule from '$lib/shared/sentry'; import { getMockWithType } from '$lib/shared/core/testing'; +import { ORIGINAL_PATH_URL_QUERY_PARAM_NAME } from '$lib/shared/core/utils'; +import { getMockAuthUser } from '$lib/shared/lucia/testing'; +import * as libSharedSentryModule from '$lib/shared/sentry'; +import { getMockFormValue } from '$lib/shared/superforms/testing'; + +import { type FormSchema, load } from './+page.server'; +import { actions } from './+page.server'; +import type { PageServerLoadEvent, RequestEvent } from './$types'; describe(load.name, () => { afterEach(async () => { @@ -262,7 +264,7 @@ describe('actions', () => { libServerLuciaOauthGoogleModule, 'GOOGLE_OAUTH_STATE_COOKIE_NAME', 'get', - ).mockReturnValue('mock-state-cookie-name'); + ).mockReturnValue('mock-state-cookie-name' as any); const redirectSpy = vi.spyOn(sveltejsKitModule, 'redirect'); await expect(actions['google-auth'](mockEvent)).rejects.toThrow(); @@ -311,7 +313,7 @@ describe('actions', () => { libServerLuciaOauthGoogleModule, 'GOOGLE_OAUTH_STATE_COOKIE_NAME', 'get', - ).mockReturnValue('mock-state-cookie-name'); + ).mockReturnValue('mock-state-cookie-name' as any); const redirectSpy = vi.spyOn(sveltejsKitModule, 'redirect'); await expect(actions['google-auth'](mockEvent)).rejects.toThrow(); diff --git a/src/routes/sign-in/page.svelte.dom-test.ts b/src/routes/sign-in/page.svelte.dom-test.ts index 5d70b9b..c0fdfb7 100644 --- a/src/routes/sign-in/page.svelte.dom-test.ts +++ b/src/routes/sign-in/page.svelte.dom-test.ts @@ -1,15 +1,17 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import type { ToastStore } from '@skeletonlabs/skeleton'; +import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; import { - render, cleanup, - type RenderResult, queries, + render, + type RenderResult, } from '@testing-library/svelte'; -import Component from './+page.svelte'; -import * as skeletonlabsSkeletonModule from '@skeletonlabs/skeleton'; -import type { FormSchema } from './+page.server'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + import { getMockFormValue } from '$lib/shared/superforms/testing'; -import type { ToastStore } from '@skeletonlabs/skeleton'; + +import type { FormSchema } from './+page.server'; +import Component from './+page.svelte'; describe(Component.name, () => { let renderResult: RenderResult; diff --git a/tailwind.config.ts b/tailwind.config.ts index 31dbd0d..3be1342 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,8 +1,8 @@ -import { join } from 'path'; -import type { Config } from 'tailwindcss'; import { skeleton } from '@skeletonlabs/tw-plugin'; import forms from '@tailwindcss/forms'; import typography from '@tailwindcss/typography'; +import { join } from 'path'; +import type { Config } from 'tailwindcss'; import defaultTheme from 'tailwindcss/defaultTheme'; const config = { @@ -17,7 +17,7 @@ const config = { plugins: [ forms, typography, - // @ts-ignore + // @ts-expect-error skeleton({ themes: { preset: [{ name: 'wintry', enhancements: true }] }, }), diff --git a/tests/learning/browser/index.browser-test.ts b/tests/learning/browser/index.browser-test.ts deleted file mode 100644 index 964d287..0000000 --- a/tests/learning/browser/index.browser-test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { describe, it, expect } from 'vitest'; - -describe('sum test', () => { - it('adds 1 + 2 to equal 3', () => { - expect(1 + 2).toBe(3); - }); -}); diff --git a/tests/learning/browser/lodash.browser-test.ts b/tests/learning/browser/lodash.browser-test.ts deleted file mode 100644 index 314e25b..0000000 --- a/tests/learning/browser/lodash.browser-test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import partition from 'lodash/partition'; -import { describe, it, expect } from 'vitest'; - -/** - * Currently fails because of the following error: - * "TypeError: __vi_esm_0__.default is not a function or its return value is not iterable" - * https://github.com/vitest-dev/vitest/issues/4097 - */ -describe('lodash', () => { - describe('partition', () => { - it('should partition array', () => { - const [odd, even] = partition([1, 2, 3, 4], (n) => n % 2); - - expect(odd).toEqual([1, 3]); - expect(even).toEqual([2, 4]); - }); - }); -}); diff --git a/tests/playwright/api/tests/index.api-setup.ts b/tests/playwright/api/tests/index.api-setup.ts index 2f8bf83..a96aa2a 100644 --- a/tests/playwright/api/tests/index.api-setup.ts +++ b/tests/playwright/api/tests/index.api-setup.ts @@ -1,14 +1,19 @@ import { test as setup } from '@playwright/test'; + +import { config } from '../../common/lib/config'; import { - signIn, saveSignedInUserBeforeSignOutRoleState, saveSignedInUserRoleState, saveVisitorRoleState, seedDb, + signIn, } from '../../common/lib/setup'; -import { config } from '../../common/lib/config'; setup('setup API', async ({ page, baseURL }) => { + if (!baseURL) { + throw new Error('Base URL is not set'); + } + seedDb(); await saveVisitorRoleState(page); diff --git a/tests/playwright/api/tests/index.api-teardown.ts b/tests/playwright/api/tests/index.api-teardown.ts index c2c0821..4c0415e 100644 --- a/tests/playwright/api/tests/index.api-teardown.ts +++ b/tests/playwright/api/tests/index.api-teardown.ts @@ -1,5 +1,5 @@ import { test as teardown } from '@playwright/test'; -teardown('teardown API', async () => { +teardown('teardown API', () => { console.log('API teardown complete'); }); diff --git a/tests/playwright/api/tests/signed-in-user--before-sign-out/sign-out.api-test.ts b/tests/playwright/api/tests/signed-in-user--before-sign-out/sign-out.api-test.ts index 9fed29d..b334a05 100644 --- a/tests/playwright/api/tests/signed-in-user--before-sign-out/sign-out.api-test.ts +++ b/tests/playwright/api/tests/signed-in-user--before-sign-out/sign-out.api-test.ts @@ -1,16 +1,13 @@ -import { test, expect, type Page } from '@playwright/test'; -import { HomePage } from '../../../e2e/page-objects/pages/home.page'; +import { expect, type Page, test } from '@playwright/test'; + import { config } from '../../../common/lib/config'; +import { HomePage } from '../../../e2e/page-objects/pages/home.page'; test.describe('POST /profile?/sign-out', () => { test('successfully logs user out and redirects to home page', async ({ page, baseURL, }) => { - if (!baseURL) { - throw new Error('Base URL is not set'); - } - const homePage = new HomePage(page); await homePage.doNavigateTo(); @@ -19,7 +16,7 @@ test.describe('POST /profile?/sign-out', () => { const response = await page.request.post('/profile?/sign-out', { headers: { // Needed to pass CSRF check - origin: baseURL, + origin: baseURL!, }, form: {}, }); @@ -34,15 +31,11 @@ test.describe('POST /profile?/sign-out', () => { }); test('returns 401 if user is not logged in', async ({ page, baseURL }) => { - if (!baseURL) { - throw new Error('Base URL is not set'); - } - await page.context().clearCookies(); const response = await page.request.post('/profile?/sign-out', { headers: { // Needed to pass CSRF check - origin: baseURL, + origin: baseURL!, }, form: {}, }); diff --git a/tests/playwright/api/tests/signed-in-user/code-snippets/create.api-test.ts b/tests/playwright/api/tests/signed-in-user/code-snippets/create.api-test.ts index 83af33c..5826f0c 100644 --- a/tests/playwright/api/tests/signed-in-user/code-snippets/create.api-test.ts +++ b/tests/playwright/api/tests/signed-in-user/code-snippets/create.api-test.ts @@ -1,6 +1,7 @@ -import { test, expect } from '@playwright/test'; -import { HomePage } from '../../../../e2e/page-objects/pages/home.page'; +import { expect, test } from '@playwright/test'; + import { config } from '../../../../common/lib/config'; +import { HomePage } from '../../../../e2e/page-objects/pages/home.page'; const CODE_SNIPPET = config.testData.codeSnippets.forCreation; @@ -9,17 +10,13 @@ test.describe('POST /code-snippets/create?/create', () => { page, baseURL, }) => { - if (!baseURL) { - throw new Error('Base URL is not set'); - } - const homePage = new HomePage(page); await homePage.doNavigateTo(); const response = await page.request.post('/code-snippets/create?/create', { headers: { // Needed to pass CSRF check - origin: baseURL, + origin: baseURL!, }, multipart: { name: CODE_SNIPPET.name, diff --git a/tests/playwright/api/tests/signed-in-user/code-snippets/delete.api-test.ts b/tests/playwright/api/tests/signed-in-user/code-snippets/delete.api-test.ts index a4a3a8b..81f1993 100644 --- a/tests/playwright/api/tests/signed-in-user/code-snippets/delete.api-test.ts +++ b/tests/playwright/api/tests/signed-in-user/code-snippets/delete.api-test.ts @@ -1,6 +1,7 @@ -import { test, expect } from '@playwright/test'; -import { HomePage } from '../../../../e2e/page-objects/pages/home.page'; +import { expect, test } from '@playwright/test'; + import { config } from '../../../../common/lib/config'; +import { HomePage } from '../../../../e2e/page-objects/pages/home.page'; const CODE_SNIPPET = config.testData.codeSnippets.forDeletion; @@ -9,10 +10,6 @@ test.describe('POST /code-snippets/:id?/delete', () => { page, baseURL, }) => { - if (!baseURL) { - throw new Error('Base URL is not set'); - } - const homePage = new HomePage(page); await homePage.doNavigateTo(); @@ -21,7 +18,7 @@ test.describe('POST /code-snippets/:id?/delete', () => { { headers: { // Needed to pass CSRF check - origin: baseURL, + origin: baseURL!, }, multipart: {}, }, diff --git a/tests/playwright/api/tests/signed-in-user/code-snippets/edit.api-test.ts b/tests/playwright/api/tests/signed-in-user/code-snippets/edit.api-test.ts index cdc09bf..ce24d2e 100644 --- a/tests/playwright/api/tests/signed-in-user/code-snippets/edit.api-test.ts +++ b/tests/playwright/api/tests/signed-in-user/code-snippets/edit.api-test.ts @@ -1,6 +1,7 @@ -import { test, expect } from '@playwright/test'; -import { HomePage } from '../../../../e2e/page-objects/pages/home.page'; +import { expect, test } from '@playwright/test'; + import { config } from '../../../../common/lib/config'; +import { HomePage } from '../../../../e2e/page-objects/pages/home.page'; const CODE_SNIPPET = config.testData.codeSnippets.forEditing; @@ -9,10 +10,6 @@ test.describe('POST /code-snippets/:id/edit?/edit', () => { page, baseURL, }) => { - if (!baseURL) { - throw new Error('Base URL is not set'); - } - const homePage = new HomePage(page); await homePage.doNavigateTo(); @@ -21,7 +18,7 @@ test.describe('POST /code-snippets/:id/edit?/edit', () => { { headers: { // Needed to pass CSRF check - origin: baseURL, + origin: baseURL!, }, multipart: { name: CODE_SNIPPET.newName, diff --git a/tests/playwright/api/tests/visitor/sign-in.api-test.ts b/tests/playwright/api/tests/visitor/sign-in.api-test.ts index 49babfc..d43f0c7 100644 --- a/tests/playwright/api/tests/visitor/sign-in.api-test.ts +++ b/tests/playwright/api/tests/visitor/sign-in.api-test.ts @@ -1,18 +1,14 @@ -import { test, expect } from '@playwright/test'; +import { expect, test } from '@playwright/test'; test.describe('POST /sign-in?/google-auth', () => { test('successfully redirects to /auth/google page', async ({ request, baseURL, }, testInfo) => { - if (!baseURL) { - throw new Error('Base URL is not set'); - } - const response = await request.post('/sign-in?/google-auth', { headers: { // Needed to pass CSRF check - origin: baseURL, + origin: baseURL!, }, form: {}, }); diff --git a/tests/playwright/common/lib/setup.ts b/tests/playwright/common/lib/setup.ts index 61af171..5eac8ef 100644 --- a/tests/playwright/common/lib/setup.ts +++ b/tests/playwright/common/lib/setup.ts @@ -1,10 +1,11 @@ import { expect, type Page } from '@playwright/test'; import dayjs from 'dayjs'; import path from 'path'; -import { COMMON_SAVED_STATES_FOLDER } from './constants'; +import shelljs from 'shelljs'; + import { HomePage } from '../../e2e/page-objects/pages/home.page'; import { config } from './config'; -import shelljs from 'shelljs'; +import { COMMON_SAVED_STATES_FOLDER } from './constants'; export async function signIn( page: Page, diff --git a/tests/playwright/e2e/page-objects/pages/home.page.ts b/tests/playwright/e2e/page-objects/pages/home.page.ts index 677fa5c..7d20f9f 100644 --- a/tests/playwright/e2e/page-objects/pages/home.page.ts +++ b/tests/playwright/e2e/page-objects/pages/home.page.ts @@ -1,4 +1,5 @@ import { expect, type Locator, type Page } from '@playwright/test'; + import { NavigationBarComponent } from '../components/navigation-bar.component'; export class HomePage { diff --git a/tests/playwright/e2e/tests/index.e2e-setup.ts b/tests/playwright/e2e/tests/index.e2e-setup.ts index e543920..ce69d3f 100644 --- a/tests/playwright/e2e/tests/index.e2e-setup.ts +++ b/tests/playwright/e2e/tests/index.e2e-setup.ts @@ -1,12 +1,13 @@ import { test as setup } from '@playwright/test'; + +import { config } from '../../common/lib/config'; import { - signIn, + saveSignedInUserBeforeSignOutRoleState, saveSignedInUserRoleState, saveVisitorRoleState, - saveSignedInUserBeforeSignOutRoleState, seedDb, + signIn, } from '../../common/lib/setup'; -import { config } from '../../common/lib/config'; setup('setup E2E', async ({ page, baseURL }) => { seedDb(); diff --git a/tests/playwright/e2e/tests/index.e2e-teardown.ts b/tests/playwright/e2e/tests/index.e2e-teardown.ts index 5567fa6..9f3b11a 100644 --- a/tests/playwright/e2e/tests/index.e2e-teardown.ts +++ b/tests/playwright/e2e/tests/index.e2e-teardown.ts @@ -1,5 +1,5 @@ import { test as teardown } from '@playwright/test'; -teardown('teardown E2E', async () => { +teardown('teardown E2E', () => { console.log('E2E teardown complete'); }); diff --git a/tests/playwright/e2e/tests/signed-in-user--before-sign-out/sign-out.e2e-test.ts b/tests/playwright/e2e/tests/signed-in-user--before-sign-out/sign-out.e2e-test.ts index bc36f05..befb2d0 100644 --- a/tests/playwright/e2e/tests/signed-in-user--before-sign-out/sign-out.e2e-test.ts +++ b/tests/playwright/e2e/tests/signed-in-user--before-sign-out/sign-out.e2e-test.ts @@ -1,4 +1,5 @@ -import { test, expect } from '@playwright/test'; +import { expect, test } from '@playwright/test'; + import { HomePage } from '../../page-objects/pages/home.page.js'; import { ProfilePage } from '../../page-objects/pages/profile.page.js'; @@ -11,7 +12,7 @@ test.describe('Feature: Sign out', () => { await expect( homePage.componentNavigationBar.getSignInButton(), - ).not.toBeVisible(); + ).toBeHidden(); await expect( homePage.componentNavigationBar.getProfileButton(), ).toBeVisible(); @@ -28,6 +29,6 @@ test.describe('Feature: Sign out', () => { ).toBeVisible(); await expect( homePage.componentNavigationBar.getProfileButton(), - ).not.toBeVisible(); + ).toBeHidden(); }); }); diff --git a/tests/playwright/e2e/tests/signed-in-user/code-snippets/create.e2e-test.ts b/tests/playwright/e2e/tests/signed-in-user/code-snippets/create.e2e-test.ts index ce01c62..049fee4 100644 --- a/tests/playwright/e2e/tests/signed-in-user/code-snippets/create.e2e-test.ts +++ b/tests/playwright/e2e/tests/signed-in-user/code-snippets/create.e2e-test.ts @@ -1,7 +1,8 @@ import { test } from '@playwright/test'; -import { HomePage } from '../../../page-objects/pages/home.page.js'; -import { CodeSnippetCreatePage } from '../../../page-objects/pages/code-snippets/create.page.js'; + import { config } from '../../../../common/lib/config'; +import { CodeSnippetCreatePage } from '../../../page-objects/pages/code-snippets/create.page.js'; +import { HomePage } from '../../../page-objects/pages/home.page.js'; const CODE_SNIPPET = config.testData.codeSnippets.forCreation; diff --git a/tests/playwright/e2e/tests/signed-in-user/code-snippets/delete.e2e-test.ts b/tests/playwright/e2e/tests/signed-in-user/code-snippets/delete.e2e-test.ts index fc81d3a..ace7845 100644 --- a/tests/playwright/e2e/tests/signed-in-user/code-snippets/delete.e2e-test.ts +++ b/tests/playwright/e2e/tests/signed-in-user/code-snippets/delete.e2e-test.ts @@ -1,7 +1,8 @@ import { test } from '@playwright/test'; -import { HomePage } from '../../../page-objects/pages/home.page'; -import { CodeSnippetViewDetailsPage } from '../../../page-objects/pages/code-snippets/view-details.page'; + import { config } from '../../../../common/lib/config'; +import { CodeSnippetViewDetailsPage } from '../../../page-objects/pages/code-snippets/view-details.page'; +import { HomePage } from '../../../page-objects/pages/home.page'; const CODE_SNIPPET = config.testData.codeSnippets.forDeletion; diff --git a/tests/playwright/e2e/tests/signed-in-user/code-snippets/edit.e2e-test.ts b/tests/playwright/e2e/tests/signed-in-user/code-snippets/edit.e2e-test.ts index 2741b31..3ece790 100644 --- a/tests/playwright/e2e/tests/signed-in-user/code-snippets/edit.e2e-test.ts +++ b/tests/playwright/e2e/tests/signed-in-user/code-snippets/edit.e2e-test.ts @@ -1,7 +1,8 @@ import { test } from '@playwright/test'; -import { HomePage } from '../../../page-objects/pages/home.page.js'; -import { CodeSnippetEditPage } from '../../../page-objects/pages/code-snippets/edit.page.js'; + import { config } from '../../../../common/lib/config'; +import { CodeSnippetEditPage } from '../../../page-objects/pages/code-snippets/edit.page.js'; +import { HomePage } from '../../../page-objects/pages/home.page.js'; const CODE_SNIPPET = config.testData.codeSnippets.forEditing; diff --git a/tests/playwright/e2e/tests/signed-in-user/code-snippets/view-details.e2e-test.ts b/tests/playwright/e2e/tests/signed-in-user/code-snippets/view-details.e2e-test.ts index 7c04526..e11d9e8 100644 --- a/tests/playwright/e2e/tests/signed-in-user/code-snippets/view-details.e2e-test.ts +++ b/tests/playwright/e2e/tests/signed-in-user/code-snippets/view-details.e2e-test.ts @@ -1,6 +1,7 @@ import { test } from '@playwright/test'; -import { CodeSnippetViewDetailsPage } from '../../../page-objects/pages/code-snippets/view-details.page'; + import { config } from '../../../../common/lib/config'; +import { CodeSnippetViewDetailsPage } from '../../../page-objects/pages/code-snippets/view-details.page'; const CODE_SNIPPET = config.testData.codeSnippets.forViewing; diff --git a/tests/playwright/e2e/tests/signed-in-user/code-snippets/view.e2e-test.ts b/tests/playwright/e2e/tests/signed-in-user/code-snippets/view.e2e-test.ts index 0f14e7a..61cc493 100644 --- a/tests/playwright/e2e/tests/signed-in-user/code-snippets/view.e2e-test.ts +++ b/tests/playwright/e2e/tests/signed-in-user/code-snippets/view.e2e-test.ts @@ -1,4 +1,5 @@ import { test } from '@playwright/test'; + import { config } from '../../../../common/lib/config'; import { HomePage } from '../../../page-objects/pages/home.page'; diff --git a/tests/playwright/e2e/tests/visitor/code-snippets/view-details.e2e-test.ts b/tests/playwright/e2e/tests/visitor/code-snippets/view-details.e2e-test.ts index 8608cb6..572e04a 100644 --- a/tests/playwright/e2e/tests/visitor/code-snippets/view-details.e2e-test.ts +++ b/tests/playwright/e2e/tests/visitor/code-snippets/view-details.e2e-test.ts @@ -1,6 +1,7 @@ import { test } from '@playwright/test'; -import { CodeSnippetViewDetailsPage } from '../../../page-objects/pages/code-snippets/view-details.page'; + import { config } from '../../../../common/lib/config'; +import { CodeSnippetViewDetailsPage } from '../../../page-objects/pages/code-snippets/view-details.page'; const CODE_SNIPPET = config.testData.codeSnippets.forViewing; diff --git a/tests/playwright/e2e/tests/visitor/code-snippets/view.e2e-test.ts b/tests/playwright/e2e/tests/visitor/code-snippets/view.e2e-test.ts index 17d9e82..6e9ec47 100644 --- a/tests/playwright/e2e/tests/visitor/code-snippets/view.e2e-test.ts +++ b/tests/playwright/e2e/tests/visitor/code-snippets/view.e2e-test.ts @@ -1,4 +1,5 @@ import { test } from '@playwright/test'; + import { config } from '../../../../common/lib/config'; import { HomePage } from '../../../page-objects/pages/home.page'; diff --git a/tests/playwright/e2e/tests/visitor/sign-in.e2e-test.ts b/tests/playwright/e2e/tests/visitor/sign-in.e2e-test.ts index de282ec..89c738c 100644 --- a/tests/playwright/e2e/tests/visitor/sign-in.e2e-test.ts +++ b/tests/playwright/e2e/tests/visitor/sign-in.e2e-test.ts @@ -1,4 +1,5 @@ -import { test, expect } from '@playwright/test'; +import { expect, test } from '@playwright/test'; + import { HomePage } from '../../page-objects/pages/home.page.js'; import { SignInPage } from '../../page-objects/pages/sign-in.page.js'; @@ -13,7 +14,7 @@ test.describe('Feature: Sign in/Sign up via Google', () => { ).toBeVisible(); await expect( homePage.componentNavigationBar.getProfileButton(), - ).not.toBeVisible(); + ).toBeHidden(); await homePage.componentNavigationBar.doClickSignInButton(); diff --git a/tsconfig.json b/tsconfig.json index d070d7b..38e69da 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,7 +26,7 @@ "./.*.ts", "./scripts/app/**/*.js", "./scripts/stack/**/*.js", - "./scripts/ci/**/*.js" + "./scripts/testing/**/*.js" ], "compilerOptions": { "useDefineForClassFields": true, diff --git a/vite.config.ts b/vite.config.ts index 8af009b..0513718 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,11 +1,11 @@ +import { sentrySvelteKit } from '@sentry/sveltekit'; +import type { SentrySvelteKitPluginOptions } from '@sentry/sveltekit/types/vite/sentryVitePlugins'; import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig, loadEnv } from 'vite'; -import { purgeCss } from 'vite-plugin-tailwind-purgecss'; +import { visualizer } from 'rollup-plugin-visualizer'; import Icons from 'unplugin-icons/vite'; import type { PluginOption } from 'vite'; -import { visualizer } from 'rollup-plugin-visualizer'; -import { sentrySvelteKit } from '@sentry/sveltekit'; -import type { SentrySvelteKitPluginOptions } from '@sentry/sveltekit/types/vite/sentryVitePlugins'; +import { defineConfig, loadEnv } from 'vite'; +import { purgeCss } from 'vite-plugin-tailwind-purgecss'; export default defineConfig(({ mode }) => { // Load env file based on `mode` in the current working directory. @@ -17,12 +17,12 @@ export default defineConfig(({ mode }) => { minify: 'esbuild', }, server: { - host: env['VITE_DEV_HOST'] ?? 'localhost', - port: parseInt(env['VITE_DEV_PORT'] ?? '') || 5173, + host: 'localhost', + port: 3000, strictPort: true, }, preview: { - port: parseInt(env['VITE_PREVIEW_PORT'] ?? '') || 4173, + port: 3000, }, plugins: [ ...getWrappedSentrySvelteKitPlugin(mode, env), diff --git a/vitest.browser.config.ts b/vitest.browser.config.ts index b37f7f9..a177964 100644 --- a/vitest.browser.config.ts +++ b/vitest.browser.config.ts @@ -3,6 +3,7 @@ */ import { defineConfig, mergeConfig } from 'vitest/config'; + import commonConfig from './vitest.common.config'; export default defineConfig((configEnv) => diff --git a/vitest.browser.learning.config.ts b/vitest.browser.learning.config.ts deleted file mode 100644 index 03bde3b..0000000 --- a/vitest.browser.learning.config.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Used for running learning browser tests. - */ - -import { defineConfig, mergeConfig, type UserConfig } from 'vitest/config'; -import browserConfig from './vitest.browser.config'; - -const mergedConfig = defineConfig((configEnv) => - mergeConfig( - browserConfig(configEnv), - defineConfig({ - test: { - coverage: { - reportsDirectory: './reports/vitest/coverage/learning/browser', - }, - }, - }) as UserConfig, - ), -); - -const config = defineConfig((configEnv) => ({ - ...mergedConfig(configEnv), - test: { - ...mergedConfig(configEnv).test, - include: ['tests/learning/browser/**/*.browser-test.{js,ts}'], - }, -})); - -export default config; diff --git a/vitest.common.config.ts b/vitest.common.config.ts index bbd751e..616dd3f 100644 --- a/vitest.common.config.ts +++ b/vitest.common.config.ts @@ -1,4 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config'; + import viteConfig from './vite.config'; export default defineConfig((configEnv) => diff --git a/vitest.dom.config.ts b/vitest.dom.config.ts index 5537c39..5d640e6 100644 --- a/vitest.dom.config.ts +++ b/vitest.dom.config.ts @@ -3,6 +3,7 @@ */ import { defineConfig, mergeConfig } from 'vitest/config'; + import commonConfig from './vitest.common.config'; export default defineConfig((configEnv) => diff --git a/vitest.node.config.ts b/vitest.node.config.ts index 2144813..6bfae90 100644 --- a/vitest.node.config.ts +++ b/vitest.node.config.ts @@ -3,6 +3,7 @@ */ import { defineConfig, mergeConfig } from 'vitest/config'; + import commonConfig from './vitest.common.config'; export default defineConfig((configEnv) =>

AltStyle によって変換されたページ (->オリジナル) /