From d8422e978e0c74b6fa8b6a134b4b60db7070550e Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 10:18:55 +0800 Subject: [PATCH 01/87] test: add template cypress test and CI --- .eslintrc.js | 1 + .github/workflows/e2e.yml | 19 + .github/workflows/lint.yml | 2 +- .github/workflows/prettify.yml | 2 +- cypress.config.mjs | 10 + cypress/e2e/spec.cy.ts | 5 + cypress/fixtures/example.json | 5 + cypress/support/commands.ts | 37 + cypress/support/e2e.ts | 20 + package-lock.json | 1783 +++++++++++++++++++++++++++++++- package.json | 4 +- 11 files changed, 1836 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/e2e.yml create mode 100644 cypress.config.mjs create mode 100644 cypress/e2e/spec.cy.ts create mode 100644 cypress/fixtures/example.json create mode 100644 cypress/support/commands.ts create mode 100644 cypress/support/e2e.ts diff --git a/.eslintrc.js b/.eslintrc.js index e3b35fc2..178fd2ea 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -91,6 +91,7 @@ module.exports = { // Must use default export { files: [ + 'cypress.config.mjs', 'next.config.mjs', 'prettier.config.mjs', 'app/**/page.tsx', diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 00000000..e488f120 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,19 @@ +name: E2E +on: deployment_status + +jobs: + e2e-chrome: + if: github.event.deployment_status.state == 'success' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'npm' + - run: npm ci + - uses: cypress-io/github-action@v6 + with: + browser: chrome + env: + CYPRESS_BASE_URL: ${{github.event.deployment_status.environment_url}} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d6faf9d9..1a2f2448 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,5 @@ name: Lint Code -on: [pull_request, push] +on: push jobs: lint: diff --git a/.github/workflows/prettify.yml b/.github/workflows/prettify.yml index 79bf11e0..62cdaece 100644 --- a/.github/workflows/prettify.yml +++ b/.github/workflows/prettify.yml @@ -1,5 +1,5 @@ name: Prettify Code -on: [pull_request, push] +on: push jobs: prettier: diff --git a/cypress.config.mjs b/cypress.config.mjs new file mode 100644 index 00000000..aa80788a --- /dev/null +++ b/cypress.config.mjs @@ -0,0 +1,10 @@ +// @ts-check + +import { defineConfig } from 'cypress'; + +export default defineConfig({ + e2e: { + baseUrl: 'http://localhost:3000', + experimentalWebKitSupport: true, + }, +}); diff --git a/cypress/e2e/spec.cy.ts b/cypress/e2e/spec.cy.ts new file mode 100644 index 00000000..619af472 --- /dev/null +++ b/cypress/e2e/spec.cy.ts @@ -0,0 +1,5 @@ +describe('template spec', () => { + it('passes', () => { + cy.visit('/'); + }); +}); diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 00000000..02e42543 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts new file mode 100644 index 00000000..698b01a4 --- /dev/null +++ b/cypress/support/commands.ts @@ -0,0 +1,37 @@ +/// +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) +// +// declare global { +// namespace Cypress { +// interface Chainable { +// login(email: string, password: string): Chainable +// drag(subject: string, options?: Partial): Chainable +// dismiss(subject: string, options?: Partial): Chainable +// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable +// } +// } +// } \ No newline at end of file diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts new file mode 100644 index 00000000..f80f74f8 --- /dev/null +++ b/cypress/support/e2e.ts @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f2783bc6..92d0597d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", + "cypress": "^13.6.4", "dotenv-cli": "^7.3.0", "eslint": "^8.56.0", "patch-package": "^8.0.0", @@ -1918,6 +1919,16 @@ "node": ">=6.9.0" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@contentful/rich-text-types": { "version": "16.3.4", "resolved": "https://registry.npmjs.org/@contentful/rich-text-types/-/rich-text-types-16.3.4.tgz", @@ -1926,6 +1937,83 @@ "node": ">=6.0.0" } }, + "node_modules/@cypress/request": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz", + "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.10.4", + "safe-buffer": "^5.1.2", + "tough-cookie": "^4.1.3", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@cypress/request/node_modules/qs": { + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", + "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/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/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -3429,11 +3517,33 @@ "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", "dev": true }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "dev": true + }, "node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", @@ -3867,6 +3977,19 @@ "node": ">=0.4.0" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -3883,6 +4006,42 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -3903,6 +4062,26 @@ "node": ">=4" } }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -4070,12 +4249,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", "dev": true }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/astring": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", @@ -4084,6 +4290,12 @@ "astring": "bin/astring" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, "node_modules/asynciterator.prototype": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", @@ -4119,6 +4331,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "dev": true + }, "node_modules/axe-core": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", @@ -4238,6 +4465,47 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -4297,6 +4565,39 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -4320,6 +4621,15 @@ "node": ">=10.16.0" } }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -4377,6 +4687,12 @@ } ] }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -4443,6 +4759,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -4479,67 +4804,174 @@ "node": ">=0.8.0" } }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" - }, - "node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, "engines": { "node": ">=6" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, "dependencies": { - "color-name": "1.1.3" + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, "dependencies": { - "delayed-stream": "~1.0.0" + "string-width": "^4.2.0" }, "engines": { - "node": ">= 0.8" + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" } }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, "node_modules/contentful": { "version": "10.6.21", "resolved": "https://registry.npmjs.org/contentful/-/contentful-10.6.21.tgz", @@ -4600,6 +5032,12 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -4719,12 +5157,226 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/cypress": { + "version": "13.6.4", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.4.tgz", + "integrity": "sha512-pYJjCfDYB+hoOoZuhysbbYhEmNW7DEDsqn+ToCLwuVowxUXppIWRr7qk4TVRIU471ksfzyZcH+mkoF0CQUKnpw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@cypress/request": "^3.0.0", + "@cypress/xvfb": "^1.2.4", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.6.0", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "process": "^0.11.10", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.5.3", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" + } + }, + "node_modules/cypress/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cypress/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cypress/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cypress/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cypress/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cypress/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cypress/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cypress/node_modules/proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", + "dev": true + }, + "node_modules/cypress/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cypress/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/cypress/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/cypress/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", @@ -5006,6 +5658,16 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.668", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.668.tgz", @@ -5018,6 +5680,15 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -5031,6 +5702,19 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -6373,11 +7057,87 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", + "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "dev": true + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, "node_modules/fast-copy": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-2.1.7.tgz", @@ -6438,6 +7198,39 @@ "reusify": "^1.0.4" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -6556,6 +7349,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -6672,6 +7474,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -6701,6 +7518,24 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/getos": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", + "dev": true, + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/git-hooks-list": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-3.1.0.tgz", @@ -6749,6 +7584,21 @@ "node": ">=10.13.0" } }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dev": true, + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -7164,6 +8014,49 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -7222,6 +8115,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", @@ -7376,6 +8278,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -7492,6 +8406,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dev": true, + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", @@ -7611,6 +8541,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -7656,6 +8598,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakmap": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", @@ -7714,6 +8674,12 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -7767,6 +8733,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -7790,6 +8762,12 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -7858,6 +8836,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -7917,6 +8910,15 @@ "node": ">=0.10" } }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -7935,6 +8937,103 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/listr2/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7977,11 +9076,205 @@ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-update/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } }, "node_modules/longest-streak": { "version": "3.1.0", @@ -8227,6 +9520,12 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/merge-sx": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-sx/-/merge-sx-2.0.0.tgz", @@ -8896,6 +10195,15 @@ "node": ">= 0.6" } }, + "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/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -9084,6 +10392,18 @@ "semver": "bin/semver" } }, + "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/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -9222,6 +10542,21 @@ "wrappy": "1" } }, + "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/open": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", @@ -9273,6 +10608,12 @@ "node": ">=0.10.0" } }, + "node_modules/ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", + "dev": true + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -9303,6 +10644,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/p-throttle/-/p-throttle-4.1.1.tgz", @@ -9647,6 +11003,18 @@ "node": ">=8" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, "node_modules/periscopic": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", @@ -9674,6 +11042,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -9768,6 +11145,18 @@ "prettier": ">=2 || >=3" } }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/prisma": { "version": "5.9.1", "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.9.1.tgz", @@ -9784,6 +11173,15 @@ "node": ">=16.13" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -9813,6 +11211,22 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -9836,6 +11250,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -10436,6 +11856,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -10469,6 +11904,25 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -10479,6 +11933,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -10559,6 +12019,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -10588,6 +12057,26 @@ "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", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", @@ -10605,6 +12094,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -10746,6 +12241,53 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", @@ -10868,6 +12410,31 @@ "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -11053,6 +12620,15 @@ "node": ">=4" } }, + "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/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -11196,6 +12772,21 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/throttleit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", + "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -11237,6 +12828,30 @@ "node": ">=6" } }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -11317,6 +12932,24 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -11603,6 +13236,15 @@ "node": ">= 10.0.0" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -11642,6 +13284,25 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/uvu": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", @@ -11674,6 +13335,20 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "node_modules/vfile": { "version": "5.3.7", "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", @@ -12086,6 +13761,16 @@ "node": ">= 14" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index d54a83b2..5a6e64b1 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,13 @@ "private": true, "scripts": { "build": "next build", + "cypress:open": "cypress open", "dev": "next dev", "format": "prettier --write .", "postinstall": "patch-package && npm run prisma:generate", "lint": "next lint", + "prisma:db:push": "dotenv -e .env.development.local -- prisma db push", "prisma:generate": "prisma generate", - "prisma:push": "dotenv -e .env.development.local -- prisma db push", "prisma:studio": "dotenv -e .env.development.local -- prisma studio", "start": "next start" }, @@ -53,6 +54,7 @@ "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", + "cypress": "^13.6.4", "dotenv-cli": "^7.3.0", "eslint": "^8.56.0", "patch-package": "^8.0.0", From 31175c4f9ca6ba1252cd57572fed8718237a410d Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 10:31:22 +0800 Subject: [PATCH 02/87] test: debug --- cypress/e2e/spec.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cypress/e2e/spec.cy.ts b/cypress/e2e/spec.cy.ts index 619af472..50192ea7 100644 --- a/cypress/e2e/spec.cy.ts +++ b/cypress/e2e/spec.cy.ts @@ -1,5 +1,6 @@ describe('template spec', () => { it('passes', () => { - cy.visit('/'); + // eslint-disable-next-line no-console -- debug + cy.visit('/').then((win) => console.log(win.location.href)); }); }); From 57485edc15cfd081fc7b300b0258dd52f7d80af7 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 10:32:34 +0800 Subject: [PATCH 03/87] Revert "test: debug" This reverts commit c2f80d686a4f49a4ab36a9dc6bc07141bfc8fa54. --- cypress/e2e/spec.cy.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cypress/e2e/spec.cy.ts b/cypress/e2e/spec.cy.ts index 50192ea7..619af472 100644 --- a/cypress/e2e/spec.cy.ts +++ b/cypress/e2e/spec.cy.ts @@ -1,6 +1,5 @@ describe('template spec', () => { it('passes', () => { - // eslint-disable-next-line no-console -- debug - cy.visit('/').then((win) => console.log(win.location.href)); + cy.visit('/'); }); }); From dc8ccc49dfd8c54152e590cd98070c6361df3f26 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 10:33:16 +0800 Subject: [PATCH 04/87] chore: prettier code format --- cypress/support/commands.ts | 2 +- cypress/support/e2e.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 698b01a4..95857aea 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -34,4 +34,4 @@ // visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable // } // } -// } \ No newline at end of file +// } diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index f80f74f8..598ab5f0 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -14,7 +14,7 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -import './commands' +import './commands'; // Alternatively you can use CommonJS syntax: -// require('./commands') \ No newline at end of file +// require('./commands') From 3c459b816d96c86afad624d66734ffd2da0cc345 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 10:41:55 +0800 Subject: [PATCH 05/87] ci: run E2E on multiple browsers --- .github/workflows/e2e.yml | 7 +++++-- package-lock.json | 29 +++++++++++++++++++++++++++++ package.json | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e488f120..7d4bb736 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -5,6 +5,9 @@ jobs: e2e-chrome: if: github.event.deployment_status.state == 'success' runs-on: ubuntu-latest + strategy: + matrix: + browser: [chrome, edge, firefox, webkit] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -14,6 +17,6 @@ jobs: - run: npm ci - uses: cypress-io/github-action@v6 with: - browser: chrome + browser: ${{ matrix.browser }} env: - CYPRESS_BASE_URL: ${{github.event.deployment_status.environment_url}} + CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} diff --git a/package-lock.json b/package-lock.json index 92d0597d..6a606f43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,6 +52,7 @@ "dotenv-cli": "^7.3.0", "eslint": "^8.56.0", "patch-package": "^8.0.0", + "playwright-webkit": "^1.41.2", "prettier": "^3.2.5", "prettier-plugin-prisma": "^5.0.0", "prisma": "^5.9.1", @@ -11051,6 +11052,34 @@ "node": ">=0.10.0" } }, + "node_modules/playwright-core": { + "version": "1.41.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.41.2.tgz", + "integrity": "sha512-VaTvwCA4Y8kxEe+kfm2+uUUw5Lubf38RxF7FpBxLPmGe5sdNkSg5e3ChEigaGrX7qdqT3pt2m/98LiyvU2x6CA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/playwright-webkit": { + "version": "1.41.2", + "resolved": "https://registry.npmjs.org/playwright-webkit/-/playwright-webkit-1.41.2.tgz", + "integrity": "sha512-fkQC7Tz64V9Wi2mJa9IIQrgoqkEcVcQPz1uR2j+MIkZBfEj8i3A9C61A0V3k7rHuOw7veP9SwyAxi215qfnTOg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "playwright-core": "1.41.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", diff --git a/package.json b/package.json index 5a6e64b1..52401526 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "dotenv-cli": "^7.3.0", "eslint": "^8.56.0", "patch-package": "^8.0.0", + "playwright-webkit": "^1.41.2", "prettier": "^3.2.5", "prettier-plugin-prisma": "^5.0.0", "prisma": "^5.9.1", From 18f5863a9bfb08b1b5878bd71412043de9abdb25 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 10:45:42 +0800 Subject: [PATCH 06/87] ci: fix job name --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 7d4bb736..5ac8d33a 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -2,7 +2,7 @@ name: E2E on: deployment_status jobs: - e2e-chrome: + e2e: if: github.event.deployment_status.state == 'success' runs-on: ubuntu-latest strategy: From cf0ca5d189e8ad0889240ddde4b568aba2531bec Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 11:11:50 +0800 Subject: [PATCH 07/87] ci: install webkit deps --- .github/workflows/e2e.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 5ac8d33a..2519af17 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -15,8 +15,10 @@ jobs: node-version: 20.x cache: 'npm' - run: npm ci + - run: npx playwright install-deps webkit - uses: cypress-io/github-action@v6 with: + install: false browser: ${{ matrix.browser }} env: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} From 76a4c132383a52320449450474c7eb75eefbba26 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 11:21:18 +0800 Subject: [PATCH 08/87] ci: conditionally install webkit deps --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 2519af17..291262db 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -16,6 +16,7 @@ jobs: cache: 'npm' - run: npm ci - run: npx playwright install-deps webkit + if: matrix.browser == 'webkit' - uses: cypress-io/github-action@v6 with: install: false From 65866ce5952f7b77847fd4a32235e796524a2819 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 11:39:40 +0800 Subject: [PATCH 09/87] ci: e2e condition --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 291262db..dc1b6da3 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -3,7 +3,7 @@ on: deployment_status jobs: e2e: - if: github.event.deployment_status.state == 'success' + if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' runs-on: ubuntu-latest strategy: matrix: From 5f9e79633f824d30e7e07d5303d6d59c9d9f43de Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 12:05:25 +0800 Subject: [PATCH 10/87] ci: check if ref exists --- .github/workflows/e2e.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index dc1b6da3..c7198bca 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -9,6 +9,9 @@ jobs: matrix: browser: [chrome, edge, firefox, webkit] steps: + - run: echo $GITHUB_REF + - run: echo ${{ github.event.deployment.ref }} + - run: export GITHUB_REF="${{ github.event.deployment.ref }}" - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: From 5394fd3de4875d5b985e364a32022d11ec633855 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 16:44:12 +0800 Subject: [PATCH 11/87] test: add incomplete navigation tests --- .eslintrc.js | 4 +++ .gitignore | 5 ++++ components/header.tsx | 2 ++ components/nav-drawer.tsx | 7 ++++- cypress/e2e/navigation.cy.ts | 55 +++++++++++++++++++++++++++++++++++ cypress/e2e/spec.cy.ts | 5 ---- cypress/fixtures/nav.ts | 39 +++++++++++++++++++++++++ cypress/fixtures/viewports.ts | 2 ++ package-lock.json | 40 +++++++++++++++++++++++++ package.json | 1 + 10 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 cypress/e2e/navigation.cy.ts delete mode 100644 cypress/e2e/spec.cy.ts create mode 100644 cypress/fixtures/nav.ts create mode 100644 cypress/fixtures/viewports.ts diff --git a/.eslintrc.js b/.eslintrc.js index 178fd2ea..47ead19b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -113,5 +113,9 @@ module.exports = { files: ['**/*.d.ts'], rules: { 'import/no-default-export': 'off' }, }, + { + files: ['cypress/**'], + extends: ['plugin:cypress/recommended'], + }, ], }; diff --git a/.gitignore b/.gitignore index 8f322f0d..d92ccd00 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,8 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# cypress +cypress/downloads/ +cypress/screenshots/ +cypress/videos/ \ No newline at end of file diff --git a/components/header.tsx b/components/header.tsx index 7250dad1..8385700b 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -52,11 +52,13 @@ export const Header: FC = async (props) => { = ({ slotProps }) => { return ( <> - setOpen(true)} {...slotProps?.drawerButton}> + setOpen(true)} + {...slotProps?.drawerButton} + > setOpen(false)} open={open}> theme.spacing(1), diff --git a/cypress/e2e/navigation.cy.ts b/cypress/e2e/navigation.cy.ts new file mode 100644 index 00000000..d90525b5 --- /dev/null +++ b/cypress/e2e/navigation.cy.ts @@ -0,0 +1,55 @@ +import { blog, home, nav, privacyPolicy } from '../fixtures/nav'; +import { md, xs } from '../fixtures/viewports'; + +describe('Site navigation', () => { + it('navigates to home page on logo click', () => { + cy.visit(blog.pathname); + cy.get('[data-cy="logo"]').click(); + cy.location('pathname').should('equal', home.pathname); + }); + + describe('Menu button', () => { + beforeEach(() => cy.visit('/')); + it('shows in mdDown', xs, () => { + cy.get('[data-cy="menu-button"]').should('be.visible'); + }); + + it('hides in mdUp', md, () => { + cy.get('[data-cy="menu-button"]').should('not.be.visible'); + }); + }); + + for (const [key, viewport] of [ + ['xs', xs], + ['md', md], + ] as const) { + describe(`Viewport: ${key}`, viewport, () => { + beforeEach(() => { + cy.visit(home.pathname); + if (key === 'xs') { + cy.get('[data-cy="menu-button"]').click(); + } + }); + + for (const { id, label, pathname: navPathname } of nav) { + it(`navigates to ${label} page/section`, () => { + cy.get(`[data-cy="nav-list-${key}"]`).contains(label).click(); + cy.location().should(({ pathname, hash }) => { + expect(pathname).to.eq(navPathname); + expect(hash).to.eq(id ? `#${id}` : ''); + }); + }); + } + }); + } + + it(`navigates to ${privacyPolicy.label} page`, () => { + cy.visit(home.pathname); + // FIXME: we need force = true here because for some reasons, + // click event is not triggered (but no error is thrown) if the page scrolls right before it. + cy.get('footer').contains(privacyPolicy.label).click({ force: true }); + cy.location('pathname').should('equal', privacyPolicy.pathname); + }); + + // TODO: platform profile links tests +}); diff --git a/cypress/e2e/spec.cy.ts b/cypress/e2e/spec.cy.ts deleted file mode 100644 index 619af472..00000000 --- a/cypress/e2e/spec.cy.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe('template spec', () => { - it('passes', () => { - cy.visit('/'); - }); -}); diff --git a/cypress/fixtures/nav.ts b/cypress/fixtures/nav.ts new file mode 100644 index 00000000..9c2a57c3 --- /dev/null +++ b/cypress/fixtures/nav.ts @@ -0,0 +1,39 @@ +export const home = { id: '', label: 'Home', pathname: '/' } as const; +export const about = { id: 'about', label: 'About', pathname: '/' } as const; +export const experience = { + id: 'experience', + label: 'Experience', + pathname: '/', +} as const; +export const education = { + id: 'education', + label: 'Education', + pathname: '/', +} as const; +export const contact = { + id: 'contact', + label: 'Contact', + pathname: '/', +} as const; +export const contactForm = { + id: 'contactForm', + label: undefined, + pathname: '/', +} as const; +export const blog = { + id: undefined, + label: 'Blog', + pathname: '/blog', +} as const; +export const guestbook = { + id: undefined, + label: 'Guestbook', + pathname: '/guestbook', +} as const; +export const privacyPolicy = { + id: undefined, + label: 'Privacy Policy', + pathname: '/privacy-policy', +} as const; + +export const nav = [about, experience, education, contact, blog, guestbook]; diff --git a/cypress/fixtures/viewports.ts b/cypress/fixtures/viewports.ts new file mode 100644 index 00000000..80e4ca77 --- /dev/null +++ b/cypress/fixtures/viewports.ts @@ -0,0 +1,2 @@ +export const xs = { viewportWidth: 414, viewportHeight: 896 }; +export const md = { viewportWidth: 1000, viewportHeight: 600 }; diff --git a/package-lock.json b/package-lock.json index 6a606f43..02c42988 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,6 +51,7 @@ "cypress": "^13.6.4", "dotenv-cli": "^7.3.0", "eslint": "^8.56.0", + "eslint-plugin-cypress": "^2.15.1", "patch-package": "^8.0.0", "playwright-webkit": "^1.41.2", "prettier": "^3.2.5", @@ -6051,6 +6052,45 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-plugin-cypress": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.15.1.tgz", + "integrity": "sha512-eLHLWP5Q+I4j2AWepYq0PgFEei9/s5LvjuSqWrxurkg1YZ8ltxdvMNmdSf0drnsNo57CTgYY/NIHHLRSWejR7w==", + "dev": true, + "dependencies": { + "globals": "^13.20.0" + }, + "peerDependencies": { + "eslint": ">= 3.2.1" + } + }, + "node_modules/eslint-plugin-cypress/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-cypress/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-eslint-comments": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", diff --git a/package.json b/package.json index 52401526..6b537dc0 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "cypress": "^13.6.4", "dotenv-cli": "^7.3.0", "eslint": "^8.56.0", + "eslint-plugin-cypress": "^2.15.1", "patch-package": "^8.0.0", "playwright-webkit": "^1.41.2", "prettier": "^3.2.5", From 15968772e864d0161c7be296f89a7273e31ee517 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 16:54:10 +0800 Subject: [PATCH 12/87] ci(e2e): remove debug messages --- .github/workflows/e2e.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c7198bca..dc1b6da3 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -9,9 +9,6 @@ jobs: matrix: browser: [chrome, edge, firefox, webkit] steps: - - run: echo $GITHUB_REF - - run: echo ${{ github.event.deployment.ref }} - - run: export GITHUB_REF="${{ github.event.deployment.ref }}" - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: From 77af5ac723ae82163e7bea941790c96fb29c9c43 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 17:06:17 +0800 Subject: [PATCH 13/87] test: Cypress uses dedicated TS config --- cypress/tsconfig.json | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 cypress/tsconfig.json diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json new file mode 100644 index 00000000..8611cad4 --- /dev/null +++ b/cypress/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@vercel/style-guide/typescript/node20", + "compilerOptions": { + "target": "es5", + "lib": ["es5", "dom"], + "types": ["cypress", "node"] + }, + "include": ["**/*.ts"] +} From ca155e4ae438e3e9adcd543c51e29a8eb2f2adca Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 18:51:01 +0800 Subject: [PATCH 14/87] feat: add cypress to tech stack --- components/contentful.tsx | 2 + constants/contentful-ids.ts | 1 + logos/cypress-light.svg | 98 +++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 logos/cypress-light.svg diff --git a/components/contentful.tsx b/components/contentful.tsx index 000b8fd3..77d0f9aa 100644 --- a/components/contentful.tsx +++ b/components/contentful.tsx @@ -31,6 +31,7 @@ import { LiteralUnion } from 'type-fest'; import * as contentfulIds from '@/constants/contentful-ids'; import ContentfulLight from '@/logos/contentful-light.svg'; +import CypressLight from '@/logos/cypress-light.svg'; import EmailJs from '@/logos/emailjs.svg'; import ImprovMx from '@/logos/improvmx.svg'; import Mui from '@/logos/mui.svg'; @@ -112,6 +113,7 @@ const Logos = { light: PrismaLight, dark: PrismaDark, }, + [contentfulIds.cypress]: { light: CypressLight, dark: undefined }, }; export interface LogoProps extends SVGProps { diff --git a/constants/contentful-ids.ts b/constants/contentful-ids.ts index c684eb31..a0cf24e7 100644 --- a/constants/contentful-ids.ts +++ b/constants/contentful-ids.ts @@ -36,3 +36,4 @@ export const prismaReadReplicasExtension = '6myzHQnxgEBbUt9RMvHx5g'; export const muiCore = '34jdGzLYPeSdsX8ufmmtnX'; export const vercelStyleGuide = '6scCFCr3pGATuvQEFnpkC7'; export const valibot = 'ULFnAQDuQIweV6ehX8od0'; +export const cypress = '2ZcY6scvuQb0WabbaaV4mO'; diff --git a/logos/cypress-light.svg b/logos/cypress-light.svg new file mode 100644 index 00000000..fb8bf6d4 --- /dev/null +++ b/logos/cypress-light.svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3d220e0c71527f3c32a6bf0b266a136d99480102 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 19:32:20 +0800 Subject: [PATCH 15/87] test: run E2E in headed browsers --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index dc1b6da3..9308730d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -21,5 +21,6 @@ jobs: with: install: false browser: ${{ matrix.browser }} + headed: true env: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} From 4eb9f19017d206e53dd999f8c6a01e1b9223dd96 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 19:45:22 +0800 Subject: [PATCH 16/87] Revert "test: run E2E in headed browsers" This reverts commit 509fe0ba612d72daa20e8b791ffdf52fa3f5671d. --- .github/workflows/e2e.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9308730d..dc1b6da3 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -21,6 +21,5 @@ jobs: with: install: false browser: ${{ matrix.browser }} - headed: true env: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} From 7e175aadc354c9d3665fd9f20c228838365fd62c Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 20:05:40 +0800 Subject: [PATCH 17/87] test: ignore `ValiError` --- cypress/support/e2e.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index 598ab5f0..7e267084 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -1,3 +1,5 @@ +import { ValiError } from 'valibot'; + // *********************************************************** // This example support/e2e.ts is processed and // loaded automatically before your test files. @@ -18,3 +20,10 @@ import './commands'; // Alternatively you can use CommonJS syntax: // require('./commands') + +Cypress.on('uncaught:exception', (err) => { + // FIXME: This error is some times thrown when testing in webkit browser for unknown reasons + if (err instanceof ValiError) { + return false; + } +}); From c298409fd69d1f154451b0176561682fc586de8e Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 14 Feb 2024 20:20:48 +0800 Subject: [PATCH 18/87] test: fix ignoring ValiError handling --- cypress/support/e2e.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index 7e267084..9bb54d03 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -1,5 +1,3 @@ -import { ValiError } from 'valibot'; - // *********************************************************** // This example support/e2e.ts is processed and // loaded automatically before your test files. @@ -23,7 +21,7 @@ import './commands'; Cypress.on('uncaught:exception', (err) => { // FIXME: This error is some times thrown when testing in webkit browser for unknown reasons - if (err instanceof ValiError) { + if (err.name === 'ValiError') { return false; } }); From 5e24c8fa731f9c01e8bfac82a833575b5e1c51f4 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 09:26:41 +0800 Subject: [PATCH 19/87] chore: Package update --- package-lock.json | 425 ++++++++++++++++++---------------------------- package.json | 2 +- 2 files changed, 170 insertions(+), 257 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02c42988..d933c1cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "@prisma/client": "^5.9.1", "@prisma/extension-read-replicas": "^0.3.0", "@vercel/analytics": "^1.1.3", - "@vercel/speed-insights": "^1.0.9", + "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", "dayjs": "^1.11.10", @@ -2417,6 +2417,23 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -2447,9 +2464,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" @@ -2772,32 +2789,32 @@ } }, "node_modules/@next/bundle-analyzer": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.52.tgz", - "integrity": "sha512-/McNdQBFDLP86PIaJ9OLum/s8TikhHBaWEdiRMQtxD6zARzDfGQAsMPdQNUwpmnGlewiAomvUONoK1BjtVNV8Q==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.54.tgz", + "integrity": "sha512-eTeQs7V7iOfzwJvJ/OK4iD/4O1KYgsmjSEjR48h3/F7UsRQJwaF032WfdJnTHZJu+xED4J8+fXDpOPznuG8q4g==", "dev": true, "dependencies": { "webpack-bundle-analyzer": "4.10.1" } }, "node_modules/@next/env": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.52.tgz", - "integrity": "sha512-SfRVxhbN7HQC/YaDpscc1fVZzDEMF8aKcMKb5EVX//AAZ7fuTX+KZ28xzT+Pwf8OCSVJ1zgpZHdCFykMSJN/lw==" + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.54.tgz", + "integrity": "sha512-YaLOEFgbGaZCtrwpqW4E7Y3FQVOB/cp+g93a2BnGk/pWPbkMMg3vrtMAd/7p3Hbzr/TiAg8Uuy6A2uHIL6CROA==" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.52.tgz", - "integrity": "sha512-C1uvGAt1NVWWfi/LuUo3KLwHf8++wo+oKzWDt8YYXee9dcrZbW1r79pbs73KUSyHTVTITxaQquoxcFbaaLNYaA==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.54.tgz", + "integrity": "sha512-t7aQxdwYrqOqlPCCgCB8XFyJvZ/xCKKM7AcjR39OachMmp/V1nal1C67K9A4nQipD1AZfipiBmB6KL1BJyNYqw==", "dev": true, "dependencies": { "glob": "10.3.10" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.52.tgz", - "integrity": "sha512-eyoFcTvQe/H0oEP2CcoUIAw3TN6D90I0tYGoCjUMJHUxrCdqVkEOKrjvOq0vd7aqqRWkipmq9ETICSyLsnvYvQ==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.54.tgz", + "integrity": "sha512-c9H5fpL3j0cVfZ8PhKd9I2a7scmtC5QwrwtG3N+qaWKYCaawR03gC3oRFoXFQgB4cICKsgtZ6hea0fn6xi3TYQ==", "cpu": [ "arm64" ], @@ -2810,9 +2827,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.52.tgz", - "integrity": "sha512-jyAdKWtzMghK5yX/9K9zWrg1K79t0q7hLRmJeHxQg63H7Na5II/K/X+oSfAymWRTCe/ckaDQeKKodVi9smU+qg==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.54.tgz", + "integrity": "sha512-IkOsCNfMQZTUG/bDTg2QWtZbY/OGFsNhfhwi+1MnbmnbA95+ernPX7tJl+veBuLUEFe+lxEVPngZDvUZU3DIjQ==", "cpu": [ "x64" ], @@ -2825,9 +2842,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.52.tgz", - "integrity": "sha512-mLvWgfeiTuFTJMsOgSreV8ojz4pJJQT6KuPg+zMGW8i9vm9hWPwday4Y+fxIA2npWYSz16ckd0zOjXKcUA/suQ==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.54.tgz", + "integrity": "sha512-UiIyiPD8eBxlOu+vHjPtECB1IT7qnsysGCPKpTTFNt67ENsjkqdprNVAgVcN8BJbOsAZEsudK8WT67rDNGrrZQ==", "cpu": [ "arm64" ], @@ -2840,9 +2857,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.52.tgz", - "integrity": "sha512-dym9qWN39ksJb1OT9QWeS3z0M2F7E+d8VLGVDqYBU1kwjg0Td3o+gnPfPx45eruTniGcWZKNzyvSbVDVs4nVhQ==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.54.tgz", + "integrity": "sha512-RenLi+h+A8g0/XYL6PAzdorgwPsnA094EsmhsQdI8qgf5oHnpkR6WCa4hzJgODs2TghZg9dPqDOGErA7chFd8A==", "cpu": [ "arm64" ], @@ -2855,9 +2872,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.52.tgz", - "integrity": "sha512-bCcgWLIrSnyREceLYjiHXTY9kMGv5YLr7PEZ51N1kuXfLedtIpdQ1Z95zvsI23BCsTH4sTgSsckarRpLFo9EzQ==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.54.tgz", + "integrity": "sha512-VBGbm4y6wAf7nnJLznltnbWHu068xIT7MJE4ezAUs8Nk9+bxWStDE6tudWB8K6A+c39/79kX79QVvDv3A5A4+A==", "cpu": [ "x64" ], @@ -2870,9 +2887,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.52.tgz", - "integrity": "sha512-svuC6vqFg/3oGM5Aovwq4THiq5FalXokdGKiPy5mGxfgqnQWA4XxQIz2rp4QlU1m0lepPG7ieIlEdd+xU4QNWw==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.54.tgz", + "integrity": "sha512-YKufA1FOpIC081o1UnioIUJdmboFOJyvvalWAMX5tvdOdC8BNti2sm6tnl8+zRTMz92OjAch+R4O1/l9Qd/SQQ==", "cpu": [ "x64" ], @@ -2885,9 +2902,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.52.tgz", - "integrity": "sha512-zeGPaTFOv4Qw28RSIZxQag83Nx1Pp+sM0ttx5HeUsc/9hQwqrLNRST1j1k9H2yg7KGVz0wKgSOJHeVH0+TDcLQ==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.54.tgz", + "integrity": "sha512-EYrV3xRI35qeN7zW9/OZ6iYd9NpWq0tsVNLHNeBRU2MmuGuMAgR59lB47eb0fV20LnpXQJCybtxqWZOvyy9QiQ==", "cpu": [ "arm64" ], @@ -2900,9 +2917,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.52.tgz", - "integrity": "sha512-dE95Yv9N5UQIEdnP14iJ0LhpSdilBM8lBtSkm0VLcDA7nkUMig5sK1aEvFxea5P7bE9jOur/thmhTD0PgUy6cg==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.54.tgz", + "integrity": "sha512-sMxEwl64bEe35iJ1jxZpB4K3vf+zHY0pvMueYEZDSMEC+42qCqk0XtVNn129aWPNA/n5dNG6pcxKNYRS6XesEA==", "cpu": [ "ia32" ], @@ -2915,9 +2932,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.52.tgz", - "integrity": "sha512-oru22Z4gwg14bGtlg0xzSF9ND9xvziQvRpo8onHa+VW/Nd2VMqSA6fPNl6utSJca89HfYhvr3IUyIsLLkcXavw==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.54.tgz", + "integrity": "sha512-UyisjAS2lHKTjKy9gRWlNN9zgFhJCvFG/jtExEq1Ozq1qmAsWUEmgWQNmPFZfNbJ0stc43rgOC7U8NOOFtRXRw==", "cpu": [ "x64" ], @@ -3862,9 +3879,9 @@ } }, "node_modules/@vercel/speed-insights": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@vercel/speed-insights/-/speed-insights-1.0.9.tgz", - "integrity": "sha512-f+XFP0O+aZ4Olj9h+BitkB1b4NJQaxtyCb69wWuDxytJHY6Pa4QtZPdBUftHOcajUCHRVeq062fk3MKXKtjNVQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@vercel/speed-insights/-/speed-insights-1.0.10.tgz", + "integrity": "sha512-4uzdKB0RW6Ff2FkzshzjZ+RlJfLPxgm/00i0XXgxfMPhwnnsk92YgtqsxT9OcPLdJUyVU1DqFlSWWjIQMPkh0g==", "hasInstallScript": true, "peerDependencies": { "@sveltejs/kit": "^1 || ^2", @@ -4536,9 +4553,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", - "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -4555,8 +4572,8 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001580", - "electron-to-chromium": "^1.4.648", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, @@ -4842,26 +4859,6 @@ "@colors/colors": "1.5.0" } }, - "node_modules/cli-table3/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cli-truncate": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", @@ -4878,26 +4875,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -4951,12 +4928,12 @@ } }, "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true, "engines": { - "node": ">= 10" + "node": ">= 6" } }, "node_modules/common-tags": { @@ -5022,12 +4999,12 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/core-js-compat": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.1.tgz", - "integrity": "sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw==", + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", "dev": true, "dependencies": { - "browserslist": "^4.22.2" + "browserslist": "^4.22.3" }, "funding": { "type": "opencollective", @@ -5277,15 +5254,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/cypress/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/cypress/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5343,18 +5311,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/cypress/node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, "node_modules/cypress/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -5671,9 +5627,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.668", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.668.tgz", - "integrity": "sha512-ZOBocMYCehr9W31+GpMclR+KBaDZOoAEabLdhpZ8oU1JFDwIaFY0UDbpXVEUFc0BIP2O2Qn3rkfCjQmMR4T/bQ==", + "version": "1.4.669", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.669.tgz", + "integrity": "sha512-E2SmpffFPrZhBSgf8ibqanRS2mpuk3FIRDzLDwt7WFpfgJMKDHJs0hmacyP0PS1cWsq0dVkwIIzlscNaterkPg==", "dev": true }, "node_modules/emoji-regex": { @@ -7127,12 +7083,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/executable": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", @@ -7390,6 +7340,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -9038,26 +9000,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/listr2/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/listr2/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/listr2/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -9266,12 +9208,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/log-update/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/log-update/node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -9289,20 +9225,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/log-update/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/log-update/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -10333,11 +10255,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.1-canary.52", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.52.tgz", - "integrity": "sha512-hceXmdGWRt+vPtoOhBcQ0c5foNNT2rqpDaKKsr+r9XQXWIoshKfdcdT7H5HFo0jwEg2lUEDqL8MtTKtkwjtqvg==", + "version": "14.1.1-canary.54", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.54.tgz", + "integrity": "sha512-upsM73QNXv4rPg8QUbReEQ3uB/KMcEM6suRTNYHbjmqWBAY7J6jLW5aHGUDipfBlRsy/4HdU4m0dpcKqcDJniQ==", "dependencies": { - "@next/env": "14.1.1-canary.52", + "@next/env": "14.1.1-canary.54", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -10352,15 +10274,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.1-canary.52", - "@next/swc-darwin-x64": "14.1.1-canary.52", - "@next/swc-linux-arm64-gnu": "14.1.1-canary.52", - "@next/swc-linux-arm64-musl": "14.1.1-canary.52", - "@next/swc-linux-x64-gnu": "14.1.1-canary.52", - "@next/swc-linux-x64-musl": "14.1.1-canary.52", - "@next/swc-win32-arm64-msvc": "14.1.1-canary.52", - "@next/swc-win32-ia32-msvc": "14.1.1-canary.52", - "@next/swc-win32-x64-msvc": "14.1.1-canary.52" + "@next/swc-darwin-arm64": "14.1.1-canary.54", + "@next/swc-darwin-x64": "14.1.1-canary.54", + "@next/swc-linux-arm64-gnu": "14.1.1-canary.54", + "@next/swc-linux-arm64-musl": "14.1.1-canary.54", + "@next/swc-linux-x64-gnu": "14.1.1-canary.54", + "@next/swc-linux-x64-musl": "14.1.1-canary.54", + "@next/swc-win32-arm64-msvc": "14.1.1-canary.54", + "@next/swc-win32-ia32-msvc": "14.1.1-canary.54", + "@next/swc-win32-x64-msvc": "14.1.1-canary.54" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -10973,6 +10895,18 @@ "node": ">=8" } }, + "node_modules/patch-package/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/patch-package/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -11986,12 +11920,6 @@ "node": ">=8" } }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -12276,16 +12204,10 @@ } }, "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, "node_modules/sirv": { "version": "2.0.4", @@ -12513,20 +12435,17 @@ } }, "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/string-width-cjs": { @@ -12550,32 +12469,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/string.prototype.matchall": { "version": "4.0.10", @@ -12810,6 +12708,15 @@ "url": "https://opencollective.com/svgo" } }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/synckit": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.0.tgz", @@ -12857,15 +12764,15 @@ "dev": true }, "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dev": true, "dependencies": { - "os-tmpdir": "~1.0.2" + "rimraf": "^3.0.0" }, "engines": { - "node": ">=0.6.0" + "node": ">=8.17.0" } }, "node_modules/to-fast-properties": { @@ -13570,6 +13477,15 @@ "node": ">= 10.13.0" } }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -13729,26 +13645,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -13773,6 +13669,23 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", diff --git a/package.json b/package.json index 6b537dc0..7c1c0494 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@prisma/client": "^5.9.1", "@prisma/extension-read-replicas": "^0.3.0", "@vercel/analytics": "^1.1.3", - "@vercel/speed-insights": "^1.0.9", + "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", "dayjs": "^1.11.10", From a9bd849dde3fa8843bf6cb960d176f28e1608f53 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 09:59:30 +0800 Subject: [PATCH 20/87] test: refactor navigation test --- cypress/e2e/navigation.cy.ts | 66 +++++++++++++++++++----------------- package.json | 1 + 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/cypress/e2e/navigation.cy.ts b/cypress/e2e/navigation.cy.ts index d90525b5..d01e576e 100644 --- a/cypress/e2e/navigation.cy.ts +++ b/cypress/e2e/navigation.cy.ts @@ -8,46 +8,50 @@ describe('Site navigation', () => { cy.location('pathname').should('equal', home.pathname); }); - describe('Menu button', () => { - beforeEach(() => cy.visit('/')); - it('shows in mdDown', xs, () => { - cy.get('[data-cy="menu-button"]').should('be.visible'); + describe('Main navigation', () => { + beforeEach(() => cy.visit(home.pathname)); + + it('shows in drawer ONLY in mdDown', xs, () => { + cy.get('[data-cy="nav-list-xs"]').should('not.be.visible'); + cy.get('[data-cy="menu-button"]').click(); + cy.get('[data-cy="nav-list-xs"]').should('be.visible'); }); - it('hides in mdUp', md, () => { + it('shows next to logo ONLY in mdUp', md, () => { + cy.get('[data-cy="nav-list-md"]').should('be.visible'); cy.get('[data-cy="menu-button"]').should('not.be.visible'); + cy.get('[data-cy="nav-list-xs"]').should('not.be.visible'); }); - }); - for (const [key, viewport] of [ - ['xs', xs], - ['md', md], - ] as const) { - describe(`Viewport: ${key}`, viewport, () => { - beforeEach(() => { - cy.visit(home.pathname); - if (key === 'xs') { - cy.get('[data-cy="menu-button"]').click(); - } - }); + for (const [key, viewport] of [ + ['xs', xs], + ['md', md], + ] as const) { + describe(`Viewport: ${key}`, viewport, () => { + beforeEach(() => { + if (key === 'xs') { + cy.get('[data-cy="menu-button"]').click(); + } + }); - for (const { id, label, pathname: navPathname } of nav) { - it(`navigates to ${label} page/section`, () => { - cy.get(`[data-cy="nav-list-${key}"]`).contains(label).click(); - cy.location().should(({ pathname, hash }) => { - expect(pathname).to.eq(navPathname); - expect(hash).to.eq(id ? `#${id}` : ''); + for (const { id, label, pathname: navPathname } of nav) { + it(`navigates to ${label} page/section`, () => { + cy.get(`[data-cy="nav-list-${key}"]`).contains(label).click(); + cy.location().should(({ pathname, hash }) => { + expect(pathname).to.eq(navPathname); + expect(hash).to.eq(id ? `#${id}` : ''); + }); }); - }); - } - }); - } + } + }); + } + }); - it(`navigates to ${privacyPolicy.label} page`, () => { + it(`navigates to ${privacyPolicy.label} page when clicking "Privacy Policy" in footer`, () => { cy.visit(home.pathname); - // FIXME: we need force = true here because for some reasons, - // click event is not triggered (but no error is thrown) if the page scrolls right before it. - cy.get('footer').contains(privacyPolicy.label).click({ force: true }); + // FIXME: we need to use trigger() here because for some reasons, + // click() is not triggered (but no error is thrown) if the page scrolls right before it. + cy.get('footer').contains(privacyPolicy.label).trigger('click'); cy.location('pathname').should('equal', privacyPolicy.pathname); }); diff --git a/package.json b/package.json index 7c1c0494..a21eb9a2 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "scripts": { "build": "next build", "cypress:open": "cypress open", + "cypress:run": "cypress run --browser chrome", "dev": "next dev", "format": "prettier --write .", "postinstall": "patch-package && npm run prisma:generate", From 29a6fb410164d5e70a73eee4dfc04218f85a1b5b Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 14:19:52 +0800 Subject: [PATCH 21/87] test: incomplete nav tests with invalid RSS test --- cypress/e2e/navigation.cy.ts | 81 +++++++++++++++++++++++++-- cypress/fixtures/example.json | 5 -- cypress/fixtures/platform-profiles.ts | 5 ++ 3 files changed, 82 insertions(+), 9 deletions(-) delete mode 100644 cypress/fixtures/example.json create mode 100644 cypress/fixtures/platform-profiles.ts diff --git a/cypress/e2e/navigation.cy.ts b/cypress/e2e/navigation.cy.ts index d01e576e..821e6967 100644 --- a/cypress/e2e/navigation.cy.ts +++ b/cypress/e2e/navigation.cy.ts @@ -1,4 +1,10 @@ import { blog, home, nav, privacyPolicy } from '../fixtures/nav'; +import { + github, + linkedin, + rss, + stackOverflow, +} from '../fixtures/platform-profiles'; import { md, xs } from '../fixtures/viewports'; describe('Site navigation', () => { @@ -23,10 +29,7 @@ describe('Site navigation', () => { cy.get('[data-cy="nav-list-xs"]').should('not.be.visible'); }); - for (const [key, viewport] of [ - ['xs', xs], - ['md', md], - ] as const) { + for (const [key, viewport] of Object.entries({ xs, md })) { describe(`Viewport: ${key}`, viewport, () => { beforeEach(() => { if (key === 'xs') { @@ -56,4 +59,74 @@ describe('Site navigation', () => { }); // TODO: platform profile links tests + describe.only('Platform profile links', () => { + const allLinks = { + GitHub: github, + LinkedIn: linkedin, + 'Stack Overflow': stackOverflow, + RSS: rss, + }; + + const containers = [ + { + component: 'header', + visibleLinks: { GitHub: github, LinkedIn: linkedin }, + }, + { + component: 'footer', + visibleLinks: allLinks, + }, + ]; + + beforeEach(() => cy.visit(home.pathname)); + + for (const { component, visibleLinks } of containers) { + describe(component, () => { + for (const [iconTitle, url] of Object.entries(visibleLinks)) { + describe(`${iconTitle} link`, () => { + beforeEach(() => { + // suppress all errors thrown by stackoverflow.com + cy.origin('https://stackoverflow.com', () => { + cy.on('uncaught:exception', () => false); + }); + }); + + it(`opens ${url} in a new tab`, () => { + cy.get(component) + .find('svg') + .contains('title', iconTitle) + .parents('a') + .should('have.attr', 'target', '_blank') + .invoke('attr', 'target', '_self') + .click({ force: true }); + + if (url.startsWith('https')) { + cy.origin(url, { args: { url } }, ({ url }) => { + cy.url().should('equal', url); + }); + } else { + cy.location('pathname').should('equal', url); + } + }); + }); + } + + const visibleIconTitles = Object.keys(visibleLinks); + const notExistIconTitles = Object.keys(allLinks).filter( + (iconTitle) => !visibleIconTitles.includes(iconTitle), + ); + + for (const iconTitle of notExistIconTitles) { + describe(`${iconTitle} link`, () => { + it(`should not exist`, () => { + cy.get(component) + .find('svg') + .contains('title', iconTitle) + .should('not.exist'); + }); + }); + } + }); + } + }); }); diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json deleted file mode 100644 index 02e42543..00000000 --- a/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/cypress/fixtures/platform-profiles.ts b/cypress/fixtures/platform-profiles.ts new file mode 100644 index 00000000..417e9f8c --- /dev/null +++ b/cypress/fixtures/platform-profiles.ts @@ -0,0 +1,5 @@ +export const rss = '/blog/rss.xml'; +export const stackOverflow = + 'https://stackoverflow.com/users/10579013/matthew-kwong'; +export const linkedin = 'https://www.linkedin.com/in/mwskwong'; +export const github = 'https://github.com/mwskwong'; From 3f4a3d6fa9abd0589560d1d8a6229c3a5c9eef53 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 15:49:25 +0800 Subject: [PATCH 22/87] test: use another way to test platform profile links, since WebKit can't use `cy.origin()` --- cypress/e2e/navigation.cy.ts | 52 ++++++++++++++++++++++-------------- cypress/tsconfig.json | 3 +-- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/cypress/e2e/navigation.cy.ts b/cypress/e2e/navigation.cy.ts index 821e6967..a82d268c 100644 --- a/cypress/e2e/navigation.cy.ts +++ b/cypress/e2e/navigation.cy.ts @@ -1,3 +1,5 @@ +import { pick } from 'lodash-es'; + import { blog, home, nav, privacyPolicy } from '../fixtures/nav'; import { github, @@ -59,7 +61,7 @@ describe('Site navigation', () => { }); // TODO: platform profile links tests - describe.only('Platform profile links', () => { + describe('Platform profile links', () => { const allLinks = { GitHub: github, LinkedIn: linkedin, @@ -70,7 +72,7 @@ describe('Site navigation', () => { const containers = [ { component: 'header', - visibleLinks: { GitHub: github, LinkedIn: linkedin }, + visibleLinks: pick(allLinks, ['GitHub', 'LinkedIn']), }, { component: 'footer', @@ -78,35 +80,45 @@ describe('Site navigation', () => { }, ]; + /** + * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#successful_responses} + */ + const successfulAndRedirectionStatusCodes = [ + 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, + 305, 306, 307, 308, + ]; + beforeEach(() => cy.visit(home.pathname)); for (const { component, visibleLinks } of containers) { describe(component, () => { for (const [iconTitle, url] of Object.entries(visibleLinks)) { describe(`${iconTitle} link`, () => { - beforeEach(() => { - // suppress all errors thrown by stackoverflow.com - cy.origin('https://stackoverflow.com', () => { - cy.on('uncaught:exception', () => false); - }); - }); - it(`opens ${url} in a new tab`, () => { cy.get(component) .find('svg') .contains('title', iconTitle) .parents('a') - .should('have.attr', 'target', '_blank') - .invoke('attr', 'target', '_self') - .click({ force: true }); - - if (url.startsWith('https')) { - cy.origin(url, { args: { url } }, ({ url }) => { - cy.url().should('equal', url); - }); - } else { - cy.location('pathname').should('equal', url); - } + .as('link'); + + cy.get('@link').should('have.attr', 'href', url); + cy.get('@link').should('have.attr', 'target', '_blank'); + + cy.request({ url, failOnStatusCode: false }).then( + ({ status }) => { + const validStatusCodes = [ + ...successfulAndRedirectionStatusCodes, + ]; + + // LinkedIn's specially HTTP status code + // It returns for any "unauthorized" access to prevent random sites from linking to it + if (url.includes('linkedin')) { + validStatusCodes.push(999); + } + + expect(status).to.be.oneOf(validStatusCodes); + }, + ); }); }); } diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index 8611cad4..2c399cb4 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -1,9 +1,8 @@ { - "extends": "@vercel/style-guide/typescript/node20", "compilerOptions": { "target": "es5", "lib": ["es5", "dom"], - "types": ["cypress", "node"] + "types": ["cypress", "node", "lodash-es"] }, "include": ["**/*.ts"] } From 2bfaa17021eaf65d23c80e2dc0491023da00f940 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 16:57:50 +0800 Subject: [PATCH 23/87] ci(unlighthouse): add unlighthouse benchmark --- .github/workflows/unlighthouse.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/unlighthouse.yml diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml new file mode 100644 index 00000000..ae129031 --- /dev/null +++ b/.github/workflows/unlighthouse.yml @@ -0,0 +1,20 @@ +name: E2E +on: deployment_status + +jobs: + e2e: + if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' + runs-on: ubuntu-latest + steps: + - uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'npm' + - run: npm install -g @unlighthouse/cli puppeteer + - run: | + unlighthouse-ci \ + --site ${{ github.event.deployment_status.environment_url }} \ + --budget 90 \ + --no-cache \ + --throttle \ + --samples 3 From 6b45b538b0cef76a16b0ed0f8c86c8da11f57b0f Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 17:01:04 +0800 Subject: [PATCH 24/87] ci(unlighthouse): workflow name --- .github/workflows/unlighthouse.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index ae129031..7aa0caf0 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -1,15 +1,11 @@ -name: E2E +name: Unlighthouse on: deployment_status jobs: - e2e: + unlighthouse: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v4 - with: - node-version: 20.x - cache: 'npm' - run: npm install -g @unlighthouse/cli puppeteer - run: | unlighthouse-ci \ From 57e2b61864533a3d87a1748efea8a8f64a970303 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 17:11:11 +0800 Subject: [PATCH 25/87] ci(unlighthouse): reduce sample to 2 to workaround the error --- .github/workflows/unlighthouse.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index 7aa0caf0..e0cd6822 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -13,4 +13,4 @@ jobs: --budget 90 \ --no-cache \ --throttle \ - --samples 3 + --samples 2 From ad78b8e787112aecdf60bf1ca1267b3d52cba514 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 17:16:09 +0800 Subject: [PATCH 26/87] ci(unlighthouse): remove samples for now due to known issue --- .github/workflows/unlighthouse.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index e0cd6822..b97a71bf 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -12,5 +12,4 @@ jobs: --site ${{ github.event.deployment_status.environment_url }} \ --budget 90 \ --no-cache \ - --throttle \ - --samples 2 + --throttle From 502fcdb40a20f7efd4573e6ca8c91bc17d92d60e Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 17:28:03 +0800 Subject: [PATCH 27/87] test(unlighthouse): upload result as artifact --- .github/workflows/unlighthouse.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index b97a71bf..e0de5556 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -13,3 +13,6 @@ jobs: --budget 90 \ --no-cache \ --throttle + - uses: actions/upload-artifact@v4 + with: + path: ./.unlighthouse/ci-result.json From 975f0d1d80861e2dd0a84c742a90274a204fbe0f Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 17:35:34 +0800 Subject: [PATCH 28/87] ci(unlighthouse): always upload result --- .github/workflows/unlighthouse.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index e0de5556..00e038c9 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -14,5 +14,6 @@ jobs: --no-cache \ --throttle - uses: actions/upload-artifact@v4 + if: always() with: path: ./.unlighthouse/ci-result.json From 19f9119febb2365854768f8fe016570de0c0a166 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 17:51:12 +0800 Subject: [PATCH 29/87] test(unlighthouse): use expanded report --- .github/workflows/unlighthouse.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index 00e038c9..966a4d8d 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -10,6 +10,7 @@ jobs: - run: | unlighthouse-ci \ --site ${{ github.event.deployment_status.environment_url }} \ + --reporter jsonExpanded \ --budget 90 \ --no-cache \ --throttle From 3ef5315ac5d8f0d5a21213c6978b19b633b67625 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 19:48:20 +0800 Subject: [PATCH 30/87] ci(unlighthouse): reduce budget to 80 --- .github/workflows/unlighthouse.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index 966a4d8d..459fd574 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -11,7 +11,7 @@ jobs: unlighthouse-ci \ --site ${{ github.event.deployment_status.environment_url }} \ --reporter jsonExpanded \ - --budget 90 \ + --budget 80 \ --no-cache \ --throttle - uses: actions/upload-artifact@v4 From 9ff60d25f8636a9e147525759dd789522fc05e60 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 20:00:41 +0800 Subject: [PATCH 31/87] ci(unlighthouse): use config file --- .eslintrc.js | 1 + .github/workflows/unlighthouse.yml | 9 ++------- unlighthouse.config.ts | 12 ++++++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 unlighthouse.config.ts diff --git a/.eslintrc.js b/.eslintrc.js index 47ead19b..7e68d53e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -94,6 +94,7 @@ module.exports = { 'cypress.config.mjs', 'next.config.mjs', 'prettier.config.mjs', + 'unlighthouse.config.ts', 'app/**/page.tsx', 'app/**/layout.tsx', 'app/**/not-found.tsx', diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index 459fd574..a28b9503 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -6,14 +6,9 @@ jobs: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - run: npm install -g @unlighthouse/cli puppeteer - - run: | - unlighthouse-ci \ - --site ${{ github.event.deployment_status.environment_url }} \ - --reporter jsonExpanded \ - --budget 80 \ - --no-cache \ - --throttle + - run: unlighthouse-ci --site ${{ github.event.deployment_status.environment_url }} - uses: actions/upload-artifact@v4 if: always() with: diff --git a/unlighthouse.config.ts b/unlighthouse.config.ts new file mode 100644 index 00000000..1f907b4d --- /dev/null +++ b/unlighthouse.config.ts @@ -0,0 +1,12 @@ +export default { + cache: false, + ci: { + reporter: 'jsonExpanded', + budget: { + performance: 70, + accessibility: 98, + 'best-practices': 83, + seo: 92, + }, + }, +}; From efa20ad3de943147286d3b5c91b4819c94f5f653 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 20:02:30 +0800 Subject: [PATCH 32/87] feat: update base URL in non-prod --- constants/site-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constants/site-config.ts b/constants/site-config.ts index b1141dc1..6bd77893 100644 --- a/constants/site-config.ts +++ b/constants/site-config.ts @@ -3,7 +3,7 @@ import { capitalize } from 'lodash-es'; export const baseUrl = `https://${ process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview' || process.env.NEXT_PUBLIC_VERCEL_ENV === 'development' - ? process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL + ? process.env.NEXT_PUBLIC_VERCEL_URL : process.env.NEXT_PUBLIC_PROD_URL }`; From 8f37b8e6dd88f5d5f1ff6fc47cf96c03e20f1299 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 20:03:56 +0800 Subject: [PATCH 33/87] chore: format code --- unlighthouse.config.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/unlighthouse.config.ts b/unlighthouse.config.ts index 1f907b4d..5d218347 100644 --- a/unlighthouse.config.ts +++ b/unlighthouse.config.ts @@ -1,12 +1,12 @@ -export default { - cache: false, - ci: { - reporter: 'jsonExpanded', - budget: { - performance: 70, - accessibility: 98, - 'best-practices': 83, - seo: 92, - }, - }, -}; +export default { + cache: false, + ci: { + reporter: 'jsonExpanded', + budget: { + performance: 70, + accessibility: 98, + 'best-practices': 83, + seo: 92, + }, + }, +}; From 4519d87e5e5bb0e9a2babee421c0b270711abe1b Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 23:26:18 +0800 Subject: [PATCH 34/87] test: tsconfig extends vercel base config --- cypress/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index 2c399cb4..2e44e740 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -1,4 +1,5 @@ { + "extends": "@vercel/style-guide/typescript", "compilerOptions": { "target": "es5", "lib": ["es5", "dom"], From 1c99ae827f97ddd3dbc74bd72fc54c902e2809dc Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Thu, 15 Feb 2024 23:47:50 +0800 Subject: [PATCH 35/87] ci(unlighthouse): adjust budget --- unlighthouse.config.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/unlighthouse.config.ts b/unlighthouse.config.ts index 5d218347..d20ba3ee 100644 --- a/unlighthouse.config.ts +++ b/unlighthouse.config.ts @@ -3,10 +3,10 @@ export default { ci: { reporter: 'jsonExpanded', budget: { - performance: 70, - accessibility: 98, - 'best-practices': 83, - seo: 92, + performance: 90, + accessibility: 98, // minus point from code blocks some times have color contrast issue + 'best-practices': 92, // minus point from hydration errors are some times logged + seo: 92, // minus point from non-PROD not being indexable }, }, }; From 93f80db3f0e9d3b00747503b12a4e8cbdf9cc636 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Fri, 16 Feb 2024 09:50:54 +0800 Subject: [PATCH 36/87] ci(unlighthouse): update config --- .github/workflows/unlighthouse.yml | 9 +++++++-- unlighthouse.config.ts | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index a28b9503..3b9a23ae 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -8,8 +8,13 @@ jobs: steps: - uses: actions/checkout@v4 - run: npm install -g @unlighthouse/cli puppeteer - - run: unlighthouse-ci --site ${{ github.event.deployment_status.environment_url }} + # FIXME: --samples is currently bugged, set it to 3 when unlighthouse is using lighthouse v10+ + # FIXME: --throttle is not recognized when specified in config file, specifying it with CLI option instead + - run: | + unlighthouse-ci \ + --site ${{ github.event.deployment_status.environment_url }} \ + --throttle - uses: actions/upload-artifact@v4 if: always() with: - path: ./.unlighthouse/ci-result.json + path: .unlighthouse diff --git a/unlighthouse.config.ts b/unlighthouse.config.ts index d20ba3ee..e7e0d5b3 100644 --- a/unlighthouse.config.ts +++ b/unlighthouse.config.ts @@ -1,11 +1,11 @@ export default { cache: false, ci: { - reporter: 'jsonExpanded', + buildStatic: true, budget: { performance: 90, - accessibility: 98, // minus point from code blocks some times have color contrast issue - 'best-practices': 92, // minus point from hydration errors are some times logged + accessibility: 98, // minus point from code blocks sometimes have color contrast issue + 'best-practices': 92, // minus point from hydration errors are sometimes logged due to PPR seo: 92, // minus point from non-PROD not being indexable }, }, From 9b980e27d6fd4c0353a6c6dd3e3d7ac6e1b65807 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Fri, 16 Feb 2024 10:00:29 +0800 Subject: [PATCH 37/87] chore: Package update --- package-lock.json | 140 +++++++++++++++++++++++----------------------- package.json | 6 +- 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/package-lock.json b/package-lock.json index d933c1cf..5525de24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,14 +19,14 @@ "@mui/styled-engine": "^5.15.9", "@prisma/client": "^5.9.1", "@prisma/extension-read-replicas": "^0.3.0", - "@vercel/analytics": "^1.1.3", + "@vercel/analytics": "^1.1.4", "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", "dayjs": "^1.11.10", "geist": "^1.2.2", "lodash-es": "^4.17.21", - "lucide-react": "^0.330.0", + "lucide-react": "^0.331.0", "merge-sx": "^2.0.0", "next": "canary", "next-mdx-remote": "^4.4.1", @@ -44,7 +44,7 @@ "@next/eslint-plugin-next": "canary", "@svgr/webpack": "^8.1.0", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.17", + "@types/node": "^20.11.19", "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", @@ -2789,32 +2789,32 @@ } }, "node_modules/@next/bundle-analyzer": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.54.tgz", - "integrity": "sha512-eTeQs7V7iOfzwJvJ/OK4iD/4O1KYgsmjSEjR48h3/F7UsRQJwaF032WfdJnTHZJu+xED4J8+fXDpOPznuG8q4g==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.56.tgz", + "integrity": "sha512-DAFKmwdWB/E3xi9L59jsz/p2/zbByCDuwqAeH3zvQxNChxa51MmW0FDlcAJrLcdoqdojat9lklWVifRa+SPRUQ==", "dev": true, "dependencies": { "webpack-bundle-analyzer": "4.10.1" } }, "node_modules/@next/env": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.54.tgz", - "integrity": "sha512-YaLOEFgbGaZCtrwpqW4E7Y3FQVOB/cp+g93a2BnGk/pWPbkMMg3vrtMAd/7p3Hbzr/TiAg8Uuy6A2uHIL6CROA==" + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.56.tgz", + "integrity": "sha512-2C+38wg1ZTb9N3HagtLZIjhPg0cbB97PmbgAKLMg+QOttyjmBiVjb231XWHKjqoEhY9u/ILWNbzgQ8gD5JplkA==" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.54.tgz", - "integrity": "sha512-t7aQxdwYrqOqlPCCgCB8XFyJvZ/xCKKM7AcjR39OachMmp/V1nal1C67K9A4nQipD1AZfipiBmB6KL1BJyNYqw==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.56.tgz", + "integrity": "sha512-6wCtfVxCfng5kRTzaCJMbqkZcl4U4rj+RtcaQBfXmQkTqgS8CY8yEjhtW3XdpPcn2zrBNLwimPWBE5i6Y8z0WQ==", "dev": true, "dependencies": { "glob": "10.3.10" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.54.tgz", - "integrity": "sha512-c9H5fpL3j0cVfZ8PhKd9I2a7scmtC5QwrwtG3N+qaWKYCaawR03gC3oRFoXFQgB4cICKsgtZ6hea0fn6xi3TYQ==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.56.tgz", + "integrity": "sha512-xqCZidAakgTw0iQaWK3IRgbu1o8i2dRFjLkvAF1QPZruVFlSaCIKoSo3GUebJcrvzcHVzRkDKnr+FlWLmES5zA==", "cpu": [ "arm64" ], @@ -2827,9 +2827,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.54.tgz", - "integrity": "sha512-IkOsCNfMQZTUG/bDTg2QWtZbY/OGFsNhfhwi+1MnbmnbA95+ernPX7tJl+veBuLUEFe+lxEVPngZDvUZU3DIjQ==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.56.tgz", + "integrity": "sha512-febsltDU+jnNhK3qZriJ58FSmyZtJkOtih5t0VDusgM8MdfwVfcfv0kMVSZOygdWrJLhml5OKBC4XdX4BDGpEw==", "cpu": [ "x64" ], @@ -2842,9 +2842,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.54.tgz", - "integrity": "sha512-UiIyiPD8eBxlOu+vHjPtECB1IT7qnsysGCPKpTTFNt67ENsjkqdprNVAgVcN8BJbOsAZEsudK8WT67rDNGrrZQ==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.56.tgz", + "integrity": "sha512-4Zj09znOpXxU6y2BBVEo5jfa4aeiJVg5d4dbcAnuDL7n26xzQL62UOXflSLdijZ8842qcIUN5SQa1kqZlixj+w==", "cpu": [ "arm64" ], @@ -2857,9 +2857,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.54.tgz", - "integrity": "sha512-RenLi+h+A8g0/XYL6PAzdorgwPsnA094EsmhsQdI8qgf5oHnpkR6WCa4hzJgODs2TghZg9dPqDOGErA7chFd8A==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.56.tgz", + "integrity": "sha512-CfDodJ/hjqdYYDpVZ0Jxjab8lmrl74Z3Y1tp12lzZA3jnrjXq66Wj8ckQ81H+Omn4ObovpMD+DRL8/xKXdC7HQ==", "cpu": [ "arm64" ], @@ -2872,9 +2872,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.54.tgz", - "integrity": "sha512-VBGbm4y6wAf7nnJLznltnbWHu068xIT7MJE4ezAUs8Nk9+bxWStDE6tudWB8K6A+c39/79kX79QVvDv3A5A4+A==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.56.tgz", + "integrity": "sha512-tHUaCQOaFxuUWR/7tvnFQTNOVKmmtKE2SdNfh5rzYz00JjYhVf3aR9hqOvCBmck0LJ77FmZK+8pBwUb8Jouz9g==", "cpu": [ "x64" ], @@ -2887,9 +2887,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.54.tgz", - "integrity": "sha512-YKufA1FOpIC081o1UnioIUJdmboFOJyvvalWAMX5tvdOdC8BNti2sm6tnl8+zRTMz92OjAch+R4O1/l9Qd/SQQ==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.56.tgz", + "integrity": "sha512-OEdHeNFb7BM+byb6JrpLF9/na2oCpxNbC6n+zQHcM/CV/y2OBniz9JDngckJG3esfnD6q9aCjEEt6LF9/LKZyw==", "cpu": [ "x64" ], @@ -2902,9 +2902,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.54.tgz", - "integrity": "sha512-EYrV3xRI35qeN7zW9/OZ6iYd9NpWq0tsVNLHNeBRU2MmuGuMAgR59lB47eb0fV20LnpXQJCybtxqWZOvyy9QiQ==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.56.tgz", + "integrity": "sha512-qWVDIia8BJ8209XUVw4QNPi4mup2OwRZVLlrD1WZwAmDGy5p/gwFqGCvQ5BeiCUl8Et9xWsVwou1/n5mobj0Dw==", "cpu": [ "arm64" ], @@ -2917,9 +2917,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.54.tgz", - "integrity": "sha512-sMxEwl64bEe35iJ1jxZpB4K3vf+zHY0pvMueYEZDSMEC+42qCqk0XtVNn129aWPNA/n5dNG6pcxKNYRS6XesEA==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.56.tgz", + "integrity": "sha512-e26LjHCGlg/X6iS5iqILGykgAFM+hLoNP1HTpsEXebn8iOaAJ4w2YEyk5+CGk4aImM9YwXGsquPWq/S+SwVMaQ==", "cpu": [ "ia32" ], @@ -2932,9 +2932,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.54.tgz", - "integrity": "sha512-UyisjAS2lHKTjKy9gRWlNN9zgFhJCvFG/jtExEq1Ozq1qmAsWUEmgWQNmPFZfNbJ0stc43rgOC7U8NOOFtRXRw==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.56.tgz", + "integrity": "sha512-ylkY6s0wXjS8V7e7fFLtkT+VY0oLfZUDDdLPBL1hDxjh3m4H2kKB+Hq67fkRem7DoF3zn1pqCjbz4Gby/nXisg==", "cpu": [ "x64" ], @@ -3482,9 +3482,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.11.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz", - "integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==", + "version": "20.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", + "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -3871,9 +3871,9 @@ "dev": true }, "node_modules/@vercel/analytics": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.1.3.tgz", - "integrity": "sha512-Z0l0y8TnUnnxr+on7oIMB9qQOoSJIniYMzUng6+NU8VVDkZ+kt2QGD5hzODwsuiRJAsjW528iUEtbWCEGkSCCg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.1.4.tgz", + "integrity": "sha512-CVzw3SLcPSc31tRDLLqDGqWQCv6/ylpEZnW7AYMvtvRsO2Q8hmjBVOqvo2Ok6MZnYf262O8c86LB2K9vK1/ZbQ==", "dependencies": { "server-only": "^0.0.1" } @@ -5627,9 +5627,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.669", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.669.tgz", - "integrity": "sha512-E2SmpffFPrZhBSgf8ibqanRS2mpuk3FIRDzLDwt7WFpfgJMKDHJs0hmacyP0PS1cWsq0dVkwIIzlscNaterkPg==", + "version": "1.4.671", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.671.tgz", + "integrity": "sha512-UUlE+/rWbydmp+FW8xlnnTA5WNA0ZZd2XL8CuMS72rh+k4y1f8+z6yk3UQhEwqHQWj6IBdL78DwWOdGMvYfQyA==", "dev": true }, "node_modules/emoji-regex": { @@ -9278,9 +9278,9 @@ } }, "node_modules/lucide-react": { - "version": "0.330.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.330.0.tgz", - "integrity": "sha512-CQwY+Fpbt2kxCoVhuN0RCZDCYlbYnqB870Bl/vIQf3ER/cnDDQ6moLmEkguRyruAUGd4j3Lc4mtnJosXnqHheA==", + "version": "0.331.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.331.0.tgz", + "integrity": "sha512-CHFJ0ve9vaZ7bB2VRAl27SlX1ELh6pfNC0jS96qGpPEEzLkLDGq4pDBFU8RhOoRMqsjXqTzLm9U6bZ1OcIHq7Q==", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } @@ -10255,11 +10255,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.1-canary.54", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.54.tgz", - "integrity": "sha512-upsM73QNXv4rPg8QUbReEQ3uB/KMcEM6suRTNYHbjmqWBAY7J6jLW5aHGUDipfBlRsy/4HdU4m0dpcKqcDJniQ==", + "version": "14.1.1-canary.56", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.56.tgz", + "integrity": "sha512-/rqfqDzofP3xoOlGsRZXSc9eDBRn+f6UTIrJepappiFIJ2Bk54xVgQV+0HWG7szQoYt1tf+ZYCK1+h46/y5/oA==", "dependencies": { - "@next/env": "14.1.1-canary.54", + "@next/env": "14.1.1-canary.56", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -10274,15 +10274,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.1-canary.54", - "@next/swc-darwin-x64": "14.1.1-canary.54", - "@next/swc-linux-arm64-gnu": "14.1.1-canary.54", - "@next/swc-linux-arm64-musl": "14.1.1-canary.54", - "@next/swc-linux-x64-gnu": "14.1.1-canary.54", - "@next/swc-linux-x64-musl": "14.1.1-canary.54", - "@next/swc-win32-arm64-msvc": "14.1.1-canary.54", - "@next/swc-win32-ia32-msvc": "14.1.1-canary.54", - "@next/swc-win32-x64-msvc": "14.1.1-canary.54" + "@next/swc-darwin-arm64": "14.1.1-canary.56", + "@next/swc-darwin-x64": "14.1.1-canary.56", + "@next/swc-linux-arm64-gnu": "14.1.1-canary.56", + "@next/swc-linux-arm64-musl": "14.1.1-canary.56", + "@next/swc-linux-x64-gnu": "14.1.1-canary.56", + "@next/swc-linux-x64-musl": "14.1.1-canary.56", + "@next/swc-win32-arm64-msvc": "14.1.1-canary.56", + "@next/swc-win32-ia32-msvc": "14.1.1-canary.56", + "@next/swc-win32-x64-msvc": "14.1.1-canary.56" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -11115,9 +11115,9 @@ } }, "node_modules/prettier-plugin-packagejson": { - "version": "2.4.10", - "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.4.10.tgz", - "integrity": "sha512-qFzOfQDHi1tzvVJRuZ2jh1j6IFV5MURh5m5WDt+qfEMOf4SSL5RpwSysiX8u0W1PJYsM0vKJGNULt43wwteKiQ==", + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.4.11.tgz", + "integrity": "sha512-zmOmM96GkAjT2zUdHSQJnpyVpbisBkewDluo2NLHjI/JN7uOCZlEzWVaMhdqyZ8LVdQDfzamvbvSw4swd3Az1A==", "dev": true, "dependencies": { "sort-package-json": "2.7.0", @@ -12380,9 +12380,9 @@ } }, "node_modules/spdx-exceptions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz", - "integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, "node_modules/spdx-expression-parse": { diff --git a/package.json b/package.json index a21eb9a2..98f9ae66 100644 --- a/package.json +++ b/package.json @@ -26,14 +26,14 @@ "@mui/styled-engine": "^5.15.9", "@prisma/client": "^5.9.1", "@prisma/extension-read-replicas": "^0.3.0", - "@vercel/analytics": "^1.1.3", + "@vercel/analytics": "^1.1.4", "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", "dayjs": "^1.11.10", "geist": "^1.2.2", "lodash-es": "^4.17.21", - "lucide-react": "^0.330.0", + "lucide-react": "^0.331.0", "merge-sx": "^2.0.0", "next": "canary", "next-mdx-remote": "^4.4.1", @@ -51,7 +51,7 @@ "@next/eslint-plugin-next": "canary", "@svgr/webpack": "^8.1.0", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.17", + "@types/node": "^20.11.19", "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", From 9425c3e498f5c838b3b5313e49ece7754eb1ff1c Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Fri, 16 Feb 2024 16:28:58 +0800 Subject: [PATCH 38/87] ci(e2e): use headed browser --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index dc1b6da3..9308730d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -21,5 +21,6 @@ jobs: with: install: false browser: ${{ matrix.browser }} + headed: true env: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} From 6b07d600cc0a7a375ed2864171db88918c582631 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Fri, 16 Feb 2024 16:37:56 +0800 Subject: [PATCH 39/87] test: remove `cy.request` to social media site, since some of them are blocking automated access --- cypress/e2e/navigation.cy.ts | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/cypress/e2e/navigation.cy.ts b/cypress/e2e/navigation.cy.ts index a82d268c..0643de74 100644 --- a/cypress/e2e/navigation.cy.ts +++ b/cypress/e2e/navigation.cy.ts @@ -80,14 +80,6 @@ describe('Site navigation', () => { }, ]; - /** - * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#successful_responses} - */ - const successfulAndRedirectionStatusCodes = [ - 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, - 305, 306, 307, 308, - ]; - beforeEach(() => cy.visit(home.pathname)); for (const { component, visibleLinks } of containers) { @@ -103,22 +95,6 @@ describe('Site navigation', () => { cy.get('@link').should('have.attr', 'href', url); cy.get('@link').should('have.attr', 'target', '_blank'); - - cy.request({ url, failOnStatusCode: false }).then( - ({ status }) => { - const validStatusCodes = [ - ...successfulAndRedirectionStatusCodes, - ]; - - // LinkedIn's specially HTTP status code - // It returns for any "unauthorized" access to prevent random sites from linking to it - if (url.includes('linkedin')) { - validStatusCodes.push(999); - } - - expect(status).to.be.oneOf(validStatusCodes); - }, - ); }); }); } From 415ad7ed9ef65407febe4e68fd70a5e964858fbd Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Fri, 16 Feb 2024 17:07:24 +0800 Subject: [PATCH 40/87] ci(unlighthouse): update throttle method --- unlighthouse.config.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unlighthouse.config.ts b/unlighthouse.config.ts index e7e0d5b3..b81c3788 100644 --- a/unlighthouse.config.ts +++ b/unlighthouse.config.ts @@ -9,4 +9,7 @@ export default { seo: 92, // minus point from non-PROD not being indexable }, }, + lighthouseOptions: { + throttlingMethod: 'devtools', + }, }; From 66d0904b2a65addcc44883a035d3a2ace5c64b3a Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Fri, 16 Feb 2024 17:21:34 +0800 Subject: [PATCH 41/87] Revert "ci(unlighthouse): update throttle method" This reverts commit 340039f0774c140f10c54d0682994dc31f917a28. --- unlighthouse.config.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/unlighthouse.config.ts b/unlighthouse.config.ts index b81c3788..e7e0d5b3 100644 --- a/unlighthouse.config.ts +++ b/unlighthouse.config.ts @@ -9,7 +9,4 @@ export default { seo: 92, // minus point from non-PROD not being indexable }, }, - lighthouseOptions: { - throttlingMethod: 'devtools', - }, }; From d421d6c5c598928d728b8c9b2f6f7578f7a1cf10 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sat, 17 Feb 2024 09:14:04 +0800 Subject: [PATCH 42/87] chore: Package update --- package-lock.json | 146 +++++++++++++++++++++++++--------------------- package.json | 4 +- 2 files changed, 81 insertions(+), 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5525de24..007ec982 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "@mui/styled-engine": "^5.15.9", "@prisma/client": "^5.9.1", "@prisma/extension-read-replicas": "^0.3.0", - "@vercel/analytics": "^1.1.4", + "@vercel/analytics": "^1.2.0", "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", @@ -36,7 +36,7 @@ "rehype-pretty-code": "^0.13.0", "rehype-slug": "^6.0.0", "schema-dts": "^1.1.2", - "shiki": "^1.1.2", + "shiki": "^1.1.3", "valibot": "^0.28.1" }, "devDependencies": { @@ -2789,32 +2789,32 @@ } }, "node_modules/@next/bundle-analyzer": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.56.tgz", - "integrity": "sha512-DAFKmwdWB/E3xi9L59jsz/p2/zbByCDuwqAeH3zvQxNChxa51MmW0FDlcAJrLcdoqdojat9lklWVifRa+SPRUQ==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.58.tgz", + "integrity": "sha512-KwUBUUWx6lrNYVqpBn02bN+KPgITYOsD/Eh7JHQVyUxNHMrtth1C3CRpm30QZJ2uF4XJW1qPyTKTwxABvECeAg==", "dev": true, "dependencies": { "webpack-bundle-analyzer": "4.10.1" } }, "node_modules/@next/env": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.56.tgz", - "integrity": "sha512-2C+38wg1ZTb9N3HagtLZIjhPg0cbB97PmbgAKLMg+QOttyjmBiVjb231XWHKjqoEhY9u/ILWNbzgQ8gD5JplkA==" + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.58.tgz", + "integrity": "sha512-xMoPPiWVEIyIPoWaLhswlMq2Tnfkcv+XRmUAEhKkJgWdHIMFh45tiniWrZQLfrn4DAnF8gEAoejJaniNShFm7w==" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.56.tgz", - "integrity": "sha512-6wCtfVxCfng5kRTzaCJMbqkZcl4U4rj+RtcaQBfXmQkTqgS8CY8yEjhtW3XdpPcn2zrBNLwimPWBE5i6Y8z0WQ==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.58.tgz", + "integrity": "sha512-A+kH2788C5keH/UEPUX9gWExdstBYaqWgsHuPpbN77S0kjcYQY5ayvVoOQKoJwSXeY+BKpo8CnXtXEIevekRTQ==", "dev": true, "dependencies": { "glob": "10.3.10" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.56.tgz", - "integrity": "sha512-xqCZidAakgTw0iQaWK3IRgbu1o8i2dRFjLkvAF1QPZruVFlSaCIKoSo3GUebJcrvzcHVzRkDKnr+FlWLmES5zA==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.58.tgz", + "integrity": "sha512-exDpEe9ptK0NJEEyA+sThnR/6Oif/XaPK1y10fkcTNoQJkUCENL46nR1bCEYDAQrS5w03C1BHs3LSIOuoQcIag==", "cpu": [ "arm64" ], @@ -2827,9 +2827,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.56.tgz", - "integrity": "sha512-febsltDU+jnNhK3qZriJ58FSmyZtJkOtih5t0VDusgM8MdfwVfcfv0kMVSZOygdWrJLhml5OKBC4XdX4BDGpEw==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.58.tgz", + "integrity": "sha512-Q+38djBg+yaZjB8R6kst8kqHLIpTIM2RzuIvFGOflb8WaVI1ApXERTJKd345BOp42s0rIJ1UqynRplNCqYebeA==", "cpu": [ "x64" ], @@ -2842,9 +2842,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.56.tgz", - "integrity": "sha512-4Zj09znOpXxU6y2BBVEo5jfa4aeiJVg5d4dbcAnuDL7n26xzQL62UOXflSLdijZ8842qcIUN5SQa1kqZlixj+w==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.58.tgz", + "integrity": "sha512-wv2457qPqh7ENqQ3t8sCWCsNStEW/o8qejZ6Ywdwl3eKP1jnFNtn4OWfOuP2FUl1XmVEzbABozuOyiCGAtD63Q==", "cpu": [ "arm64" ], @@ -2857,9 +2857,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.56.tgz", - "integrity": "sha512-CfDodJ/hjqdYYDpVZ0Jxjab8lmrl74Z3Y1tp12lzZA3jnrjXq66Wj8ckQ81H+Omn4ObovpMD+DRL8/xKXdC7HQ==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.58.tgz", + "integrity": "sha512-xvfU/+mZfLpW/tRy743JtkNPlNI2t1dSkIzvDHHn/V28k1c+4YmsNxKMZRqqcxi73hwnuWYgor/96Sm4r9pmQQ==", "cpu": [ "arm64" ], @@ -2872,9 +2872,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.56.tgz", - "integrity": "sha512-tHUaCQOaFxuUWR/7tvnFQTNOVKmmtKE2SdNfh5rzYz00JjYhVf3aR9hqOvCBmck0LJ77FmZK+8pBwUb8Jouz9g==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.58.tgz", + "integrity": "sha512-OgayNv+ChIjsPYMkBit2LTI0tMJ72or4w5DfQe2i1M2Ccy09p/LSRCiOptkV3XKyO+Tz8+fAqN+PdLRxfxQiuQ==", "cpu": [ "x64" ], @@ -2887,9 +2887,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.56.tgz", - "integrity": "sha512-OEdHeNFb7BM+byb6JrpLF9/na2oCpxNbC6n+zQHcM/CV/y2OBniz9JDngckJG3esfnD6q9aCjEEt6LF9/LKZyw==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.58.tgz", + "integrity": "sha512-6epwXWxSUyNKzOt0FSRW0QioPaWA9xlu8LM5N0c9eg8vaI3FvZmQegtHIzuzNc7RyWE1a5ZY4uDBVA1JaUJRow==", "cpu": [ "x64" ], @@ -2902,9 +2902,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.56.tgz", - "integrity": "sha512-qWVDIia8BJ8209XUVw4QNPi4mup2OwRZVLlrD1WZwAmDGy5p/gwFqGCvQ5BeiCUl8Et9xWsVwou1/n5mobj0Dw==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.58.tgz", + "integrity": "sha512-Qa79WuVRcrkmbxzTXr/tmWvFHVMjUu9KpxNrKn+HO/DmrVEnR4NxmuzOOxc6QkCb+Rb86rfV7tttPQqw7YigBA==", "cpu": [ "arm64" ], @@ -2917,9 +2917,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.56.tgz", - "integrity": "sha512-e26LjHCGlg/X6iS5iqILGykgAFM+hLoNP1HTpsEXebn8iOaAJ4w2YEyk5+CGk4aImM9YwXGsquPWq/S+SwVMaQ==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.58.tgz", + "integrity": "sha512-fuqdt6XKc4kvUpgOMh/LL2eqJ/eltxknClpaAg9Nt0dGTQIF0rjKEVm8NRwv832URZKKBbz9AtBp5TEmOquG9g==", "cpu": [ "ia32" ], @@ -2932,9 +2932,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.56.tgz", - "integrity": "sha512-ylkY6s0wXjS8V7e7fFLtkT+VY0oLfZUDDdLPBL1hDxjh3m4H2kKB+Hq67fkRem7DoF3zn1pqCjbz4Gby/nXisg==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.58.tgz", + "integrity": "sha512-P/DkKFiZo1mILb2UGt1YiurmuKo9LLvgC0l77YQ5g2b8jrTbYS9JeJJcdhLXnsHPPQrR/QgnEDJ2zWRtIhUJZA==", "cpu": [ "x64" ], @@ -3110,9 +3110,9 @@ "dev": true }, "node_modules/@shikijs/core": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.2.tgz", - "integrity": "sha512-ERVzNQz88ZkDqUpWeC57Kp+Kmx5RjqeDBR1M8AGWGom4yrkITiTfXCGmjchlDSw12MhDTuPYR4HVFW8uT61RaQ==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.3.tgz", + "integrity": "sha512-1QWSvWcPbvZXsDxB1F7ejW+Kuxp3z/JHs944hp/f8BYOlFd5gplzseFIkE/GTu/qytFef3zNME4qw1oHbQ0j2A==" }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", @@ -3871,11 +3871,23 @@ "dev": true }, "node_modules/@vercel/analytics": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.1.4.tgz", - "integrity": "sha512-CVzw3SLcPSc31tRDLLqDGqWQCv6/ylpEZnW7AYMvtvRsO2Q8hmjBVOqvo2Ok6MZnYf262O8c86LB2K9vK1/ZbQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.0.tgz", + "integrity": "sha512-Q9hduY6+i73Is1m57Y3OlawleeYVi4cvuh/0j6IwmSndMOE4+BKkMwjnwz+7xnqfZCanipIG6+q+zHalH9X0Zg==", "dependencies": { "server-only": "^0.0.1" + }, + "peerDependencies": { + "next": ">= 13", + "react": "^18 || ^19" + }, + "peerDependenciesMeta": { + "next": { + "optional": true + }, + "react": { + "optional": true + } } }, "node_modules/@vercel/speed-insights": { @@ -5627,9 +5639,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.671", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.671.tgz", - "integrity": "sha512-UUlE+/rWbydmp+FW8xlnnTA5WNA0ZZd2XL8CuMS72rh+k4y1f8+z6yk3UQhEwqHQWj6IBdL78DwWOdGMvYfQyA==", + "version": "1.4.673", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", + "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==", "dev": true }, "node_modules/emoji-regex": { @@ -6150,9 +6162,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "27.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.8.0.tgz", - "integrity": "sha512-347hVFiu4ZKMYl5xFp0X81gLNwBdno0dl0CMpUMjwuAux9X/M2a7z+ab2VHmPL6XCT87q8nv1vaVzhIO4TE/hw==", + "version": "27.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz", + "integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.10.0" @@ -10255,11 +10267,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.1-canary.56", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.56.tgz", - "integrity": "sha512-/rqfqDzofP3xoOlGsRZXSc9eDBRn+f6UTIrJepappiFIJ2Bk54xVgQV+0HWG7szQoYt1tf+ZYCK1+h46/y5/oA==", + "version": "14.1.1-canary.58", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.58.tgz", + "integrity": "sha512-rL4Tmm5ldL4VA+lTz0sQfJcDOe3vXB7LItcWuILb8eDs/6X1wrXNF9KDtviJH0tq/jrrTOihN7aBCkkge85m6g==", "dependencies": { - "@next/env": "14.1.1-canary.56", + "@next/env": "14.1.1-canary.58", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -10274,15 +10286,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.1-canary.56", - "@next/swc-darwin-x64": "14.1.1-canary.56", - "@next/swc-linux-arm64-gnu": "14.1.1-canary.56", - "@next/swc-linux-arm64-musl": "14.1.1-canary.56", - "@next/swc-linux-x64-gnu": "14.1.1-canary.56", - "@next/swc-linux-x64-musl": "14.1.1-canary.56", - "@next/swc-win32-arm64-msvc": "14.1.1-canary.56", - "@next/swc-win32-ia32-msvc": "14.1.1-canary.56", - "@next/swc-win32-x64-msvc": "14.1.1-canary.56" + "@next/swc-darwin-arm64": "14.1.1-canary.58", + "@next/swc-darwin-x64": "14.1.1-canary.58", + "@next/swc-linux-arm64-gnu": "14.1.1-canary.58", + "@next/swc-linux-arm64-musl": "14.1.1-canary.58", + "@next/swc-linux-x64-gnu": "14.1.1-canary.58", + "@next/swc-linux-x64-musl": "14.1.1-canary.58", + "@next/swc-win32-arm64-msvc": "14.1.1-canary.58", + "@next/swc-win32-ia32-msvc": "14.1.1-canary.58", + "@next/swc-win32-x64-msvc": "14.1.1-canary.58" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -12179,11 +12191,11 @@ } }, "node_modules/shiki": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.2.tgz", - "integrity": "sha512-qNzFwTv5uhEDNUIwp7wHjsrffVeLbmOgWnM5mZZhoiz7G2qAUvqVfUzuWfieD45/YAKipzCtdV9SndacKtABow==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.3.tgz", + "integrity": "sha512-k/B4UvtWmGcHMLp6JnQminlex3Go5MHKXEiormmzTJECAiSQiwSon6USuwTyto8EMUQc9aYRJ7HojkfVLbBk+g==", "dependencies": { - "@shikijs/core": "1.1.2" + "@shikijs/core": "1.1.3" } }, "node_modules/side-channel": { diff --git a/package.json b/package.json index 98f9ae66..fb550d61 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@mui/styled-engine": "^5.15.9", "@prisma/client": "^5.9.1", "@prisma/extension-read-replicas": "^0.3.0", - "@vercel/analytics": "^1.1.4", + "@vercel/analytics": "^1.2.0", "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", @@ -43,7 +43,7 @@ "rehype-pretty-code": "^0.13.0", "rehype-slug": "^6.0.0", "schema-dts": "^1.1.2", - "shiki": "^1.1.2", + "shiki": "^1.1.3", "valibot": "^0.28.1" }, "devDependencies": { From 5547dbb4d400bd023c038e1e3d61f1f4a44e9cb8 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sat, 17 Feb 2024 09:56:09 +0800 Subject: [PATCH 43/87] test: add color mode test --- components/mode-toggle-button.tsx | 5 +++- cypress/e2e/color-mode.cy.ts | 42 +++++++++++++++++++++++++++++++ cypress/fixtures/colors.ts | 10 ++++++++ package.json | 2 +- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 cypress/e2e/color-mode.cy.ts create mode 100644 cypress/fixtures/colors.ts diff --git a/components/mode-toggle-button.tsx b/components/mode-toggle-button.tsx index f32e8abf..cf1fcb03 100644 --- a/components/mode-toggle-button.tsx +++ b/components/mode-toggle-button.tsx @@ -12,10 +12,13 @@ export const ModeToggleButton: FC = (props) => { return ( setMode(mode === 'dark' ? 'light' : 'dark')} {...props} > - {mode === 'dark' ? : } + + {mode === 'dark' ? : } + ); diff --git a/cypress/e2e/color-mode.cy.ts b/cypress/e2e/color-mode.cy.ts new file mode 100644 index 00000000..f6b0a1bf --- /dev/null +++ b/cypress/e2e/color-mode.cy.ts @@ -0,0 +1,42 @@ +import { colors } from '../fixtures/colors'; + +describe('Color mode', () => { + const expectColorMode = (colorMode: 'dark' | 'light') => { + cy.get('html').should('have.attr', 'data-joy-color-scheme', colorMode); + cy.get('body') + .should('have.css', 'background-color', colors[colorMode].bgColor) + .and('have.css', 'color', colors[colorMode].color); + }; + + beforeEach(() => cy.visit('/')); + + it('default is light mode', () => expectColorMode('light')); + + describe('Mode toggle button', () => { + it('toggles color mode', () => { + cy.get('[data-cy="mode-toggle-button"]').click(); + expectColorMode('dark'); + + cy.get('[data-cy="mode-toggle-button"]').click(); + expectColorMode('light'); + }); + + it('updates icon according to color mode', () => { + const expectIcon = (icon: 'sun' | 'moon') => { + cy.get('[data-cy="mode-toggle-button"]') + .find('[data-cy="moon"]') + .should(icon === 'moon' ? 'be.visible' : 'not.exist'); + + cy.get('[data-cy="mode-toggle-button"]') + .find('[data-cy="sun"]') + .should(icon === 'sun' ? 'be.visible' : 'not.exist'); + }; + + expectIcon('moon'); + cy.get('[data-cy="mode-toggle-button"]').click(); + expectIcon('sun'); + cy.get('[data-cy="mode-toggle-button"]').click(); + expectIcon('moon'); + }); + }); +}); diff --git a/cypress/fixtures/colors.ts b/cypress/fixtures/colors.ts new file mode 100644 index 00000000..1c9c4550 --- /dev/null +++ b/cypress/fixtures/colors.ts @@ -0,0 +1,10 @@ +export const colors = { + light: { + bgColor: 'rgb(255, 255, 255)', + color: 'rgb(50, 56, 62)', + }, + dark: { + bgColor: 'rgb(9, 9, 11)', + color: 'rgb(205, 215, 225)', + }, +}; diff --git a/package.json b/package.json index fb550d61..9c001eb1 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "build": "next build", "cypress:open": "cypress open", - "cypress:run": "cypress run --browser chrome", + "cypress:run": "cypress run --browser edge", "dev": "next dev", "format": "prettier --write .", "postinstall": "patch-package && npm run prisma:generate", From 8d3819fa98bf1b9ba9a7abe17682d17e4653ebbf Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sat, 17 Feb 2024 10:01:28 +0800 Subject: [PATCH 44/87] chore: format code --- cypress/e2e/color-mode.cy.ts | 84 ++++++++++++++++++------------------ cypress/fixtures/colors.ts | 20 ++++----- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/cypress/e2e/color-mode.cy.ts b/cypress/e2e/color-mode.cy.ts index f6b0a1bf..8491bb48 100644 --- a/cypress/e2e/color-mode.cy.ts +++ b/cypress/e2e/color-mode.cy.ts @@ -1,42 +1,42 @@ -import { colors } from '../fixtures/colors'; - -describe('Color mode', () => { - const expectColorMode = (colorMode: 'dark' | 'light') => { - cy.get('html').should('have.attr', 'data-joy-color-scheme', colorMode); - cy.get('body') - .should('have.css', 'background-color', colors[colorMode].bgColor) - .and('have.css', 'color', colors[colorMode].color); - }; - - beforeEach(() => cy.visit('/')); - - it('default is light mode', () => expectColorMode('light')); - - describe('Mode toggle button', () => { - it('toggles color mode', () => { - cy.get('[data-cy="mode-toggle-button"]').click(); - expectColorMode('dark'); - - cy.get('[data-cy="mode-toggle-button"]').click(); - expectColorMode('light'); - }); - - it('updates icon according to color mode', () => { - const expectIcon = (icon: 'sun' | 'moon') => { - cy.get('[data-cy="mode-toggle-button"]') - .find('[data-cy="moon"]') - .should(icon === 'moon' ? 'be.visible' : 'not.exist'); - - cy.get('[data-cy="mode-toggle-button"]') - .find('[data-cy="sun"]') - .should(icon === 'sun' ? 'be.visible' : 'not.exist'); - }; - - expectIcon('moon'); - cy.get('[data-cy="mode-toggle-button"]').click(); - expectIcon('sun'); - cy.get('[data-cy="mode-toggle-button"]').click(); - expectIcon('moon'); - }); - }); -}); +import { colors } from '../fixtures/colors'; + +describe('Color mode', () => { + const expectColorMode = (colorMode: 'dark' | 'light') => { + cy.get('html').should('have.attr', 'data-joy-color-scheme', colorMode); + cy.get('body') + .should('have.css', 'background-color', colors[colorMode].bgColor) + .and('have.css', 'color', colors[colorMode].color); + }; + + beforeEach(() => cy.visit('/')); + + it('default is light mode', () => expectColorMode('light')); + + describe('Mode toggle button', () => { + it('toggles color mode', () => { + cy.get('[data-cy="mode-toggle-button"]').click(); + expectColorMode('dark'); + + cy.get('[data-cy="mode-toggle-button"]').click(); + expectColorMode('light'); + }); + + it('updates icon according to color mode', () => { + const expectIcon = (icon: 'sun' | 'moon') => { + cy.get('[data-cy="mode-toggle-button"]') + .find('[data-cy="moon"]') + .should(icon === 'moon' ? 'be.visible' : 'not.exist'); + + cy.get('[data-cy="mode-toggle-button"]') + .find('[data-cy="sun"]') + .should(icon === 'sun' ? 'be.visible' : 'not.exist'); + }; + + expectIcon('moon'); + cy.get('[data-cy="mode-toggle-button"]').click(); + expectIcon('sun'); + cy.get('[data-cy="mode-toggle-button"]').click(); + expectIcon('moon'); + }); + }); +}); diff --git a/cypress/fixtures/colors.ts b/cypress/fixtures/colors.ts index 1c9c4550..eb01f979 100644 --- a/cypress/fixtures/colors.ts +++ b/cypress/fixtures/colors.ts @@ -1,10 +1,10 @@ -export const colors = { - light: { - bgColor: 'rgb(255, 255, 255)', - color: 'rgb(50, 56, 62)', - }, - dark: { - bgColor: 'rgb(9, 9, 11)', - color: 'rgb(205, 215, 225)', - }, -}; +export const colors = { + light: { + bgColor: 'rgb(255, 255, 255)', + color: 'rgb(50, 56, 62)', + }, + dark: { + bgColor: 'rgb(9, 9, 11)', + color: 'rgb(205, 215, 225)', + }, +}; From c21c4234bdc244af39bbafd3089ee074ee304b29 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sat, 17 Feb 2024 10:03:09 +0800 Subject: [PATCH 45/87] ci(e2e): use headless browser --- .github/workflows/e2e.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9308730d..dc1b6da3 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -21,6 +21,5 @@ jobs: with: install: false browser: ${{ matrix.browser }} - headed: true env: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} From b49aeeca5f51543c924ec28aa87a1568fd803f64 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sat, 17 Feb 2024 10:14:23 +0800 Subject: [PATCH 46/87] feat: remove redundant tooltip --- app/(main)/blog/[slug]/page.tsx | 39 ++++++++++++---------------- components/blog/copy-url-button.tsx | 37 ++++++++++---------------- components/blog/share-dropdown.tsx | 12 ++++----- components/footer.tsx | 40 ++++++++++++++--------------- components/header.tsx | 23 ++++++++--------- components/mode-toggle-button.tsx | 23 ++++++++--------- components/nav-drawer.tsx | 18 ++++++------- 7 files changed, 85 insertions(+), 107 deletions(-) diff --git a/app/(main)/blog/[slug]/page.tsx b/app/(main)/blog/[slug]/page.tsx index b0bdd4ed..0ace7ae1 100644 --- a/app/(main)/blog/[slug]/page.tsx +++ b/app/(main)/blog/[slug]/page.tsx @@ -8,7 +8,6 @@ import { Grid, IconButton, Stack, - Tooltip, Typography, } from '@mui/joy'; import { Metadata } from 'next'; @@ -157,31 +156,27 @@ const Blog: FC = async ({ params: { slug } }) => { {platformProfiles.map( ({ platform, url }) => platform && ( - - - - - + + ), )} - - - - - + + + > = (props) => { useEffect(() => () => clearTimeout(timeout.current), []); return ( - - { - await navigator.clipboard.writeText(url); - setCopied(true); - timeout.current = setTimeout(() => setCopied(false), 1000); - }} - sx={{ - '&[aria-pressed="true"]:not(:active)': { - bgcolor: 'transparent', - '&:hover': { - bgcolor: (theme) => - theme.vars.palette[copied ? 'success' : 'neutral'].plainHoverBg, - }, - }, - }} - {...props} - > - {copied ? : } - - + { + await navigator.clipboard.writeText(url); + setCopied(true); + timeout.current = setTimeout(() => setCopied(false), 1000); + }} + {...props} + > + {copied ? : } + ); }; diff --git a/components/blog/share-dropdown.tsx b/components/blog/share-dropdown.tsx index 7f362fe8..9b128c2f 100644 --- a/components/blog/share-dropdown.tsx +++ b/components/blog/share-dropdown.tsx @@ -15,7 +15,6 @@ import { Menu, MenuButton, MenuItem, - Tooltip, } from '@mui/joy'; import { Share2 } from 'lucide-react'; import { usePathname } from 'next/navigation'; @@ -66,11 +65,12 @@ export const ShareDropdown: FC = ({ blog, ...props }) => { return ( - - - - - + + + {socialMediaOptions.map(({ Icon, name, url }) => ( diff --git a/components/footer.tsx b/components/footer.tsx index 708e50b4..ef617ac0 100644 --- a/components/footer.tsx +++ b/components/footer.tsx @@ -9,7 +9,6 @@ import { ListItem, ListItemButton, Stack, - Tooltip, Typography, } from '@mui/joy'; import NextLink from 'next/link'; @@ -35,28 +34,27 @@ export const Footer: FC = async (props) => { {platformProfiles.map( ({ platform, url }) => platform && ( - - - - - + + + ), )} - - - - - + + + diff --git a/components/header.tsx b/components/header.tsx index 8385700b..b3460164 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -8,7 +8,6 @@ import { ListItem, ListItemButton, Stack, - Tooltip, } from '@mui/joy'; import NextLink from 'next/link'; import { FC } from 'react'; @@ -85,17 +84,17 @@ export const Header: FC = async (props) => { {platformProfiles.map( ({ platform, url }) => platform && ( - - - - - + + + ), )} diff --git a/components/mode-toggle-button.tsx b/components/mode-toggle-button.tsx index cf1fcb03..06221b45 100644 --- a/components/mode-toggle-button.tsx +++ b/components/mode-toggle-button.tsx @@ -1,7 +1,7 @@ 'use client'; import { NoSsr } from '@mui/base'; -import { IconButton, IconButtonProps, Tooltip, useColorScheme } from '@mui/joy'; +import { IconButton, IconButtonProps, useColorScheme } from '@mui/joy'; import { Moon, Sun } from 'lucide-react'; import { FC } from 'react'; @@ -10,16 +10,15 @@ export const ModeToggleButton: FC = (props) => { const { mode, setMode } = useColorScheme(); return ( - - setMode(mode === 'dark' ? 'light' : 'dark')} - {...props} - > - - {mode === 'dark' ? : } - - - + setMode(mode === 'dark' ? 'light' : 'dark')} + {...props} + > + + {mode === 'dark' ? : } + + ); }; diff --git a/components/nav-drawer.tsx b/components/nav-drawer.tsx index 0964052d..b4f30571 100644 --- a/components/nav-drawer.tsx +++ b/components/nav-drawer.tsx @@ -8,7 +8,6 @@ import { List, ListItem, ListItemButton, - Tooltip, } from '@mui/joy'; import { Menu } from 'lucide-react'; import NextLink from 'next/link'; @@ -26,15 +25,14 @@ export const NavDrawer: FC = ({ slotProps }) => { const [open, setOpen] = useState(false); return ( <> - - setOpen(true)} - {...slotProps?.drawerButton} - > - - - + setOpen(true)} + {...slotProps?.drawerButton} + > + + setOpen(false)} open={open}> Date: Sat, 17 Feb 2024 12:10:20 +0800 Subject: [PATCH 47/87] ci(unlighthouse): remove budget for now since it is unreliable --- unlighthouse.config.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/unlighthouse.config.ts b/unlighthouse.config.ts index e7e0d5b3..94c8d01c 100644 --- a/unlighthouse.config.ts +++ b/unlighthouse.config.ts @@ -2,11 +2,11 @@ export default { cache: false, ci: { buildStatic: true, - budget: { - performance: 90, - accessibility: 98, // minus point from code blocks sometimes have color contrast issue - 'best-practices': 92, // minus point from hydration errors are sometimes logged due to PPR - seo: 92, // minus point from non-PROD not being indexable - }, + // budget: { + // performance: 90, + // accessibility: 98, // minus point from code blocks sometimes have color contrast issue + // 'best-practices': 92, // minus point from hydration errors are sometimes logged due to PPR + // seo: 92, // minus point from non-PROD not being indexable + // }, }, }; From 00d734b2c4586349c3e501d9bbe93acd8e87f776 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sat, 17 Feb 2024 20:07:03 +0800 Subject: [PATCH 48/87] feat: optimize SVG --- next.config.mjs | 22 +++++++++++++++++++++- package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index 853a551b..293f5661 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -2,6 +2,16 @@ import NextBundleAnalyzer from '@next/bundle-analyzer'; +const sharedSvgoPlugins = [ + 'prefixIds', + 'removeRasterImages', + 'removeScriptElement', + 'removeOffCanvasPaths', + 'reusePaths', + 'removeXlink', + 'removeXMLNS', +]; + /** @type {import('next').NextConfig} */ const config = { compiler: { @@ -52,6 +62,7 @@ const config = { params: { overrides: { inlineStyles: false } }, }, 'removeStyleElement', + ...sharedSvgoPlugins, ], }, }, @@ -65,7 +76,16 @@ const config = { // exclude if *.svg?url and *.svg?monochrome not: [...fileLoaderRule.resourceQuery.not, /monochrome/, /url/], }, - use: ['@svgr/webpack'], + use: [ + { + loader: '@svgr/webpack', + options: { + svgoConfig: { + plugins: ['preset-default', ...sharedSvgoPlugins], + }, + }, + }, + ], }, ); diff --git a/package-lock.json b/package-lock.json index 007ec982..4753c2e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ "@svgr/webpack": "^8.1.0", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.19", - "@types/react": "^18.2.55", + "@types/react": "^18.2.56", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", "cypress": "^13.6.4", @@ -3507,9 +3507,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "18.2.55", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.55.tgz", - "integrity": "sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==", + "version": "18.2.56", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.56.tgz", + "integrity": "sha512-NpwHDMkS/EFZF2dONFQHgkPRwhvgq/OAvIaGQzxGSBmaeR++kTg6njr15Vatz0/2VcCEwJQFi6Jf4Q0qBu0rLA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", diff --git a/package.json b/package.json index 9c001eb1..6d8600d0 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@svgr/webpack": "^8.1.0", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.19", - "@types/react": "^18.2.55", + "@types/react": "^18.2.56", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", "cypress": "^13.6.4", From fdee50be1acf02e2d62f6d371743650f477a928b Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 15:46:19 +0800 Subject: [PATCH 49/87] chore: Package update --- package-lock.json | 117 +++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4753c2e0..f0965dd9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2789,32 +2789,32 @@ } }, "node_modules/@next/bundle-analyzer": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.58.tgz", - "integrity": "sha512-KwUBUUWx6lrNYVqpBn02bN+KPgITYOsD/Eh7JHQVyUxNHMrtth1C3CRpm30QZJ2uF4XJW1qPyTKTwxABvECeAg==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.59.tgz", + "integrity": "sha512-L/DoVhU4R4Y5EfAJqZoN/hEmVNWN4kSJiMDX1jd5dcZwwiZckWdib3+BfniZwqMfX3IfuZmCtl0ZV1FJqTb+2A==", "dev": true, "dependencies": { "webpack-bundle-analyzer": "4.10.1" } }, "node_modules/@next/env": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.58.tgz", - "integrity": "sha512-xMoPPiWVEIyIPoWaLhswlMq2Tnfkcv+XRmUAEhKkJgWdHIMFh45tiniWrZQLfrn4DAnF8gEAoejJaniNShFm7w==" + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.59.tgz", + "integrity": "sha512-7tBm5NJmAkmiBZf/HRe5RUIYln24SsxVUKdJpDGW7/OHcrQXZ9iO1WsGpZLJFAWpfLQU9aUXyovKLuKvqhyOTQ==" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.58.tgz", - "integrity": "sha512-A+kH2788C5keH/UEPUX9gWExdstBYaqWgsHuPpbN77S0kjcYQY5ayvVoOQKoJwSXeY+BKpo8CnXtXEIevekRTQ==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.59.tgz", + "integrity": "sha512-0pztyQSTINQC7MMgEPAtzqMJjR9l8KdcXt+gCg/CNgW1LGYPWZx/2Tu15MP2/MQ2D5Ip2WZ+MA3qieWnmeTE+Q==", "dev": true, "dependencies": { "glob": "10.3.10" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.58.tgz", - "integrity": "sha512-exDpEe9ptK0NJEEyA+sThnR/6Oif/XaPK1y10fkcTNoQJkUCENL46nR1bCEYDAQrS5w03C1BHs3LSIOuoQcIag==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.59.tgz", + "integrity": "sha512-WVSg1dkNvprYkakRIYYHhkIiSvaU7+S/bCffs0hGKRmKr45Lc7HfvwVAWHPxIO3d7cUtnz1d7fXRD42pWom4EQ==", "cpu": [ "arm64" ], @@ -2827,9 +2827,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.58.tgz", - "integrity": "sha512-Q+38djBg+yaZjB8R6kst8kqHLIpTIM2RzuIvFGOflb8WaVI1ApXERTJKd345BOp42s0rIJ1UqynRplNCqYebeA==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.59.tgz", + "integrity": "sha512-yvVLVK9QPdU+JfviXNuUkGV2/dKo/Toy0g8VBN1n4oltTJWsZRnqguz5dZAfFX/fdQmc7QhK7TgJbpsk99+aUg==", "cpu": [ "x64" ], @@ -2842,9 +2842,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.58.tgz", - "integrity": "sha512-wv2457qPqh7ENqQ3t8sCWCsNStEW/o8qejZ6Ywdwl3eKP1jnFNtn4OWfOuP2FUl1XmVEzbABozuOyiCGAtD63Q==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.59.tgz", + "integrity": "sha512-aKAAEjTA0kQDuPcpSji26RiyIJVHMvSfa6V14oI270wkzGDzA+I7yDIdfAjghZg2AqpqP37sppTtk94hpg0Jpw==", "cpu": [ "arm64" ], @@ -2857,9 +2857,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.58.tgz", - "integrity": "sha512-xvfU/+mZfLpW/tRy743JtkNPlNI2t1dSkIzvDHHn/V28k1c+4YmsNxKMZRqqcxi73hwnuWYgor/96Sm4r9pmQQ==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.59.tgz", + "integrity": "sha512-63sUd3fspUDPP8pKfSDBpegxNV8t7QqM9uKCWiVVF253/fjLrm21ziTSP22Ij2HyxMzYDjUcXXw3oaV0/9+lHw==", "cpu": [ "arm64" ], @@ -2872,9 +2872,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.58.tgz", - "integrity": "sha512-OgayNv+ChIjsPYMkBit2LTI0tMJ72or4w5DfQe2i1M2Ccy09p/LSRCiOptkV3XKyO+Tz8+fAqN+PdLRxfxQiuQ==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.59.tgz", + "integrity": "sha512-XguNPS4Q7b3plMqfiYJvY4dQ+vyoEITt/rLxjRmnNmT0inaPA4Q9Lbl0rST6luVPYNaysmk1lzF1Rqodb5uudw==", "cpu": [ "x64" ], @@ -2887,9 +2887,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.58.tgz", - "integrity": "sha512-6epwXWxSUyNKzOt0FSRW0QioPaWA9xlu8LM5N0c9eg8vaI3FvZmQegtHIzuzNc7RyWE1a5ZY4uDBVA1JaUJRow==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.59.tgz", + "integrity": "sha512-Hy+av18riWV3kYpO5vK0eQq6lN1NcZvnYG70mnsFwxiFaT2XVJimbIdSWiXNIB5QNF1Vv7AjcCVAw0nTojRKVg==", "cpu": [ "x64" ], @@ -2902,9 +2902,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.58.tgz", - "integrity": "sha512-Qa79WuVRcrkmbxzTXr/tmWvFHVMjUu9KpxNrKn+HO/DmrVEnR4NxmuzOOxc6QkCb+Rb86rfV7tttPQqw7YigBA==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.59.tgz", + "integrity": "sha512-Z7dj8ox/ih0HiKp5J2R5SV9sZLQ8mbuYy9g6MvwwmtGLkoCH9trLuo966ubYZ+nIFrzItWGf1HnMrnvNS00KlA==", "cpu": [ "arm64" ], @@ -2917,9 +2917,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.58.tgz", - "integrity": "sha512-fuqdt6XKc4kvUpgOMh/LL2eqJ/eltxknClpaAg9Nt0dGTQIF0rjKEVm8NRwv832URZKKBbz9AtBp5TEmOquG9g==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.59.tgz", + "integrity": "sha512-VQpCBFfbUiQax+/CWwjPwYHGZwUydpd7ZoUskkHHA0ZTbIDsSj64EzMFhK3tdo8JOOnNfVDAT/l95afmxYnzSA==", "cpu": [ "ia32" ], @@ -2932,9 +2932,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.58.tgz", - "integrity": "sha512-P/DkKFiZo1mILb2UGt1YiurmuKo9LLvgC0l77YQ5g2b8jrTbYS9JeJJcdhLXnsHPPQrR/QgnEDJ2zWRtIhUJZA==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.59.tgz", + "integrity": "sha512-p7h/35PoqYxDNxce2EPkegIhe0149Wvdcq+HyVYkN8tp2fwAy2kKQM0RK8HlMU8NbiRwmlAx4lST/0pu+sd95g==", "cpu": [ "x64" ], @@ -4700,9 +4700,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", + "version": "1.0.30001588", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", + "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", "funding": [ { "type": "opencollective", @@ -10267,11 +10267,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.1-canary.58", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.58.tgz", - "integrity": "sha512-rL4Tmm5ldL4VA+lTz0sQfJcDOe3vXB7LItcWuILb8eDs/6X1wrXNF9KDtviJH0tq/jrrTOihN7aBCkkge85m6g==", + "version": "14.1.1-canary.59", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.59.tgz", + "integrity": "sha512-MZOg68cUQQ3owGiPkBNr25X45LaEMqC0uX1uvTzfRWZISw9l6BR7aeI24Zv/g6YWszGG/YGfMDt/g/37FgstYA==", "dependencies": { - "@next/env": "14.1.1-canary.58", + "@next/env": "14.1.1-canary.59", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -10286,15 +10286,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.1-canary.58", - "@next/swc-darwin-x64": "14.1.1-canary.58", - "@next/swc-linux-arm64-gnu": "14.1.1-canary.58", - "@next/swc-linux-arm64-musl": "14.1.1-canary.58", - "@next/swc-linux-x64-gnu": "14.1.1-canary.58", - "@next/swc-linux-x64-musl": "14.1.1-canary.58", - "@next/swc-win32-arm64-msvc": "14.1.1-canary.58", - "@next/swc-win32-ia32-msvc": "14.1.1-canary.58", - "@next/swc-win32-x64-msvc": "14.1.1-canary.58" + "@next/swc-darwin-arm64": "14.1.1-canary.59", + "@next/swc-darwin-x64": "14.1.1-canary.59", + "@next/swc-linux-arm64-gnu": "14.1.1-canary.59", + "@next/swc-linux-arm64-musl": "14.1.1-canary.59", + "@next/swc-linux-x64-gnu": "14.1.1-canary.59", + "@next/swc-linux-x64-musl": "14.1.1-canary.59", + "@next/swc-win32-arm64-msvc": "14.1.1-canary.59", + "@next/swc-win32-ia32-msvc": "14.1.1-canary.59", + "@next/swc-win32-x64-msvc": "14.1.1-canary.59" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -12994,16 +12994,17 @@ } }, "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==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz", + "integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.7", "for-each": "^0.3.3", + "gopd": "^1.0.1", "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" From c7173f08dcbccd7bf88d16b2e9d486da327a0803 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 15:46:39 +0800 Subject: [PATCH 50/87] ci(e2e): assign vercel env to env var --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index dc1b6da3..16ab6282 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -22,4 +22,5 @@ jobs: install: false browser: ${{ matrix.browser }} env: + VERCEL_ENV: ${{ github.event.deployment_status.environment }} CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} From 7239898f74da6cd3b703d1c3b0a094d199517c3e Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 16:34:17 +0800 Subject: [PATCH 51/87] test: add download CV test --- .github/workflows/e2e.yml | 5 ++++- .gitignore | 3 ++- constants/contentful-ids.ts | 3 +++ cypress/e2e/download-cv.cy.ts | 17 +++++++++++++++++ cypress/fixtures/contentful-ids.ts | 1 + cypress/support/clients.ts | 8 ++++++++ cypress/tsconfig.json | 2 +- lib/queries.ts | 8 ++++---- 8 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 cypress/e2e/download-cv.cy.ts create mode 100644 cypress/fixtures/contentful-ids.ts create mode 100644 cypress/support/clients.ts diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 16ab6282..13f6259c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -4,6 +4,7 @@ on: deployment_status jobs: e2e: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' + environment: ${{ github.event.deployment_status.environment }} runs-on: ubuntu-latest strategy: matrix: @@ -22,5 +23,7 @@ jobs: install: false browser: ${{ matrix.browser }} env: - VERCEL_ENV: ${{ github.event.deployment_status.environment }} CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} + CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }} + CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }} + ENVIRONMENT: ${{ github.event.deployment_status.environment }} diff --git a/.gitignore b/.gitignore index d92ccd00..3634d888 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,5 @@ next-env.d.ts # cypress cypress/downloads/ cypress/screenshots/ -cypress/videos/ \ No newline at end of file +cypress/videos/ +cypress.env.json \ No newline at end of file diff --git a/constants/contentful-ids.ts b/constants/contentful-ids.ts index a0cf24e7..8b3b58e0 100644 --- a/constants/contentful-ids.ts +++ b/constants/contentful-ids.ts @@ -37,3 +37,6 @@ export const muiCore = '34jdGzLYPeSdsX8ufmmtnX'; export const vercelStyleGuide = '6scCFCr3pGATuvQEFnpkC7'; export const valibot = 'ULFnAQDuQIweV6ehX8od0'; export const cypress = '2ZcY6scvuQb0WabbaaV4mO'; + +export const cv = '6mTh13ou7wM2Cs7ZC1tcdn'; +export const privacyPolicy = '13hUvxPc7WtvdUSAJK5WAm'; diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts new file mode 100644 index 00000000..37f309e9 --- /dev/null +++ b/cypress/e2e/download-cv.cy.ts @@ -0,0 +1,17 @@ +import { cv } from '../fixtures/contentful-ids'; +import { contentful } from '../support/clients'; + +describe('Download CV', () => { + it('should download CV', () => { + cy.visit('/'); + cy.contains('Download CV') + .should('have.attr', 'target', '_blank') + .invoke('attr', 'href') + .then((href) => { + void contentful.getAsset(cv).then((asset) => { + expect(asset.fields.file?.contentType).to.equal('application/pdf'); + expect(href).to.equal(`https:${asset.fields.file?.url}`); + }); + }); + }); +}); diff --git a/cypress/fixtures/contentful-ids.ts b/cypress/fixtures/contentful-ids.ts new file mode 100644 index 00000000..32ba8f0b --- /dev/null +++ b/cypress/fixtures/contentful-ids.ts @@ -0,0 +1 @@ +export const cv = '6mTh13ou7wM2Cs7ZC1tcdn'; diff --git a/cypress/support/clients.ts b/cypress/support/clients.ts new file mode 100644 index 00000000..da83ee9e --- /dev/null +++ b/cypress/support/clients.ts @@ -0,0 +1,8 @@ +import { createClient } from 'contentful'; + +export const contentful = createClient({ + space: Cypress.env('CONTENTFUL_SPACE_ID') as string, + accessToken: Cypress.env('CONTENTFUL_ACCESS_TOKEN') as string, + environment: + Cypress.env('ENVIRONMENT') === 'Production' ? 'master' : 'develop', +}).withoutUnresolvableLinks; diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index 2e44e740..df33ff75 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "target": "es5", "lib": ["es5", "dom"], - "types": ["cypress", "node", "lodash-es"] + "types": ["cypress", "node", "lodash-es", "contentful"] }, "include": ["**/*.ts"] } diff --git a/lib/queries.ts b/lib/queries.ts index 0e88ade1..2765cb81 100644 --- a/lib/queries.ts +++ b/lib/queries.ts @@ -8,6 +8,8 @@ import { } from 'next/cache'; import { cache as reactCache } from 'react'; +import { cv, privacyPolicy } from '@/constants/contentful-ids'; + import { contentful, prisma } from './clients'; import { BlogSkeleton, @@ -106,7 +108,7 @@ export const getCourses = cache(async () => { }); export const getCv = cache(async () => { - const asset = await contentful.getAsset('6mTh13ou7wM2Cs7ZC1tcdn'); + const asset = await contentful.getAsset(cv); return asset.fields.file && `https:${asset.fields.file.url}`; }); @@ -265,9 +267,7 @@ export const getTechStack = cache(async () => { }); export const getPrivacyPolicy = cache(async () => { - const entry = await contentful.getEntry( - '13hUvxPc7WtvdUSAJK5WAm', - ); + const entry = await contentful.getEntry(privacyPolicy); return { createdAt: entry.sys.createdAt, From d5004ffbeef03f5963ec92373900b1a9bae1e26a Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 16:34:56 +0800 Subject: [PATCH 52/87] chore: format code --- cypress/e2e/download-cv.cy.ts | 34 +++++++++++++++--------------- cypress/fixtures/contentful-ids.ts | 2 +- cypress/support/clients.ts | 16 +++++++------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index 37f309e9..3a347af3 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -1,17 +1,17 @@ -import { cv } from '../fixtures/contentful-ids'; -import { contentful } from '../support/clients'; - -describe('Download CV', () => { - it('should download CV', () => { - cy.visit('/'); - cy.contains('Download CV') - .should('have.attr', 'target', '_blank') - .invoke('attr', 'href') - .then((href) => { - void contentful.getAsset(cv).then((asset) => { - expect(asset.fields.file?.contentType).to.equal('application/pdf'); - expect(href).to.equal(`https:${asset.fields.file?.url}`); - }); - }); - }); -}); +import { cv } from '../fixtures/contentful-ids'; +import { contentful } from '../support/clients'; + +describe('Download CV', () => { + it('should download CV', () => { + cy.visit('/'); + cy.contains('Download CV') + .should('have.attr', 'target', '_blank') + .invoke('attr', 'href') + .then((href) => { + void contentful.getAsset(cv).then((asset) => { + expect(asset.fields.file?.contentType).to.equal('application/pdf'); + expect(href).to.equal(`https:${asset.fields.file?.url}`); + }); + }); + }); +}); diff --git a/cypress/fixtures/contentful-ids.ts b/cypress/fixtures/contentful-ids.ts index 32ba8f0b..b049e7a8 100644 --- a/cypress/fixtures/contentful-ids.ts +++ b/cypress/fixtures/contentful-ids.ts @@ -1 +1 @@ -export const cv = '6mTh13ou7wM2Cs7ZC1tcdn'; +export const cv = '6mTh13ou7wM2Cs7ZC1tcdn'; diff --git a/cypress/support/clients.ts b/cypress/support/clients.ts index da83ee9e..3fb1fb4e 100644 --- a/cypress/support/clients.ts +++ b/cypress/support/clients.ts @@ -1,8 +1,8 @@ -import { createClient } from 'contentful'; - -export const contentful = createClient({ - space: Cypress.env('CONTENTFUL_SPACE_ID') as string, - accessToken: Cypress.env('CONTENTFUL_ACCESS_TOKEN') as string, - environment: - Cypress.env('ENVIRONMENT') === 'Production' ? 'master' : 'develop', -}).withoutUnresolvableLinks; +import { createClient } from 'contentful'; + +export const contentful = createClient({ + space: Cypress.env('CONTENTFUL_SPACE_ID') as string, + accessToken: Cypress.env('CONTENTFUL_ACCESS_TOKEN') as string, + environment: + Cypress.env('ENVIRONMENT') === 'Production' ? 'master' : 'develop', +}).withoutUnresolvableLinks; From af2efa464143806983f31bf7b9f1ed5f075a30c1 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 16:51:22 +0800 Subject: [PATCH 53/87] ci(e2e): fix env access --- .github/workflows/e2e.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 13f6259c..aa6c9345 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -24,6 +24,7 @@ jobs: browser: ${{ matrix.browser }} env: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} - CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }} - CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }} - ENVIRONMENT: ${{ github.event.deployment_status.environment }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CYPRESS_CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }} + CYPRESS_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }} + CYPRESS_ENVIRONMENT: ${{ github.event.deployment_status.environment }} From e2d97fbf276bdc7439587ce3fd26247a14acd437 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 16:57:39 +0800 Subject: [PATCH 54/87] ci(unlighthouse): some how loops forever --- .github/workflows/unlighthouse.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index 3b9a23ae..a0c2fd8b 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -4,6 +4,7 @@ on: deployment_status jobs: unlighthouse: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' + environment: ${{ github.event.deployment_status.environment }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From f186fb6fc08651f4a2617f54eb58e5091e2ad4fd Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 17:00:26 +0800 Subject: [PATCH 55/87] Revert "ci(unlighthouse): some how loops forever" This reverts commit 066b045f6129186e606da2976000bf9698b95b7b. --- .github/workflows/unlighthouse.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index a0c2fd8b..3b9a23ae 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -4,7 +4,6 @@ on: deployment_status jobs: unlighthouse: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' - environment: ${{ github.event.deployment_status.environment }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 3ed63cc1f02656f0dd403ef19e3a02cc4c401c91 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 17:04:35 +0800 Subject: [PATCH 56/87] ci(e2e): debug if `environment` is causing actions to spawn endlessly --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index aa6c9345..61195a6c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -4,7 +4,7 @@ on: deployment_status jobs: e2e: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' - environment: ${{ github.event.deployment_status.environment }} + # environment: ${{ github.event.deployment_status.environment }} runs-on: ubuntu-latest strategy: matrix: From 616e826ec980192102ba7713711bcbe1172278d8 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 17:11:33 +0800 Subject: [PATCH 57/87] Revert "ci(e2e): debug if `environment` is causing actions to spawn endlessly" This reverts commit 2fc3fd34fc614f053c83e2997ef0e514a76e2b6a. --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 61195a6c..aa6c9345 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -4,7 +4,7 @@ on: deployment_status jobs: e2e: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' - # environment: ${{ github.event.deployment_status.environment }} + environment: ${{ github.event.deployment_status.environment }} runs-on: ubuntu-latest strategy: matrix: From 7357cc26150cafdad39f1323fa9a0d4854f3a3fb Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 17:22:06 +0800 Subject: [PATCH 58/87] ci(e2e): prevent triggering redeploy --- .github/workflows/e2e.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index aa6c9345..422c78a9 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -28,3 +28,5 @@ jobs: CYPRESS_CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }} CYPRESS_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }} CYPRESS_ENVIRONMENT: ${{ github.event.deployment_status.environment }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 904208622ad1b1b00d55a1897bd05f157d16194b Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 17:32:31 +0800 Subject: [PATCH 59/87] ci(e2e): avoid infinite loop --- .github/workflows/e2e.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 422c78a9..647cefdf 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -4,7 +4,6 @@ on: deployment_status jobs: e2e: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' - environment: ${{ github.event.deployment_status.environment }} runs-on: ubuntu-latest strategy: matrix: @@ -26,7 +25,5 @@ jobs: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CYPRESS_CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }} - CYPRESS_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }} + CYPRESS_CONTENTFUL_ACCESS_TOKEN: ${{ github.event.deployment_status.environment == 'Production' && secrets.CONTENTFUL_ACCESS_TOKEN_PROD || secrets.CONTENTFUL_ACCESS_TOKEN_DEVELOP }} CYPRESS_ENVIRONMENT: ${{ github.event.deployment_status.environment }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From ed0b961c969ee71d0c3fdf62e012e3e16f17dd48 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Sun, 18 Feb 2024 21:24:37 +0800 Subject: [PATCH 60/87] ci(e2e): minor formatting --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 647cefdf..3a334a59 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -25,5 +25,5 @@ jobs: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CYPRESS_CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }} - CYPRESS_CONTENTFUL_ACCESS_TOKEN: ${{ github.event.deployment_status.environment == 'Production' && secrets.CONTENTFUL_ACCESS_TOKEN_PROD || secrets.CONTENTFUL_ACCESS_TOKEN_DEVELOP }} + CYPRESS_CONTENTFUL_ACCESS_TOKEN: ${{ github.event.deployment_status.environment == 'Production' && secrets.CONTENTFUL_ACCESS_TOKEN_PROD || secrets.CONTENTFUL_ACCESS_TOKEN_DEVELOP }} CYPRESS_ENVIRONMENT: ${{ github.event.deployment_status.environment }} From 52ef3271d99dcf205c7e2eebfd95aff431e075e7 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Mon, 19 Feb 2024 09:27:56 +0800 Subject: [PATCH 61/87] chore: Package update --- package-lock.json | 114 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/package-lock.json b/package-lock.json index f0965dd9..25468971 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "rehype-pretty-code": "^0.13.0", "rehype-slug": "^6.0.0", "schema-dts": "^1.1.2", - "shiki": "^1.1.3", + "shiki": "^1.1.5", "valibot": "^0.28.1" }, "devDependencies": { @@ -2789,32 +2789,32 @@ } }, "node_modules/@next/bundle-analyzer": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.59.tgz", - "integrity": "sha512-L/DoVhU4R4Y5EfAJqZoN/hEmVNWN4kSJiMDX1jd5dcZwwiZckWdib3+BfniZwqMfX3IfuZmCtl0ZV1FJqTb+2A==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.61.tgz", + "integrity": "sha512-kkwO4A3+g65tCM6Vl4ErQSP5WbaFUMYf4r7NvLaa7PJv8dmdfL74Z8bZxLkRLOoFx/Yasl55owlFUUB6q/TB+Q==", "dev": true, "dependencies": { "webpack-bundle-analyzer": "4.10.1" } }, "node_modules/@next/env": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.59.tgz", - "integrity": "sha512-7tBm5NJmAkmiBZf/HRe5RUIYln24SsxVUKdJpDGW7/OHcrQXZ9iO1WsGpZLJFAWpfLQU9aUXyovKLuKvqhyOTQ==" + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.61.tgz", + "integrity": "sha512-vS5tg1qFIPyKGx7ZBDrOc7Iq2P2amhwTmlu/rzo99q5+5Gh0NvGmF4/vBw1PIP2WZAp8AqEwdL8klbW0wMmmJw==" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.59.tgz", - "integrity": "sha512-0pztyQSTINQC7MMgEPAtzqMJjR9l8KdcXt+gCg/CNgW1LGYPWZx/2Tu15MP2/MQ2D5Ip2WZ+MA3qieWnmeTE+Q==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.61.tgz", + "integrity": "sha512-0LkUpS2XwzVBd/5WyZp/vHanwDBj4ljL24yjfFM2VkB8x3/mEFlZjQrrPftDbAo/EDq5lSdCbUCxrepFP7iGwg==", "dev": true, "dependencies": { "glob": "10.3.10" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.59.tgz", - "integrity": "sha512-WVSg1dkNvprYkakRIYYHhkIiSvaU7+S/bCffs0hGKRmKr45Lc7HfvwVAWHPxIO3d7cUtnz1d7fXRD42pWom4EQ==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.61.tgz", + "integrity": "sha512-Di/e/vfAbI8Ae2Wxuu2DZh2JBj5+DC8pl5C0XACO0Iu7j0qlUsNStk2SMFVfZpIANT0mF6Lz5T3ycaG86oUFSA==", "cpu": [ "arm64" ], @@ -2827,9 +2827,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.59.tgz", - "integrity": "sha512-yvVLVK9QPdU+JfviXNuUkGV2/dKo/Toy0g8VBN1n4oltTJWsZRnqguz5dZAfFX/fdQmc7QhK7TgJbpsk99+aUg==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.61.tgz", + "integrity": "sha512-EeT1cMyW+cECRVWkV1i26iPG+1EFToaL473YLUU/Q2EKSXQVw0T0F5pwIpZcSr+ecSvYYGbEdw2xdgGgNlqyDg==", "cpu": [ "x64" ], @@ -2842,9 +2842,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.59.tgz", - "integrity": "sha512-aKAAEjTA0kQDuPcpSji26RiyIJVHMvSfa6V14oI270wkzGDzA+I7yDIdfAjghZg2AqpqP37sppTtk94hpg0Jpw==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.61.tgz", + "integrity": "sha512-LArfX7VejoNhxAeu0prjnyFJaJBpsaVxL7SOu6PVwnrP6dvmDI/cNFraoJ28yzsfBXI9swYdtRLUD7rEOJSftQ==", "cpu": [ "arm64" ], @@ -2857,9 +2857,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.59.tgz", - "integrity": "sha512-63sUd3fspUDPP8pKfSDBpegxNV8t7QqM9uKCWiVVF253/fjLrm21ziTSP22Ij2HyxMzYDjUcXXw3oaV0/9+lHw==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.61.tgz", + "integrity": "sha512-uJnXfyKNcNXgT2XCX3wIF1b/P58HK7V/+WlY0bUss3tVHdaMtvia/WZYDe60LzNsmQJEtQXoBtVw0Y+YIxyBVg==", "cpu": [ "arm64" ], @@ -2872,9 +2872,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.59.tgz", - "integrity": "sha512-XguNPS4Q7b3plMqfiYJvY4dQ+vyoEITt/rLxjRmnNmT0inaPA4Q9Lbl0rST6luVPYNaysmk1lzF1Rqodb5uudw==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.61.tgz", + "integrity": "sha512-Nik6CNMgt57et+2dqhOCQHZGmMQ0ju0sWu4O19y0XsfJnyhzQD7FYXuT+3jIZ9fiwdBNSEAyyZ4vUDqEFLdO3w==", "cpu": [ "x64" ], @@ -2887,9 +2887,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.59.tgz", - "integrity": "sha512-Hy+av18riWV3kYpO5vK0eQq6lN1NcZvnYG70mnsFwxiFaT2XVJimbIdSWiXNIB5QNF1Vv7AjcCVAw0nTojRKVg==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.61.tgz", + "integrity": "sha512-dirPIeN0So3WLOBmfjfGL4lwpZbEHf8Ez2M5U0tZ75ZWF4xd5sKXLJDBlZ/1YBDH9RI7yivqbT4Rr5QN/W3V1w==", "cpu": [ "x64" ], @@ -2902,9 +2902,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.59.tgz", - "integrity": "sha512-Z7dj8ox/ih0HiKp5J2R5SV9sZLQ8mbuYy9g6MvwwmtGLkoCH9trLuo966ubYZ+nIFrzItWGf1HnMrnvNS00KlA==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.61.tgz", + "integrity": "sha512-akv1zuBx286ZF1t1qmB8HMftZUvry+1g2JmpkVbvmuOq50MaGxFPdKsDZOnTrmvLezGrQV12JxC8CUwcBpZKLw==", "cpu": [ "arm64" ], @@ -2917,9 +2917,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.59.tgz", - "integrity": "sha512-VQpCBFfbUiQax+/CWwjPwYHGZwUydpd7ZoUskkHHA0ZTbIDsSj64EzMFhK3tdo8JOOnNfVDAT/l95afmxYnzSA==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.61.tgz", + "integrity": "sha512-heJt1MdizMmD1U2XzcolDaEaBg5SyHlA6+A0PSdVGvO3/PgA33YvxU48umlGwF0OQKIoeqj0d2m8vXdJGvLkZA==", "cpu": [ "ia32" ], @@ -2932,9 +2932,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.59.tgz", - "integrity": "sha512-p7h/35PoqYxDNxce2EPkegIhe0149Wvdcq+HyVYkN8tp2fwAy2kKQM0RK8HlMU8NbiRwmlAx4lST/0pu+sd95g==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.61.tgz", + "integrity": "sha512-5AhTzPf1Xn2j8OoAexC2LmDt4x1h5pCB8gjeZ8jYxm6Z8pSOUtowsrOFmqbZpxWHKMTTjM1LbzIcY0AYo+O+bA==", "cpu": [ "x64" ], @@ -3110,9 +3110,9 @@ "dev": true }, "node_modules/@shikijs/core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.3.tgz", - "integrity": "sha512-1QWSvWcPbvZXsDxB1F7ejW+Kuxp3z/JHs944hp/f8BYOlFd5gplzseFIkE/GTu/qytFef3zNME4qw1oHbQ0j2A==" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.5.tgz", + "integrity": "sha512-cKc5vGQ4p/4sjx48BHIO7CvLaN32vqpz5Wh7v2n+U1EezGdfX4Wms7khBctKz3iCg9yYq4sfGUc2t+JWj6EUsw==" }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", @@ -10267,11 +10267,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.1-canary.59", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.59.tgz", - "integrity": "sha512-MZOg68cUQQ3owGiPkBNr25X45LaEMqC0uX1uvTzfRWZISw9l6BR7aeI24Zv/g6YWszGG/YGfMDt/g/37FgstYA==", + "version": "14.1.1-canary.61", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.61.tgz", + "integrity": "sha512-QMePsaNHDLX3nBi05+2im7fLn/AWq6BYP7quQVqUI3zr+C6rkhr5Zs6+K+9JILh7y7Vdgb6Ajohj6SJfvfy8DQ==", "dependencies": { - "@next/env": "14.1.1-canary.59", + "@next/env": "14.1.1-canary.61", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -10286,15 +10286,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.1-canary.59", - "@next/swc-darwin-x64": "14.1.1-canary.59", - "@next/swc-linux-arm64-gnu": "14.1.1-canary.59", - "@next/swc-linux-arm64-musl": "14.1.1-canary.59", - "@next/swc-linux-x64-gnu": "14.1.1-canary.59", - "@next/swc-linux-x64-musl": "14.1.1-canary.59", - "@next/swc-win32-arm64-msvc": "14.1.1-canary.59", - "@next/swc-win32-ia32-msvc": "14.1.1-canary.59", - "@next/swc-win32-x64-msvc": "14.1.1-canary.59" + "@next/swc-darwin-arm64": "14.1.1-canary.61", + "@next/swc-darwin-x64": "14.1.1-canary.61", + "@next/swc-linux-arm64-gnu": "14.1.1-canary.61", + "@next/swc-linux-arm64-musl": "14.1.1-canary.61", + "@next/swc-linux-x64-gnu": "14.1.1-canary.61", + "@next/swc-linux-x64-musl": "14.1.1-canary.61", + "@next/swc-win32-arm64-msvc": "14.1.1-canary.61", + "@next/swc-win32-ia32-msvc": "14.1.1-canary.61", + "@next/swc-win32-x64-msvc": "14.1.1-canary.61" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -12191,11 +12191,11 @@ } }, "node_modules/shiki": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.3.tgz", - "integrity": "sha512-k/B4UvtWmGcHMLp6JnQminlex3Go5MHKXEiormmzTJECAiSQiwSon6USuwTyto8EMUQc9aYRJ7HojkfVLbBk+g==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.5.tgz", + "integrity": "sha512-754GuKIwkUdT810Xm8btuyNQPL+q3PqOkwGW/VlmAWyMYp+HbvvDt69sWXO1sm5aeczBJQjmQTTMR4GkKQNQPw==", "dependencies": { - "@shikijs/core": "1.1.3" + "@shikijs/core": "1.1.5" } }, "node_modules/side-channel": { diff --git a/package.json b/package.json index 6d8600d0..40318f41 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "rehype-pretty-code": "^0.13.0", "rehype-slug": "^6.0.0", "schema-dts": "^1.1.2", - "shiki": "^1.1.3", + "shiki": "^1.1.5", "valibot": "^0.28.1" }, "devDependencies": { From 659dde553b764a12768415c05bd554c0369e29dd Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Mon, 19 Feb 2024 09:37:12 +0800 Subject: [PATCH 62/87] ci(e2e): disable npm cache, since it doesn't work in `deployment_status` --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 3a334a59..3bf0b23b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 20.x - cache: 'npm' + # cache: 'npm' # currently npm cache doesn't work in deployment_status - run: npm ci - run: npx playwright install-deps webkit if: matrix.browser == 'webkit' From 08b040618eb67931e088f11ba612b0e27ae86acd Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Mon, 19 Feb 2024 09:47:12 +0800 Subject: [PATCH 63/87] ci(e2e): ensure other tests continue to run even if it fails on one of the browser --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 3bf0b23b..ced261da 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -8,6 +8,7 @@ jobs: strategy: matrix: browser: [chrome, edge, firefox, webkit] + fail-fast: false steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 From c1117de8d3032fac590ae564910220301272f1fa Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Mon, 19 Feb 2024 19:50:06 +0800 Subject: [PATCH 64/87] test(download-cy): refactor --- cypress/e2e/download-cv.cy.ts | 2 +- cypress/support/commands.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index 3a347af3..32c44b6f 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -8,7 +8,7 @@ describe('Download CV', () => { .should('have.attr', 'target', '_blank') .invoke('attr', 'href') .then((href) => { - void contentful.getAsset(cv).then((asset) => { + cy.wrap(contentful.getAsset(cv)).then((asset) => { expect(asset.fields.file?.contentType).to.equal('application/pdf'); expect(href).to.equal(`https:${asset.fields.file?.url}`); }); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 95857aea..0c538960 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-namespace -- Cypress extension */ +/* eslint-disable @typescript-eslint/method-signature-style -- this is how Cypress defined the interface and the extension should match that */ /// // *********************************************** // This example commands.ts shows you how to @@ -35,3 +37,20 @@ // } // } // } + +declare global { + namespace Cypress { + interface Chainable { + wrap( + element: E | JQuery, + options?: Partial, + ): Chainable>; + wrap( + object: S | Promise, + options?: Partial, + ): Chainable; + } + } +} + +export {}; From 8001a18c48a38d481a4b58acf8522f9250028847 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Mon, 19 Feb 2024 19:53:53 +0800 Subject: [PATCH 65/87] test(download-cv): validate the CV actually downloads --- cypress/e2e/download-cv.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index 32c44b6f..d96c312f 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -7,11 +7,12 @@ describe('Download CV', () => { cy.contains('Download CV') .should('have.attr', 'target', '_blank') .invoke('attr', 'href') - .then((href) => { + .then((href: string) => { cy.wrap(contentful.getAsset(cv)).then((asset) => { expect(asset.fields.file?.contentType).to.equal('application/pdf'); expect(href).to.equal(`https:${asset.fields.file?.url}`); }); + cy.request(href).its('isOkStatusCode'); }); }); }); From 95e870f1df82dba4dae4c826d91be29fb630fe2a Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Mon, 19 Feb 2024 20:08:38 +0800 Subject: [PATCH 66/87] test(download-cv): refactoring --- cypress/e2e/download-cv.cy.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index d96c312f..74adc66e 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -9,10 +9,11 @@ describe('Download CV', () => { .invoke('attr', 'href') .then((href: string) => { cy.wrap(contentful.getAsset(cv)).then((asset) => { - expect(asset.fields.file?.contentType).to.equal('application/pdf'); expect(href).to.equal(`https:${asset.fields.file?.url}`); }); - cy.request(href).its('isOkStatusCode'); + cy.request(href) + .its('headers') + .should('have.a.property', 'content-type', 'application/pdf'); }); }); }); From 67ff37f441525d500a1101b4a8360851d8f5506b Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Mon, 19 Feb 2024 20:22:04 +0800 Subject: [PATCH 67/87] feat: add `suppressHydrationWarning` to `html` --- app/layout.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/layout.tsx b/app/layout.tsx index 31872fc3..3311cb71 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -14,7 +14,8 @@ import { baseUrl } from '@/constants/site-config'; import { Providers } from './providers'; const RootLayout: FC = ({ children }) => ( - + // data-joy-color-scheme is dynamically injected, suppressing the hydration warning in this case + {children} From 5e9470b498708897dd3fa5ab1c10966970f13016 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 09:16:12 +0800 Subject: [PATCH 68/87] ci(e2e): runs on mac to omit installing webkit deps --- .github/workflows/e2e.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index ced261da..aa763ab7 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -4,7 +4,7 @@ on: deployment_status jobs: e2e: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' - runs-on: ubuntu-latest + runs-on: macos-latest strategy: matrix: browser: [chrome, edge, firefox, webkit] @@ -16,8 +16,6 @@ jobs: node-version: 20.x # cache: 'npm' # currently npm cache doesn't work in deployment_status - run: npm ci - - run: npx playwright install-deps webkit - if: matrix.browser == 'webkit' - uses: cypress-io/github-action@v6 with: install: false From c75e5c7245ae601644817d0f5bfcb9e68951c8e0 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 09:19:15 +0800 Subject: [PATCH 69/87] chore: Package update --- package-lock.json | 158 +++++++++++++++++++++++++--------------------- package.json | 6 +- 2 files changed, 88 insertions(+), 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index 25468971..6deb3fcc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,14 +19,14 @@ "@mui/styled-engine": "^5.15.9", "@prisma/client": "^5.9.1", "@prisma/extension-read-replicas": "^0.3.0", - "@vercel/analytics": "^1.2.0", + "@vercel/analytics": "^1.2.1", "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", "dayjs": "^1.11.10", "geist": "^1.2.2", "lodash-es": "^4.17.21", - "lucide-react": "^0.331.0", + "lucide-react": "^0.334.0", "merge-sx": "^2.0.0", "next": "canary", "next-mdx-remote": "^4.4.1", @@ -45,7 +45,7 @@ "@svgr/webpack": "^8.1.0", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.19", - "@types/react": "^18.2.56", + "@types/react": "^18.2.57", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", "cypress": "^13.6.4", @@ -2789,32 +2789,32 @@ } }, "node_modules/@next/bundle-analyzer": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.61.tgz", - "integrity": "sha512-kkwO4A3+g65tCM6Vl4ErQSP5WbaFUMYf4r7NvLaa7PJv8dmdfL74Z8bZxLkRLOoFx/Yasl55owlFUUB6q/TB+Q==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.62.tgz", + "integrity": "sha512-48zgNFndbpDrszAMLFoctf+8q6nC5/nFSt8wg8OVG/ZiamzLZacnQ1NfuODLSTq8JCsLk+lk+BWTStfOx27SXQ==", "dev": true, "dependencies": { "webpack-bundle-analyzer": "4.10.1" } }, "node_modules/@next/env": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.61.tgz", - "integrity": "sha512-vS5tg1qFIPyKGx7ZBDrOc7Iq2P2amhwTmlu/rzo99q5+5Gh0NvGmF4/vBw1PIP2WZAp8AqEwdL8klbW0wMmmJw==" + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.62.tgz", + "integrity": "sha512-lW88VAxTGm6VeXWxHGCHnTQ3ndF9onShjpMibJVqRNsG49AAzzrk4LKb0+ILLWimIuRo8kYtX9/WNJMvzoMxgg==" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.61.tgz", - "integrity": "sha512-0LkUpS2XwzVBd/5WyZp/vHanwDBj4ljL24yjfFM2VkB8x3/mEFlZjQrrPftDbAo/EDq5lSdCbUCxrepFP7iGwg==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.62.tgz", + "integrity": "sha512-IbeTBUgk3PlZT3IW7k3hOoSnD/8wTbNhmFsdV6LUIgCU2nVjfjuQeY8U1qyLYpkcnSFO5aCiOqzUidKJKgvflQ==", "dev": true, "dependencies": { "glob": "10.3.10" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.61.tgz", - "integrity": "sha512-Di/e/vfAbI8Ae2Wxuu2DZh2JBj5+DC8pl5C0XACO0Iu7j0qlUsNStk2SMFVfZpIANT0mF6Lz5T3ycaG86oUFSA==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.62.tgz", + "integrity": "sha512-o8yJK9TmweAP9tGm6sLyWD0sSB+n+3thRiHD0Chm+tsJN9vjHhACj11O6UIgPLI7vu+bbBPt3xrU+4wxIYexUQ==", "cpu": [ "arm64" ], @@ -2827,9 +2827,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.61.tgz", - "integrity": "sha512-EeT1cMyW+cECRVWkV1i26iPG+1EFToaL473YLUU/Q2EKSXQVw0T0F5pwIpZcSr+ecSvYYGbEdw2xdgGgNlqyDg==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.62.tgz", + "integrity": "sha512-R7/opKdbsm1du+LnFNgJPYLvguMMlOF3R0d7xAurAg7MBUwWUh2f50tHcTDrVzNbdZEhk1jhlcmS/lrCxv3uYA==", "cpu": [ "x64" ], @@ -2842,9 +2842,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.61.tgz", - "integrity": "sha512-LArfX7VejoNhxAeu0prjnyFJaJBpsaVxL7SOu6PVwnrP6dvmDI/cNFraoJ28yzsfBXI9swYdtRLUD7rEOJSftQ==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.62.tgz", + "integrity": "sha512-hKysZWKQ5uuUcxhJafPJFfFz/6nrH2t6fAZfxV4skB+FxikMLUNMETeu6A2gRtXwHhqttlinD2BNlxHlEx5UoQ==", "cpu": [ "arm64" ], @@ -2857,9 +2857,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.61.tgz", - "integrity": "sha512-uJnXfyKNcNXgT2XCX3wIF1b/P58HK7V/+WlY0bUss3tVHdaMtvia/WZYDe60LzNsmQJEtQXoBtVw0Y+YIxyBVg==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.62.tgz", + "integrity": "sha512-2nVWU4ihwVypYltvukvRXuoH2Y8l38etaOdwmN1LcllKJ5Hu1DmXDFq2bmFML6q6HBs9LsX0YEHxfeVLd6pLXg==", "cpu": [ "arm64" ], @@ -2872,9 +2872,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.61.tgz", - "integrity": "sha512-Nik6CNMgt57et+2dqhOCQHZGmMQ0ju0sWu4O19y0XsfJnyhzQD7FYXuT+3jIZ9fiwdBNSEAyyZ4vUDqEFLdO3w==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.62.tgz", + "integrity": "sha512-SFqP1ZVUQqWmdX3PtNgel62sffV5wZHbtW/J4E4P/QrBaNbGQlziw34tFvlssjOGRG3ZzuDGCgqtVr0l4/QvfQ==", "cpu": [ "x64" ], @@ -2887,9 +2887,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.61.tgz", - "integrity": "sha512-dirPIeN0So3WLOBmfjfGL4lwpZbEHf8Ez2M5U0tZ75ZWF4xd5sKXLJDBlZ/1YBDH9RI7yivqbT4Rr5QN/W3V1w==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.62.tgz", + "integrity": "sha512-adlHzPGxVc9PuorODAWLPZtjjrJVFIEmMAVvwLJy9vz4T/c+CrTfgWxUy+uIx5Xr+zw0GU3+E4D0FqqTKS6FDw==", "cpu": [ "x64" ], @@ -2902,9 +2902,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.61.tgz", - "integrity": "sha512-akv1zuBx286ZF1t1qmB8HMftZUvry+1g2JmpkVbvmuOq50MaGxFPdKsDZOnTrmvLezGrQV12JxC8CUwcBpZKLw==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.62.tgz", + "integrity": "sha512-gm5GnQz9I2yWst7RZqHf5frtfmjp+SP+FRzuTbCwWo04vOZqt/nrDOFha3O8VHfH/H+R1mECV6MiCR3vW64S/g==", "cpu": [ "arm64" ], @@ -2917,9 +2917,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.61.tgz", - "integrity": "sha512-heJt1MdizMmD1U2XzcolDaEaBg5SyHlA6+A0PSdVGvO3/PgA33YvxU48umlGwF0OQKIoeqj0d2m8vXdJGvLkZA==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.62.tgz", + "integrity": "sha512-zB/UXYimoYSmqAq3o4EH4vOFeAFaXdrwqpt7ptow2kLRt2w3hahp6dd4om/qhopd2fraezxdMxvuUoKKDCtzXw==", "cpu": [ "ia32" ], @@ -2932,9 +2932,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.61.tgz", - "integrity": "sha512-5AhTzPf1Xn2j8OoAexC2LmDt4x1h5pCB8gjeZ8jYxm6Z8pSOUtowsrOFmqbZpxWHKMTTjM1LbzIcY0AYo+O+bA==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.62.tgz", + "integrity": "sha512-wjDYA9PiricK8de+/xWQUc6q29KfA9sLUcxWfMzQQqBWKkx4AZsKJpQla8mf4ueJFKiWyy5wSjpUUqtQYObk4Q==", "cpu": [ "x64" ], @@ -3507,9 +3507,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "18.2.56", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.56.tgz", - "integrity": "sha512-NpwHDMkS/EFZF2dONFQHgkPRwhvgq/OAvIaGQzxGSBmaeR++kTg6njr15Vatz0/2VcCEwJQFi6Jf4Q0qBu0rLA==", + "version": "18.2.57", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.57.tgz", + "integrity": "sha512-ZvQsktJgSYrQiMirAN60y4O/LRevIV8hUzSOSNB6gfR3/o3wCBFQx3sPwIYtuDMeiVgsSS3UzCV26tEzgnfvQw==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3871,9 +3871,9 @@ "dev": true }, "node_modules/@vercel/analytics": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.0.tgz", - "integrity": "sha512-Q9hduY6+i73Is1m57Y3OlawleeYVi4cvuh/0j6IwmSndMOE4+BKkMwjnwz+7xnqfZCanipIG6+q+zHalH9X0Zg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.1.tgz", + "integrity": "sha512-ZB5gDPCQvHu0DcBbywIwMm5aY9mTV8mBl7Mmk8QD84JqBnuYbsNCDnnDuzblNjd82tDtRjAqruZ0mzNm6MAWpA==", "dependencies": { "server-only": "^0.0.1" }, @@ -4351,10 +4351,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", - "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -5639,9 +5642,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==", + "version": "1.4.675", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.675.tgz", + "integrity": "sha512-+1u3F/XPNIdUwv8i1lDxHAxCvNNU0QIqgb1Ycn+Jnng8ITzWSvUqixRSM7NOazJuwhf65IV17f/VbKj8DmL26A==", "dev": true }, "node_modules/emoji-regex": { @@ -7724,9 +7727,9 @@ } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "engines": { "node": ">= 0.4" }, @@ -8447,9 +8450,9 @@ } }, "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==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -9290,9 +9293,9 @@ } }, "node_modules/lucide-react": { - "version": "0.331.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.331.0.tgz", - "integrity": "sha512-CHFJ0ve9vaZ7bB2VRAl27SlX1ELh6pfNC0jS96qGpPEEzLkLDGq4pDBFU8RhOoRMqsjXqTzLm9U6bZ1OcIHq7Q==", + "version": "0.334.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.334.0.tgz", + "integrity": "sha512-y0Rv/Xx6qAq4FutZ3L/efl3O9vl6NC/1p0YOg6mBfRbQ4k1JCE2rz0rnV7WC8Moxq1RY99vLATvjcqUegGJTvA==", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } @@ -10267,11 +10270,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.1-canary.61", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.61.tgz", - "integrity": "sha512-QMePsaNHDLX3nBi05+2im7fLn/AWq6BYP7quQVqUI3zr+C6rkhr5Zs6+K+9JILh7y7Vdgb6Ajohj6SJfvfy8DQ==", + "version": "14.1.1-canary.62", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.62.tgz", + "integrity": "sha512-Qjb/nzmExeYmpOLnrR8LKJo8v9X2H7iWfPhS7fHPxpYC+Aj/XrbWplH6YllMaJR/VHRKeeXDqWEvCqr+q4+8zQ==", "dependencies": { - "@next/env": "14.1.1-canary.61", + "@next/env": "14.1.1-canary.62", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -10286,15 +10289,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.1-canary.61", - "@next/swc-darwin-x64": "14.1.1-canary.61", - "@next/swc-linux-arm64-gnu": "14.1.1-canary.61", - "@next/swc-linux-arm64-musl": "14.1.1-canary.61", - "@next/swc-linux-x64-gnu": "14.1.1-canary.61", - "@next/swc-linux-x64-musl": "14.1.1-canary.61", - "@next/swc-win32-arm64-msvc": "14.1.1-canary.61", - "@next/swc-win32-ia32-msvc": "14.1.1-canary.61", - "@next/swc-win32-x64-msvc": "14.1.1-canary.61" + "@next/swc-darwin-arm64": "14.1.1-canary.62", + "@next/swc-darwin-x64": "14.1.1-canary.62", + "@next/swc-linux-arm64-gnu": "14.1.1-canary.62", + "@next/swc-linux-arm64-musl": "14.1.1-canary.62", + "@next/swc-linux-x64-gnu": "14.1.1-canary.62", + "@next/swc-linux-x64-musl": "14.1.1-canary.62", + "@next/swc-win32-arm64-msvc": "14.1.1-canary.62", + "@next/swc-win32-ia32-msvc": "14.1.1-canary.62", + "@next/swc-win32-x64-msvc": "14.1.1-canary.62" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -11075,6 +11078,15 @@ "node": ">=4" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", diff --git a/package.json b/package.json index 40318f41..ae26dd5d 100644 --- a/package.json +++ b/package.json @@ -26,14 +26,14 @@ "@mui/styled-engine": "^5.15.9", "@prisma/client": "^5.9.1", "@prisma/extension-read-replicas": "^0.3.0", - "@vercel/analytics": "^1.2.0", + "@vercel/analytics": "^1.2.1", "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", "dayjs": "^1.11.10", "geist": "^1.2.2", "lodash-es": "^4.17.21", - "lucide-react": "^0.331.0", + "lucide-react": "^0.334.0", "merge-sx": "^2.0.0", "next": "canary", "next-mdx-remote": "^4.4.1", @@ -52,7 +52,7 @@ "@svgr/webpack": "^8.1.0", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.19", - "@types/react": "^18.2.56", + "@types/react": "^18.2.57", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", "cypress": "^13.6.4", From 0c1431ad8d32419e4b665b66c67d6cde91b2c1c6 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 09:25:32 +0800 Subject: [PATCH 70/87] feat: ensure the entire site is blocking bots --- app/robots.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/robots.ts b/app/robots.ts index 491881d6..a42372ae 100644 --- a/app/robots.ts +++ b/app/robots.ts @@ -6,7 +6,7 @@ const robots = () => ({ rules: { userAgent: '*', - allow: '/', + disallow: process.env.VERCEL_ENV === 'production' ? undefined : '/', }, sitemap: `${baseUrl}/sitemap.xml`, }) satisfies MetadataRoute.Robots; From 7fcd875166ba3889d384c58f97aa1edd8087fcb1 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 09:43:55 +0800 Subject: [PATCH 71/87] ci: cache Cypress binary and minor changes --- .github/workflows/e2e.yml | 10 ++++++++-- .github/workflows/lint.yml | 5 +++-- .github/workflows/prettify.yml | 5 +++-- .github/workflows/unlighthouse.yml | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index aa763ab7..facb9a8d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -11,11 +11,17 @@ jobs: fail-fast: false steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - name: Use Node.js 20 + uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 20 # cache: 'npm' # currently npm cache doesn't work in deployment_status - run: npm ci + - name: Cache Cypress binary + uses: actions/cache@v4 + with: + path: ~/.cache/Cypress + key: cypress-${{ runner.os }}-cypress-${{ hashFiles('**/package-lock.json') }} - uses: cypress-io/github-action@v6 with: install: false diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1a2f2448..cfc189e6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,9 +6,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - name: Use Node.js 20 + uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 20 cache: 'npm' - run: npm ci - run: npx next lint diff --git a/.github/workflows/prettify.yml b/.github/workflows/prettify.yml index 62cdaece..cdfcdacd 100644 --- a/.github/workflows/prettify.yml +++ b/.github/workflows/prettify.yml @@ -6,9 +6,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - name: Use Node.js 20 + uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 20 cache: 'npm' - run: npm ci - run: npx prettier . --check diff --git a/.github/workflows/unlighthouse.yml b/.github/workflows/unlighthouse.yml index 3b9a23ae..6198f31c 100644 --- a/.github/workflows/unlighthouse.yml +++ b/.github/workflows/unlighthouse.yml @@ -17,4 +17,4 @@ jobs: - uses: actions/upload-artifact@v4 if: always() with: - path: .unlighthouse + path: ./.unlighthouse From 689d9aef70cd2d0e453bad1abbdf1aef041e0589 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 09:47:40 +0800 Subject: [PATCH 72/87] ci(e2e): simplify workflow --- .github/workflows/e2e.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index facb9a8d..6504a7fe 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -11,20 +11,8 @@ jobs: fail-fast: false steps: - uses: actions/checkout@v4 - - name: Use Node.js 20 - uses: actions/setup-node@v4 - with: - node-version: 20 - # cache: 'npm' # currently npm cache doesn't work in deployment_status - - run: npm ci - - name: Cache Cypress binary - uses: actions/cache@v4 - with: - path: ~/.cache/Cypress - key: cypress-${{ runner.os }}-cypress-${{ hashFiles('**/package-lock.json') }} - uses: cypress-io/github-action@v6 with: - install: false browser: ${{ matrix.browser }} env: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} From 3aea788042dafa5ed60989b3fc41843c03a712e9 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 10:01:15 +0800 Subject: [PATCH 73/87] Revert "ci(e2e): simplify workflow" This reverts commit d0739d511e40d350bc09ec6848ea9850faa6fec3. --- .github/workflows/e2e.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 6504a7fe..facb9a8d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -11,8 +11,20 @@ jobs: fail-fast: false steps: - uses: actions/checkout@v4 + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + # cache: 'npm' # currently npm cache doesn't work in deployment_status + - run: npm ci + - name: Cache Cypress binary + uses: actions/cache@v4 + with: + path: ~/.cache/Cypress + key: cypress-${{ runner.os }}-cypress-${{ hashFiles('**/package-lock.json') }} - uses: cypress-io/github-action@v6 with: + install: false browser: ${{ matrix.browser }} env: CYPRESS_BASE_URL: ${{ github.event.deployment_status.environment_url }} From 985ede723682d1bf512a9c023481103960153838 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 10:04:00 +0800 Subject: [PATCH 74/87] Revert "ci(e2e): runs on mac to omit installing webkit deps" This reverts commit a74f43898f30084c42c7d7e2a777fb0bbc8cdec6. --- .github/workflows/e2e.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index facb9a8d..b6ed18d1 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -4,7 +4,7 @@ on: deployment_status jobs: e2e: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' - runs-on: macos-latest + runs-on: ubuntu-latest strategy: matrix: browser: [chrome, edge, firefox, webkit] @@ -22,6 +22,8 @@ jobs: with: path: ~/.cache/Cypress key: cypress-${{ runner.os }}-cypress-${{ hashFiles('**/package-lock.json') }} + - run: npx playwright install-deps webkit + if: matrix.browser == 'webkit' - uses: cypress-io/github-action@v6 with: install: false From 369524b172422af57524ad2e8596303c1e7ccce2 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 10:06:03 +0800 Subject: [PATCH 75/87] ci(e2e): remove Cypress binary cache since it is not supported in deployment_status --- .github/workflows/e2e.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index b6ed18d1..b735430b 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -17,11 +17,6 @@ jobs: node-version: 20 # cache: 'npm' # currently npm cache doesn't work in deployment_status - run: npm ci - - name: Cache Cypress binary - uses: actions/cache@v4 - with: - path: ~/.cache/Cypress - key: cypress-${{ runner.os }}-cypress-${{ hashFiles('**/package-lock.json') }} - run: npx playwright install-deps webkit if: matrix.browser == 'webkit' - uses: cypress-io/github-action@v6 From b5ba85ff2a15469161fd0f1c47ecea2ac53c6252 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 22:52:13 +0800 Subject: [PATCH 76/87] test: use nav constant --- cypress/e2e/color-mode.cy.ts | 3 ++- cypress/e2e/download-cv.cy.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/color-mode.cy.ts b/cypress/e2e/color-mode.cy.ts index 8491bb48..d79c098a 100644 --- a/cypress/e2e/color-mode.cy.ts +++ b/cypress/e2e/color-mode.cy.ts @@ -1,4 +1,5 @@ import { colors } from '../fixtures/colors'; +import { home } from '../fixtures/nav'; describe('Color mode', () => { const expectColorMode = (colorMode: 'dark' | 'light') => { @@ -8,7 +9,7 @@ describe('Color mode', () => { .and('have.css', 'color', colors[colorMode].color); }; - beforeEach(() => cy.visit('/')); + beforeEach(() => cy.visit(home.pathname)); it('default is light mode', () => expectColorMode('light')); diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index 74adc66e..0a38a003 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -1,9 +1,10 @@ import { cv } from '../fixtures/contentful-ids'; +import { home } from '../fixtures/nav'; import { contentful } from '../support/clients'; describe('Download CV', () => { it('should download CV', () => { - cy.visit('/'); + cy.visit(home.pathname); cy.contains('Download CV') .should('have.attr', 'target', '_blank') .invoke('attr', 'href') From adaa46d14a58b352b9a0e432e38f566d23dcc447 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 22:54:53 +0800 Subject: [PATCH 77/87] test: add linkedin --- cypress/e2e/linkedin.cy.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 cypress/e2e/linkedin.cy.ts diff --git a/cypress/e2e/linkedin.cy.ts b/cypress/e2e/linkedin.cy.ts new file mode 100644 index 00000000..57627748 --- /dev/null +++ b/cypress/e2e/linkedin.cy.ts @@ -0,0 +1,11 @@ +import { home } from '../fixtures/nav'; +import { linkedin } from '../fixtures/platform-profiles'; + +describe('LinkedIn', () => { + it('should links to my LinkedIn profile', () => { + cy.visit(home.pathname); + cy.contains('LinkedIn') + .should('have.attr', 'target', '_blank') + .and('have.attr', 'href', linkedin); + }); +}); From 31858b8702bf18d702028599015af6dcb3fb8bf8 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Tue, 20 Feb 2024 23:50:29 +0800 Subject: [PATCH 78/87] test: add incomplete skill set test --- components/home/about.tsx | 8 +-- components/home/skill-set.tsx | 23 ++++----- cypress.config.mjs | 1 + cypress/e2e/navigation.cy.ts | 6 +-- cypress/e2e/skill-set.cy.ts | 80 ++++++++++++++++++++++++++++++ cypress/fixtures/contentful-ids.ts | 11 ++++ cypress/support/types.ts | 19 +++++++ lib/queries.ts | 2 +- 8 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 cypress/e2e/skill-set.cy.ts create mode 100644 cypress/support/types.ts diff --git a/components/home/about.tsx b/components/home/about.tsx index b0079a5f..0be101dc 100644 --- a/components/home/about.tsx +++ b/components/home/about.tsx @@ -3,7 +3,7 @@ import { FC } from 'react'; import { firstName, lastName, selfIntroduction } from '@/constants/content'; import { about } from '@/constants/nav'; -import { getPersonalPhoto, getSkillCategories } from '@/lib/queries'; +import { getPersonalPhoto, getSkillSet } from '@/lib/queries'; import { Image } from '../image'; @@ -11,9 +11,9 @@ import { SkillSet } from './skill-set'; export type AboutProps = Omit, 'children'>; export const About: FC = async (props) => { - const [personalPhoto, skillCategories] = await Promise.all([ + const [personalPhoto, skillSet] = await Promise.all([ getPersonalPhoto(), - getSkillCategories(), + getSkillSet(), ]); return ( @@ -42,7 +42,7 @@ export const About: FC = async (props) => { {selfIntroduction} - + diff --git a/components/home/skill-set.tsx b/components/home/skill-set.tsx index ccd2d19e..0f79c45d 100644 --- a/components/home/skill-set.tsx +++ b/components/home/skill-set.tsx @@ -16,22 +16,19 @@ import { FC, useDeferredValue, useMemo, useState } from 'react'; import { Icon } from '../contentful'; export interface SkillSetProps extends Omit { - skillCategories?: { + skillSet?: { id: string; name?: string; skills: { name?: string; proficiency?: number; url?: string }[]; }[]; } -export const SkillSet: FC = ({ - skillCategories = [], - ...props -}) => { +export const SkillSet: FC = ({ skillSet = [], ...props }) => { const [proficiency, setProficiency] = useState<[number, number]>([1, 5]); const deferredProficiency = useDeferredValue(proficiency); - const filteredSkillCategories = useMemo( + const filteredSkillSet = useMemo( () => - skillCategories + skillSet .map(({ skills, ...category }) => ({ ...category, skills: skills.filter( @@ -41,11 +38,11 @@ export const SkillSet: FC = ({ ), })) .filter(({ skills }) => skills.length > 0), - [deferredProficiency, skillCategories], + [deferredProficiency, skillSet], ); return ( - + Skill Proficiency = ({ '& > *': { breakInside: 'avoid', mb: 4 }, }} > - {filteredSkillCategories.map(({ id, name, skills }) => ( - + {filteredSkillSet.map(({ id, name, skills }) => ( + = ({ - {name} + + {name} + {skills.map(({ name, url }) => ( { .find('svg') .contains('title', iconTitle) .parents('a') - .as('link'); - - cy.get('@link').should('have.attr', 'href', url); - cy.get('@link').should('have.attr', 'target', '_blank'); + .should('have.attr', 'target', '_blank') + .and('have.attr', 'href', url); }); }); } diff --git a/cypress/e2e/skill-set.cy.ts b/cypress/e2e/skill-set.cy.ts new file mode 100644 index 00000000..a5738570 --- /dev/null +++ b/cypress/e2e/skill-set.cy.ts @@ -0,0 +1,80 @@ +import { about } from '../fixtures/nav'; +import { contentful } from '../support/clients'; +import { SkillCategorySkeleton, SkillSkeleton } from '../support/types'; + +const getSkillSet = async () => { + const [{ items: skills }, { items: skillCategories }] = await Promise.all([ + contentful.getEntries({ + content_type: 'skill', + 'fields.category[exists]': true, + order: ['-fields.proficiency', 'fields.name'], + }), + contentful.getEntries({ + content_type: 'skillCategory', + order: ['-fields.proficiency', 'fields.name'], + }), + ]); + + return skillCategories.map((skillCategory) => ({ + id: skillCategory.sys.id, + name: skillCategory.fields.name, + skills: skills + .filter((skill) => skill.fields.category?.sys.id === skillCategory.sys.id) + .map((skill) => ({ + name: skill.fields.name, + proficiency: skill.fields.proficiency, + url: skill.fields.url, + })), + })); +}; + +type SkillSet = Awaited>; + +describe('Skill Set', () => { + beforeEach(() => { + cy.visit(`${about.pathname}#${about.id}`); + cy.wrap(getSkillSet()).as('skillSet'); + cy.get('[data-cy="skill-set"]').as('skillSetElem'); + }); + + it('displays the entire skill set with the skill category name as the title and skills listed out', () => { + cy.get('@skillSet').then((skillSet) => { + for (const { id, name, skills } of skillSet) { + cy.get('@skillSetElem') + .get(`[data-cy=${id}]`) + .within(() => { + cy.get('[data-cy="title"]').contains(name).should('be.visible'); + for (const { name } of skills) { + cy.contains(name).should('be.visible'); + } + }); + } + }); + }); + + describe('Skills', () => { + it('displays the skill name and links to the corresponding webpage', () => { + cy.get('@skillSet').then((skillSet) => { + for (const { id, skills } of skillSet) { + cy.get('@skillSetElem') + .get(`[data-cy=${id}]`) + .within(() => { + for (const { name, url } of skills) { + cy.contains(name).parent().as('chip'); + if (url) { + cy.get('@chip') + .find('a') + .should('have.attr', 'target', '_blank') + .and('have.attr', 'href', url); + } else { + cy.get('@chip').find('a').should('not.exist'); + } + } + }); + } + }); + }); + }); + + // TODO: test for filter by proficiency +}); diff --git a/cypress/fixtures/contentful-ids.ts b/cypress/fixtures/contentful-ids.ts index b049e7a8..a2db8d07 100644 --- a/cypress/fixtures/contentful-ids.ts +++ b/cypress/fixtures/contentful-ids.ts @@ -1 +1,12 @@ export const cv = '6mTh13ou7wM2Cs7ZC1tcdn'; + +export const backend = '2FtEFXEYpFad3n0eE4CNyF'; +export const cms = '6RuL6dXWQqCMYjaLuA14A4'; +export const database = '1ga6JyLWtemRU5cf9oTOQa'; +export const devOps = '9zrJS3ggkoVadUxZTvwyc'; +export const frontend = '3sdnCkE0j79D4kRSGuUjhp'; +export const machineLearning = '4nOEnXVl1fCJGetHGVnsZ8'; +export const mobile = '3biweEjbkRyZaII8ZgkQhI'; +export const qa = '119H1LBXMmT8xLTdnAq1PS'; +export const monitoring = '632XHEYS6JH9L1l61PHQLx'; +export const toolsAndPlatforms = '49VijdvfwgdRLADfqZ3vTk'; diff --git a/cypress/support/types.ts b/cypress/support/types.ts new file mode 100644 index 00000000..a4f1fc98 --- /dev/null +++ b/cypress/support/types.ts @@ -0,0 +1,19 @@ +import { EntryFieldTypes } from 'contentful'; + +export interface SkillSkeleton { + contentTypeId: 'skill'; + fields: { + name: EntryFieldTypes.Symbol; + category?: EntryFieldTypes.EntryLink; + proficiency: EntryFieldTypes.Integer; + url?: EntryFieldTypes.Symbol; + }; +} + +export interface SkillCategorySkeleton { + contentTypeId: 'skillCategory'; + fields: { + name: EntryFieldTypes.Symbol; + proficiency?: EntryFieldTypes.Integer; + }; +} diff --git a/lib/queries.ts b/lib/queries.ts index 2765cb81..45e0ac1c 100644 --- a/lib/queries.ts +++ b/lib/queries.ts @@ -226,7 +226,7 @@ export const getPlatformProfiles = cache(async () => { return orderBy(platformProfiles, 'platform.name'); }); -export const getSkillCategories = cache(async () => { +export const getSkillSet = cache(async () => { const [{ items: skills }, { items: skillCategories }] = await Promise.all([ contentful.getEntries({ content_type: 'skill', From b1c1b429bc8971fa5adec51cf0a7fc096615a53a Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 09:18:15 +0800 Subject: [PATCH 79/87] chore: Package update --- package-lock.json | 289 ++++++++++++++++++++++++---------------------- package.json | 14 +-- 2 files changed, 155 insertions(+), 148 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6deb3fcc..4cb89d5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,16 +17,16 @@ "@mui/base": "5.0.0-beta.36", "@mui/joy": "5.0.0-beta.28", "@mui/styled-engine": "^5.15.9", - "@prisma/client": "^5.9.1", + "@prisma/client": "^5.10.1", "@prisma/extension-read-replicas": "^0.3.0", - "@vercel/analytics": "^1.2.1", + "@vercel/analytics": "^1.2.2", "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", "dayjs": "^1.11.10", "geist": "^1.2.2", "lodash-es": "^4.17.21", - "lucide-react": "^0.334.0", + "lucide-react": "^0.335.0", "merge-sx": "^2.0.0", "next": "canary", "next-mdx-remote": "^4.4.1", @@ -36,8 +36,8 @@ "rehype-pretty-code": "^0.13.0", "rehype-slug": "^6.0.0", "schema-dts": "^1.1.2", - "shiki": "^1.1.5", - "valibot": "^0.28.1" + "shiki": "^1.1.6", + "valibot": "^0.29.0" }, "devDependencies": { "@next/bundle-analyzer": "canary", @@ -48,7 +48,7 @@ "@types/react": "^18.2.57", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", - "cypress": "^13.6.4", + "cypress": "^13.6.5", "dotenv-cli": "^7.3.0", "eslint": "^8.56.0", "eslint-plugin-cypress": "^2.15.1", @@ -56,7 +56,7 @@ "playwright-webkit": "^1.41.2", "prettier": "^3.2.5", "prettier-plugin-prisma": "^5.0.0", - "prisma": "^5.9.1", + "prisma": "^5.10.1", "type-fest": "^4.10.2", "typescript": "^5.3.3" } @@ -2789,32 +2789,32 @@ } }, "node_modules/@next/bundle-analyzer": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.62.tgz", - "integrity": "sha512-48zgNFndbpDrszAMLFoctf+8q6nC5/nFSt8wg8OVG/ZiamzLZacnQ1NfuODLSTq8JCsLk+lk+BWTStfOx27SXQ==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.1.1-canary.65.tgz", + "integrity": "sha512-+pKNYzmU9uRjXrpNckkD37hO7q8ej6IiXgTYPUgnfgDIr+hMyaU35SflT8pCbBCND7k5oFgUhszPkjmviR689A==", "dev": true, "dependencies": { "webpack-bundle-analyzer": "4.10.1" } }, "node_modules/@next/env": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.62.tgz", - "integrity": "sha512-lW88VAxTGm6VeXWxHGCHnTQ3ndF9onShjpMibJVqRNsG49AAzzrk4LKb0+ILLWimIuRo8kYtX9/WNJMvzoMxgg==" + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.1-canary.65.tgz", + "integrity": "sha512-dRDptxh4OuL8IcaHVCC4J2WhBxvW1yIL3McqlVG6/oZc0ixUWOomVh8h2I1EkjXVxfkfn+J6FBxEAMcyJgOk1g==" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.62.tgz", - "integrity": "sha512-IbeTBUgk3PlZT3IW7k3hOoSnD/8wTbNhmFsdV6LUIgCU2nVjfjuQeY8U1qyLYpkcnSFO5aCiOqzUidKJKgvflQ==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.1-canary.65.tgz", + "integrity": "sha512-+B91sMrbGIwfWGQTuF0o7hJIrMP/260ILiv3HBA/UIUWoO7jooqqy446PbYy1j+4hCZROcprilJIk2xuQ2QWAQ==", "dev": true, "dependencies": { "glob": "10.3.10" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.62.tgz", - "integrity": "sha512-o8yJK9TmweAP9tGm6sLyWD0sSB+n+3thRiHD0Chm+tsJN9vjHhACj11O6UIgPLI7vu+bbBPt3xrU+4wxIYexUQ==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.1-canary.65.tgz", + "integrity": "sha512-aGW1TR4Qzn8AEo5EZO46COIIvo22F7bCQc2UX2Qc5eEuzVMbVnzzlySDPQT8MtnQ1cQZVMLcN2KA1RE/hJ3Niw==", "cpu": [ "arm64" ], @@ -2827,9 +2827,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.62.tgz", - "integrity": "sha512-R7/opKdbsm1du+LnFNgJPYLvguMMlOF3R0d7xAurAg7MBUwWUh2f50tHcTDrVzNbdZEhk1jhlcmS/lrCxv3uYA==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.1-canary.65.tgz", + "integrity": "sha512-IRNh80ojRTZVlUjUY7EnIcyynotMtT6karQmMrGjjniewledfI5RTIkpWjjD5AAXKCZTIV7rgZshzTk94ZeDTg==", "cpu": [ "x64" ], @@ -2842,9 +2842,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.62.tgz", - "integrity": "sha512-hKysZWKQ5uuUcxhJafPJFfFz/6nrH2t6fAZfxV4skB+FxikMLUNMETeu6A2gRtXwHhqttlinD2BNlxHlEx5UoQ==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.1-canary.65.tgz", + "integrity": "sha512-FjV0hXX1xwsZmsw4vcOHPdl2QW+7QkRYXbcY3L6CuFxa/8uFxaiRdWiTIdNjzIv6x25Xhe2f66SeibzXuH2koQ==", "cpu": [ "arm64" ], @@ -2857,9 +2857,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.62.tgz", - "integrity": "sha512-2nVWU4ihwVypYltvukvRXuoH2Y8l38etaOdwmN1LcllKJ5Hu1DmXDFq2bmFML6q6HBs9LsX0YEHxfeVLd6pLXg==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.1-canary.65.tgz", + "integrity": "sha512-0Vpl0fNj2LIkVIY9ZPyNuuX7KSwhbDQkgoMoi1kxSU91JDuUU6t0HNGmF/YwAgBWU5bmOg6Kpob9vBn8cHlHiA==", "cpu": [ "arm64" ], @@ -2872,9 +2872,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.62.tgz", - "integrity": "sha512-SFqP1ZVUQqWmdX3PtNgel62sffV5wZHbtW/J4E4P/QrBaNbGQlziw34tFvlssjOGRG3ZzuDGCgqtVr0l4/QvfQ==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.1-canary.65.tgz", + "integrity": "sha512-pIbXT6ENh0bfABGLpmFZgDmJrAjg9dSq3gj7ze91OpsDPl1S9K7MVl67y9p+emcC42DKdvhxXHMnfKqmPt/3jg==", "cpu": [ "x64" ], @@ -2887,9 +2887,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.62.tgz", - "integrity": "sha512-adlHzPGxVc9PuorODAWLPZtjjrJVFIEmMAVvwLJy9vz4T/c+CrTfgWxUy+uIx5Xr+zw0GU3+E4D0FqqTKS6FDw==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.1-canary.65.tgz", + "integrity": "sha512-Q3HdTQ0FiABW3gaMJkTEaUPCzkjbyr7phDWpcVOv3zwuqjQhoOCSgZmqjnHdTHSIQdGwMB6y2bGzXgXaoA/aTw==", "cpu": [ "x64" ], @@ -2902,9 +2902,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.62.tgz", - "integrity": "sha512-gm5GnQz9I2yWst7RZqHf5frtfmjp+SP+FRzuTbCwWo04vOZqt/nrDOFha3O8VHfH/H+R1mECV6MiCR3vW64S/g==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.1-canary.65.tgz", + "integrity": "sha512-szCer+XtV8dkjri/6UEMLw7AUSNePhaewWraEYN5r9ba8I9EI32KYNlhEfdH6iL8Uc3h42jRenaB8XaKlcoYSA==", "cpu": [ "arm64" ], @@ -2917,9 +2917,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.62.tgz", - "integrity": "sha512-zB/UXYimoYSmqAq3o4EH4vOFeAFaXdrwqpt7ptow2kLRt2w3hahp6dd4om/qhopd2fraezxdMxvuUoKKDCtzXw==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.1-canary.65.tgz", + "integrity": "sha512-Jhfgw+KoP7LppzCPPZ1p/p//mofbRFBrL2Zd460bmJToUe9VZX5CoCa2shYSe6J4qf/N6Apf0n6FiRnTRjghmQ==", "cpu": [ "ia32" ], @@ -2932,9 +2932,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.62.tgz", - "integrity": "sha512-wjDYA9PiricK8de+/xWQUc6q29KfA9sLUcxWfMzQQqBWKkx4AZsKJpQla8mf4ueJFKiWyy5wSjpUUqtQYObk4Q==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.1-canary.65.tgz", + "integrity": "sha512-4X/zI49OoFFquw193Fho+weFwRQaXOA9IaMecg7awnOHma4nVzAl/ANAOFEkp5qJzGUSvL1qKBJpmkmstq8roQ==", "cpu": [ "x64" ], @@ -3028,9 +3028,9 @@ } }, "node_modules/@prisma/client": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.9.1.tgz", - "integrity": "sha512-caSOnG4kxcSkhqC/2ShV7rEoWwd3XrftokxJqOCMVvia4NYV/TPtJlS9C2os3Igxw/Qyxumj9GBQzcStzECvtQ==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.10.1.tgz", + "integrity": "sha512-4R8Vp6sSwVJSnOxw8WU1WSLqE/G3WJy1xA05XvW87cINoB1hEY7endw5Ppy6TrIBCCtHQim2lqfHkbPvv+i7bQ==", "hasInstallScript": true, "engines": { "node": ">=16.13" @@ -3045,28 +3045,28 @@ } }, "node_modules/@prisma/debug": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.9.1.tgz", - "integrity": "sha512-yAHFSFCg8KVoL0oRUno3m60GAjsUKYUDkQ+9BA2X2JfVR3kRVSJFc/GpQ2fSORi4pSHZR9orfM4UC9OVXIFFTA==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.10.1.tgz", + "integrity": "sha512-Ipo9y/lCMzedXMtEBe4YCdvVVivSy6MdG7aYTM15t86g4CRzwdlEsw8Czxnw20w9Qgzdx0MX2iLsCCIG4JoHbA==", "dev": true }, "node_modules/@prisma/engines": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.9.1.tgz", - "integrity": "sha512-gkdXmjxQ5jktxWNdDA5aZZ6R8rH74JkoKq6LD5mACSvxd2vbqWeWIOV0Py5wFC8vofOYShbt6XUeCIUmrOzOnQ==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.10.1.tgz", + "integrity": "sha512-75oJa900Pw+GAXjPJmKZqsD7bgSgQbpeGLxCwchrbgPIM70y3h0FbjIsiSAjuhwIGUCCNWzctUNv67rvSmoQAQ==", "dev": true, "hasInstallScript": true, "dependencies": { - "@prisma/debug": "5.9.1", - "@prisma/engines-version": "5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64", - "@prisma/fetch-engine": "5.9.1", - "@prisma/get-platform": "5.9.1" + "@prisma/debug": "5.10.1", + "@prisma/engines-version": "5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9", + "@prisma/fetch-engine": "5.10.1", + "@prisma/get-platform": "5.10.1" } }, "node_modules/@prisma/engines-version": { - "version": "5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64.tgz", - "integrity": "sha512-HFl7275yF0FWbdcNvcSRbbu9JCBSLMcurYwvWc8WGDnpu7APxQo2ONtZrUggU3WxLxUJ2uBX+0GOFIcJeVeOOQ==", + "version": "5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9.tgz", + "integrity": "sha512-uCy/++3Jx/O3ufM+qv2H1L4tOemTNqcP/gyEVOlZqTpBvYJUe0tWtW0y3o2Ueq04mll4aM5X3f6ugQftOSLdFQ==", "dev": true }, "node_modules/@prisma/extension-read-replicas": { @@ -3078,23 +3078,23 @@ } }, "node_modules/@prisma/fetch-engine": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.9.1.tgz", - "integrity": "sha512-l0goQOMcNVOJs1kAcwqpKq3ylvkD9F04Ioe1oJoCqmz05mw22bNAKKGWuDd3zTUoUZr97va0c/UfLNru+PDmNA==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.10.1.tgz", + "integrity": "sha512-xg3I3RM/qENykZNGBna+14gBkkZL2TVkyX3OX2GWI8MV23Meq5jYdqvlgBrZne25ZxiulctSEA2D6Y5fq1eLog==", "dev": true, "dependencies": { - "@prisma/debug": "5.9.1", - "@prisma/engines-version": "5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64", - "@prisma/get-platform": "5.9.1" + "@prisma/debug": "5.10.1", + "@prisma/engines-version": "5.10.0-34.5a9203d0590c951969e85a7d07215503f4672eb9", + "@prisma/get-platform": "5.10.1" } }, "node_modules/@prisma/get-platform": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.9.1.tgz", - "integrity": "sha512-6OQsNxTyhvG+T2Ksr8FPFpuPeL4r9u0JF0OZHUBI/Uy9SS43sPyAIutt4ZEAyqWQt104ERh70EZedkHZKsnNbg==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.10.1.tgz", + "integrity": "sha512-0rE8lSE3y+Ua3LaOcXlWADz21+kGkf9NWmGNuh8n9I6uaCq90LQxM002l4NSYg6ELtiJXyDgJ4nRhM0x0OXjDQ==", "dev": true, "dependencies": { - "@prisma/debug": "5.9.1" + "@prisma/debug": "5.10.1" } }, "node_modules/@prisma/prisma-schema-wasm": { @@ -3110,9 +3110,9 @@ "dev": true }, "node_modules/@shikijs/core": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.5.tgz", - "integrity": "sha512-cKc5vGQ4p/4sjx48BHIO7CvLaN32vqpz5Wh7v2n+U1EezGdfX4Wms7khBctKz3iCg9yYq4sfGUc2t+JWj6EUsw==" + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.6.tgz", + "integrity": "sha512-kt9hhvrWTm0EPtRDIsoAZnSsFlIDBVBBI5CQewpA/NZCPin+MOKRXg+JiWc4y+8fZ/v0HzfDhu/UC+OTZGMt7A==" }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", @@ -3871,9 +3871,9 @@ "dev": true }, "node_modules/@vercel/analytics": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.1.tgz", - "integrity": "sha512-ZB5gDPCQvHu0DcBbywIwMm5aY9mTV8mBl7Mmk8QD84JqBnuYbsNCDnnDuzblNjd82tDtRjAqruZ0mzNm6MAWpA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.2.2.tgz", + "integrity": "sha512-X0rctVWkQV1e5Y300ehVNqpOfSOufo7ieA5PIdna8yX/U7Vjz0GFsGf4qvAhxV02uQ2CVt7GYcrFfddXXK2Y4A==", "dependencies": { "server-only": "^0.0.1" }, @@ -5152,9 +5152,9 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cypress": { - "version": "13.6.4", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.4.tgz", - "integrity": "sha512-pYJjCfDYB+hoOoZuhysbbYhEmNW7DEDsqn+ToCLwuVowxUXppIWRr7qk4TVRIU471ksfzyZcH+mkoF0CQUKnpw==", + "version": "13.6.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.5.tgz", + "integrity": "sha512-2NxSDcO2zHw5kTcosc6dzv2zppEqiXrFFhZw5cx/EWrSNZABTzpr/EyvYzGgrWm46o5173JUfuJfDQcaiZZPVQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -5165,7 +5165,7 @@ "arch": "^2.2.0", "blob-util": "^2.0.2", "bluebird": "^3.7.2", - "buffer": "^5.6.0", + "buffer": "^5.7.1", "cachedir": "^2.3.0", "chalk": "^4.1.0", "check-more-types": "^2.24.0", @@ -5183,7 +5183,7 @@ "figures": "^3.2.0", "fs-extra": "^9.1.0", "getos": "^3.2.1", - "is-ci": "^3.0.0", + "is-ci": "^3.0.1", "is-installed-globally": "~0.4.0", "lazy-ass": "^1.6.0", "listr2": "^3.8.3", @@ -5584,9 +5584,9 @@ } }, "node_modules/dotenv": { - "version": "16.4.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", - "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "dev": true, "engines": { "node": ">=12" @@ -5642,9 +5642,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.675", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.675.tgz", - "integrity": "sha512-+1u3F/XPNIdUwv8i1lDxHAxCvNNU0QIqgb1Ycn+Jnng8ITzWSvUqixRSM7NOazJuwhf65IV17f/VbKj8DmL26A==", + "version": "1.4.677", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.677.tgz", + "integrity": "sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==", "dev": true }, "node_modules/emoji-regex": { @@ -5814,14 +5814,14 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -7306,9 +7306,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.0.tgz", + "integrity": "sha512-noqGuLw158+DuD9UPRKHpJ2hGxpFyDlYYrfM0mWt4XhT4n0lwzTLh70Tkdyy4kyTmyTT9Bv7bWAJqw7cgkEXDg==", "dev": true }, "node_modules/follow-redirects": { @@ -9293,9 +9293,9 @@ } }, "node_modules/lucide-react": { - "version": "0.334.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.334.0.tgz", - "integrity": "sha512-y0Rv/Xx6qAq4FutZ3L/efl3O9vl6NC/1p0YOg6mBfRbQ4k1JCE2rz0rnV7WC8Moxq1RY99vLATvjcqUegGJTvA==", + "version": "0.335.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.335.0.tgz", + "integrity": "sha512-FNmIG4JLdvpK86ZFJjrT0SnFEa95KhsiNokVicA5mWEf1oe+ujP2C/bTr0PVQzr/wzvZpzgxaOySq0O79q2oMA==", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } @@ -10270,11 +10270,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.1-canary.62", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.62.tgz", - "integrity": "sha512-Qjb/nzmExeYmpOLnrR8LKJo8v9X2H7iWfPhS7fHPxpYC+Aj/XrbWplH6YllMaJR/VHRKeeXDqWEvCqr+q4+8zQ==", + "version": "14.1.1-canary.65", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.1-canary.65.tgz", + "integrity": "sha512-R2cHGTguLRL38HlX2UYQY1M6SdRkz2Fu4sl6gYk/bR/HrmrekvEwpQG87o2BkII2ygLTOWgJHe9+iuaZpXeysg==", "dependencies": { - "@next/env": "14.1.1-canary.62", + "@next/env": "14.1.1-canary.65", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -10289,15 +10289,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.1-canary.62", - "@next/swc-darwin-x64": "14.1.1-canary.62", - "@next/swc-linux-arm64-gnu": "14.1.1-canary.62", - "@next/swc-linux-arm64-musl": "14.1.1-canary.62", - "@next/swc-linux-x64-gnu": "14.1.1-canary.62", - "@next/swc-linux-x64-musl": "14.1.1-canary.62", - "@next/swc-win32-arm64-msvc": "14.1.1-canary.62", - "@next/swc-win32-ia32-msvc": "14.1.1-canary.62", - "@next/swc-win32-x64-msvc": "14.1.1-canary.62" + "@next/swc-darwin-arm64": "14.1.1-canary.65", + "@next/swc-darwin-x64": "14.1.1-canary.65", + "@next/swc-linux-arm64-gnu": "14.1.1-canary.65", + "@next/swc-linux-arm64-musl": "14.1.1-canary.65", + "@next/swc-linux-x64-gnu": "14.1.1-canary.65", + "@next/swc-linux-x64-musl": "14.1.1-canary.65", + "@next/swc-win32-arm64-msvc": "14.1.1-canary.65", + "@next/swc-win32-ia32-msvc": "14.1.1-canary.65", + "@next/swc-win32-x64-msvc": "14.1.1-canary.65" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -11185,13 +11185,13 @@ } }, "node_modules/prisma": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.9.1.tgz", - "integrity": "sha512-Hy/8KJZz0ELtkw4FnG9MS9rNWlXcJhf98Z2QMqi0QiVMoS8PzsBkpla0/Y5hTlob8F3HeECYphBjqmBxrluUrQ==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.10.1.tgz", + "integrity": "sha512-2VLQ8dMXZGd5qS6XIDyAzK2W4xdPJDt/E3IBcjByn64Fnp33llqq/HBxx0EroZO7ezKiw1gS3BOrkpyzPfeFhA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "5.9.1" + "@prisma/engines": "5.10.1" }, "bin": { "prisma": "build/index.js" @@ -12168,14 +12168,15 @@ } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -12203,11 +12204,11 @@ } }, "node_modules/shiki": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.5.tgz", - "integrity": "sha512-754GuKIwkUdT810Xm8btuyNQPL+q3PqOkwGW/VlmAWyMYp+HbvvDt69sWXO1sm5aeczBJQjmQTTMR4GkKQNQPw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.6.tgz", + "integrity": "sha512-j4pcpvaQWHb42cHeV+W6P+X/VcK7Y2ctvEham6zB8wsuRQroT6cEMIkiUmBU2Nqg2qnHZDH6ZyRdVldcy0l6xw==", "dependencies": { - "@shikijs/core": "1.1.5" + "@shikijs/core": "1.1.6" } }, "node_modules/side-channel": { @@ -12974,12 +12975,12 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", - "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "is-typed-array": "^1.1.13" }, @@ -13006,16 +13007,16 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz", - "integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.6", + "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "is-typed-array": "^1.1.13" }, "engines": { @@ -13026,14 +13027,20 @@ } }, "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==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13322,9 +13329,9 @@ } }, "node_modules/valibot": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.28.1.tgz", - "integrity": "sha512-zQnjwNJuXk6362Leu0+4eFa/SMwRom3/hEvH6s1EGf3oXIPbo2WFKDra9ymnbVh3clLRvd8hw4sKF5ruI2Lyvw==" + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.29.0.tgz", + "integrity": "sha512-JhZn08lwZPhAamOCfBwBkv/btQt4KeQhekULPH8crH053zUCLSOGEF2zKExu3bFf245tsj6J1dY0ysd/jUiMIQ==" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", diff --git a/package.json b/package.json index ae26dd5d..871bef25 100644 --- a/package.json +++ b/package.json @@ -24,16 +24,16 @@ "@mui/base": "5.0.0-beta.36", "@mui/joy": "5.0.0-beta.28", "@mui/styled-engine": "^5.15.9", - "@prisma/client": "^5.9.1", + "@prisma/client": "^5.10.1", "@prisma/extension-read-replicas": "^0.3.0", - "@vercel/analytics": "^1.2.1", + "@vercel/analytics": "^1.2.2", "@vercel/speed-insights": "^1.0.10", "clsx": "^2.1.0", "contentful": "^10.6.21", "dayjs": "^1.11.10", "geist": "^1.2.2", "lodash-es": "^4.17.21", - "lucide-react": "^0.334.0", + "lucide-react": "^0.335.0", "merge-sx": "^2.0.0", "next": "canary", "next-mdx-remote": "^4.4.1", @@ -43,8 +43,8 @@ "rehype-pretty-code": "^0.13.0", "rehype-slug": "^6.0.0", "schema-dts": "^1.1.2", - "shiki": "^1.1.5", - "valibot": "^0.28.1" + "shiki": "^1.1.6", + "valibot": "^0.29.0" }, "devDependencies": { "@next/bundle-analyzer": "canary", @@ -55,7 +55,7 @@ "@types/react": "^18.2.57", "@types/react-dom": "^18.2.19", "@vercel/style-guide": "^5.2.0", - "cypress": "^13.6.4", + "cypress": "^13.6.5", "dotenv-cli": "^7.3.0", "eslint": "^8.56.0", "eslint-plugin-cypress": "^2.15.1", @@ -63,7 +63,7 @@ "playwright-webkit": "^1.41.2", "prettier": "^3.2.5", "prettier-plugin-prisma": "^5.0.0", - "prisma": "^5.9.1", + "prisma": "^5.10.1", "type-fest": "^4.10.2", "typescript": "^5.3.3" } From 2fe3090f5298d1b8e1d3a1da430e31a61a2bf1ae Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 09:44:08 +0800 Subject: [PATCH 80/87] test: refactor tests --- cypress/e2e/color-mode.cy.ts | 14 +++++++------- cypress/e2e/download-cv.cy.ts | 33 ++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/cypress/e2e/color-mode.cy.ts b/cypress/e2e/color-mode.cy.ts index d79c098a..574f4f66 100644 --- a/cypress/e2e/color-mode.cy.ts +++ b/cypress/e2e/color-mode.cy.ts @@ -1,14 +1,14 @@ import { colors } from '../fixtures/colors'; import { home } from '../fixtures/nav'; -describe('Color mode', () => { - const expectColorMode = (colorMode: 'dark' | 'light') => { - cy.get('html').should('have.attr', 'data-joy-color-scheme', colorMode); - cy.get('body') - .should('have.css', 'background-color', colors[colorMode].bgColor) - .and('have.css', 'color', colors[colorMode].color); - }; +const expectColorMode = (colorMode: 'dark' | 'light') => { + cy.get('html').should('have.attr', 'data-joy-color-scheme', colorMode); + cy.get('body') + .should('have.css', 'background-color', colors[colorMode].bgColor) + .and('have.css', 'color', colors[colorMode].color); +}; +describe('Color mode', () => { beforeEach(() => cy.visit(home.pathname)); it('default is light mode', () => expectColorMode('light')); diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index 0a38a003..ab64f57f 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -1,20 +1,31 @@ +import { Asset } from 'contentful'; + import { cv } from '../fixtures/contentful-ids'; import { home } from '../fixtures/nav'; import { contentful } from '../support/clients'; describe('Download CV', () => { - it('should download CV', () => { - cy.visit(home.pathname); + const ctx = { + cv: undefined as Asset<'WITHOUT_UNRESOLVABLE_LINKS'> | undefined, + }; + + before(() => { + cy.wrap(contentful.getAsset(cv)).then((asset) => { + ctx.cv = asset; + }); + }); + + beforeEach(() => cy.visit(home.pathname)); + + it('should open CV in a new tab (for browsers with PDF reader built-in)', () => { + const href = `https:${ctx.cv?.fields.file?.url}`; + cy.contains('Download CV') .should('have.attr', 'target', '_blank') - .invoke('attr', 'href') - .then((href: string) => { - cy.wrap(contentful.getAsset(cv)).then((asset) => { - expect(href).to.equal(`https:${asset.fields.file?.url}`); - }); - cy.request(href) - .its('headers') - .should('have.a.property', 'content-type', 'application/pdf'); - }); + .should('have.attr', 'href', href); + + cy.request(href) + .its('headers') + .should('have.a.property', 'content-type', 'application/pdf'); }); }); From f05ccc96ea27c4970b31b3d88b379a191f88db1d Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 10:11:10 +0800 Subject: [PATCH 81/87] test: refactor ctx type definition --- cypress/e2e/download-cv.cy.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index ab64f57f..aef5a482 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -4,10 +4,12 @@ import { cv } from '../fixtures/contentful-ids'; import { home } from '../fixtures/nav'; import { contentful } from '../support/clients'; +interface DownloadCvCtx { + cv?: Asset<'WITHOUT_UNRESOLVABLE_LINKS'>; +} + describe('Download CV', () => { - const ctx = { - cv: undefined as Asset<'WITHOUT_UNRESOLVABLE_LINKS'> | undefined, - }; + const ctx: DownloadCvCtx = {}; before(() => { cy.wrap(contentful.getAsset(cv)).then((asset) => { From 9075eca8f4d3e50df5c1279a438f6b448481be8c Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 10:39:41 +0800 Subject: [PATCH 82/87] test: extract queries to dedicated file and refactored skill set test --- cypress/e2e/download-cv.cy.ts | 11 ++-- cypress/e2e/skill-set.cy.ts | 99 ++++++++++++----------------------- cypress/support/queries.ts | 37 +++++++++++++ 3 files changed, 75 insertions(+), 72 deletions(-) create mode 100644 cypress/support/queries.ts diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index aef5a482..89652262 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -1,18 +1,15 @@ -import { Asset } from 'contentful'; - -import { cv } from '../fixtures/contentful-ids'; import { home } from '../fixtures/nav'; -import { contentful } from '../support/clients'; +import { Cv, getCv } from '../support/queries'; interface DownloadCvCtx { - cv?: Asset<'WITHOUT_UNRESOLVABLE_LINKS'>; + cv?: Cv; } describe('Download CV', () => { const ctx: DownloadCvCtx = {}; before(() => { - cy.wrap(contentful.getAsset(cv)).then((asset) => { + cy.wrap(getCv()).then((asset) => { ctx.cv = asset; }); }); @@ -20,7 +17,7 @@ describe('Download CV', () => { beforeEach(() => cy.visit(home.pathname)); it('should open CV in a new tab (for browsers with PDF reader built-in)', () => { - const href = `https:${ctx.cv?.fields.file?.url}`; + const href = `https:${ctx.cv}`; cy.contains('Download CV') .should('have.attr', 'target', '_blank') diff --git a/cypress/e2e/skill-set.cy.ts b/cypress/e2e/skill-set.cy.ts index a5738570..a250a4e1 100644 --- a/cypress/e2e/skill-set.cy.ts +++ b/cypress/e2e/skill-set.cy.ts @@ -1,79 +1,48 @@ import { about } from '../fixtures/nav'; -import { contentful } from '../support/clients'; -import { SkillCategorySkeleton, SkillSkeleton } from '../support/types'; +import { SkillSet, getSkillSet } from '../support/queries'; -const getSkillSet = async () => { - const [{ items: skills }, { items: skillCategories }] = await Promise.all([ - contentful.getEntries({ - content_type: 'skill', - 'fields.category[exists]': true, - order: ['-fields.proficiency', 'fields.name'], - }), - contentful.getEntries({ - content_type: 'skillCategory', - order: ['-fields.proficiency', 'fields.name'], - }), - ]); +interface SkillSetCtx { + skillSet?: SkillSet; +} - return skillCategories.map((skillCategory) => ({ - id: skillCategory.sys.id, - name: skillCategory.fields.name, - skills: skills - .filter((skill) => skill.fields.category?.sys.id === skillCategory.sys.id) - .map((skill) => ({ - name: skill.fields.name, - proficiency: skill.fields.proficiency, - url: skill.fields.url, - })), - })); -}; +describe('Skill Set', () => { + const ctx: SkillSetCtx = {}; -type SkillSet = Awaited>; + before(() => { + cy.wrap(getSkillSet()).then((skillSet) => { + ctx.skillSet = skillSet; + }); + }); -describe('Skill Set', () => { beforeEach(() => { cy.visit(`${about.pathname}#${about.id}`); - cy.wrap(getSkillSet()).as('skillSet'); cy.get('[data-cy="skill-set"]').as('skillSetElem'); }); - it('displays the entire skill set with the skill category name as the title and skills listed out', () => { - cy.get('@skillSet').then((skillSet) => { - for (const { id, name, skills } of skillSet) { - cy.get('@skillSetElem') - .get(`[data-cy=${id}]`) - .within(() => { - cy.get('[data-cy="title"]').contains(name).should('be.visible'); - for (const { name } of skills) { - cy.contains(name).should('be.visible'); - } - }); - } - }); - }); + it('displays the entire skill set', () => { + for (const { id, name, skills } of ctx.skillSet ?? []) { + cy.log(`Testing ${name} category`); - describe('Skills', () => { - it('displays the skill name and links to the corresponding webpage', () => { - cy.get('@skillSet').then((skillSet) => { - for (const { id, skills } of skillSet) { - cy.get('@skillSetElem') - .get(`[data-cy=${id}]`) - .within(() => { - for (const { name, url } of skills) { - cy.contains(name).parent().as('chip'); - if (url) { - cy.get('@chip') - .find('a') - .should('have.attr', 'target', '_blank') - .and('have.attr', 'href', url); - } else { - cy.get('@chip').find('a').should('not.exist'); - } - } - }); - } - }); - }); + cy.get('@skillSetElem') + .get(`[data-cy=${id}]`) + .within(() => { + cy.get('[data-cy="title"]').contains(name).should('be.visible'); + + for (const { name, url } of skills) { + cy.log(`Testing ${name} skill`); + + cy.contains(name).should('be.visible').parent().as('chip'); + if (url) { + cy.get('@chip') + .find('a') + .should('have.attr', 'target', '_blank') + .and('have.attr', 'href', url); + } else { + cy.get('@chip').find('a').should('not.exist'); + } + } + }); + } }); // TODO: test for filter by proficiency diff --git a/cypress/support/queries.ts b/cypress/support/queries.ts new file mode 100644 index 00000000..b889cdc7 --- /dev/null +++ b/cypress/support/queries.ts @@ -0,0 +1,37 @@ +import { cv } from '../fixtures/contentful-ids'; + +import { contentful } from './clients'; +import { SkillCategorySkeleton, SkillSkeleton } from './types'; + +export type SkillSet = Awaited>; +export const getSkillSet = async () => { + const [{ items: skills }, { items: skillCategories }] = await Promise.all([ + contentful.getEntries({ + content_type: 'skill', + 'fields.category[exists]': true, + order: ['-fields.proficiency', 'fields.name'], + }), + contentful.getEntries({ + content_type: 'skillCategory', + order: ['-fields.proficiency', 'fields.name'], + }), + ]); + + return skillCategories.map((skillCategory) => ({ + id: skillCategory.sys.id, + name: skillCategory.fields.name, + skills: skills + .filter((skill) => skill.fields.category?.sys.id === skillCategory.sys.id) + .map((skill) => ({ + name: skill.fields.name, + proficiency: skill.fields.proficiency, + url: skill.fields.url, + })), + })); +}; + +export type Cv = Awaited>; +export const getCv = async () => { + const asset = await contentful.getAsset(cv); + return asset.fields.file && `https:${asset.fields.file.url}`; +}; From 47fcbec34179a4eb7cb790df8e246894b6303e5b Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 11:31:04 +0800 Subject: [PATCH 83/87] test: add WIP slider dragging interaction --- components/home/skill-set.tsx | 1 + cypress/e2e/skill-set.cy.ts | 47 +++++++++++++++++++++++++++++++++-- cypress/support/commands.ts | 4 +-- cypress/tsconfig.json | 9 ++++++- package-lock.json | 10 ++++++++ package.json | 1 + 6 files changed, 67 insertions(+), 5 deletions(-) diff --git a/components/home/skill-set.tsx b/components/home/skill-set.tsx index 0f79c45d..d68d6153 100644 --- a/components/home/skill-set.tsx +++ b/components/home/skill-set.tsx @@ -46,6 +46,7 @@ export const SkillSet: FC = ({ skillSet = [], ...props }) => { Skill Proficiency 'Skill proficiency range'} max={5} min={1} diff --git a/cypress/e2e/skill-set.cy.ts b/cypress/e2e/skill-set.cy.ts index a250a4e1..0a897759 100644 --- a/cypress/e2e/skill-set.cy.ts +++ b/cypress/e2e/skill-set.cy.ts @@ -1,3 +1,5 @@ +import { sliderClasses } from '@mui/joy'; + import { about } from '../fixtures/nav'; import { SkillSet, getSkillSet } from '../support/queries'; @@ -5,7 +7,7 @@ interface SkillSetCtx { skillSet?: SkillSet; } -describe('Skill Set', () => { +describe('Skill set', () => { const ctx: SkillSetCtx = {}; before(() => { @@ -19,7 +21,7 @@ describe('Skill Set', () => { cy.get('[data-cy="skill-set"]').as('skillSetElem'); }); - it('displays the entire skill set', () => { + it('displays the entire skill set initially', () => { for (const { id, name, skills } of ctx.skillSet ?? []) { cy.log(`Testing ${name} category`); @@ -46,4 +48,45 @@ describe('Skill Set', () => { }); // TODO: test for filter by proficiency + // describe('Skill proficiency slider', () => { + // it.only('filters the skill set by proficiency', () => { + // // cy.get('[data-cy="skill-set"]').as('skillSetElem'); + // // cy.get('[data-cy="skill-set-proficiency-slider"]').as('slider'); + // // cy.get('@slider').invoke('val', 3).trigger('change'); + // // cy.get('@skillSetElem').should('have.length', 1); + + // cy.get('@skillSetElem') + // .get('[data-cy="skill-proficiency-slider"]') + // .within(($slider) => { + // cy.get(`.${sliderClasses.thumb}`).as('thumbs'); + // cy.get('@thumbs').first().as('leftThumb'); + // cy.get('@thumbs').last().as('rightThumb'); + + // const sliderBoundingBox = $slider.get(0).getBoundingClientRect(); + // const targetRange = [2, 4] as const; + // const min = 1; + // const max = 5; + + // cy.get('@leftThumb').drag(`.${sliderClasses.thumb}`, { + // target: { + // // use force here because Cypress mistakenly thinks the slider root is covering the slider thumb + // x: sliderBoundingBox.width * (targetRange[0] / max), + // y: 0, + // force: true, + // }, + // }); + // cy.get('@leftThumb').contains(targetRange[0]).should('be.visible'); + + // cy.get('@rightThumb').drag(`.${sliderClasses.thumb}`, { + // target: { + // // use force here because Cypress mistakenly thinks the slider root is covering the slider thumb + // x: -sliderBoundingBox.width * ((max - targetRange[1]) / max), + // y: 0, + // force: true, + // }, + // }); + // cy.get('@rightThumb').contains(targetRange[1]).should('be.visible'); + // }); + // }); + // }); }); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 0c538960..183b34f5 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -1,6 +1,8 @@ /* eslint-disable @typescript-eslint/no-namespace -- Cypress extension */ /* eslint-disable @typescript-eslint/method-signature-style -- this is how Cypress defined the interface and the extension should match that */ /// +import '@4tw/cypress-drag-drop'; + // *********************************************** // This example commands.ts shows you how to // create various custom commands and overwrite @@ -52,5 +54,3 @@ declare global { } } } - -export {}; diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index df33ff75..04bda79f 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -3,7 +3,14 @@ "compilerOptions": { "target": "es5", "lib": ["es5", "dom"], - "types": ["cypress", "node", "lodash-es", "contentful"] + "types": [ + "cypress", + "node", + "lodash-es", + "contentful", + "@4tw/cypress-drag-drop", + "@mui/joy" + ] }, "include": ["**/*.ts"] } diff --git a/package-lock.json b/package-lock.json index 4cb89d5f..5030a8a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "valibot": "^0.29.0" }, "devDependencies": { + "@4tw/cypress-drag-drop": "^2.2.5", "@next/bundle-analyzer": "canary", "@next/eslint-plugin-next": "canary", "@svgr/webpack": "^8.1.0", @@ -61,6 +62,15 @@ "typescript": "^5.3.3" } }, + "node_modules/@4tw/cypress-drag-drop": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@4tw/cypress-drag-drop/-/cypress-drag-drop-2.2.5.tgz", + "integrity": "sha512-3ghTmzhOmUqeN6U3QmUnKRUxI7OMLbJA4hHUY/eS/FhWJgxbiGgcaELbolWnBAOpajPXcsNQGYEj9brd59WH6A==", + "dev": true, + "peerDependencies": { + "cypress": "2 - 13" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", diff --git a/package.json b/package.json index 871bef25..f1d9e154 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "valibot": "^0.29.0" }, "devDependencies": { + "@4tw/cypress-drag-drop": "^2.2.5", "@next/bundle-analyzer": "canary", "@next/eslint-plugin-next": "canary", "@svgr/webpack": "^8.1.0", From 68eadadd1c42974c4156894a63433e42f349b0c2 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 15:31:14 +0800 Subject: [PATCH 84/87] test: put helper func in test suite --- cypress/e2e/color-mode.cy.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cypress/e2e/color-mode.cy.ts b/cypress/e2e/color-mode.cy.ts index 574f4f66..5258fadb 100644 --- a/cypress/e2e/color-mode.cy.ts +++ b/cypress/e2e/color-mode.cy.ts @@ -1,25 +1,25 @@ import { colors } from '../fixtures/colors'; import { home } from '../fixtures/nav'; -const expectColorMode = (colorMode: 'dark' | 'light') => { - cy.get('html').should('have.attr', 'data-joy-color-scheme', colorMode); - cy.get('body') - .should('have.css', 'background-color', colors[colorMode].bgColor) - .and('have.css', 'color', colors[colorMode].color); -}; - describe('Color mode', () => { beforeEach(() => cy.visit(home.pathname)); - it('default is light mode', () => expectColorMode('light')); + const expectColorModeToBe = (colorMode: 'dark' | 'light') => { + cy.get('html').should('have.attr', 'data-joy-color-scheme', colorMode); + cy.get('body') + .should('have.css', 'background-color', colors[colorMode].bgColor) + .and('have.css', 'color', colors[colorMode].color); + }; + + it('default is light mode', () => expectColorModeToBe('light')); describe('Mode toggle button', () => { it('toggles color mode', () => { cy.get('[data-cy="mode-toggle-button"]').click(); - expectColorMode('dark'); + expectColorModeToBe('dark'); cy.get('[data-cy="mode-toggle-button"]').click(); - expectColorMode('light'); + expectColorModeToBe('light'); }); it('updates icon according to color mode', () => { From 7d4bac312357e5486424f96c163139788c9212b6 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 15:31:24 +0800 Subject: [PATCH 85/87] test: complete skill set test suite --- cypress/e2e/skill-set.cy.ts | 100 ++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/cypress/e2e/skill-set.cy.ts b/cypress/e2e/skill-set.cy.ts index 0a897759..8f607db9 100644 --- a/cypress/e2e/skill-set.cy.ts +++ b/cypress/e2e/skill-set.cy.ts @@ -21,8 +21,8 @@ describe('Skill set', () => { cy.get('[data-cy="skill-set"]').as('skillSetElem'); }); - it('displays the entire skill set initially', () => { - for (const { id, name, skills } of ctx.skillSet ?? []) { + const expectSkillSetToDisplay = (skillSet: SkillSet) => { + for (const { id, name, skills } of skillSet) { cy.log(`Testing ${name} category`); cy.get('@skillSetElem') @@ -45,48 +45,62 @@ describe('Skill set', () => { } }); } + }; + + it('displays the entire skill set initially', () => { + if (ctx.skillSet) { + expectSkillSetToDisplay(ctx.skillSet); + } }); // TODO: test for filter by proficiency - // describe('Skill proficiency slider', () => { - // it.only('filters the skill set by proficiency', () => { - // // cy.get('[data-cy="skill-set"]').as('skillSetElem'); - // // cy.get('[data-cy="skill-set-proficiency-slider"]').as('slider'); - // // cy.get('@slider').invoke('val', 3).trigger('change'); - // // cy.get('@skillSetElem').should('have.length', 1); - - // cy.get('@skillSetElem') - // .get('[data-cy="skill-proficiency-slider"]') - // .within(($slider) => { - // cy.get(`.${sliderClasses.thumb}`).as('thumbs'); - // cy.get('@thumbs').first().as('leftThumb'); - // cy.get('@thumbs').last().as('rightThumb'); - - // const sliderBoundingBox = $slider.get(0).getBoundingClientRect(); - // const targetRange = [2, 4] as const; - // const min = 1; - // const max = 5; - - // cy.get('@leftThumb').drag(`.${sliderClasses.thumb}`, { - // target: { - // // use force here because Cypress mistakenly thinks the slider root is covering the slider thumb - // x: sliderBoundingBox.width * (targetRange[0] / max), - // y: 0, - // force: true, - // }, - // }); - // cy.get('@leftThumb').contains(targetRange[0]).should('be.visible'); - - // cy.get('@rightThumb').drag(`.${sliderClasses.thumb}`, { - // target: { - // // use force here because Cypress mistakenly thinks the slider root is covering the slider thumb - // x: -sliderBoundingBox.width * ((max - targetRange[1]) / max), - // y: 0, - // force: true, - // }, - // }); - // cy.get('@rightThumb').contains(targetRange[1]).should('be.visible'); - // }); - // }); - // }); + describe('Skill proficiency slider', () => { + it('filters the skill set by proficiency 2 - 4', () => { + const targetProficiency = [2, 4] as const; + + cy.get('@skillSetElem') + .get('[data-cy="skill-proficiency-slider"]') + .within(($slider) => { + cy.get(`.${sliderClasses.thumb}`).as('thumbs'); + cy.get('@thumbs').first().as('leftThumb'); + cy.get('@thumbs').last().as('rightThumb'); + + const sliderBoundingBox = $slider.get(0).getBoundingClientRect(); + const maxProficiency = 5; + + cy.root().click( + sliderBoundingBox.width * + (targetProficiency[0] / maxProficiency) * + 0.9, + 0, + ); + cy.get('@leftThumb') + .contains(targetProficiency[0]) + .should('be.visible'); + + cy.root().click( + sliderBoundingBox.width * (targetProficiency[1] / maxProficiency), + 0, + ); + cy.get('@rightThumb') + .contains(targetProficiency[1]) + .should('be.visible'); + }); + + if (ctx.skillSet) { + expectSkillSetToDisplay( + ctx.skillSet + .map(({ skills, ...skillCategory }) => ({ + ...skillCategory, + skills: skills.filter( + ({ proficiency }) => + proficiency >= targetProficiency[0] && + proficiency <= targetProficiency[1], + ), + })) + .filter(({ skills }) => skills.length), + ); + } + }); + }); }); From 691f4b5ad4c571b1ab22d31dfa762a025592fa70 Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 15:35:18 +0800 Subject: [PATCH 86/87] test: fix expected CV URL --- cypress/e2e/download-cv.cy.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cypress/e2e/download-cv.cy.ts b/cypress/e2e/download-cv.cy.ts index 89652262..f33df6af 100644 --- a/cypress/e2e/download-cv.cy.ts +++ b/cypress/e2e/download-cv.cy.ts @@ -17,14 +17,14 @@ describe('Download CV', () => { beforeEach(() => cy.visit(home.pathname)); it('should open CV in a new tab (for browsers with PDF reader built-in)', () => { - const href = `https:${ctx.cv}`; + if (ctx.cv) { + cy.contains('Download CV') + .should('have.attr', 'target', '_blank') + .should('have.attr', 'href', ctx.cv); - cy.contains('Download CV') - .should('have.attr', 'target', '_blank') - .should('have.attr', 'href', href); - - cy.request(href) - .its('headers') - .should('have.a.property', 'content-type', 'application/pdf'); + cy.request(ctx.cv) + .its('headers') + .should('have.a.property', 'content-type', 'application/pdf'); + } }); }); From 0c80ffb0c6cd67edbc27a8ce2f2dbd5c95a89ded Mon Sep 17 00:00:00 2001 From: Matthew Kwong Date: Wed, 21 Feb 2024 15:45:28 +0800 Subject: [PATCH 87/87] test: make skill set test or reliable --- cypress/e2e/skill-set.cy.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cypress/e2e/skill-set.cy.ts b/cypress/e2e/skill-set.cy.ts index 8f607db9..ce4e0868 100644 --- a/cypress/e2e/skill-set.cy.ts +++ b/cypress/e2e/skill-set.cy.ts @@ -53,7 +53,6 @@ describe('Skill set', () => { } }); - // TODO: test for filter by proficiency describe('Skill proficiency slider', () => { it('filters the skill set by proficiency 2 - 4', () => { const targetProficiency = [2, 4] as const; @@ -70,8 +69,8 @@ describe('Skill set', () => { cy.root().click( sliderBoundingBox.width * - (targetProficiency[0] / maxProficiency) * - 0.9, + // (the selection range is between 1 - 1.999... so the sweetest spot is the middle of it, i.e. 1.5) + ((targetProficiency[0] - 0.5) / maxProficiency), 0, ); cy.get('@leftThumb') @@ -79,7 +78,8 @@ describe('Skill set', () => { .should('be.visible'); cy.root().click( - sliderBoundingBox.width * (targetProficiency[1] / maxProficiency), + sliderBoundingBox.width * + ((targetProficiency[1] - 0.5) / maxProficiency), 0, ); cy.get('@rightThumb')