From e453b1bdddbd90f68fdd447286a63006d69ba023 Mon Sep 17 00:00:00 2001 From: Tim Diekmann <21277928+TimDiekmann@users.noreply.github.com> Date: Wed, 11 Dec 2024 10:48:44 +0100 Subject: [PATCH 1/4] H-3710: Support DNS for HaRPC client and align environment variables (#5856) --- .env | 8 +- .env.development | 3 + apps/hash-ai-worker-ts/README.md | 6 +- .../src/activities/shared/graph-api-client.ts | 4 +- apps/hash-ai-worker-ts/src/main.ts | 4 +- .../src/ensure-system-graph-is-initialized.ts | 4 +- .../src/generate-ontology-type-ids.ts | 4 +- apps/hash-api/src/index.ts | 12 +- .../src/seed-data/seed-flow-test-types.ts | 4 +- .../docker-compose.prod.yml | 10 +- apps/hash-graph/src/subcommand/server.rs | 29 ++-- apps/hash-graph/src/subcommand/test_server.rs | 12 +- apps/hash-integration-worker/README.md | 6 +- apps/hash-integration-worker/src/main.ts | 4 +- infra/terraform/hash/.terraform.lock.hcl | 127 +++++++++++------- infra/terraform/hash/hash_application/api.tf | 12 +- .../terraform/hash/hash_application/graph.tf | 57 +++++--- infra/terraform/hash/hash_application/main.tf | 27 +++- .../hash_application/temporal_worker_ai_ts.tf | 6 +- .../temporal_worker_integration.tf | 6 +- infra/terraform/hash/main.tf | 2 + infra/terraform/hash/prod-usea1.tfvars | 6 +- .../src/tests/util.ts | 4 +- tests/hash-backend-load/src/graph/api.ts | 4 +- 24 files changed, 217 insertions(+), 144 deletions(-) diff --git a/.env b/.env index 951fd1c773d..c8c770b5c88 100644 --- a/.env +++ b/.env @@ -70,7 +70,7 @@ HASH_TEMPORAL_VISIBILITY_PG_DATABASE=temporal_visibility HASH_GRAPH_PG_USER=graph HASH_GRAPH_PG_PASSWORD=graph HASH_GRAPH_PG_DATABASE=graph -HASH_GRAPH_LOG_LEVEL=trace,h2=info,tokio_util=debug,tower=info,tonic=debug,hyper=info,tokio_postgres=info,rustls=info,tarpc=warn +HASH_GRAPH_LOG_LEVEL=info HASH_GRAPH_TYPE_FETCHER_HOST=localhost HASH_GRAPH_TYPE_FETCHER_PORT=4455 @@ -78,8 +78,10 @@ HASH_GRAPH_TYPE_FETCHER_PORT=4455 HASH_GRAPH_REALTIME_PG_USER=realtime HASH_GRAPH_REALTIME_PG_PASSWORD=realtime -HASH_GRAPH_API_HOST=127.0.0.1 -HASH_GRAPH_API_PORT=4000 +HASH_GRAPH_HTTP_HOST=127.0.0.1 +HASH_GRAPH_HTTP_PORT=4000 +HASH_GRAPH_RPC_HOST=127.0.0.1 +HASH_GRAPH_RPC_PORT=4002 HASH_GRAPH_TEST_API_HOST=127.0.0.1 HASH_GRAPH_TEST_API_PORT=4001 diff --git a/.env.development b/.env.development index 0fb81c8a829..183708f08c3 100644 --- a/.env.development +++ b/.env.development @@ -8,6 +8,9 @@ HASH_TEMPORAL_PG_DATABASE=dev_temporal HASH_TEMPORAL_VISIBILITY_PG_DATABASE=dev_temporal_visibility HASH_GRAPH_PG_DATABASE=dev_graph +HASH_GRAPH_RPC_ENABLED=true +HASH_RPC_ENABLED=true + # For locally-running minio instance AWS_REGION=local AWS_S3_UPLOADS_ENDPOINT=http://localhost:9000 diff --git a/apps/hash-ai-worker-ts/README.md b/apps/hash-ai-worker-ts/README.md index c7ca127c15b..fd9d5ee4767 100644 --- a/apps/hash-ai-worker-ts/README.md +++ b/apps/hash-ai-worker-ts/README.md @@ -10,8 +10,10 @@ The service uses the following environment variables: - `HASH_TEMPORAL_SERVER_PORT`: The port that the Temporal server is running on (defaults to `7233`). - `OPENAI_API_KEY`: The OpenAI API key that is made available to workflows and activities. - `ANTHROPIC_API_KEY`: The Anthropic API key that is made available to workflows and activities. -- `HASH_GRAPH_API_HOST`: The host address that the HASH Graph API is running on, e.g. `graph`, `127.0.0.1` -- `HASH_GRAPH_API_PORT`: The port that the HASH Graph API is running on, e.g. `4000` +- `HASH_GRAPH_HTTP_HOST`: The host address that the HASH Graph service is running on, e.g. `graph`, `127.0.0.1` +- `HASH_GRAPH_HTTP_PORT`: The port that the HASH Graph HTTP service is running on, e.g. `4000` +- `HASH_GRAPH_RPC_HOST`: The host address that the HASH Graph RPC service is running on, e.g. `graph`, `127.0.0.1` +- `HASH_GRAPH_RPC_PORT`: The port that the HASH Graph RPC service is running on, e.g. `4002` - `INTERNAL_API_HOST`: The host for the internal API, required if the internal API is not running locally for workflows making use of the `getWebSearchResultsActivity` activity - `INTERNAL_API_KEY`: The API key used to authenticate with the internal API, required for workflows making use of the `getWebSearchResultsActivity` activity - `HASH_VAULT_HOST`: The host address (including protocol) that the Vault server is running on, e.g. `http://127.0.0.1` diff --git a/apps/hash-ai-worker-ts/src/activities/shared/graph-api-client.ts b/apps/hash-ai-worker-ts/src/activities/shared/graph-api-client.ts index bd02e593e79..4fd91257959 100644 --- a/apps/hash-ai-worker-ts/src/activities/shared/graph-api-client.ts +++ b/apps/hash-ai-worker-ts/src/activities/shared/graph-api-client.ts @@ -4,6 +4,6 @@ import { getRequiredEnv } from "@local/hash-backend-utils/environment"; import { logger } from "../../shared/logger.js"; export const graphApiClient = createGraphClient(logger, { - host: getRequiredEnv("HASH_GRAPH_API_HOST"), - port: parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10), + host: getRequiredEnv("HASH_GRAPH_HTTP_HOST"), + port: parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10), }); diff --git a/apps/hash-ai-worker-ts/src/main.ts b/apps/hash-ai-worker-ts/src/main.ts index 504a5c4d92c..f1d5ddec316 100644 --- a/apps/hash-ai-worker-ts/src/main.ts +++ b/apps/hash-ai-worker-ts/src/main.ts @@ -100,8 +100,8 @@ async function run() { logger.info("Starting AI worker..."); const graphApiClient = createGraphClient(logger, { - host: getRequiredEnv("HASH_GRAPH_API_HOST"), - port: parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10), + host: getRequiredEnv("HASH_GRAPH_HTTP_HOST"), + port: parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10), }); logger.info("Created Graph client"); diff --git a/apps/hash-api/src/ensure-system-graph-is-initialized.ts b/apps/hash-api/src/ensure-system-graph-is-initialized.ts index 380923429f1..0ae3562763d 100644 --- a/apps/hash-api/src/ensure-system-graph-is-initialized.ts +++ b/apps/hash-api/src/ensure-system-graph-is-initialized.ts @@ -14,8 +14,8 @@ const context: ImpureGraphContext = { }, }, graphApi: createGraphClient(logger, { - host: getRequiredEnv("HASH_GRAPH_API_HOST"), - port: parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10), + host: getRequiredEnv("HASH_GRAPH_HTTP_HOST"), + port: parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10), }), temporalClient: await createTemporalClient(logger), }; diff --git a/apps/hash-api/src/generate-ontology-type-ids.ts b/apps/hash-api/src/generate-ontology-type-ids.ts index 7aca3bbf2b6..a7cc35c1206 100644 --- a/apps/hash-api/src/generate-ontology-type-ids.ts +++ b/apps/hash-api/src/generate-ontology-type-ids.ts @@ -184,8 +184,8 @@ const generateOntologyIds = async () => { serviceName: "generate-ontology-ids", }); - const graphApiHost = getRequiredEnv("HASH_GRAPH_API_HOST"); - const graphApiPort = parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10); + const graphApiHost = getRequiredEnv("HASH_GRAPH_HTTP_HOST"); + const graphApiPort = parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10); const graphApi = createGraphClient(logger, { host: graphApiHost, diff --git a/apps/hash-api/src/index.ts b/apps/hash-api/src/index.ts index d5733cab7f7..79af0468000 100644 --- a/apps/hash-api/src/index.ts +++ b/apps/hash-api/src/index.ts @@ -212,8 +212,8 @@ const main = async () => { const redisEncryptedTransit = process.env.HASH_REDIS_ENCRYPTED_TRANSIT === "true"; - const graphApiHost = getRequiredEnv("HASH_GRAPH_API_HOST"); - const graphApiPort = parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10); + const graphApiHost = getRequiredEnv("HASH_GRAPH_HTTP_HOST"); + const graphApiPort = parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10); await Promise.all([ waitOnResource(`tcp:${redisHost}:${redisPort}`, logger), @@ -542,8 +542,8 @@ const main = async () => { shutdown.addCleanup("ManagedRuntime", () => runtime.dispose()); - const rpcHost = process.env.HASH_RPC_HOST ?? "127.0.0.1"; - const rpcPort = parseInt(process.env.HASH_RPC_PORT ?? "4002", 10); + const rpcHost = getRequiredEnv("HASH_GRAPH_RPC_HOST"); + const rpcPort = parseInt(process.env.HASH_GRAPH_RPC_PORT ?? "4002", 10); app.get("/rpc/echo", (req, res, next) => { // eslint-disable-next-line func-names @@ -560,10 +560,10 @@ const main = async () => { }).pipe( Effect.provide( RpcClient.connectLayer( - Transport.multiaddr(`/ip4/${rpcHost}/tcp/${rpcPort}`), + Transport.multiaddr(`/dns/${rpcHost}/tcp/${rpcPort}`), ), ), - Logger.withMinimumLogLevel(LogLevel.Trace), + Logger.withMinimumLogLevel(LogLevel.Info), ); runtime.runCallback(effect, { diff --git a/apps/hash-api/src/seed-data/seed-flow-test-types.ts b/apps/hash-api/src/seed-data/seed-flow-test-types.ts index 39255ac2606..5aaa088b941 100644 --- a/apps/hash-api/src/seed-data/seed-flow-test-types.ts +++ b/apps/hash-api/src/seed-data/seed-flow-test-types.ts @@ -165,8 +165,8 @@ const createSystemEntityTypeIfNotExists: ImpureGraphFunction< */ const seedFlowTestTypes = async () => { const graphApi = createGraphClient(logger, { - host: getRequiredEnv("HASH_GRAPH_API_HOST"), - port: parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10), + host: getRequiredEnv("HASH_GRAPH_HTTP_HOST"), + port: parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10), }); const context = { graphApi, provenance }; diff --git a/apps/hash-external-services/docker-compose.prod.yml b/apps/hash-external-services/docker-compose.prod.yml index 1f6ccea9777..822c55d3d4e 100644 --- a/apps/hash-external-services/docker-compose.prod.yml +++ b/apps/hash-external-services/docker-compose.prod.yml @@ -153,8 +153,8 @@ services: HASH_GRAPH_ALLOWED_URL_DOMAIN_PATTERN: "${HASH_GRAPH_ALLOWED_URL_DOMAIN_PATTERN}" HASH_GRAPH_TYPE_FETCHER_HOST: "type-fetcher" HASH_GRAPH_TYPE_FETCHER_PORT: "${HASH_GRAPH_TYPE_FETCHER_PORT}" - HASH_GRAPH_API_HOST: "0.0.0.0" - HASH_GRAPH_API_PORT: "${HASH_GRAPH_API_PORT}" + HASH_GRAPH_HTTP_HOST: "0.0.0.0" + HASH_GRAPH_HTTP_PORT: "${HASH_GRAPH_HTTP_PORT}" HASH_GRAPH_LOG_LEVEL: "${HASH_GRAPH_LOG_LEVEL}" HASH_GRAPH_LOG_CONSOLE_FORMAT: "${HASH_GRAPH_LOG_CONSOLE_FORMAT:-full}" HASH_GRAPH_LOG_FOLDER: "/logs/graph-service" @@ -173,7 +173,7 @@ services: "server", "--healthcheck", "--api-port", - "${HASH_GRAPH_API_PORT}", + "${HASH_GRAPH_HTTP_PORT}", ] interval: 2s timeout: 2s @@ -197,8 +197,8 @@ services: API_ORIGIN: "${API_ORIGIN}" HASH_SEED_USERS: "${HASH_SEED_USERS}" - HASH_GRAPH_API_HOST: "graph" - HASH_GRAPH_API_PORT: "${HASH_GRAPH_API_PORT}" + HASH_GRAPH_HTTP_HOST: "graph" + HASH_GRAPH_HTTP_PORT: "${HASH_GRAPH_HTTP_PORT}" LOG_LEVEL: "${LOG_LEVEL}" HASH_REDIS_HOST: "redis" diff --git a/apps/hash-graph/src/subcommand/server.rs b/apps/hash-graph/src/subcommand/server.rs index ef12041b08a..a0d44339a2d 100644 --- a/apps/hash-graph/src/subcommand/server.rs +++ b/apps/hash-graph/src/subcommand/server.rs @@ -38,33 +38,22 @@ use crate::{ }; #[derive(Debug, Clone, Parser)] -pub struct ApiAddress { +pub struct HttpAddress { /// The host the REST client is listening at. - #[clap(long, default_value = "127.0.0.1", env = "HASH_GRAPH_API_HOST")] + #[clap(long, default_value = "127.0.0.1", env = "HASH_GRAPH_HTTP_HOST")] pub api_host: String, /// The port the REST client is listening at. - #[clap(long, default_value_t = 4000, env = "HASH_GRAPH_API_PORT")] + #[clap(long, default_value_t = 4000, env = "HASH_GRAPH_HTTP_PORT")] pub api_port: u16, } -impl fmt::Display for ApiAddress { +impl fmt::Display for HttpAddress { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { write!(fmt, "{}:{}", self.api_host, self.api_port) } } -impl TryFrom for SocketAddr { - type Error = Report; - - fn try_from(address: ApiAddress) -> Result> { - address - .to_string() - .parse::() - .attach_printable(address) - } -} - #[derive(Debug, Clone, Parser)] pub struct RpcAddress { /// The host the RPC client is listening at. @@ -107,7 +96,7 @@ pub struct ServerArgs { /// The address the REST server is listening at. #[clap(flatten)] - pub api_address: ApiAddress, + pub http_address: HttpAddress, /// Enable the experimental RPC server. #[clap(long, default_value_t = false, env = "HASH_GRAPH_RPC_ENABLED")] @@ -237,7 +226,7 @@ where pub async fn server(args: ServerArgs) -> Result<(), Report> { if args.healthcheck { return wait_healthcheck( - || healthcheck(args.api_address.clone()), + || healthcheck(args.http_address.clone()), args.wait, args.timeout.map(Duration::from_secs), ) @@ -330,9 +319,9 @@ pub async fn server(args: ServerArgs) -> Result<(), Report> { rest_api_router(dependencies) }; - tracing::info!("Listening on {}", args.api_address); + tracing::info!("Listening on {}", args.http_address); axum::serve( - TcpListener::bind((args.api_address.api_host, args.api_address.api_port)) + TcpListener::bind((args.http_address.api_host, args.http_address.api_port)) .await .change_context(GraphError)?, router.into_make_service_with_connect_info::(), @@ -343,7 +332,7 @@ pub async fn server(args: ServerArgs) -> Result<(), Report> { Ok(()) } -pub async fn healthcheck(address: ApiAddress) -> Result<(), Report> { +pub async fn healthcheck(address: HttpAddress) -> Result<(), Report> { let request_url = format!("http://{address}/api-doc/openapi.json"); timeout( diff --git a/apps/hash-graph/src/subcommand/test_server.rs b/apps/hash-graph/src/subcommand/test_server.rs index 0ada05304c7..28a66faefc4 100644 --- a/apps/hash-graph/src/subcommand/test_server.rs +++ b/apps/hash-graph/src/subcommand/test_server.rs @@ -17,7 +17,7 @@ use tokio_postgres::NoTls; use crate::{ error::{GraphError, HealthcheckError}, - subcommand::{server::ApiAddress, wait_healthcheck}, + subcommand::{server::HttpAddress, wait_healthcheck}, }; #[derive(Debug, Parser)] @@ -31,7 +31,7 @@ pub struct TestServerArgs { /// The address the REST server is listening at. #[clap(flatten)] - pub api_address: ApiAddress, + pub http_address: HttpAddress, /// Runs the healthcheck for the test server. #[clap(long, default_value_t = false)] @@ -63,7 +63,7 @@ pub async fn test_server(args: TestServerArgs) -> Result<(), Report> if args.healthcheck { return wait_healthcheck( - || healthcheck(args.api_address.clone()), + || healthcheck(args.http_address.clone()), args.wait, args.timeout.map(Duration::from_secs), ) @@ -101,9 +101,9 @@ pub async fn test_server(args: TestServerArgs) -> Result<(), Report> let router = hash_graph_test_server::routes(pool, zanzibar_client); - tracing::info!("Listening on {}", args.api_address); + tracing::info!("Listening on {}", args.http_address); axum::serve( - TcpListener::bind((args.api_address.api_host, args.api_address.api_port)) + TcpListener::bind((args.http_address.api_host, args.http_address.api_port)) .await .change_context(GraphError)?, router.into_make_service_with_connect_info::(), @@ -114,7 +114,7 @@ pub async fn test_server(args: TestServerArgs) -> Result<(), Report> Ok(()) } -pub async fn healthcheck(address: ApiAddress) -> Result<(), Report> { +pub async fn healthcheck(address: HttpAddress) -> Result<(), Report> { let request_url = format!("http://{address}/snapshot"); timeout( diff --git a/apps/hash-integration-worker/README.md b/apps/hash-integration-worker/README.md index e5351b2d1d4..738b6fc54cf 100644 --- a/apps/hash-integration-worker/README.md +++ b/apps/hash-integration-worker/README.md @@ -6,8 +6,10 @@ This app is a Temporal worker that is able to run workflows and activities for d The service uses the following environment variables: -- `HASH_GRAPH_API_HOST`: The host address (including protocol) that the HASH Graph API is running on, e.g. `http://localhost` -- `HASH_GRAPH_API_PORT`: The port that the HASH Graph API is running on, e.g. `4000` +- `HASH_GRAPH_HTTP_HOST`: The host address that the HASH Graph HTTP service is running on, e.g. `graph`, `127.0.0.1` +- `HASH_GRAPH_HTTP_PORT`: The port that the HASH Graph HTTP service is running on, e.g. `4000` +- `HASH_GRAPH_RPC_HOST`: The host address that the HASH Graph RPC service is running on, e.g. `graph`, `127.0.0.1` +- `HASH_GRAPH_RPC_PORT`: The port that the HASH Graph RPC service is running on, e.g. `4002` - `HASH_TEMPORAL_SERVER_HOST`: The host address (including protocol) that the Temporal server is running on (defaults to `http://localhost`). - `HASH_TEMPORAL_SERVER_PORT`: The port that the Temporal server is running on (defaults to `7233`). - `HASH_VAULT_HOST`: The host address (including protocol) that the Vault server is running on, e.g. `http://127.0.0.1` diff --git a/apps/hash-integration-worker/src/main.ts b/apps/hash-integration-worker/src/main.ts index 519b7e1307e..62360813c69 100644 --- a/apps/hash-integration-worker/src/main.ts +++ b/apps/hash-integration-worker/src/main.ts @@ -84,8 +84,8 @@ async function run() { // eslint-disable-next-line no-console console.info("Starting integration worker..."); const graphApiClient = createGraphClient(logger, { - host: getRequiredEnv("HASH_GRAPH_API_HOST"), - port: parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10), + host: getRequiredEnv("HASH_GRAPH_HTTP_HOST"), + port: parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10), }); const worker = await Worker.create({ diff --git a/infra/terraform/hash/.terraform.lock.hcl b/infra/terraform/hash/.terraform.lock.hcl index c7fc6608c3b..4e30f3aad9c 100644 --- a/infra/terraform/hash/.terraform.lock.hcl +++ b/infra/terraform/hash/.terraform.lock.hcl @@ -1,6 +1,29 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. +provider "registry.terraform.io/cloudflare/cloudflare" { + version = "4.47.0" + constraints = "~> 4.0" + hashes = [ + "h1:1Te3c+iMmpQYOHrB2WP3rHSjOQgT46T8qfbwV6ocz3I=", + "zh:1df6a36bad08e95518987a15584e535a1dad5fa0ee6e067c0c39d709a285f6b9", + "zh:20dce2a63f24f571f4d52d3217811d71e8d21f149f751d5972ec19200674638a", + "zh:6571aeeb61d4a27b4210a1979028119a1905e162b0c3845e7b549d6e0a08c36d", + "zh:87ec7ebe65c8884e174999c22970e2f28b0da4e0f65bdc92db051eb3dd649f78", + "zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f", + "zh:a20d1c0865a9443ada90ab7c83bd8605024452cf1e9f3b2ed2efcf06221b7835", + "zh:a5a5a91f658029ae3bb0414643ca09bd6a98a1980e197a9eb2ea4ba96a190d88", + "zh:b12623a85840821c465b87b1d65542f8f4a77079afef0ad2cc102a9f6eb4045c", + "zh:b83ac4f0b81aee32b3670f5870245172741bb86b153623da687d3c45ec9c1af9", + "zh:bb1ad4fcb949b12e5b40a21e65963ff64e20e72ab4c87a3ec91306b440a2cf35", + "zh:cb5a8bc24444a9d8f536b5acb7f6346f12c03e23539b183cb370f4876992360f", + "zh:ce6cc02ac4fc8cdf48a64254fdb0ea859b5b48e7fc08c7f1fcb8e9364ed32434", + "zh:e44643c86d38799991f5eb2378c00ca4738ec0f21dd64536dadffd71a337d778", + "zh:e5024d6792fcaa974b5f294399eea9b9c7d3d5d228423e71941994858a20c58f", + "zh:f9b18d0443487e30e0f3b83e311f17c85d184dc9f55b3f9b31332e815c41745a", + ] +} + provider "registry.terraform.io/cyrilgdn/postgresql" { version = "1.18.0" constraints = "1.18.0" @@ -47,78 +70,78 @@ provider "registry.terraform.io/hashicorp/aws" { } provider "registry.terraform.io/hashicorp/external" { - version = "2.3.1" + version = "2.3.4" hashes = [ - "h1:gznGscVJ0USxy4CdihpjRKPsKvyGr/zqPvBoFLJTQDc=", - "zh:001e2886dc81fc98cf17cf34c0d53cb2dae1e869464792576e11b0f34ee92f54", - "zh:2eeac58dd75b1abdf91945ac4284c9ccb2bfb17fa9bdb5f5d408148ff553b3ee", - "zh:2fc39079ba61411a737df2908942e6970cb67ed2f4fb19090cd44ce2082903dd", - "zh:472a71c624952cff7aa98a7b967f6c7bb53153dbd2b8f356ceb286e6743bb4e2", - "zh:4cff06d31272aac8bc35e9b7faec42cf4554cbcbae1092eaab6ab7f643c215d9", + "h1:cCabxnWQ5fX1lS7ZqgUzsvWmKZw9FA7NRxAZ94vcTcc=", + "zh:037fd82cd86227359bc010672cd174235e2d337601d4686f526d0f53c87447cb", + "zh:0ea1db63d6173d01f2fa8eb8989f0809a55135a0d8d424b08ba5dabad73095fa", + "zh:17a4d0a306566f2e45778fbac48744b6fd9c958aaa359e79f144c6358cb93af0", + "zh:298e5408ab17fd2e90d2cd6d406c6d02344fe610de5b7dae943a58b958e76691", + "zh:38ecfd29ee0785fd93164812dcbe0664ebbe5417473f3b2658087ca5a0286ecb", + "zh:59f6a6f31acf66f4ea3667a555a70eba5d406c6e6d93c2c641b81d63261eeace", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7ed16ccd2049fa089616b98c0bd57219f407958f318f3c697843e2397ddf70df", - "zh:842696362c92bf2645eb85c739410fd51376be6c488733efae44f4ce688da50e", - "zh:8985129f2eccfd7f1841ce06f3bf2bbede6352ec9e9f926fbaa6b1a05313b326", - "zh:a5f0602d8ec991a5411ef42f872aa90f6347e93886ce67905c53cfea37278e05", - "zh:bf4ab82cbe5256dcef16949973bf6aa1a98c2c73a98d6a44ee7bc40809d002b8", - "zh:e70770be62aa70198fa899526d671643ff99eecf265bf1a50e798fc3480bd417", + "zh:ad0279dfd09d713db0c18469f585e58d04748ca72d9ada83883492e0dd13bd58", + "zh:c69f66fd21f5e2c8ecf7ca68d9091c40f19ad913aef21e3ce23836e91b8cbb5f", + "zh:d4a56f8c48aa86fc8e0c233d56850f5783f322d6336f3bf1916e293246b6b5d4", + "zh:f2b394ebd4af33f343835517e80fc876f79361f4688220833bc3c77655dd2202", + "zh:f31982f29f12834e5d21e010856eddd19d59cd8f449adf470655bfd19354377e", ] } provider "registry.terraform.io/hashicorp/local" { - version = "2.4.0" + version = "2.5.2" hashes = [ - "h1:ZUEYUmm2t4vxwzxy1BvN1wL6SDWrDxfH7pxtzX8c6d0=", - "zh:53604cd29cb92538668fe09565c739358dc53ca56f9f11312b9d7de81e48fab9", - "zh:66a46e9c508716a1c98efbf793092f03d50049fa4a83cd6b2251e9a06aca2acf", - "zh:70a6f6a852dd83768d0778ce9817d81d4b3f073fab8fa570bff92dcb0824f732", + "h1:IyFbOIO6mhikFNL/2h1iZJ6kyN3U00jgkpCLUCThAfE=", + "zh:136299545178ce281c56f36965bf91c35407c11897f7082b3b983d86cb79b511", + "zh:3b4486858aa9cb8163378722b642c57c529b6c64bfbfc9461d940a84cd66ebea", + "zh:4855ee628ead847741aa4f4fc9bed50cfdbf197f2912775dd9fe7bc43fa077c0", + "zh:4b8cd2583d1edcac4011caafe8afb7a95e8110a607a1d5fb87d921178074a69b", + "zh:52084ddaff8c8cd3f9e7bcb7ce4dc1eab00602912c96da43c29b4762dc376038", + "zh:71562d330d3f92d79b2952ffdda0dad167e952e46200c767dd30c6af8d7c0ed3", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:82a803f2f484c8b766e2e9c32343e9c89b91997b9f8d2697f9f3837f62926b35", - "zh:9708a4e40d6cc4b8afd1352e5186e6e1502f6ae599867c120967aebe9d90ed04", - "zh:973f65ce0d67c585f4ec250c1e634c9b22d9c4288b484ee2a871d7fa1e317406", - "zh:c8fa0f98f9316e4cfef082aa9b785ba16e36ff754d6aba8b456dab9500e671c6", - "zh:cfa5342a5f5188b20db246c73ac823918c189468e1382cb3c48a9c0c08fc5bf7", - "zh:e0e2b477c7e899c63b06b38cd8684a893d834d6d0b5e9b033cedc06dd7ffe9e2", - "zh:f62d7d05ea1ee566f732505200ab38d94315a4add27947a60afa29860822d3fc", - "zh:fa7ce69dde358e172bd719014ad637634bbdabc49363104f4fca759b4b73f2ce", + "zh:805f81ade06ff68fa8b908d31892eaed5c180ae031c77ad35f82cb7a74b97cf4", + "zh:8b6b3ebeaaa8e38dd04e56996abe80db9be6f4c1df75ac3cccc77642899bd464", + "zh:ad07750576b99248037b897de71113cc19b1a8d0bc235eb99173cc83d0de3b1b", + "zh:b9f1c3bfadb74068f5c205292badb0661e17ac05eb23bfe8bd809691e4583d0e", + "zh:cc4cbcd67414fefb111c1bf7ab0bc4beb8c0b553d01719ad17de9a047adff4d1", ] } provider "registry.terraform.io/hashicorp/tls" { - version = "4.0.4" + version = "4.0.6" hashes = [ - "h1:GZcFizg5ZT2VrpwvxGBHQ/hO9r6g0vYdQqx3bFD3anY=", - "zh:23671ed83e1fcf79745534841e10291bbf34046b27d6e68a5d0aab77206f4a55", - "zh:45292421211ffd9e8e3eb3655677700e3c5047f71d8f7650d2ce30242335f848", - "zh:59fedb519f4433c0fdb1d58b27c210b27415fddd0cd73c5312530b4309c088be", - "zh:5a8eec2409a9ff7cd0758a9d818c74bcba92a240e6c5e54b99df68fff312bbd5", - "zh:5e6a4b39f3171f53292ab88058a59e64825f2b842760a4869e64dc1dc093d1fe", - "zh:810547d0bf9311d21c81cc306126d3547e7bd3f194fc295836acf164b9f8424e", - "zh:824a5f3617624243bed0259d7dd37d76017097dc3193dac669be342b90b2ab48", - "zh:9361ccc7048be5dcbc2fafe2d8216939765b3160bd52734f7a9fd917a39ecbd8", - "zh:aa02ea625aaf672e649296bce7580f62d724268189fe9ad7c1b36bb0fa12fa60", - "zh:c71b4cd40d6ec7815dfeefd57d88bc592c0c42f5e5858dcc88245d371b4b8b1e", - "zh:dabcd52f36b43d250a3d71ad7abfa07b5622c69068d989e60b79b2bb4f220316", + "h1:n3M50qfWfRSpQV9Pwcvuse03pEizqrmYEryxKky4so4=", + "zh:10de0d8af02f2e578101688fd334da3849f56ea91b0d9bd5b1f7a243417fdda8", + "zh:37fc01f8b2bc9d5b055dc3e78bfd1beb7c42cfb776a4c81106e19c8911366297", + "zh:4578ca03d1dd0b7f572d96bd03f744be24c726bfd282173d54b100fd221608bb", + "zh:6c475491d1250050765a91a493ef330adc24689e8837a0f07da5a0e1269e11c1", + "zh:81bde94d53cdababa5b376bbc6947668be4c45ab655de7aa2e8e4736dfd52509", + "zh:abdce260840b7b050c4e401d4f75c7a199fafe58a8b213947a258f75ac18b3e8", + "zh:b754cebfc5184873840f16a642a7c9ef78c34dc246a8ae29e056c79939963c7a", + "zh:c928b66086078f9917aef0eec15982f2e337914c5c4dbc31dd4741403db7eb18", + "zh:cded27bee5f24de6f2ee0cfd1df46a7f88e84aaffc2ecbf3ff7094160f193d50", + "zh:d65eb3867e8f69aaf1b8bb53bd637c99c6b649ba3db16ded50fa9a01076d1a27", + "zh:ecb0c8b528c7a619fa71852bb3fb5c151d47576c5aab2bf3af4db52588722eeb", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } provider "registry.terraform.io/hashicorp/vault" { - version = "3.19.0" + version = "3.25.0" constraints = "~> 3.15" hashes = [ - "h1:wt3U9/SC+IDaif2Kkmxpl5pmEJ4spgKlus6UH6Ab95Q=", - "zh:2571ca03777afcb70d51d7f591bfa0bf770bbcc93bb87563ec295b17a9b21947", - "zh:25d096ab433e4eb5ed0f17f82beb661681c6abac93df35c15d5adf26da822709", - "zh:33776aa50d597448539251b4b706b4dbaf599ebee47a4244361400f93cd10986", - "zh:4d9d1fe67c0a7d2097f3d67fa867fd34dec6d880fe4d76e93bb38ccf74a2fadf", - "zh:5c2310226e1be065e75b7cf29633fd175a2180f5d9d9fb6f587e6b3d6ffb328d", - "zh:66b0e3e2819bb34fd592bb436391b08cb34f345832f4db1057b0169872537931", + "h1:3GN5k6zxDAI5gfcKENb/jnJyFGWA/0JoumnD6eyVZjs=", + "zh:430308f5dbd322a2e5afafd2be810f44eb35e28afa0aa0ac30b270cd6f413da8", + "zh:6c36da504c4af84ea9fbaf1e6c2560f691dc3d2d7f0b382a937bfae78830fa17", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:85f44baf07eae1c9087c9ddb867d561d0fb6adf8f081558587c71bb99aba034f", - "zh:92cffaeebf531b27f5f1d798dca04813ae1541381e67cffe7157facf84a8f9c7", - "zh:c2964602306935ddd2d005b38207b57a919c1574737c3daff82e058a16439d7a", - "zh:cd7fe84a7030b59bc4457a251ec97e0286956a0c3fb489323affcb306116fdd1", - "zh:f68303735e4a2ac0e9122feb65f338d99bee835a4309ca34dac77879c8bfd637", + "zh:7bc39cb2a7d91631cb8be54b0b06de29fb47910923e54f779e74d8b218b1ab70", + "zh:7e4a5bebcfa19b9f1e3a6bbda5c6771b6dd28b3dfa19fdf3d4fced419cfa416f", + "zh:7ea473203b37d006a0d2b1cdc8bff55c96b3c5819dbb62862cdabff6f2f0e2f2", + "zh:9ad136feece62f0c545fefa4592b2cdaa896a39acb697fb129233dce880a69aa", + "zh:ad0c9980295c902804af23da0250830b912eb13089349bf5c7be0649fac2689c", + "zh:b305835cc13dcd9ec996d49d23163c6311f30786296f86ca5657b93aea4f3591", + "zh:d8fe6ab7da12efbb5b122ae9b6856375c5a3759add9df577a8fb448898ceffe3", + "zh:ef59ef2c06a55571e64fdd5888a074ed9556436738e9737e32bacab93ca133ff", + "zh:f59c2605d916e1806dc494241467dd430194f5e7bdbf331c5aca904873347ad8", ] } diff --git a/infra/terraform/hash/hash_application/api.tf b/infra/terraform/hash/hash_application/api.tf index 57df0aea3a8..da2564028f3 100644 --- a/infra/terraform/hash/hash_application/api.tf +++ b/infra/terraform/hash/hash_application/api.tf @@ -56,8 +56,10 @@ locals { [ { name = "HASH_TEMPORAL_SERVER_HOST", value = var.temporal_host }, { name = "HASH_TEMPORAL_SERVER_PORT", value = var.temporal_port }, - { name = "HASH_GRAPH_API_HOST", value = local.graph_container_port_dns }, - { name = "HASH_GRAPH_API_PORT", value = tostring(local.graph_container_port) }, + { name = "HASH_GRAPH_HTTP_HOST", value = local.graph_http_container_port_dns }, + { name = "HASH_GRAPH_HTTP_PORT", value = tostring(local.graph_http_container_port) }, + { name = "HASH_GRAPH_RPC_HOST", value = local.graph_rpc_container_port_dns }, + { name = "HASH_GRAPH_RPC_PORT", value = tostring(local.graph_rpc_container_port) }, ]) secrets = [ @@ -112,8 +114,10 @@ locals { [ { name = "HASH_TEMPORAL_SERVER_HOST", value = var.temporal_host }, { name = "HASH_TEMPORAL_SERVER_PORT", value = var.temporal_port }, - { name = "HASH_GRAPH_API_HOST", value = local.graph_container_port_dns }, - { name = "HASH_GRAPH_API_PORT", value = tostring(local.graph_container_port) }, + { name = "HASH_GRAPH_HTTP_HOST", value = local.graph_http_container_port_dns }, + { name = "HASH_GRAPH_HTTP_PORT", value = tostring(local.graph_http_container_port) }, + { name = "HASH_GRAPH_RPC_HOST", value = local.graph_rpc_container_port_dns }, + { name = "HASH_GRAPH_RPC_PORT", value = tostring(local.graph_rpc_container_port) }, ]) secrets = [ diff --git a/infra/terraform/hash/hash_application/graph.tf b/infra/terraform/hash/hash_application/graph.tf index a3efb0ba1ce..77e28b89e6b 100644 --- a/infra/terraform/hash/hash_application/graph.tf +++ b/infra/terraform/hash/hash_application/graph.tf @@ -1,10 +1,13 @@ locals { - graph_service_name = "graph" - graph_prefix = "${var.prefix}-${local.graph_service_name}" - graph_param_prefix = "${local.param_prefix}/${local.graph_service_name}" - graph_container_port = 4000 - graph_container_port_name = local.graph_service_name - graph_container_port_dns = "${local.graph_container_port_name}.${aws_service_discovery_private_dns_namespace.app.name}" + graph_service_name = "graph" + graph_prefix = "${var.prefix}-${local.graph_service_name}" + graph_param_prefix = "${local.param_prefix}/${local.graph_service_name}" + graph_http_container_port = 4000 + graph_http_container_port_name = "${local.graph_service_name}-http" + graph_http_container_port_dns = "${local.graph_http_container_port_name}.${aws_service_discovery_private_dns_namespace.app.name}" + graph_rpc_container_port = 4002 + graph_rpc_container_port_name = "${local.graph_service_name}-rpc" + graph_rpc_container_port_dns = "${local.graph_rpc_container_port_name}.${aws_service_discovery_private_dns_namespace.app.name}" } @@ -82,10 +85,18 @@ resource "aws_security_group" "graph" { } ingress { - from_port = local.graph_container_port - to_port = local.graph_container_port + from_port = local.graph_http_container_port + to_port = local.graph_http_container_port protocol = "tcp" - description = "Allow communication with the graph" + description = "Allow communication with the graph through OpenAPI" + cidr_blocks = [var.vpc.cidr_block] + } + + ingress { + from_port = local.graph_rpc_container_port + to_port = local.graph_rpc_container_port + protocol = "tcp" + description = "Allow communication with the graph through HaRPC" cidr_blocks = [var.vpc.cidr_block] } } @@ -124,10 +135,18 @@ resource "aws_ecs_service" "graph" { namespace = aws_service_discovery_private_dns_namespace.app.arn service { - port_name = local.graph_container_port_name + port_name = local.graph_http_container_port_name client_alias { - port = local.graph_container_port + port = local.graph_http_container_port + } + } + + service { + port_name = local.graph_rpc_container_port_name + + client_alias { + port = local.graph_rpc_container_port } } } @@ -180,9 +199,15 @@ locals { } portMappings = [ { - name = local.graph_container_port_name + name = local.graph_http_container_port_name appProtocol = "http" - containerPort = local.graph_container_port + containerPort = local.graph_http_container_port + protocol = "tcp" + }, + { + name = local.graph_rpc_container_port_name + appProtocol = "http2" + containerPort = local.graph_rpc_container_port protocol = "tcp" } ] @@ -200,8 +225,10 @@ locals { { name = env_var.name, value = env_var.value } if !env_var.secret ], [ - { name = "HASH_GRAPH_API_HOST", value = "0.0.0.0" }, - { name = "HASH_GRAPH_API_PORT", value = tostring(local.graph_container_port) }, + { name = "HASH_GRAPH_HTTP_HOST", value = "0.0.0.0" }, + { name = "HASH_GRAPH_HTTP_PORT", value = tostring(local.graph_http_container_port) }, + { name = "HASH_GRAPH_RPC_HOST", value = "0.0.0.0" }, + { name = "HASH_GRAPH_RPC_PORT", value = tostring(local.graph_rpc_container_port) }, { name = "HASH_GRAPH_TYPE_FETCHER_HOST", value = local.type_fetcher_container_port_dns }, { name = "HASH_GRAPH_TYPE_FETCHER_PORT", value = tostring(local.type_fetcher_container_port) }, { name = "HASH_SPICEDB_HOST", value = "http://${local.spicedb_container_http_port_dns}" }, diff --git a/infra/terraform/hash/hash_application/main.tf b/infra/terraform/hash/hash_application/main.tf index 0de27f0f4e5..c155f1aee02 100644 --- a/infra/terraform/hash/hash_application/main.tf +++ b/infra/terraform/hash/hash_application/main.tf @@ -136,10 +136,18 @@ resource "aws_security_group" "alb_sg" { } egress { - from_port = local.graph_container_port - to_port = local.graph_container_port + from_port = local.graph_http_container_port + to_port = local.graph_http_container_port protocol = "tcp" - description = "Allow connections to the graph from the load balancer" + description = "Allow connections to the Graph HTTP endpoint from the load balancer" + cidr_blocks = [var.vpc.cidr_block] + } + + egress { + from_port = local.graph_rpc_container_port + to_port = local.graph_rpc_container_port + protocol = "tcp" + description = "Allow connections to the Graph RPC endpoint from the load balancer" cidr_blocks = [var.vpc.cidr_block] } } @@ -500,10 +508,17 @@ resource "aws_security_group" "app_sg" { cidr_blocks = ["0.0.0.0/0"] } egress { - from_port = local.graph_container_port - to_port = local.graph_container_port + from_port = local.graph_http_container_port + to_port = local.graph_http_container_port + protocol = "tcp" + description = "Allow connections to the Graph HTTP interface" + cidr_blocks = [var.vpc.cidr_block] + } + egress { + from_port = local.graph_rpc_container_port + to_port = local.graph_rpc_container_port protocol = "tcp" - description = "Allow connections to the graph" + description = "Allow connections to the Graph RPC interface" cidr_blocks = [var.vpc.cidr_block] } diff --git a/infra/terraform/hash/hash_application/temporal_worker_ai_ts.tf b/infra/terraform/hash/hash_application/temporal_worker_ai_ts.tf index f920e39cc86..b7f316f6cee 100644 --- a/infra/terraform/hash/hash_application/temporal_worker_ai_ts.tf +++ b/infra/terraform/hash/hash_application/temporal_worker_ai_ts.tf @@ -47,8 +47,10 @@ locals { [ { name = "HASH_TEMPORAL_SERVER_HOST", value = var.temporal_host }, { name = "HASH_TEMPORAL_SERVER_PORT", value = var.temporal_port }, - { name = "HASH_GRAPH_API_HOST", value = local.graph_container_port_dns }, - { name = "HASH_GRAPH_API_PORT", value = tostring(local.graph_container_port) }, + { name = "HASH_GRAPH_HTTP_HOST", value = local.graph_http_container_port_dns }, + { name = "HASH_GRAPH_HTTP_PORT", value = tostring(local.graph_http_container_port) }, + { name = "HASH_GRAPH_RPC_HOST", value = local.graph_rpc_container_port_dns }, + { name = "HASH_GRAPH_RPC_PORT", value = tostring(local.graph_rpc_container_port) }, ], ) diff --git a/infra/terraform/hash/hash_application/temporal_worker_integration.tf b/infra/terraform/hash/hash_application/temporal_worker_integration.tf index ef43a90dbf2..50ea20dac5b 100644 --- a/infra/terraform/hash/hash_application/temporal_worker_integration.tf +++ b/infra/terraform/hash/hash_application/temporal_worker_integration.tf @@ -47,8 +47,10 @@ locals { [ { name = "HASH_TEMPORAL_SERVER_HOST", value = var.temporal_host }, { name = "HASH_TEMPORAL_SERVER_PORT", value = var.temporal_port }, - { name = "HASH_GRAPH_API_HOST", value = local.graph_container_port_dns }, - { name = "HASH_GRAPH_API_PORT", value = tostring(local.graph_container_port) }, + { name = "HASH_GRAPH_HTTP_HOST", value = local.graph_http_container_port_dns }, + { name = "HASH_GRAPH_HTTP_PORT", value = tostring(local.graph_http_container_port) }, + { name = "HASH_GRAPH_RPC_HOST", value = local.graph_rpc_container_port_dns }, + { name = "HASH_GRAPH_RPC_PORT", value = tostring(local.graph_rpc_container_port) }, ], ) diff --git a/infra/terraform/hash/main.tf b/infra/terraform/hash/main.tf index 4ceb8fec619..18b5d2a6f58 100644 --- a/infra/terraform/hash/main.tf +++ b/infra/terraform/hash/main.tf @@ -257,6 +257,7 @@ module "application" { { name = "HASH_GRAPH_PG_HOST", secret = false, value = module.postgres.pg_host }, { name = "HASH_GRAPH_PG_PORT", secret = false, value = module.postgres.pg_port }, { name = "HASH_GRAPH_PG_DATABASE", secret = false, value = "graph" }, + # { name = "HASH_GRAPH_RPC_ENABLED", secret = false, value = "true" }, { name = "HASH_SPICEDB_GRPC_PRESHARED_KEY", secret = true, value = sensitive(data.vault_kv_secret_v2.secrets.data["spicedb_grpc_preshared_key"]) @@ -357,6 +358,7 @@ module "application" { { name = "HASH_REDIS_PORT", secret = false, value = module.redis.node.port }, { name = "HASH_REDIS_ENCRYPTED_TRANSIT", secret = false, value = "true" }, { name = "HASH_INTEGRATION_QUEUE_NAME", secret = false, value = "integration" }, + # { name = "HASH_RPC_ENABLED", secret = false, value = "true" }, { name = "HASH_VAULT_HOST", secret = true, value = sensitive(data.vault_kv_secret_v2.secrets.data["hash_vault_host"]) diff --git a/infra/terraform/hash/prod-usea1.tfvars b/infra/terraform/hash/prod-usea1.tfvars index df6adc48aca..2a8aa8bb024 100644 --- a/infra/terraform/hash/prod-usea1.tfvars +++ b/infra/terraform/hash/prod-usea1.tfvars @@ -39,12 +39,12 @@ hydra_env_vars = [ { name = "COOKIES_PATH", secret = false, value = "/" }, { name = "SERVE_COOKIES_DOMAIN", secret = false, value = "hash.ai" }, { name = "SERVE_COOKIES_SAME_SITE_MODE", secret = false, value = "Lax" }, - { name = "URLS_CONSENT", secret = false, value = "https://app-api.hash.ai/oauth2/consent"}, + { name = "URLS_CONSENT", secret = false, value = "https://app-api.hash.ai/oauth2/consent" }, { name = "URLS_LOGIN", secret = false, value = "https://app.hash.ai/signin" }, { name = "URLS_REGISTRATION", secret = false, value = "https://app.hash.ai/signup" }, { name = "URLS_POST_LOGOUT_REDIRECT", secret = false, value = "https://app.hash.ai" }, { name = "URLS_IDENTITY_PROVIDER_PUBLICURL", secret = false, value = "http://localhost:4433" }, # Kratos public endpoint - { name = "URLS_IDENTITY_PROVIDER_URL", secret = false, value = "http://localhost:4434" }, # Kratos admin endpoint + { name = "URLS_IDENTITY_PROVIDER_URL", secret = false, value = "http://localhost:4434" }, # Kratos admin endpoint { name = "URLS_SELF_ISSUER", secret = false, value = "https://app-api.hash.ai" }, { name = "URLS_SELF_PUBLIC", secret = false, value = "https://app-api.hash.ai" } ] @@ -57,7 +57,7 @@ hash_graph_env_vars = [ { name = "HASH_GRAPH_LOG_FILE_ENABLED", secret = false, value = "false" }, { name = "HASH_GRAPH_LOG_CONSOLE_FORMAT", secret = false, value = "full" }, { name = "HASH_GRAPH_LOG_CONSOLE_COLOR", secret = false, value = "never" }, - { name = "HASH_GRAPH_LOG_LEVEL", secret = false, value = "trace,h2=info,tokio_util=debug,tower=info,tonic=debug,hyper=info,tokio_postgres=info,rustls=info,tarpc=info" }, + { name = "HASH_GRAPH_LOG_LEVEL", secret = false, value = "info" }, { name = "RUST_BACKTRACE", secret = false, value = "1" } ] diff --git a/tests/hash-backend-integration/src/tests/util.ts b/tests/hash-backend-integration/src/tests/util.ts index e20b08692fa..e53baccc02a 100644 --- a/tests/hash-backend-integration/src/tests/util.ts +++ b/tests/hash-backend-integration/src/tests/util.ts @@ -31,8 +31,8 @@ export const createTestImpureGraphContext = (): ImpureGraphContext< serviceName: "integration-tests", }); - const graphApiHost = getRequiredEnv("HASH_GRAPH_API_HOST"); - const graphApiPort = parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10); + const graphApiHost = getRequiredEnv("HASH_GRAPH_HTTP_HOST"); + const graphApiPort = parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10); const graphApi = createGraphClient(logger, { host: graphApiHost, diff --git a/tests/hash-backend-load/src/graph/api.ts b/tests/hash-backend-load/src/graph/api.ts index 0c1070e7b32..06fc6668a32 100644 --- a/tests/hash-backend-load/src/graph/api.ts +++ b/tests/hash-backend-load/src/graph/api.ts @@ -17,8 +17,8 @@ export const getGraphApiClient = (): GraphApi => { serviceName: "hash-backend-load", }), { - host: getRequiredEnv("HASH_GRAPH_API_HOST"), - port: parseInt(getRequiredEnv("HASH_GRAPH_API_PORT"), 10), + host: getRequiredEnv("HASH_GRAPH_HTTP_HOST"), + port: parseInt(getRequiredEnv("HASH_GRAPH_HTTP_PORT"), 10), requestInterceptor: (request) => { opentelemetry.propagation.inject( opentelemetry.context.active(), From cc368949fff48d79a1647ae5d53f4570c95c0975 Mon Sep 17 00:00:00 2001 From: Ciaran Morinan <37743469+CiaranMn@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:44:11 +0000 Subject: [PATCH 2/4] H-3609: Reduce cost of polling for notification and draft entities counts (#5838) --- .../queries/knowledge/entity.queries.ts | 1 + .../entity-page-header.tsx | 25 +- apps/hash-frontend/src/pages/_app.page.tsx | 12 +- apps/hash-frontend/src/pages/actions.page.tsx | 24 +- .../draft-entities-bulk-actions-dropdown.tsx | 75 ++-- .../actions.page}/draft-entities-context.tsx | 28 +- .../src/pages/actions.page/draft-entities.tsx | 2 +- .../src/pages/actions.page/draft-entity.tsx | 2 +- .../draft-entity-action-buttons.tsx | 6 +- .../draft-entity/draft-entity-chip.tsx | 4 +- .../draft-entity/draft-entity-type.tsx | 10 +- .../src/pages/notifications.page.tsx | 366 +---------------- .../notifications-table.tsx | 374 ++++++++++++++++++ .../notifications-with-links-context.tsx | 120 +++--- .../shared/accept-draft-entity-button.tsx | 45 +-- .../shared/discard-draft-entity-button.tsx | 40 +- .../shared/draft-entities-count-context.tsx | 92 +++++ .../notifications-dropdown.tsx | 4 +- .../layout/layout-with-header/page-header.tsx | 6 +- .../layout/layout-with-sidebar/sidebar.tsx | 12 +- .../src/shared/notification-count-context.tsx | 330 ++++++++++++++++ .../shared/notification-entities-context.tsx | 334 ---------------- .../graphql/type-defs/generation.typedef.ts | 2 - .../type-defs/knowledge/entity.typedef.ts | 1 + 24 files changed, 998 insertions(+), 917 deletions(-) rename apps/hash-frontend/src/{shared => pages/actions.page}/draft-entities-context.tsx (80%) create mode 100644 apps/hash-frontend/src/pages/notifications.page/notifications-table.tsx rename apps/hash-frontend/src/pages/{shared => notifications.page}/notifications-with-links-context.tsx (84%) create mode 100644 apps/hash-frontend/src/shared/draft-entities-count-context.tsx create mode 100644 apps/hash-frontend/src/shared/notification-count-context.tsx delete mode 100644 apps/hash-frontend/src/shared/notification-entities-context.tsx diff --git a/apps/hash-frontend/src/graphql/queries/knowledge/entity.queries.ts b/apps/hash-frontend/src/graphql/queries/knowledge/entity.queries.ts index f690f36727c..6b55c04f0d9 100644 --- a/apps/hash-frontend/src/graphql/queries/knowledge/entity.queries.ts +++ b/apps/hash-frontend/src/graphql/queries/knowledge/entity.queries.ts @@ -62,6 +62,7 @@ export const getEntitySubgraphQuery = gql` ) { getEntitySubgraph(request: $request) { closedMultiEntityTypes + count definitions userPermissionsOnEntities @include(if: $includePermissions) subgraph { diff --git a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-page-wrapper/entity-page-header.tsx b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-page-wrapper/entity-page-header.tsx index 182a3076b7c..db189df4fa1 100644 --- a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-page-wrapper/entity-page-header.tsx +++ b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-page-wrapper/entity-page-header.tsx @@ -10,7 +10,6 @@ import { useRouter } from "next/router"; import type { ReactNode } from "react"; import { useContext } from "react"; -import { NotificationsWithLinksContextProvider } from "../../../../shared/notifications-with-links-context"; import { TopContextBar } from "../../../../shared/top-context-bar"; import { WorkspaceContext } from "../../../../shared/workspace-context"; import { EntityEditorTabs } from "../shared/entity-editor-tabs"; @@ -84,19 +83,17 @@ export const EntityPageHeader = ({ /> {entity && entitySubgraph ? ( - - - - - + + + ) : null} {editBar} diff --git a/apps/hash-frontend/src/pages/_app.page.tsx b/apps/hash-frontend/src/pages/_app.page.tsx index 7686fa7fb13..e0c64901c1e 100644 --- a/apps/hash-frontend/src/pages/_app.page.tsx +++ b/apps/hash-frontend/src/pages/_app.page.tsx @@ -35,14 +35,14 @@ import { hasAccessToHashQuery, meQuery } from "../graphql/queries/user.queries"; import { apolloClient } from "../lib/apollo-client"; import type { MinimalUser } from "../lib/user-and-org"; import { constructMinimalUser } from "../lib/user-and-org"; -import { DraftEntitiesContextProvider } from "../shared/draft-entities-context"; +import { DraftEntitiesCountContextProvider } from "../shared/draft-entities-count-context"; import { EntityTypesContextProvider } from "../shared/entity-types-context/provider"; import { FileUploadsProvider } from "../shared/file-upload-context"; import { KeyboardShortcutsContextProvider } from "../shared/keyboard-shortcuts-context"; import type { NextPageWithLayout } from "../shared/layout"; import { getLayoutWithSidebar, getPlainLayout } from "../shared/layout"; import { SidebarContextProvider } from "../shared/layout/layout-with-sidebar/sidebar-context"; -import { NotificationEntitiesContextProvider } from "../shared/notification-entities-context"; +import { NotificationCountContextProvider } from "../shared/notification-count-context"; import { PropertyTypesContextProvider } from "../shared/property-types-context"; import { RoutePageInfoProvider } from "../shared/routing"; import { ErrorFallback } from "./_app.page/error-fallback"; @@ -108,8 +108,8 @@ const App: FunctionComponent = ({ - - + + @@ -132,8 +132,8 @@ const App: FunctionComponent = ({ - - + + diff --git a/apps/hash-frontend/src/pages/actions.page.tsx b/apps/hash-frontend/src/pages/actions.page.tsx index 2750b6b362a..0f00c38cdec 100644 --- a/apps/hash-frontend/src/pages/actions.page.tsx +++ b/apps/hash-frontend/src/pages/actions.page.tsx @@ -24,7 +24,6 @@ import type { GetEntitySubgraphQueryVariables, } from "../graphql/api-types.gen"; import { getEntitySubgraphQuery } from "../graphql/queries/knowledge/entity.queries"; -import { useDraftEntities } from "../shared/draft-entities-context"; import { BarsSortRegularIcon } from "../shared/icons/bars-sort-regular-icon"; import type { NextPageWithLayout } from "../shared/layout"; import { getLayoutWithSidebar } from "../shared/layout"; @@ -32,8 +31,11 @@ import { MenuItem } from "../shared/ui"; import type { SortOrder } from "./actions.page/draft-entities"; import { DraftEntities } from "./actions.page/draft-entities"; import { DraftEntitiesBulkActionsDropdown } from "./actions.page/draft-entities-bulk-actions-dropdown"; +import { + DraftEntitiesContextProvider, + useDraftEntities, +} from "./actions.page/draft-entities-context"; import { InlineSelect } from "./shared/inline-select"; -import { NotificationsWithLinksContextProvider } from "./shared/notifications-with-links-context"; import { TopContextBar } from "./shared/top-context-bar"; const sortOrderHumanReadable: Record = { @@ -41,7 +43,7 @@ const sortOrderHumanReadable: Record = { "created-at-desc": "creation date/time (newest first)", }; -const ActionsPage: NextPageWithLayout = () => { +const ActionsPage = () => { const [selectedDraftEntityIds, setSelectedDraftEntityIds] = useState< EntityId[] >([]); @@ -117,7 +119,7 @@ const ActionsPage: NextPageWithLayout = () => { ); return ( - + <> { draftEntitiesWithLinkedDataSubgraph } /> - + + ); +}; + +const ActionsPageOuter: NextPageWithLayout = () => { + return ( + + + ); }; -ActionsPage.getLayout = (page) => +ActionsPageOuter.getLayout = (page) => getLayoutWithSidebar(page, { fullWidth: true, }); -export default ActionsPage; +export default ActionsPageOuter; diff --git a/apps/hash-frontend/src/pages/actions.page/draft-entities-bulk-actions-dropdown.tsx b/apps/hash-frontend/src/pages/actions.page/draft-entities-bulk-actions-dropdown.tsx index 67a2634d9d6..1f58a9b6351 100644 --- a/apps/hash-frontend/src/pages/actions.page/draft-entities-bulk-actions-dropdown.tsx +++ b/apps/hash-frontend/src/pages/actions.page/draft-entities-bulk-actions-dropdown.tsx @@ -28,11 +28,10 @@ import { archiveEntitiesMutation, updateEntitiesMutation, } from "../../graphql/queries/knowledge/entity.queries"; -import { useDraftEntities } from "../../shared/draft-entities-context"; import { LayerGroupLightIcon } from "../../shared/icons/layer-group-light-icon"; -import { useNotificationEntities } from "../../shared/notification-entities-context"; +import { useNotificationCount } from "../../shared/notification-count-context"; import { Button, MenuItem } from "../../shared/ui"; -import { useNotificationsWithLinks } from "../shared/notifications-with-links-context"; +import { useDraftEntities } from "./draft-entities-context"; export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{ selectedDraftEntityIds: EntityId[]; @@ -44,9 +43,8 @@ export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{ deselectAllDraftEntities, }) => { const { draftEntities, refetch: refetchDraftEntities } = useDraftEntities(); - const { notifications } = useNotificationsWithLinks(); - const { archiveNotifications, markNotificationsAsRead } = - useNotificationEntities(); + const { archiveNotificationsForEntity, markNotificationsAsReadForEntity } = + useNotificationCount(); const popupState = usePopupState({ variant: "popover", @@ -108,41 +106,37 @@ export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{ >(archiveEntitiesMutation); const ignoreAllSelectedDraftEntities = useCallback(async () => { - if (!notifications) { + if (!selectedDraftEntities.length) { return; } - const relatedNotifications = notifications.filter((notification) => - selectedDraftEntityIds.includes( - notification.occurredInEntity.metadata.recordId.entityId, - ), - ); - await archiveEntities({ variables: { entityIds: [ - ...selectedDraftEntities, - ...(incomingOrOutgoingDraftLinksToIgnore ?? []), - ].map(({ metadata }) => metadata.recordId.entityId), + ...selectedDraftEntityIds, + ...(incomingOrOutgoingDraftLinksToIgnore ?? []).map( + ({ metadata }) => metadata.recordId.entityId, + ), + ], }, }); - await archiveNotifications({ - notificationEntities: relatedNotifications.map(({ entity }) => entity), - }); - + await Promise.all( + selectedDraftEntityIds.map((entityId) => + archiveNotificationsForEntity({ targetEntityId: entityId }), + ), + ); await refetchDraftEntities(); deselectAllDraftEntities(); }, [ - notifications, - archiveNotifications, archiveEntities, - selectedDraftEntityIds, - selectedDraftEntities, - refetchDraftEntities, - incomingOrOutgoingDraftLinksToIgnore, + archiveNotificationsForEntity, deselectAllDraftEntities, + incomingOrOutgoingDraftLinksToIgnore, + refetchDraftEntities, + selectedDraftEntities, + selectedDraftEntityIds, ]); const [ @@ -222,15 +216,6 @@ export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{ >(updateEntitiesMutation); const acceptAllSelectedDraftEntities = useCallback(async () => { - const relatedGraphChangeNotifications = - notifications?.filter( - ({ kind, occurredInEntity }) => - kind === "graph-change" && - selectedDraftEntityIds.includes( - occurredInEntity.metadata.recordId.entityId, - ), - ) ?? []; - await updateEntities({ variables: { entityUpdates: [ @@ -244,24 +229,24 @@ export const DraftEntitiesBulkActionsDropdown: FunctionComponent<{ }, }); - await markNotificationsAsRead({ - notificationEntities: relatedGraphChangeNotifications.map( - ({ entity }) => entity, + await Promise.all( + selectedDraftEntities.map((entity) => + markNotificationsAsReadForEntity({ + targetEntityId: entity.entityId, + }), ), - }); + ); await refetchDraftEntities(); deselectAllDraftEntities(); }, [ - notifications, - markNotificationsAsRead, - selectedDraftEntityIds, - selectedDraftEntities, + deselectAllDraftEntities, leftOrRightDraftEntitiesToAccept, - updateEntities, + markNotificationsAsReadForEntity, refetchDraftEntities, - deselectAllDraftEntities, + selectedDraftEntities, + updateEntities, ]); const [ diff --git a/apps/hash-frontend/src/shared/draft-entities-context.tsx b/apps/hash-frontend/src/pages/actions.page/draft-entities-context.tsx similarity index 80% rename from apps/hash-frontend/src/shared/draft-entities-context.tsx rename to apps/hash-frontend/src/pages/actions.page/draft-entities-context.tsx index 9b44cd09240..aaf27a4e267 100644 --- a/apps/hash-frontend/src/shared/draft-entities-context.tsx +++ b/apps/hash-frontend/src/pages/actions.page/draft-entities-context.tsx @@ -13,10 +13,11 @@ import { createContext, useContext, useMemo, useState } from "react"; import type { GetEntitySubgraphQuery, GetEntitySubgraphQueryVariables, -} from "../graphql/api-types.gen"; -import { getEntitySubgraphQuery } from "../graphql/queries/knowledge/entity.queries"; -import { useAuthInfo } from "../pages/shared/auth-info-context"; -import { pollInterval } from "./poll-interval"; +} from "../../graphql/api-types.gen"; +import { getEntitySubgraphQuery } from "../../graphql/queries/knowledge/entity.queries"; +import { useDraftEntitiesCount } from "../../shared/draft-entities-count-context"; +import { pollInterval } from "../../shared/poll-interval"; +import { useAuthInfo } from "../shared/auth-info-context"; export type DraftEntitiesContextValue = { draftEntities?: Entity[]; @@ -38,6 +39,10 @@ export const useDraftEntities = () => { return draftEntitiesContext; }; +/** + * Context to provide full information of draft entities, for use in the actions page. + * A separate app-wide context provides simply a count of draft entities. + */ export const DraftEntitiesContextProvider: FunctionComponent< PropsWithChildren > = ({ children }) => { @@ -48,9 +53,11 @@ export const DraftEntitiesContextProvider: FunctionComponent< const { authenticatedUser } = useAuthInfo(); + const { refetch: refetchDraftEntitiesCount } = useDraftEntitiesCount(); + const { data: draftEntitiesData, - refetch, + refetch: refetchFullData, loading, } = useQuery( getEntitySubgraphQuery, @@ -104,10 +111,17 @@ export const DraftEntitiesContextProvider: FunctionComponent< draftEntitiesSubgraph, loading, refetch: async () => { - await refetch(); + await refetchFullData(); + await refetchDraftEntitiesCount(); }, }), - [draftEntities, draftEntitiesSubgraph, loading, refetch], + [ + draftEntities, + draftEntitiesSubgraph, + loading, + refetchFullData, + refetchDraftEntitiesCount, + ], ); return ( diff --git a/apps/hash-frontend/src/pages/actions.page/draft-entities.tsx b/apps/hash-frontend/src/pages/actions.page/draft-entities.tsx index 9e97636ca2f..d89e5e9aa30 100644 --- a/apps/hash-frontend/src/pages/actions.page/draft-entities.tsx +++ b/apps/hash-frontend/src/pages/actions.page/draft-entities.tsx @@ -17,7 +17,6 @@ import { useState, } from "react"; -import { useDraftEntities } from "../../shared/draft-entities-context"; import { Button } from "../../shared/ui"; import type { MinimalActor } from "../../shared/use-actors"; import { useActors } from "../../shared/use-actors"; @@ -30,6 +29,7 @@ import { getDraftEntityTypes, isFilerStateDefaultFilterState, } from "./draft-entities/draft-entities-filters"; +import { useDraftEntities } from "./draft-entities-context"; import { DraftEntity } from "./draft-entity"; const incrementNumberOfEntitiesToDisplay = 20; diff --git a/apps/hash-frontend/src/pages/actions.page/draft-entity.tsx b/apps/hash-frontend/src/pages/actions.page/draft-entity.tsx index 1e96a4cff0d..efd3ae37c10 100644 --- a/apps/hash-frontend/src/pages/actions.page/draft-entity.tsx +++ b/apps/hash-frontend/src/pages/actions.page/draft-entity.tsx @@ -6,11 +6,11 @@ import { Box, Checkbox, Typography } from "@mui/material"; import type { FunctionComponent } from "react"; import { useMemo, useState } from "react"; -import { useDraftEntities } from "../../shared/draft-entities-context"; import { ArrowUpRightRegularIcon } from "../../shared/icons/arrow-up-right-regular-icon"; import { Link } from "../../shared/ui"; import { EntityEditorSlideStack } from "../shared/entity-editor-slide-stack"; import { useEntityHref } from "../shared/use-entity-href"; +import { useDraftEntities } from "./draft-entities-context"; import { DraftEntityActionButtons } from "./draft-entity/draft-entity-action-buttons"; import { DraftEntityProvenance } from "./draft-entity/draft-entity-provenance"; import { DraftEntityType } from "./draft-entity/draft-entity-type"; diff --git a/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-action-buttons.tsx b/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-action-buttons.tsx index 6e44e8c84f1..cefcb42706c 100644 --- a/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-action-buttons.tsx +++ b/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-action-buttons.tsx @@ -7,16 +7,20 @@ import type { FunctionComponent } from "react"; import { CheckRegularIcon } from "../../../shared/icons/check-regular-icon"; import { AcceptDraftEntityButton } from "../../shared/accept-draft-entity-button"; import { DiscardDraftEntityButton } from "../../shared/discard-draft-entity-button"; +import { useDraftEntities } from "../draft-entities-context"; export const DraftEntityActionButtons: FunctionComponent<{ entity: Entity; subgraph: Subgraph; }> = ({ entity, subgraph }) => { + const { refetch } = useDraftEntities(); + return ( } @@ -40,7 +44,7 @@ export const DraftEntityActionButtons: FunctionComponent<{ size="xs" variant="primary" startIcon={} - onAcceptedEntity={null} + onAcceptedEntity={refetch} > Accept diff --git a/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-chip.tsx b/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-chip.tsx index 2a9708d7090..cacd334671f 100644 --- a/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-chip.tsx +++ b/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-chip.tsx @@ -6,7 +6,6 @@ export const DraftEntityChip = styled(Chip)(({ theme, clickable }) => ({ background: theme.palette.common.white, borderColor: theme.palette.gray[30], fontWeight: 500, - fontSize: 12, textTransform: "none", ...(clickable ? { @@ -20,6 +19,7 @@ export const DraftEntityChip = styled(Chip)(({ theme, clickable }) => ({ color: theme.palette.gray[50], }, [`& .${chipClasses.label}`]: { - padding: theme.spacing(0.5, 1.25), + padding: theme.spacing(0.3, 1.25), + fontSize: 12, }, })); diff --git a/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-type.tsx b/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-type.tsx index 4a9f01127f3..127cae8dd9c 100644 --- a/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-type.tsx +++ b/apps/hash-frontend/src/pages/actions.page/draft-entity/draft-entity-type.tsx @@ -76,7 +76,14 @@ export const DraftEntityType: FunctionComponent<{ alignItems: "center", }} > - + palette.gray[50]} @@ -90,6 +97,7 @@ export const DraftEntityType: FunctionComponent<{ (allOf) => allOf.$ref === linkEntityTypeUrl, ) } + sx={{ mr: 0.5 }} /> {entityType.schema.title} diff --git a/apps/hash-frontend/src/pages/notifications.page.tsx b/apps/hash-frontend/src/pages/notifications.page.tsx index efe5d34bf3b..918f52bcf99 100644 --- a/apps/hash-frontend/src/pages/notifications.page.tsx +++ b/apps/hash-frontend/src/pages/notifications.page.tsx @@ -1,332 +1,19 @@ import { BellLightIcon } from "@hashintel/design-system"; -import { generateEntityPath } from "@local/hash-isomorphic-utils/frontend-paths"; -import { simplifyProperties } from "@local/hash-isomorphic-utils/simplify-properties"; -import { - extractDraftIdFromEntityId, - extractEntityUuidFromEntityId, - extractOwnedByIdFromEntityId, -} from "@local/hash-subgraph"; import { breadcrumbsClasses, buttonClasses, Container, - Skeleton, - styled, - Table as MuiTable, - TableBody, - TableCell as MuiTableCell, - tableCellClasses, - TableHead, - TableRow as MuiTableRow, - tableRowClasses, Typography, } from "@mui/material"; -import { - differenceInDays, - differenceInMinutes, - format, - isThisYear, - isToday, -} from "date-fns"; import { NextSeo } from "next-seo"; -import type { FunctionComponent } from "react"; -import { useCallback, useMemo } from "react"; -import { useUserOrOrgShortnameByOwnedById } from "../components/hooks/use-user-or-org-shortname-by-owned-by-id"; -import { constructPageRelativeUrl } from "../lib/routes"; import type { NextPageWithLayout } from "../shared/layout"; import { getLayoutWithSidebar } from "../shared/layout"; -import { useNotificationEntities } from "../shared/notification-entities-context"; -import { Button, Link } from "../shared/ui"; -import type { - GraphChangeNotification, - Notification, - PageRelatedNotification, -} from "./shared/notifications-with-links-context"; -import { useNotificationsWithLinksContextValue } from "./shared/notifications-with-links-context"; +import { NotificationsTable } from "./notifications.page/notifications-table"; +import { NotificationsWithLinksContextProvider } from "./notifications.page/notifications-with-links-context"; import { TopContextBar } from "./shared/top-context-bar"; -const Table = styled(MuiTable)(({ theme }) => ({ - borderCollapse: "separate", - borderSpacing: 0, - background: theme.palette.common.white, - borderRadius: "8px", - borderColor: theme.palette.gray[30], - borderStyle: "solid", - borderWidth: 1, - overflow: "hidden", -})); - -const TableRow = styled(MuiTableRow)(() => ({ - [`&:last-of-type .${tableCellClasses.body}`]: { - borderBottom: "none", - }, - [`&:first-of-type .${tableCellClasses.head}`]: { - "&:first-of-type": { - borderTopLeftRadius: "8px", - }, - "&:last-of-type": { - borderTopRightRadius: "8px", - }, - }, - [`&:last-of-type .${tableCellClasses.body}`]: { - "&:first-of-type": { - borderBottomLeftRadius: "8px", - }, - "&:last-of-type": { - borderBottomRightRadius: "8px", - }, - }, -})); - -const TableCell = styled(MuiTableCell)(({ theme }) => ({ - whiteSpace: "nowrap", - border: 0, - borderStyle: "solid", - borderColor: theme.palette.gray[20], - borderBottomWidth: 1, - borderRightWidth: 1, - padding: theme.spacing(0.5, 1.5), - [`&.${tableCellClasses.head}`]: { - fontSize: 13, - fontWeight: 600, - color: theme.palette.common.black, - }, - [`&.${tableCellClasses.body}`]: { - fontSize: 14, - fontWeight: 500, - color: theme.palette.gray[90], - }, - "&:last-of-type": { - borderRightWidth: 0, - }, -})); - -const GraphChangeNotificationContent = ({ - notification, - handleNotificationClick, - targetHref, -}: { - notification: GraphChangeNotification; - handleNotificationClick: () => void; - targetHref?: string; -}) => { - const { occurredInEntityLabel, occurredInEntity, operation } = notification; - - return ( - - HASH AI {operation}d{" "} - - {occurredInEntityLabel} - {" "} - {extractDraftIdFromEntityId(occurredInEntity.metadata.recordId.entityId) - ? "as draft" - : ""} - - ); -}; - -const PageRelatedNotificationContent = ({ - notification, - handleNotificationClick, - targetHref, -}: { - notification: PageRelatedNotification; - handleNotificationClick: () => void; - targetHref?: string; -}) => { - const { kind, triggeredByUser, occurredInEntity } = notification; - - const pageTitle = useMemo(() => { - const { title } = simplifyProperties(occurredInEntity.properties); - - return title; - }, [occurredInEntity]); - - return ( - <> - - {triggeredByUser.displayName} - {" "} - {kind === "new-comment" - ? "commented on " - : kind === "comment-reply" - ? "replied to your comment on " - : kind === "page-mention" - ? "mentioned you in " - : "mentioned you in a comment on "} - - {pageTitle} - - - ); -}; - -const NotificationRow: FunctionComponent<{ notification: Notification }> = ({ - notification, -}) => { - const { markNotificationAsRead } = useNotificationEntities(); - - const handleNotificationClick = useCallback(async () => { - await markNotificationAsRead({ notificationEntity: notification.entity }); - }, [markNotificationAsRead, notification]); - - const ownedById = useMemo( - () => - extractOwnedByIdFromEntityId( - notification.occurredInEntity.metadata.recordId.entityId, - ), - [notification], - ); - - const { shortname: entityOwningShortname } = useUserOrOrgShortnameByOwnedById( - { ownedById }, - ); - - const targetHref = useMemo(() => { - if (!entityOwningShortname) { - return undefined; - } - - if (notification.kind === "graph-change") { - return generateEntityPath({ - entityId: notification.occurredInEntity.metadata.recordId.entityId, - includeDraftId: true, - shortname: entityOwningShortname, - }); - } - - const { occurredInBlock } = notification; - - /** @todo: append query param if the mention was in a comment */ - return constructPageRelativeUrl({ - workspaceShortname: entityOwningShortname, - pageEntityUuid: extractEntityUuidFromEntityId( - notification.occurredInEntity.metadata.recordId.entityId, - ), - highlightedBlockEntityId: occurredInBlock.metadata.recordId.entityId, - }); - }, [entityOwningShortname, notification]); - - const humanReadableCreatedAt = useMemo(() => { - const now = new Date(); - - const createdAtTimestamp = - notification.kind === "graph-change" - ? (notification.occurredInEntityEditionTimestamp ?? - notification.entity.metadata.provenance.createdAtDecisionTime) - : notification.entity.metadata.provenance.createdAtDecisionTime; - - const createdAt = new Date(createdAtTimestamp); - - const numberOfMinutesAgo = differenceInMinutes(now, createdAt); - - if (numberOfMinutesAgo < 1) { - return "Just now"; - } - - if (isToday(createdAt)) { - if (numberOfMinutesAgo < 60) { - return `${numberOfMinutesAgo} minute${ - numberOfMinutesAgo > 1 ? "s" : "" - } ago`; - } - const numberOfHoursAgo = Math.floor(numberOfMinutesAgo / 60); - return `${numberOfHoursAgo} hour${numberOfHoursAgo > 1 ? "s" : ""} ago`; - } - const numberOfDaysAgo = differenceInDays(now, createdAt); - - if (numberOfDaysAgo < 7) { - return format(createdAt, "h:mma iiii"); // "12:00AM Monday" - } - - if (isThisYear(createdAt)) { - return format(createdAt, "h:mma MMMM do"); // "12:00AM October 27th" - } - - return format(createdAt, "h:mma MMMM do, yyyy"); // "12:00AM December 24th, 2022" - }, [notification]); - - return ( - palette.gray[20] - : undefined, - opacity: notification.readAt ? 0.6 : 1, - }} - > - palette.gray[70], - }, - }} - > - {humanReadableCreatedAt} - - palette.blue[70], - "&:hover": { color: ({ palette }) => palette.blue[90] }, - }, - }} - > - {notification.kind === "graph-change" ? ( - - ) : ( - - )} - - - - {notification.readAt ? null : ( - - )} - - - ); -}; - const NotificationsPage: NextPageWithLayout = () => { - const { notifications } = useNotificationsWithLinksContextValue(); - return ( <> @@ -351,52 +38,9 @@ const NotificationsPage: NextPageWithLayout = () => { Notifications - {notifications && notifications.length === 0 ? ( - You don't have any notifications. - ) : ( - - - - - When - - - Title - - - Actions - - - - .${tableRowClasses.root}:last-of-type > .${tableCellClasses.root}`]: - { - borderBottomWidth: 0, - }, - }} - > - {notifications ? ( - notifications.map((notification) => ( - - )) - ) : ( - - - - - - - - - - )} - -
- )} + + + ); diff --git a/apps/hash-frontend/src/pages/notifications.page/notifications-table.tsx b/apps/hash-frontend/src/pages/notifications.page/notifications-table.tsx new file mode 100644 index 00000000000..074805c3de1 --- /dev/null +++ b/apps/hash-frontend/src/pages/notifications.page/notifications-table.tsx @@ -0,0 +1,374 @@ +import { generateEntityPath } from "@local/hash-isomorphic-utils/frontend-paths"; +import { simplifyProperties } from "@local/hash-isomorphic-utils/simplify-properties"; +import { + extractDraftIdFromEntityId, + extractEntityUuidFromEntityId, + extractOwnedByIdFromEntityId, +} from "@local/hash-subgraph"; +import { + Skeleton, + styled, + Table as MuiTable, + TableBody, + TableCell as MuiTableCell, + tableCellClasses, + TableHead, + TableRow as MuiTableRow, + tableRowClasses, + Typography, +} from "@mui/material"; +import { + differenceInDays, + differenceInMinutes, + format, + isThisYear, + isToday, +} from "date-fns"; +import type { FunctionComponent } from "react"; +import { useCallback, useMemo } from "react"; + +import { useUserOrOrgShortnameByOwnedById } from "../../components/hooks/use-user-or-org-shortname-by-owned-by-id"; +import { constructPageRelativeUrl } from "../../lib/routes"; +import { useNotificationCount } from "../../shared/notification-count-context"; +import { Button, Link } from "../../shared/ui"; +import type { + GraphChangeNotification, + Notification, + PageRelatedNotification, +} from "./notifications-with-links-context"; +import { useNotificationsWithLinks } from "./notifications-with-links-context"; + +const Table = styled(MuiTable)(({ theme }) => ({ + borderCollapse: "separate", + borderSpacing: 0, + background: theme.palette.common.white, + borderRadius: "8px", + borderColor: theme.palette.gray[30], + borderStyle: "solid", + borderWidth: 1, + overflow: "hidden", +})); + +const TableRow = styled(MuiTableRow)(() => ({ + [`&:last-of-type .${tableCellClasses.body}`]: { + borderBottom: "none", + }, + [`&:first-of-type .${tableCellClasses.head}`]: { + "&:first-of-type": { + borderTopLeftRadius: "8px", + }, + "&:last-of-type": { + borderTopRightRadius: "8px", + }, + }, + [`&:last-of-type .${tableCellClasses.body}`]: { + "&:first-of-type": { + borderBottomLeftRadius: "8px", + }, + "&:last-of-type": { + borderBottomRightRadius: "8px", + }, + }, +})); + +const TableCell = styled(MuiTableCell)(({ theme }) => ({ + whiteSpace: "nowrap", + border: 0, + borderStyle: "solid", + borderColor: theme.palette.gray[20], + borderBottomWidth: 1, + borderRightWidth: 1, + padding: theme.spacing(0.5, 1.5), + [`&.${tableCellClasses.head}`]: { + fontSize: 13, + fontWeight: 600, + color: theme.palette.common.black, + }, + [`&.${tableCellClasses.body}`]: { + fontSize: 14, + fontWeight: 500, + color: theme.palette.gray[90], + }, + "&:last-of-type": { + borderRightWidth: 0, + }, +})); + +const GraphChangeNotificationContent = ({ + notification, + handleNotificationClick, + targetHref, +}: { + notification: GraphChangeNotification; + handleNotificationClick: () => void; + targetHref?: string; +}) => { + const { occurredInEntityLabel, occurredInEntity, operation } = notification; + + return ( + + HASH AI {operation}d{" "} + + {occurredInEntityLabel} + {" "} + {extractDraftIdFromEntityId(occurredInEntity.metadata.recordId.entityId) + ? "as draft" + : ""} + + ); +}; + +const PageRelatedNotificationContent = ({ + notification, + handleNotificationClick, + targetHref, +}: { + notification: PageRelatedNotification; + handleNotificationClick: () => void; + targetHref?: string; +}) => { + const { kind, triggeredByUser, occurredInEntity } = notification; + + const pageTitle = useMemo(() => { + const { title } = simplifyProperties(occurredInEntity.properties); + + return title; + }, [occurredInEntity]); + + return ( + <> + + {triggeredByUser.displayName} + {" "} + {kind === "new-comment" + ? "commented on " + : kind === "comment-reply" + ? "replied to your comment on " + : kind === "page-mention" + ? "mentioned you in " + : "mentioned you in a comment on "} + + {pageTitle} + + + ); +}; + +const NotificationRow: FunctionComponent<{ notification: Notification }> = ({ + notification, +}) => { + const { markNotificationAsRead } = useNotificationCount(); + const { refetch } = useNotificationsWithLinks(); + + const handleNotificationClick = useCallback(async () => { + await markNotificationAsRead({ + notificationEntityId: notification.entity.entityId, + }); + refetch(); + }, [markNotificationAsRead, notification, refetch]); + + const ownedById = useMemo( + () => + extractOwnedByIdFromEntityId( + notification.occurredInEntity.metadata.recordId.entityId, + ), + [notification], + ); + + const { shortname: entityOwningShortname } = useUserOrOrgShortnameByOwnedById( + { ownedById }, + ); + + const targetHref = useMemo(() => { + if (!entityOwningShortname) { + return undefined; + } + + if (notification.kind === "graph-change") { + return generateEntityPath({ + entityId: notification.occurredInEntity.metadata.recordId.entityId, + includeDraftId: true, + shortname: entityOwningShortname, + }); + } + + const { occurredInBlock } = notification; + + /** @todo: append query param if the mention was in a comment */ + return constructPageRelativeUrl({ + workspaceShortname: entityOwningShortname, + pageEntityUuid: extractEntityUuidFromEntityId( + notification.occurredInEntity.metadata.recordId.entityId, + ), + highlightedBlockEntityId: occurredInBlock.metadata.recordId.entityId, + }); + }, [entityOwningShortname, notification]); + + const humanReadableCreatedAt = useMemo(() => { + const now = new Date(); + + const createdAtTimestamp = + notification.kind === "graph-change" + ? (notification.occurredInEntityEditionTimestamp ?? + notification.entity.metadata.provenance.createdAtDecisionTime) + : notification.entity.metadata.provenance.createdAtDecisionTime; + + const createdAt = new Date(createdAtTimestamp); + + const numberOfMinutesAgo = differenceInMinutes(now, createdAt); + + if (numberOfMinutesAgo < 1) { + return "Just now"; + } + + if (isToday(createdAt)) { + if (numberOfMinutesAgo < 60) { + return `${numberOfMinutesAgo} minute${ + numberOfMinutesAgo > 1 ? "s" : "" + } ago`; + } + const numberOfHoursAgo = Math.floor(numberOfMinutesAgo / 60); + return `${numberOfHoursAgo} hour${numberOfHoursAgo > 1 ? "s" : ""} ago`; + } + const numberOfDaysAgo = differenceInDays(now, createdAt); + + if (numberOfDaysAgo < 7) { + return format(createdAt, "h:mma iiii"); // "12:00AM Monday" + } + + if (isThisYear(createdAt)) { + return format(createdAt, "h:mma MMMM do"); // "12:00AM October 27th" + } + + return format(createdAt, "h:mma MMMM do, yyyy"); // "12:00AM December 24th, 2022" + }, [notification]); + + return ( + palette.gray[20] + : undefined, + opacity: notification.readAt ? 0.6 : 1, + }} + > + palette.gray[70], + }, + }} + > + {humanReadableCreatedAt} + + palette.blue[70], + "&:hover": { color: ({ palette }) => palette.blue[90] }, + }, + }} + > + {notification.kind === "graph-change" ? ( + + ) : ( + + )} + + + + {notification.readAt ? null : ( + + )} + + + ); +}; + +export const NotificationsTable = () => { + const { notifications } = useNotificationsWithLinks(); + + if (notifications?.length === 0) { + return You don't have any notifications.; + } + + return ( + + + + + When + + + Title + + + Actions + + + + .${tableRowClasses.root}:last-of-type > .${tableCellClasses.root}`]: + { + borderBottomWidth: 0, + }, + }} + > + {notifications ? ( + notifications.map((notification) => ( + + )) + ) : ( + + + + + + + + + + )} + +
+ ); +}; diff --git a/apps/hash-frontend/src/pages/shared/notifications-with-links-context.tsx b/apps/hash-frontend/src/pages/notifications.page/notifications-with-links-context.tsx similarity index 84% rename from apps/hash-frontend/src/pages/shared/notifications-with-links-context.tsx rename to apps/hash-frontend/src/pages/notifications.page/notifications-with-links-context.tsx index 3947902d5c9..c8bdc131cad 100644 --- a/apps/hash-frontend/src/pages/shared/notifications-with-links-context.tsx +++ b/apps/hash-frontend/src/pages/notifications.page/notifications-with-links-context.tsx @@ -1,13 +1,14 @@ import { useQuery } from "@apollo/client"; import type { VersionedUrl } from "@blockprotocol/type-system"; import { typedEntries, typedValues } from "@local/advanced-types/typed-entries"; -import type { Filter } from "@local/hash-graph-client"; import type { Entity } from "@local/hash-graph-sdk/entity"; import type { TextWithTokens } from "@local/hash-isomorphic-utils/entity"; import { generateEntityLabel } from "@local/hash-isomorphic-utils/generate-entity-label"; import { currentTimeInstantTemporalAxes, + generateVersionedUrlMatchingFilter, mapGqlSubgraphFieldsFragmentToSubgraph, + pageOrNotificationNotArchivedFilter, zeroedGraphResolveDepths, } from "@local/hash-isomorphic-utils/graph-queries"; import { @@ -32,8 +33,10 @@ import type { EntityVertex, LinkEntityAndRightEntity, } from "@local/hash-subgraph"; -import { extractEntityUuidFromEntityId } from "@local/hash-subgraph"; -import { getOutgoingLinkAndTargetEntities } from "@local/hash-subgraph/stdlib"; +import { + getOutgoingLinkAndTargetEntities, + getRoots, +} from "@local/hash-subgraph/stdlib"; import type { FunctionComponent, PropsWithChildren } from "react"; import { createContext, useContext, useMemo, useRef } from "react"; @@ -44,7 +47,8 @@ import type { import { getEntitySubgraphQuery } from "../../graphql/queries/knowledge/entity.queries"; import type { MinimalUser } from "../../lib/user-and-org"; import { constructMinimalUser } from "../../lib/user-and-org"; -import { useNotificationEntities } from "../../shared/notification-entities-context"; +import { pollInterval } from "../../shared/poll-interval"; +import { useAuthInfo } from "../shared/auth-info-context"; export type PageMentionNotification = { kind: "page-mention"; @@ -93,6 +97,7 @@ export type Notification = PageRelatedNotification | GraphChangeNotification; type NotificationsWithLinksContextValue = { notifications?: Notification[]; + refetch: () => void; }; export const NotificationsWithLinksContext = @@ -118,33 +123,30 @@ const isLinkAndRightEntityWithLinkType = export const useNotificationsWithLinksContextValue = (): NotificationsWithLinksContextValue => { - const { notificationEntities } = useNotificationEntities(); - - const getNotificationEntitiesFilter = useMemo( - () => ({ - any: - notificationEntities?.map((entity) => ({ - equal: [ - { path: ["uuid"] }, - { - parameter: extractEntityUuidFromEntityId( - entity.metadata.recordId.entityId, - ), - }, - ], - })) ?? [], - }), - [notificationEntities], - ); + const { authenticatedUser } = useAuthInfo(); - const { data: notificationsWithOutgoingLinksData } = useQuery< + const { data: notificationsWithOutgoingLinksData, refetch } = useQuery< GetEntitySubgraphQuery, GetEntitySubgraphQueryVariables >(getEntitySubgraphQuery, { variables: { includePermissions: false, request: { - filter: getNotificationEntitiesFilter, + filter: { + all: [ + { + equal: [ + { path: ["ownedById"] }, + { parameter: authenticatedUser?.accountId }, + ], + }, + generateVersionedUrlMatchingFilter( + systemEntityTypes.notification.entityTypeId, + { ignoreParents: false }, + ), + pageOrNotificationNotArchivedFilter, + ], + }, graphResolveDepths: { ...zeroedGraphResolveDepths, inheritsFrom: { outgoing: 255 }, @@ -157,16 +159,17 @@ export const useNotificationsWithLinksContextValue = includeDrafts: true, }, }, - skip: !notificationEntities || notificationEntities.length === 0, + skip: !authenticatedUser, fetchPolicy: "network-only", + pollInterval, }); - const outgoingLinksSubgraph = useMemo( + const notificationsSubgraph = useMemo( () => notificationsWithOutgoingLinksData - ? mapGqlSubgraphFieldsFragmentToSubgraph( - notificationsWithOutgoingLinksData.getEntitySubgraph.subgraph, - ) + ? mapGqlSubgraphFieldsFragmentToSubgraph< + EntityRootType + >(notificationsWithOutgoingLinksData.getEntitySubgraph.subgraph) : undefined, [notificationsWithOutgoingLinksData], ); @@ -176,12 +179,12 @@ export const useNotificationsWithLinksContextValue = ); const notifications = useMemo(() => { - if (notificationEntities && notificationEntities.length === 0) { - return []; - } else if (!outgoingLinksSubgraph || !notificationEntities) { + if (!notificationsSubgraph) { return previouslyFetchedNotificationsRef.current ?? undefined; } + const notificationEntities = getRoots(notificationsSubgraph); + const derivedNotifications = notificationEntities .map((entity) => { const { @@ -194,7 +197,7 @@ export const useNotificationsWithLinksContextValue = const { readAt } = simplifyProperties(entity.properties); const outgoingLinks = getOutgoingLinkAndTargetEntities( - outgoingLinksSubgraph, + notificationsSubgraph, entityId, ); @@ -252,7 +255,8 @@ export const useNotificationsWithLinksContextValue = return { kind: "comment-mention", readAt, - entity: entity as Entity, + entity: + entity as unknown as Entity, occurredInEntity: occurredInEntity as Entity, occurredInBlock: occurredInBlock as Entity, occurredInText: occurredInText as Entity, @@ -265,7 +269,8 @@ export const useNotificationsWithLinksContextValue = return { kind: "page-mention", readAt, - entity: entity as Entity, + entity: + entity as unknown as Entity, occurredInEntity: occurredInEntity as Entity, occurredInBlock: occurredInBlock as Entity, occurredInText: occurredInText as Entity, @@ -325,7 +330,8 @@ export const useNotificationsWithLinksContextValue = return { kind: "comment-reply", readAt, - entity: entity as Entity, + entity: + entity as unknown as Entity, occurredInEntity: occurredInEntity as Entity, occurredInBlock: occurredInBlock as Entity, triggeredByComment: @@ -338,7 +344,8 @@ export const useNotificationsWithLinksContextValue = return { kind: "new-comment", readAt, - entity: entity as Entity, + entity: + entity as unknown as Entity, occurredInEntity: occurredInEntity as Entity, occurredInBlock: occurredInBlock as Entity, triggeredByComment: @@ -380,14 +387,15 @@ export const useNotificationsWithLinksContextValue = let occurredInEntity: Entity | undefined; for (const [vertexKey, editionMap] of typedEntries( - outgoingLinksSubgraph.vertices, + notificationsSubgraph.vertices, )) { /** - * The created/updated record might be a draft, in which case it is keyed in the subgraph by `${entityId}~${draftId}`. - * We need to find the vertex that _starts with_ the entityId and contains an edition at the exact timestamp from the link. - * Needing to do this is a limitation caused by: + * The created/updated record might be a draft, in which case it is keyed in the subgraph by + * `${entityId}~${draftId}`. We need to find the vertex that _starts with_ the entityId and contains an + * edition at the exact timestamp from the link. Needing to do this is a limitation caused by: * 1. The fact that links only point to the entire Entity, not any specific edition or draft series of it - * 2. The logic for returning linked entities from the subgraph library will just return the non-draft entity if it is found + * 2. The logic for returning linked entities from the subgraph library will just return the non-draft + * entity if it is found */ if (!vertexKey.startsWith(linkRightEntityId)) { continue; @@ -396,9 +404,9 @@ export const useNotificationsWithLinksContextValue = const editions = typedValues(editionMap).flat(); /** - * We have a candidate – this might be one of multiple draft series for the entity, or the single live series. - * We match the timestamp logged in the link to the editions of the entity. - * This may result in a false positive if the live entity and any of its drafts have editions at the exact same timestamp. + * We have a candidate – this might be one of multiple draft series for the entity, or the single live + * series. We match the timestamp logged in the link to the editions of the entity. This may result in a + * false positive if the live entity and any of its drafts have editions at the exact same timestamp. */ occurredInEntity = editions.find( (vertex): vertex is EntityVertex => @@ -412,12 +420,12 @@ export const useNotificationsWithLinksContextValue = } /** - * If the entity has been updated since the notification was created, we won't have the edition in the subgraph, - * because the request above only fetches editions still valid for the current timestamp. - * In order to show the notification we just take any available edition. + * If the entity has been updated since the notification was created, we won't have the edition in the + * subgraph, because the request above only fetches editions still valid for the current timestamp. In + * order to show the notification we just take any available edition. * - * The other option would be to fetch the entire history for all entities which are the subject of a notification, - * but this might be a lot of data. + * The other option would be to fetch the entire history for all entities which are the subject of a + * notification, but this might be a lot of data. */ const anyAvailableEdition = editions.find( (vertex): vertex is EntityVertex => vertex.kind === "entity", @@ -435,14 +443,14 @@ export const useNotificationsWithLinksContextValue = } const graphChangeEntity = - entity as Entity; + entity as unknown as Entity; return { kind: "graph-change", readAt, entity: graphChangeEntity, occurredInEntityLabel: generateEntityLabel( - outgoingLinksSubgraph, + notificationsSubgraph, occurredInEntity, ), occurredInEntityEditionTimestamp, @@ -489,11 +497,15 @@ export const useNotificationsWithLinksContextValue = previouslyFetchedNotificationsRef.current = derivedNotifications; return derivedNotifications; - }, [notificationEntities, outgoingLinksSubgraph]); + }, [notificationsSubgraph]); - return { notifications }; + return { notifications, refetch }; }; +/** + * Context to provide full information on notifications, for use on the notifications page. + * A separate app-wide context provides only a count of notifications. + */ export const NotificationsWithLinksContextProvider: FunctionComponent< PropsWithChildren > = ({ children }) => { diff --git a/apps/hash-frontend/src/pages/shared/accept-draft-entity-button.tsx b/apps/hash-frontend/src/pages/shared/accept-draft-entity-button.tsx index 2b1213afc50..daa1912a07b 100644 --- a/apps/hash-frontend/src/pages/shared/accept-draft-entity-button.tsx +++ b/apps/hash-frontend/src/pages/shared/accept-draft-entity-button.tsx @@ -15,13 +15,12 @@ import type { UpdateEntityMutationVariables, } from "../../graphql/api-types.gen"; import { updateEntityMutation } from "../../graphql/queries/knowledge/entity.queries"; -import { useDraftEntities } from "../../shared/draft-entities-context"; +import { useDraftEntitiesCount } from "../../shared/draft-entities-count-context"; import { CheckRegularIcon } from "../../shared/icons/check-regular-icon"; -import { useNotificationEntities } from "../../shared/notification-entities-context"; +import { useNotificationCount } from "../../shared/notification-count-context"; import type { ButtonProps } from "../../shared/ui"; import { Button } from "../../shared/ui"; import { LinkLabelWithSourceAndDestination } from "./link-label-with-source-and-destination"; -import { useNotificationsWithLinks } from "./notifications-with-links-context"; const LeftOrRightEntityEndAdornment: FunctionComponent<{ isDraft: boolean; @@ -136,37 +135,15 @@ export const AcceptDraftEntityButton: FunctionComponent< UpdateEntityMutationVariables >(updateEntityMutation); - const { refetch: refetchDraftEntities } = useDraftEntities(); + const { refetch: refetchDraftEntitiesCount } = useDraftEntitiesCount(); - const { markNotificationAsRead } = useNotificationEntities(); - const { notifications } = useNotificationsWithLinks(); - - /** - * Notifications are no longer created for draft entities, but they will exist for existing draft entities. - * Can be removed in the future – change to stop notifs for draft entities made in March 2024. - */ - const markRelatedGraphChangeNotificationsAsRead = useCallback( - async (params: { draftEntity: Entity }) => { - const relatedGraphChangeNotifications = - notifications?.filter( - ({ kind, occurredInEntity }) => - kind === "graph-change" && - occurredInEntity.metadata.recordId.entityId === - params.draftEntity.metadata.recordId.entityId, - ) ?? []; - - await Promise.all( - relatedGraphChangeNotifications.map((notification) => - markNotificationAsRead({ notificationEntity: notification.entity }), - ), - ); - }, - [notifications, markNotificationAsRead], - ); + const { markNotificationsAsReadForEntity } = useNotificationCount(); const acceptDraftEntity = useCallback( async (params: { draftEntity: Entity }) => { - await markRelatedGraphChangeNotificationsAsRead(params); + await markNotificationsAsReadForEntity({ + targetEntityId: params.draftEntity.entityId, + }); const response = await updateEntity({ variables: { @@ -178,7 +155,7 @@ export const AcceptDraftEntityButton: FunctionComponent< }, }); - await refetchDraftEntities(); + await refetchDraftEntitiesCount(); if (!response.data) { throw new Error("An error occurred accepting the draft entity."); @@ -186,11 +163,7 @@ export const AcceptDraftEntityButton: FunctionComponent< return new Entity(response.data.updateEntity); }, - [ - updateEntity, - refetchDraftEntities, - markRelatedGraphChangeNotificationsAsRead, - ], + [markNotificationsAsReadForEntity, updateEntity, refetchDraftEntitiesCount], ); const handleAccept = useCallback(async () => { diff --git a/apps/hash-frontend/src/pages/shared/discard-draft-entity-button.tsx b/apps/hash-frontend/src/pages/shared/discard-draft-entity-button.tsx index 2b101ca5252..d7dd51748bb 100644 --- a/apps/hash-frontend/src/pages/shared/discard-draft-entity-button.tsx +++ b/apps/hash-frontend/src/pages/shared/discard-draft-entity-button.tsx @@ -16,11 +16,9 @@ import type { ArchiveEntityMutationVariables, } from "../../graphql/api-types.gen"; import { archiveEntityMutation } from "../../graphql/queries/knowledge/entity.queries"; -import { useDraftEntities } from "../../shared/draft-entities-context"; -import { useNotificationEntities } from "../../shared/notification-entities-context"; +import { useNotificationCount } from "../../shared/notification-count-context"; import type { ButtonProps } from "../../shared/ui"; import { Button } from "../../shared/ui"; -import { useNotificationsWithLinks } from "./notifications-with-links-context"; export const DiscardDraftEntityButton: FunctionComponent< { @@ -34,34 +32,7 @@ export const DiscardDraftEntityButton: FunctionComponent< onDiscardedEntity, ...buttonProps }) => { - const { refetch: refetchDraftEntities } = useDraftEntities(); - - const { archiveNotification } = useNotificationEntities(); - - const { notifications } = useNotificationsWithLinks(); - - const archiveRelatedNotifications = useCallback( - async (params: { draftEntity: Entity }) => { - const relatedNotifications = notifications?.filter( - (notification) => - notification.occurredInEntity.metadata.recordId.entityId === - params.draftEntity.metadata.recordId.entityId, - ); - - if (!relatedNotifications) { - return; - } - - await Promise.all( - relatedNotifications.map((notification) => { - return archiveNotification({ - notificationEntity: notification.entity, - }); - }), - ); - }, - [notifications, archiveNotification], - ); + const { archiveNotificationsForEntity } = useNotificationCount(); const [archiveEntity] = useMutation< ArchiveEntityMutation, @@ -70,15 +41,16 @@ export const DiscardDraftEntityButton: FunctionComponent< const discardDraftEntity = useCallback( async (params: { draftEntity: Entity }) => { - await archiveRelatedNotifications(params); + await archiveNotificationsForEntity({ + targetEntityId: params.draftEntity.entityId, + }); await archiveEntity({ variables: { entityId: params.draftEntity.metadata.recordId.entityId, }, }); - await refetchDraftEntities(); }, - [archiveEntity, archiveRelatedNotifications, refetchDraftEntities], + [archiveEntity, archiveNotificationsForEntity], ); const [ diff --git a/apps/hash-frontend/src/shared/draft-entities-count-context.tsx b/apps/hash-frontend/src/shared/draft-entities-count-context.tsx new file mode 100644 index 00000000000..04c955cdb62 --- /dev/null +++ b/apps/hash-frontend/src/shared/draft-entities-count-context.tsx @@ -0,0 +1,92 @@ +import { useQuery } from "@apollo/client"; +import { + currentTimeInstantTemporalAxes, + zeroedGraphResolveDepths, +} from "@local/hash-isomorphic-utils/graph-queries"; +import type { FunctionComponent, PropsWithChildren } from "react"; +import { createContext, useContext, useMemo } from "react"; + +import type { + GetEntitySubgraphQuery, + GetEntitySubgraphQueryVariables, +} from "../graphql/api-types.gen"; +import { getEntitySubgraphQuery } from "../graphql/queries/knowledge/entity.queries"; +import { useAuthInfo } from "../pages/shared/auth-info-context"; +import { pollInterval } from "./poll-interval"; + +export type DraftEntitiesCountContextValue = { + count?: number; + loading: boolean; + refetch: () => Promise; +}; + +export const DraftEntitiesCountContext = + createContext(null); + +export const useDraftEntitiesCount = () => { + const draftEntitiesContext = useContext(DraftEntitiesCountContext); + + if (!draftEntitiesContext) { + throw new Error("DraftEntitiesCountContext missing"); + } + + return draftEntitiesContext; +}; + +export const DraftEntitiesCountContextProvider: FunctionComponent< + PropsWithChildren +> = ({ children }) => { + const { authenticatedUser } = useAuthInfo(); + + const { + data: draftEntitiesData, + refetch, + loading, + } = useQuery( + getEntitySubgraphQuery, + { + variables: { + request: { + filter: { + all: [ + { + // @ts-expect-error -- Support null in Path parameter in structural queries in Node + // @see https://linear.app/hash/issue/H-1207 + notEqual: [{ path: ["draftId"] }, null], + }, + { + equal: [{ path: ["archived"] }, { parameter: false }], + }, + ], + }, + temporalAxes: currentTimeInstantTemporalAxes, + graphResolveDepths: zeroedGraphResolveDepths, + includeCount: true, + includeDrafts: true, + limit: 0, + }, + includePermissions: false, + }, + pollInterval, + fetchPolicy: "network-only", + skip: !authenticatedUser, + }, + ); + + const value = useMemo( + () => ({ + count: draftEntitiesData?.getEntitySubgraph.count ?? undefined, + loading, + refetch: async () => { + await refetch(); + }, + }), + [draftEntitiesData, loading, refetch], + ); + + return ( + + {children} + + ); +}; diff --git a/apps/hash-frontend/src/shared/layout/layout-with-header/notifications-dropdown.tsx b/apps/hash-frontend/src/shared/layout/layout-with-header/notifications-dropdown.tsx index d87da417b3b..d9ea8326217 100644 --- a/apps/hash-frontend/src/shared/layout/layout-with-header/notifications-dropdown.tsx +++ b/apps/hash-frontend/src/shared/layout/layout-with-header/notifications-dropdown.tsx @@ -3,14 +3,14 @@ import { FontAwesomeIcon } from "@hashintel/design-system"; import { Tooltip, useTheme } from "@mui/material"; import type { FunctionComponent } from "react"; -import { useNotificationEntities } from "../../notification-entities-context"; +import { useNotificationCount } from "../../notification-count-context"; import { Link } from "../../ui"; import { HeaderIconButtonWithCount } from "./shared/header-icon-button-with-count"; export const NotificationsDropdown: FunctionComponent = () => { const theme = useTheme(); - const { numberOfUnreadNotifications } = useNotificationEntities(); + const { numberOfUnreadNotifications } = useNotificationCount(); return ( diff --git a/apps/hash-frontend/src/shared/layout/layout-with-header/page-header.tsx b/apps/hash-frontend/src/shared/layout/layout-with-header/page-header.tsx index c549567853d..3e2fe88700d 100644 --- a/apps/hash-frontend/src/shared/layout/layout-with-header/page-header.tsx +++ b/apps/hash-frontend/src/shared/layout/layout-with-header/page-header.tsx @@ -4,7 +4,7 @@ import type { FunctionComponent, ReactNode } from "react"; import { useHashInstance } from "../../../components/hooks/use-hash-instance"; import { useLogoutFlow } from "../../../components/hooks/use-logout-flow"; import { useAuthInfo } from "../../../pages/shared/auth-info-context"; -import { useDraftEntities } from "../../draft-entities-context"; +import { useDraftEntitiesCount } from "../../draft-entities-count-context"; import { CheckRegularIcon } from "../../icons/check-regular-icon"; import { HashLockup } from "../../icons/hash-lockup"; import { Button, Link } from "../../ui"; @@ -37,7 +37,7 @@ export const PageHeader: FunctionComponent = () => { const { authenticatedUser } = useAuthInfo(); const { hashInstance } = useHashInstance(); const { logout } = useLogoutFlow(); - const { draftEntities } = useDraftEntities(); + const { count: draftEntitiesCount } = useDraftEntitiesCount(); return ( { sx={{ color: theme.palette.blue[70] }} /> } - count={draftEntities?.length} + count={draftEntitiesCount} /> diff --git a/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar.tsx b/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar.tsx index a335c56e5fc..2375e466359 100644 --- a/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar.tsx +++ b/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar.tsx @@ -17,12 +17,12 @@ import { import { useHashInstance } from "../../../components/hooks/use-hash-instance"; import { useEnabledFeatureFlags } from "../../../pages/shared/use-enabled-feature-flags"; import { useActiveWorkspace } from "../../../pages/shared/workspace-context"; -import { useDraftEntities } from "../../draft-entities-context"; +import { useDraftEntitiesCount } from "../../draft-entities-count-context"; import { ArrowRightToLineIcon } from "../../icons"; import { BoltLightIcon } from "../../icons/bolt-light-icon"; import { InboxIcon } from "../../icons/inbox-icon"; import { NoteIcon } from "../../icons/note-icon"; -import { useNotificationEntities } from "../../notification-entities-context"; +import { useNotificationCount } from "../../notification-count-context"; import { useRoutePageInfo } from "../../routing"; import { useUserPreferences } from "../../use-user-preferences"; import { AccountEntitiesList } from "./sidebar/account-entities-list"; @@ -72,9 +72,9 @@ export const PageSidebar: FunctionComponent = () => { const { hashInstance } = useHashInstance(); - const { numberOfUnreadNotifications } = useNotificationEntities(); + const { numberOfUnreadNotifications } = useNotificationCount(); - const { draftEntities } = useDraftEntities(); + const { count: draftEntitiesCount } = useDraftEntitiesCount(); const workersSection = useMemo( () => @@ -129,7 +129,7 @@ export const PageSidebar: FunctionComponent = () => { }); } - const numberOfPendingActions = draftEntities?.length ?? 0; + const numberOfPendingActions = draftEntitiesCount ?? 0; return [ { @@ -171,7 +171,7 @@ export const PageSidebar: FunctionComponent = () => { : []), ]; }, [ - draftEntities, + draftEntitiesCount, numberOfUnreadNotifications, enabledFeatureFlags, preferences, diff --git a/apps/hash-frontend/src/shared/notification-count-context.tsx b/apps/hash-frontend/src/shared/notification-count-context.tsx new file mode 100644 index 00000000000..abf17021242 --- /dev/null +++ b/apps/hash-frontend/src/shared/notification-count-context.tsx @@ -0,0 +1,330 @@ +import { useLazyQuery, useMutation, useQuery } from "@apollo/client"; +import type { EntityId } from "@local/hash-graph-types/entity"; +import type { BaseUrl } from "@local/hash-graph-types/ontology"; +import { + currentTimeInstantTemporalAxes, + generateVersionedUrlMatchingFilter, + mapGqlSubgraphFieldsFragmentToSubgraph, + pageOrNotificationNotArchivedFilter, + zeroedGraphResolveDepths, +} from "@local/hash-isomorphic-utils/graph-queries"; +import { systemEntityTypes } from "@local/hash-isomorphic-utils/ontology-type-ids"; +import type { + ArchivedPropertyValueWithMetadata, + Notification, + ReadAtPropertyValueWithMetadata, +} from "@local/hash-isomorphic-utils/system-types/commentnotification"; +import type { EntityRootType } from "@local/hash-subgraph"; +import { extractEntityUuidFromEntityId } from "@local/hash-subgraph"; +import { getRoots } from "@local/hash-subgraph/stdlib"; +import type { FunctionComponent, PropsWithChildren } from "react"; +import { createContext, useCallback, useContext, useMemo } from "react"; + +import type { + GetEntitySubgraphQuery, + GetEntitySubgraphQueryVariables, + UpdateEntitiesMutation, + UpdateEntitiesMutationVariables, + UpdateEntityMutation, + UpdateEntityMutationVariables, +} from "../graphql/api-types.gen"; +import { + getEntitySubgraphQuery, + updateEntitiesMutation, + updateEntityMutation, +} from "../graphql/queries/knowledge/entity.queries"; +import { useAuthInfo } from "../pages/shared/auth-info-context"; +import { pollInterval } from "./poll-interval"; + +export type NotificationCountContextValues = { + numberOfUnreadNotifications?: number; + loading: boolean; + markNotificationAsRead: (params: { + notificationEntityId: EntityId; + }) => Promise; + /** + * Mark notifications as read if they link to a specific entity + */ + markNotificationsAsReadForEntity: (params: { + targetEntityId: EntityId; + }) => Promise; + /** + * Archive notifications if they link to a specific entity + */ + archiveNotificationsForEntity: (params: { + targetEntityId: EntityId; + }) => Promise; +}; + +export const NotificationCountContext = + createContext(null); + +export const useNotificationCount = () => { + const notificationCountContext = useContext(NotificationCountContext); + + if (!notificationCountContext) { + throw new Error("Context missing"); + } + + return notificationCountContext; +}; + +/** + * This is app-wide context to provide: + * 1. The count of notifications + * 2. The ability to mark notifications as + * - read: keeps them visible on the notifications page + * - archived: they will no longer be visible, unless specifically sought out + * + * The notifications page has separate context which requests all notification data. + */ +export const NotificationCountContextProvider: FunctionComponent< + PropsWithChildren +> = ({ children }) => { + const { authenticatedUser } = useAuthInfo(); + + const { + data: notificationCountData, + loading: loadingNotificationCount, + refetch: refetchNotificationCount, + } = useQuery( + getEntitySubgraphQuery, + { + pollInterval, + variables: { + includePermissions: false, + request: { + filter: { + all: [ + { + equal: [ + { path: ["ownedById"] }, + { parameter: authenticatedUser?.accountId }, + ], + }, + generateVersionedUrlMatchingFilter( + systemEntityTypes.notification.entityTypeId, + { ignoreParents: false }, + ), + pageOrNotificationNotArchivedFilter, + ], + }, + graphResolveDepths: zeroedGraphResolveDepths, + temporalAxes: currentTimeInstantTemporalAxes, + includeDrafts: false, + includeCount: true, + limit: 0, + }, + }, + skip: !authenticatedUser, + fetchPolicy: "network-only", + }, + ); + + const [getEntitySubgraph] = useLazyQuery< + GetEntitySubgraphQuery, + GetEntitySubgraphQueryVariables + >(getEntitySubgraphQuery, { + fetchPolicy: "network-only", + }); + + const [updateEntity] = useMutation< + UpdateEntityMutation, + UpdateEntityMutationVariables + >(updateEntityMutation, { + onCompleted: () => refetchNotificationCount(), + }); + + const [updateEntities] = useMutation< + UpdateEntitiesMutation, + UpdateEntitiesMutationVariables + >(updateEntitiesMutation, { + onCompleted: () => refetchNotificationCount(), + }); + + const getNotificationsLinkingToEntity = useCallback( + async ({ targetEntityId }: { targetEntityId: EntityId }) => { + const relatedNotificationData = await getEntitySubgraph({ + variables: { + includePermissions: false, + request: { + filter: { + all: [ + { + equal: [ + { path: ["ownedById"] }, + { parameter: authenticatedUser?.accountId }, + ], + }, + generateVersionedUrlMatchingFilter( + systemEntityTypes.notification.entityTypeId, + { ignoreParents: false }, + ), + { + equal: [ + { path: ["outgoingLinks", "rightEntity", "uuid"] }, + { + parameter: extractEntityUuidFromEntityId(targetEntityId), + }, + ], + }, + ], + }, + graphResolveDepths: zeroedGraphResolveDepths, + temporalAxes: currentTimeInstantTemporalAxes, + includeDrafts: false, + }, + }, + }); + + if (!relatedNotificationData.data?.getEntitySubgraph.subgraph) { + return []; + } + + const subgraph = mapGqlSubgraphFieldsFragmentToSubgraph< + EntityRootType + >(relatedNotificationData.data.getEntitySubgraph.subgraph); + + const notifications = getRoots(subgraph); + + return notifications; + }, + [authenticatedUser?.accountId, getEntitySubgraph], + ); + + const markNotificationAsRead = useCallback< + NotificationCountContextValues["markNotificationAsRead"] + >( + async (params) => { + const { notificationEntityId } = params; + + const now = new Date(); + + await updateEntity({ + variables: { + entityUpdate: { + entityId: notificationEntityId, + propertyPatches: [ + { + op: "add", + path: [ + "https://hash.ai/@hash/types/property-type/read-at/" satisfies keyof Notification["properties"] as BaseUrl, + ], + property: { + value: now.toISOString(), + metadata: { + dataTypeId: + "https://blockprotocol.org/@blockprotocol/types/data-type/text/v/1", + }, + } satisfies ReadAtPropertyValueWithMetadata, + }, + ], + }, + }, + }); + }, + [updateEntity], + ); + + const markNotificationsAsReadForEntity = useCallback< + NotificationCountContextValues["markNotificationsAsReadForEntity"] + >( + async (params) => { + const now = new Date(); + + const { targetEntityId } = params; + + const notifications = await getNotificationsLinkingToEntity({ + targetEntityId, + }); + + if (notifications.length) { + await updateEntities({ + variables: { + entityUpdates: notifications.map((notification) => ({ + entityId: notification.metadata.recordId.entityId, + propertyPatches: [ + { + op: "add", + path: [ + "https://hash.ai/@hash/types/property-type/read-at/" satisfies keyof Notification["properties"] as BaseUrl, + ], + property: { + value: now.toISOString(), + metadata: { + dataTypeId: + "https://blockprotocol.org/@blockprotocol/types/data-type/text/v/1", + }, + } satisfies ReadAtPropertyValueWithMetadata, + }, + ], + })), + }, + }); + } + }, + [getNotificationsLinkingToEntity, updateEntities], + ); + + const archiveNotificationsForEntity = useCallback< + NotificationCountContextValues["archiveNotificationsForEntity"] + >( + async (params) => { + const { targetEntityId } = params; + + const notifications = await getNotificationsLinkingToEntity({ + targetEntityId, + }); + + if (notifications.length) { + await updateEntities({ + variables: { + entityUpdates: notifications.map((notification) => ({ + entityId: notification.metadata.recordId.entityId, + propertyPatches: [ + { + op: "add", + path: [ + "https://hash.ai/@hash/types/property-type/archived/" satisfies keyof Notification["properties"] as BaseUrl, + ], + property: { + value: true, + metadata: { + dataTypeId: + "https://blockprotocol.org/@blockprotocol/types/data-type/boolean/v/1", + }, + } satisfies ArchivedPropertyValueWithMetadata, + }, + ], + })), + }, + }); + } + }, + [getNotificationsLinkingToEntity, updateEntities], + ); + + const value = useMemo( + () => ({ + archiveNotificationsForEntity, + loading: loadingNotificationCount, + markNotificationAsRead, + markNotificationsAsReadForEntity, + numberOfUnreadNotifications: + notificationCountData?.getEntitySubgraph.count ?? undefined, + }), + [ + archiveNotificationsForEntity, + loadingNotificationCount, + markNotificationAsRead, + markNotificationsAsReadForEntity, + notificationCountData, + ], + ); + + return ( + + {children} + + ); +}; diff --git a/apps/hash-frontend/src/shared/notification-entities-context.tsx b/apps/hash-frontend/src/shared/notification-entities-context.tsx deleted file mode 100644 index c7a8b1787ca..00000000000 --- a/apps/hash-frontend/src/shared/notification-entities-context.tsx +++ /dev/null @@ -1,334 +0,0 @@ -import { useMutation, useQuery } from "@apollo/client"; -import type { Entity } from "@local/hash-graph-sdk/entity"; -import type { BaseUrl } from "@local/hash-graph-types/ontology"; -import { - currentTimeInstantTemporalAxes, - generateVersionedUrlMatchingFilter, - mapGqlSubgraphFieldsFragmentToSubgraph, - pageOrNotificationNotArchivedFilter, - zeroedGraphResolveDepths, -} from "@local/hash-isomorphic-utils/graph-queries"; -import { systemEntityTypes } from "@local/hash-isomorphic-utils/ontology-type-ids"; -import { simplifyProperties } from "@local/hash-isomorphic-utils/simplify-properties"; -import type { - ArchivedPropertyValueWithMetadata, - CommentNotification, - Notification, - ReadAtPropertyValueWithMetadata, -} from "@local/hash-isomorphic-utils/system-types/commentnotification"; -import type { GraphChangeNotification } from "@local/hash-isomorphic-utils/system-types/graphchangenotification"; -import type { MentionNotification } from "@local/hash-isomorphic-utils/system-types/mentionnotification"; -import type { EntityRootType } from "@local/hash-subgraph"; -import { getRoots } from "@local/hash-subgraph/stdlib"; -import type { FunctionComponent, PropsWithChildren } from "react"; -import { createContext, useCallback, useContext, useMemo } from "react"; - -import type { - GetEntitySubgraphQuery, - GetEntitySubgraphQueryVariables, - UpdateEntitiesMutation, - UpdateEntitiesMutationVariables, - UpdateEntityMutation, - UpdateEntityMutationVariables, -} from "../graphql/api-types.gen"; -import { - getEntitySubgraphQuery, - updateEntitiesMutation, - updateEntityMutation, -} from "../graphql/queries/knowledge/entity.queries"; -import { useAuthInfo } from "../pages/shared/auth-info-context"; -import { pollInterval } from "./poll-interval"; - -export type NotificationEntitiesContextValues = { - notificationEntities?: Entity< - | Notification - | MentionNotification - | CommentNotification - | GraphChangeNotification - >[]; - numberOfUnreadNotifications?: number; - loading: boolean; - refetch: () => Promise; - markNotificationAsRead: (params: { - notificationEntity: Entity; - }) => Promise; - markNotificationsAsRead: (params: { - notificationEntities: Entity[]; - }) => Promise; - archiveNotification: (params: { - notificationEntity: Entity; - }) => Promise; - archiveNotifications: (params: { - notificationEntities: Entity[]; - }) => Promise; -}; - -export const NotificationEntitiesContext = - createContext(null); - -export const useNotificationEntities = () => { - const notificationsEntitiesContext = useContext(NotificationEntitiesContext); - - if (!notificationsEntitiesContext) { - throw new Error("Context missing"); - } - - return notificationsEntitiesContext; -}; - -export const NotificationEntitiesContextProvider: FunctionComponent< - PropsWithChildren -> = ({ children }) => { - const { authenticatedUser } = useAuthInfo(); - - const { - data: notificationEntitiesData, - loading: loadingNotificationEntities, - refetch: refetchNotificationEntities, - } = useQuery( - getEntitySubgraphQuery, - { - pollInterval, - variables: { - includePermissions: false, - request: { - filter: { - all: [ - { - equal: [ - { path: ["ownedById"] }, - { parameter: authenticatedUser?.accountId }, - ], - }, - generateVersionedUrlMatchingFilter( - systemEntityTypes.notification.entityTypeId, - { ignoreParents: false }, - ), - pageOrNotificationNotArchivedFilter, - ], - }, - graphResolveDepths: zeroedGraphResolveDepths, - temporalAxes: currentTimeInstantTemporalAxes, - includeDrafts: false, - }, - }, - skip: !authenticatedUser, - fetchPolicy: "network-only", - }, - ); - - const notificationEntitiesSubgraph = useMemo( - () => - notificationEntitiesData - ? mapGqlSubgraphFieldsFragmentToSubgraph>( - notificationEntitiesData.getEntitySubgraph.subgraph, - ) - : undefined, - [notificationEntitiesData], - ); - - const notificationEntities = useMemo< - | Entity< - | Notification - | MentionNotification - | CommentNotification - | GraphChangeNotification - >[] - | undefined - >( - () => - notificationEntitiesSubgraph - ? getRoots(notificationEntitiesSubgraph) - : undefined, - [notificationEntitiesSubgraph], - ); - - const refetch = useCallback(async () => { - await refetchNotificationEntities(); - }, [refetchNotificationEntities]); - - const [updateEntity] = useMutation< - UpdateEntityMutation, - UpdateEntityMutationVariables - >(updateEntityMutation); - - const markNotificationAsRead = useCallback( - async (params: { notificationEntity: Entity }) => { - const { notificationEntity } = params; - - const now = new Date(); - - await updateEntity({ - variables: { - entityUpdate: { - entityId: notificationEntity.metadata.recordId.entityId, - propertyPatches: [ - { - op: "add", - path: [ - "https://hash.ai/@hash/types/property-type/read-at/" satisfies keyof Notification["properties"] as BaseUrl, - ], - property: { - value: now.toISOString(), - metadata: { - dataTypeId: - "https://blockprotocol.org/@blockprotocol/types/data-type/text/v/1", - }, - } satisfies ReadAtPropertyValueWithMetadata, - }, - ], - }, - }, - }); - - await refetch(); - }, - [updateEntity, refetch], - ); - - const [updateEntities] = useMutation< - UpdateEntitiesMutation, - UpdateEntitiesMutationVariables - >(updateEntitiesMutation); - - const markNotificationsAsRead = useCallback( - async (params: { notificationEntities: Entity[] }) => { - const now = new Date(); - - await updateEntities({ - variables: { - entityUpdates: params.notificationEntities.map( - (notificationEntity) => ({ - entityId: notificationEntity.metadata.recordId.entityId, - entityTypeIds: notificationEntity.metadata.entityTypeIds, - propertyPatches: [ - { - op: "add", - path: [ - "https://hash.ai/@hash/types/property-type/read-at/" satisfies keyof Notification["properties"] as BaseUrl, - ], - property: { - value: now.toISOString(), - metadata: { - dataTypeId: - "https://blockprotocol.org/@blockprotocol/types/data-type/text/v/1", - }, - } satisfies ReadAtPropertyValueWithMetadata, - }, - ], - }), - ), - }, - }); - - await refetch(); - }, - [updateEntities, refetch], - ); - - const archiveNotification = useCallback( - async (params: { notificationEntity: Entity; shouldRefetch?: boolean }) => { - const { notificationEntity, shouldRefetch = true } = params; - - await updateEntity({ - variables: { - entityUpdate: { - entityId: notificationEntity.metadata.recordId.entityId, - entityTypeIds: notificationEntity.metadata.entityTypeIds, - propertyPatches: [ - { - op: "add", - path: [ - "https://hash.ai/@hash/types/property-type/archived/" satisfies keyof Notification["properties"] as BaseUrl, - ], - property: { - value: true, - metadata: { - dataTypeId: - "https://blockprotocol.org/@blockprotocol/types/data-type/boolean/v/1", - }, - } satisfies ArchivedPropertyValueWithMetadata, - }, - ], - }, - }, - }); - - if (shouldRefetch) { - await refetch(); - } - }, - [updateEntity, refetch], - ); - - const archiveNotifications = useCallback( - async (params: { notificationEntities: Entity[] }) => { - await updateEntities({ - variables: { - entityUpdates: params.notificationEntities.map( - (notificationEntity) => ({ - entityId: notificationEntity.metadata.recordId.entityId, - entityTypeIds: notificationEntity.metadata.entityTypeIds, - propertyPatches: [ - { - op: "add", - path: [ - "https://hash.ai/@hash/types/property-type/archived/" satisfies keyof Notification["properties"] as BaseUrl, - ], - property: { - value: true, - metadata: { - dataTypeId: - "https://blockprotocol.org/@blockprotocol/types/data-type/boolean/v/1", - }, - } satisfies ArchivedPropertyValueWithMetadata, - }, - ], - }), - ), - }, - }); - await refetch(); - }, - [updateEntities, refetch], - ); - - const numberOfUnreadNotifications = useMemo( - () => - notificationEntities?.filter(({ properties }) => { - const { readAt } = simplifyProperties(properties); - - return !readAt; - }).length, - [notificationEntities], - ); - - const value = useMemo( - () => ({ - notificationEntities, - numberOfUnreadNotifications, - loading: loadingNotificationEntities, - archiveNotifications, - refetch, - markNotificationAsRead, - markNotificationsAsRead, - archiveNotification, - }), - [ - notificationEntities, - numberOfUnreadNotifications, - archiveNotifications, - loadingNotificationEntities, - refetch, - markNotificationAsRead, - markNotificationsAsRead, - archiveNotification, - ], - ); - - return ( - - {children} - - ); -}; diff --git a/libs/@local/hash-isomorphic-utils/src/graphql/type-defs/generation.typedef.ts b/libs/@local/hash-isomorphic-utils/src/graphql/type-defs/generation.typedef.ts index 976f10a4255..878ca394c90 100644 --- a/libs/@local/hash-isomorphic-utils/src/graphql/type-defs/generation.typedef.ts +++ b/libs/@local/hash-isomorphic-utils/src/graphql/type-defs/generation.typedef.ts @@ -9,8 +9,6 @@ export const generationTypedef = gql` extend type Query { """ Generates the plural form of a word or phrase (e.g. Company -> Companies) - - TODO handle missing API keys gracefully for self-hosted instances """ generatePlural(singular: String!): String! diff --git a/libs/@local/hash-isomorphic-utils/src/graphql/type-defs/knowledge/entity.typedef.ts b/libs/@local/hash-isomorphic-utils/src/graphql/type-defs/knowledge/entity.typedef.ts index d4fdf24323a..183f0df636d 100644 --- a/libs/@local/hash-isomorphic-utils/src/graphql/type-defs/knowledge/entity.typedef.ts +++ b/libs/@local/hash-isomorphic-utils/src/graphql/type-defs/knowledge/entity.typedef.ts @@ -24,6 +24,7 @@ export const entityTypedef = gql` } type GetEntitySubgraphResponse { + count: Int closedMultiEntityTypes: ClosedMultiEntityTypesRootMap definitions: ClosedMultiEntityTypesDefinitions userPermissionsOnEntities: UserPermissionsOnEntities! From cb79928aaf03de5dc987d14fb932eb90d466d1c9 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Wed, 11 Dec 2024 13:31:44 +0100 Subject: [PATCH 3/4] H-2457: Improved ESLint configuration (#5847) --- apps/hash-ai-worker-ts/.eslintrc.cjs | 7 - apps/hash-ai-worker-ts/eslint.config.js | 3 + apps/hash-ai-worker-ts/package.json | 4 +- .../scripts/bundle-workflow-code.ts | 5 +- .../scripts/compare-llm-response.ts | 4 +- .../scripts/sanitize-html.ts | 4 +- .../flow-activities/answer-question-action.ts | 6 +- .../get-file-from-url-action.ts | 2 +- .../infer-metadata-from-document-action.ts | 8 +- .../research-entities-action.ai.test.ts | 6 +- ...ant-links-from-content.optimize.ai.test.ts | 12 +- .../get-link-follower-next-tool-calls.ts | 10 +- .../llama-index/simple-storage-context.ts | 6 +- .../shared/coordinator-tools.ts | 45 +- .../sub-coordinating-agent.ai.test.ts | 6 +- .../shared/create-file-entity-from-url.ts | 8 +- ...ty-summaries-from-text.optimize.ai.test.ts | 6 +- ...summaries-then-claims-from-text.ai.test.ts | 6 +- .../propose-entity-from-claims-agent.ts | 4 +- .../get-ai-assistant-account-id-activity.ts | 2 +- .../infer-entities/infer-entity-summaries.ts | 2 + .../infer-entities/propose-entities.ts | 2 +- .../src/activities/shared/activity-logger.ts | 4 +- .../get-llm-response/anthropic-client.ts | 15 +- .../shared/get-llm-response/llm-message.ts | 2 + .../get-llm-response/log-llm-request.ts | 4 +- .../shared/optimize-system-prompt.ts | 6 +- apps/hash-ai-worker-ts/src/main.ts | 5 +- apps/hash-ai-worker-ts/tsconfig.json | 2 +- .../{vitest.config.js => vitest.config.ts} | 0 apps/hash-api/.eslintrc.cjs | 22 - apps/hash-api/eslint.config.js | 25 + apps/hash-api/package.json | 4 +- .../src/ai/gpt/generate-hashgpt-schema.ts | 19 +- .../src/generate-ontology-type-ids.ts | 5 +- .../migrate-ontology-types.ts | 4 +- .../migrate-ontology-types/util.ts | 4 +- ...ument-after-update-entity-hook-callback.ts | 2 +- .../generation/is-generation-available.ts | 2 +- .../resolvers/knowledge/entity/entity.ts | 2 +- .../knowledge/user/get-waitlist-position.ts | 2 +- apps/hash-api/src/seed-data/seed-users.ts | 2 +- apps/hash-api/tsconfig.json | 2 +- .../{vitest.config.js => vitest.config.ts} | 1 - apps/hash-frontend/.eslintrc.cjs | 89 - apps/hash-frontend/eslint.config.js | 101 + apps/hash-frontend/package.json | 4 +- .../components/error-block/error-block.tsx | 4 +- .../remote-block/load-remote-block.ts | 4 +- .../user-profile-info-modal-header.tsx | 4 + .../canvas-page/block-creation-dialog.tsx | 2 +- .../edit-entity-slide-over.tsx | 2 +- .../[entity-uuid].page/entity-editor-page.tsx | 2 +- .../history-section/get-history-events.ts | 2 +- .../incoming-links-table.tsx | 9 +- .../readonly-outgoing-links-table.tsx | 4 +- .../cells/value-cell/inputs/json-input.tsx | 2 +- apps/hash-frontend/src/pages/_app.page.tsx | 2 + .../src/pages/_app.page/error-fallback.tsx | 1 + .../shared/block-collection/collab/http.ts | 2 +- .../collab/use-collab-positions.ts | 2 +- .../comments/comment-placeholder-plugin.tsx | 2 + .../block-collection/create-editor-view.ts | 3 + .../block-collection/create-error-plugin.tsx | 4 + .../create-format-plugins/index.tsx | 5 + .../create-placeholder-plugin.tsx | 3 + .../create-suggester/block-suggester.tsx | 4 +- .../create-suggester/create-suggester.tsx | 3 + .../create-suggester/suggester.tsx | 12 +- .../focus-page-title-plugin.ts | 1 + .../shared/mention-suggester.tsx | 4 +- .../src/pages/shared/verify-code.tsx | 2 +- .../src/pages/shared/visualizer-views.tsx | 4 +- .../src/pages/types/[[...type-kind]].page.tsx | 13 +- .../[[...type-kind]].page/types-table.tsx | 32 +- .../src/shared/generate-link-parameters.ts | 2 +- .../account-page-list/page-tree-item.tsx | 2 +- apps/hash-integration-worker/.eslintrc.cjs | 7 - apps/hash-integration-worker/eslint.config.js | 3 + apps/hash-integration-worker/package.json | 4 +- .../scripts/bundle-workflow-code.ts | 5 +- apps/hash-integration-worker/src/main.ts | 5 +- apps/hash-realtime/.eslintrc.cjs | 7 - apps/hash-realtime/eslint.config.js | 3 + apps/hash-realtime/package.json | 4 +- apps/hash-search-loader/.eslintrc.cjs | 13 - apps/hash-search-loader/eslint.config.js | 9 + apps/hash-search-loader/package.json | 4 +- apps/hashdotdesign/package.json | 2 +- apps/hashdotdev/.eslintrc.cjs | 39 - apps/hashdotdev/eslint.config.js | 43 + apps/hashdotdev/package.json | 4 +- .../src/components/calculation-block.tsx | 2 +- apps/hashdotdev/src/components/link.tsx | 2 + apps/hashdotdev/src/components/pre-footer.tsx | 2 +- .../src/pages/blog/[...blog-slug].page.tsx | 2 +- apps/hashdotdev/src/pages/blog/index.page.tsx | 2 +- apps/hashdotdev/src/pages/index.page.tsx | 2 +- apps/hashdotdev/src/pages/shared/mdx-utils.ts | 2 + apps/plugin-browser/.eslintrc.cjs | 42 - apps/plugin-browser/eslint.config.js | 40 + apps/plugin-browser/package.json | 5 +- .../one-off/infer-entities-action.tsx | 2 +- apps/plugin-browser/tsconfig.json | 3 +- blocks/address/.eslintrc.cjs | 4 - blocks/address/eslint.config.js | 3 + blocks/address/package.json | 4 +- blocks/address/src/address-card.tsx | 2 + blocks/address/src/map-button.tsx | 2 + blocks/ai-chat/.eslintrc.cjs | 4 - blocks/ai-chat/eslint.config.js | 3 + blocks/ai-chat/package.json | 4 +- blocks/ai-image/.eslintrc.cjs | 4 - blocks/ai-image/eslint.config.js | 3 + blocks/ai-image/package.json | 4 +- blocks/ai-text/.eslintrc.cjs | 4 - blocks/ai-text/eslint.config.js | 3 + blocks/ai-text/package.json | 4 +- blocks/callout/.eslintrc.cjs | 4 - blocks/callout/eslint.config.js | 3 + blocks/callout/package.json | 4 +- blocks/chart/.eslintrc.cjs | 4 - blocks/chart/eslint.config.js | 3 + blocks/chart/package.json | 5 +- blocks/chart/src/bar-chart.tsx | 2 + blocks/code/.eslintrc.cjs | 4 - blocks/code/eslint.config.js | 3 + blocks/code/package.json | 4 +- blocks/countdown/.eslintrc.cjs | 4 - blocks/countdown/eslint.config.js | 3 + blocks/countdown/package.json | 4 +- blocks/divider/.eslintrc.cjs | 4 - blocks/divider/eslint.config.js | 3 + blocks/divider/package.json | 4 +- blocks/embed/.eslintrc.cjs | 4 - blocks/embed/eslint.config.js | 3 + blocks/embed/package.json | 4 +- blocks/embed/turbo.json | 2 +- blocks/faq/.eslintrc.cjs | 4 - blocks/faq/eslint.config.js | 3 + blocks/faq/package.json | 4 +- blocks/faq/src/app.tsx | 2 +- blocks/faq/src/dev.tsx | 2 +- blocks/faq/src/types/block-entity.ts | 105 - blocks/heading/.eslintrc.cjs | 4 - blocks/heading/eslint.config.js | 3 + blocks/heading/package.json | 4 +- blocks/how-to/.eslintrc.cjs | 4 - blocks/how-to/eslint.config.js | 3 + blocks/how-to/package.json | 4 +- blocks/how-to/src/app.tsx | 106 +- blocks/image/.eslintrc.cjs | 4 - blocks/image/eslint.config.js | 3 + blocks/image/package.json | 4 +- blocks/kanban-board/.eslintrc.cjs | 4 - blocks/kanban-board/eslint.config.js | 3 + blocks/kanban-board/package.json | 5 +- blocks/minesweeper/.eslintrc.cjs | 4 - blocks/minesweeper/eslint.config.js | 3 + blocks/minesweeper/package.json | 4 +- blocks/minesweeper/src/app.ts | 1 - blocks/paragraph/.eslintrc.cjs | 4 - blocks/paragraph/eslint.config.js | 3 + blocks/paragraph/package.json | 4 +- blocks/person/.eslintrc.cjs | 4 - blocks/person/eslint.config.js | 3 + blocks/person/package.json | 4 +- blocks/shuffle/.eslintrc.cjs | 14 - blocks/shuffle/eslint.config.js | 3 + blocks/shuffle/package.json | 4 +- blocks/shuffle/src/components/item-list.tsx | 4 +- blocks/shuffle/src/components/item.tsx | 6 +- .../shuffle/src/components/sortable-item.tsx | 3 +- blocks/shuffle/src/shuffle.tsx | 4 +- blocks/table/.eslintrc.cjs | 4 - blocks/table/eslint.config.js | 3 + blocks/table/package.json | 6 +- blocks/timer/.eslintrc.cjs | 4 - blocks/timer/eslint.config.js | 3 + blocks/timer/package.json | 4 +- blocks/video/.eslintrc.cjs | 4 - blocks/video/eslint.config.js | 3 + blocks/video/package.json | 4 +- libs/@blockprotocol/graph/.eslintrc.cjs | 7 - libs/@blockprotocol/graph/eslint.config.js | 10 + libs/@blockprotocol/graph/package.json | 4 +- libs/@blockprotocol/graph/src/codegen.ts | 2 +- .../codegen/initialize/clean-output-dir.ts | 4 +- .../initialize/ensure-output-dir-exists.ts | 6 +- .../prepend-imports-and-exports.ts | 2 +- .../src/codegen/postprocess/write-to-files.ts | 2 +- .../graph/src/stdlib/subgraph/builder.ts | 4 +- libs/@blockprotocol/graph/tsconfig.build.json | 1 + libs/@blockprotocol/graph/tsconfig.json | 2 +- .../type-system/typescript/.eslintrc.cjs | 4 - .../type-system/typescript/eslint.config.js | 6 + .../type-system/typescript/package.json | 4 +- .../type-system/typescript/tsconfig.json | 2 +- .../{vitest.config.js => vitest.config.ts} | 6 +- .../block-design-system/.eslintrc.cjs | 48 - .../block-design-system/eslint.config.js | 47 + .../block-design-system/package.json | 6 +- libs/@hashintel/design-system/.eslintrc.cjs | 48 - .../@hashintel/design-system/eslint.config.js | 47 + libs/@hashintel/design-system/package.json | 6 +- .../src/autocomplete-dropdown.tsx | 8 +- .../src/popper-placement-modifier.ts | 1 + libs/@hashintel/query-editor/.eslintrc.cjs | 43 - libs/@hashintel/query-editor/eslint.config.js | 42 + libs/@hashintel/query-editor/package.json | 5 +- libs/@hashintel/type-editor/.eslintrc.cjs | 43 - libs/@hashintel/type-editor/eslint.config.js | 42 + libs/@hashintel/type-editor/package.json | 5 +- .../type-editor/src/entity-type-editor.tsx | 1 + .../shared/type-menu-cell.tsx | 2 +- libs/@local/advanced-types/.eslintrc.cjs | 14 - libs/@local/advanced-types/eslint.config.js | 17 + libs/@local/advanced-types/package.json | 4 +- .../@local/advanced-types/tsconfig.build.json | 1 + libs/@local/advanced-types/tsconfig.json | 2 +- libs/@local/eslint-config/.eslintrc.cjs | 7 - .../eslint-config/generate-block-config.cjs | 35 - .../generate-ignore-patterns.cjs | 181 -- .../generate-workspace-config.cjs | 21 - .../legacy-base-eslintrc-to-refactor.cjs | 373 --- .../legacy-block-eslintrc-to-refactor.cjs | 15 - libs/@local/eslint-config/package.json | 36 - .../temporarily-disable-rules.cjs | 18 - libs/@local/eslint-config/tsconfig.json | 3 - .../{eslint-config => eslint}/LICENSE.md | 0 libs/@local/eslint/eslint.config.js | 3 + libs/@local/eslint/package.json | 50 + libs/@local/eslint/src/builtIn.ts | 95 + libs/@local/eslint/src/constants.ts | 2 + libs/@local/eslint/src/deprecated/base.ts | 500 ++++ libs/@local/eslint/src/deprecated/block.ts | 46 + libs/@local/eslint/src/deprecated/disable.ts | 13 + libs/@local/eslint/src/deprecated/index.ts | 9 + libs/@local/eslint/src/import.ts | 36 + libs/@local/eslint/src/index.ts | 64 + libs/@local/eslint/src/react.ts | 42 + libs/@local/eslint/src/stylistic.ts | 17 + libs/@local/eslint/src/types.ts | 59 + libs/@local/eslint/src/typescript.ts | 145 + libs/@local/eslint/src/unicorn.ts | 160 ++ libs/@local/eslint/src/utils.ts | 38 + libs/@local/eslint/tsconfig.build.json | 9 + libs/@local/eslint/tsconfig.json | 9 + libs/@local/eslint/turbo.json | 8 + .../graph/client/typescript/.eslintrc.cjs | 9 - .../graph/client/typescript/package.json | 1 - .../@local/graph/sdk/typescript/.eslintrc.cjs | 7 - .../graph/sdk/typescript/eslint.config.js | 6 + libs/@local/graph/sdk/typescript/package.json | 4 +- .../@local/graph/sdk/typescript/src/entity.ts | 2 + .../@local/graph/sdk/typescript/tsconfig.json | 2 +- .../sdk/typescript/vitest.config.ts} | 1 - libs/@local/graph/type-defs/.eslintrc.cjs | 11 - libs/@local/graph/type-defs/Cargo.toml | 2 +- libs/@local/graph/type-defs/eslint.config.js | 11 + libs/@local/graph/type-defs/package.json | 4 +- libs/@local/graph/type-defs/tsconfig.json | 2 +- .../graph/types/typescript/.eslintrc.cjs | 7 - .../graph/types/typescript/eslint.config.js | 10 + .../graph/types/typescript/package.json | 4 +- .../types/typescript/tsconfig.build.json | 1 + .../graph/types/typescript/tsconfig.json | 2 +- libs/@local/graph/types/typescript/turbo.json | 3 +- .../harpc/client/typescript/.eslintrc.cjs | 13 - .../harpc/client/typescript/eslint.config.js | 17 + .../harpc/client/typescript/package.json | 4 +- .../client/typescript/src/codec/Decoder.ts | 2 +- .../tests/codec/JsonDecoder.test.ts | 16 +- .../typescript/tests/net/Request.test.ts | 4 +- .../harpc/client/typescript/tsconfig.json | 2 +- .../{vitest.config.js => vitest.config.ts} | 0 libs/@local/hash-backend-utils/.eslintrc.cjs | 10 - .../hash-backend-utils/eslint.config.js | 9 + libs/@local/hash-backend-utils/package.json | 4 +- .../hash-backend-utils/src/environment.ts | 4 +- libs/@local/hash-backend-utils/src/google.ts | 2 +- .../hash-backend-utils/src/machine-actors.ts | 10 +- .../hash-backend-utils/tsconfig.build.json | 1 + libs/@local/hash-backend-utils/tsconfig.json | 2 +- .../vitest.config.ts} | 1 - .../hash-isomorphic-utils/.eslintrc.cjs | 50 - .../hash-isomorphic-utils/eslint.config.js | 40 + .../@local/hash-isomorphic-utils/package.json | 4 +- .../src/create-prose-mirror-state.ts | 2 + .../src/entity-store-plugin.ts | 4 + .../src/flows/action-definitions.ts | 31 +- .../src/flows/trigger-definitions.ts | 13 +- .../hash-isomorphic-utils/src/flows/types.ts | 15 +- .../hash-isomorphic-utils/src/sanitize.ts | 2 +- .../src/stringify-property-value.ts | 2 + .../src/wrap-entities-plugin.ts | 1 + .../hash-isomorphic-utils/tsconfig.json | 8 +- .../vitest.config.ts} | 1 - libs/@local/hash-subgraph/.eslintrc.cjs | 4 - libs/@local/hash-subgraph/eslint.config.js | 3 + libs/@local/hash-subgraph/package.json | 4 +- libs/@local/hash-subgraph/tsconfig.json | 2 +- .../vitest.config.ts} | 0 .../typescript/package.json | 1 - libs/@local/repo-chores/node/.eslintrc.cjs | 7 - libs/@local/repo-chores/node/eslint.config.js | 13 + libs/@local/repo-chores/node/package.json | 4 +- .../repo-chores/node/scripts/create-block.ts | 6 +- .../node/scripts/shared/monorepo.ts | 4 +- libs/@local/repo-chores/node/tsconfig.json | 1 + libs/@local/status/typescript/.eslintrc.cjs | 7 - .../@local/status/typescript/eslint.config.js | 10 + libs/@local/status/typescript/package.json | 4 +- .../status/typescript/scripts/codegen.ts | 2 +- libs/@local/status/typescript/tsconfig.json | 2 +- .../legacy-base-tsconfig-to-refactor.json | 4 +- tests/hash-backend-integration/.eslintrc.cjs | 14 - .../hash-backend-integration/eslint.config.js | 10 + tests/hash-backend-integration/package.json | 4 +- .../graph/knowledge/primitive/entity.test.ts | 1 + .../ontology/primitive/data-type.test.ts | 1 + .../ontology/primitive/entity-type.test.ts | 1 + .../ontology/primitive/property-type.test.ts | 1 + tests/hash-backend-integration/tsconfig.json | 2 +- .../{vitest.config.js => vitest.config.ts} | 0 tests/hash-backend-load/.eslintrc.cjs | 7 - tests/hash-backend-load/eslint.config.js | 10 + tests/hash-backend-load/package.json | 4 +- tests/hash-playwright/.eslintrc.cjs | 22 - tests/hash-playwright/eslint.config.js | 21 + tests/hash-playwright/package.json | 8 +- .../tests/browser-plugin/fixtures.ts | 6 +- tests/hash-playwright/tests/shared/runtime.ts | 4 + tests/hash-playwright/tsconfig.json | 1 + turbo.json | 2 +- yarn.config.cjs | 4 + yarn.lock | 2349 ++++++++++++----- 337 files changed, 4237 insertions(+), 2547 deletions(-) delete mode 100644 apps/hash-ai-worker-ts/.eslintrc.cjs create mode 100644 apps/hash-ai-worker-ts/eslint.config.js rename apps/hash-ai-worker-ts/{vitest.config.js => vitest.config.ts} (100%) delete mode 100644 apps/hash-api/.eslintrc.cjs create mode 100644 apps/hash-api/eslint.config.js rename apps/hash-api/{vitest.config.js => vitest.config.ts} (92%) delete mode 100644 apps/hash-frontend/.eslintrc.cjs create mode 100644 apps/hash-frontend/eslint.config.js delete mode 100644 apps/hash-integration-worker/.eslintrc.cjs create mode 100644 apps/hash-integration-worker/eslint.config.js delete mode 100644 apps/hash-realtime/.eslintrc.cjs create mode 100644 apps/hash-realtime/eslint.config.js delete mode 100644 apps/hash-search-loader/.eslintrc.cjs create mode 100644 apps/hash-search-loader/eslint.config.js delete mode 100644 apps/hashdotdev/.eslintrc.cjs create mode 100644 apps/hashdotdev/eslint.config.js delete mode 100644 apps/plugin-browser/.eslintrc.cjs create mode 100644 apps/plugin-browser/eslint.config.js delete mode 100644 blocks/address/.eslintrc.cjs create mode 100644 blocks/address/eslint.config.js delete mode 100644 blocks/ai-chat/.eslintrc.cjs create mode 100644 blocks/ai-chat/eslint.config.js delete mode 100644 blocks/ai-image/.eslintrc.cjs create mode 100644 blocks/ai-image/eslint.config.js delete mode 100644 blocks/ai-text/.eslintrc.cjs create mode 100644 blocks/ai-text/eslint.config.js delete mode 100644 blocks/callout/.eslintrc.cjs create mode 100644 blocks/callout/eslint.config.js delete mode 100644 blocks/chart/.eslintrc.cjs create mode 100644 blocks/chart/eslint.config.js delete mode 100644 blocks/code/.eslintrc.cjs create mode 100644 blocks/code/eslint.config.js delete mode 100644 blocks/countdown/.eslintrc.cjs create mode 100644 blocks/countdown/eslint.config.js delete mode 100644 blocks/divider/.eslintrc.cjs create mode 100644 blocks/divider/eslint.config.js delete mode 100644 blocks/embed/.eslintrc.cjs create mode 100644 blocks/embed/eslint.config.js delete mode 100644 blocks/faq/.eslintrc.cjs create mode 100644 blocks/faq/eslint.config.js delete mode 100644 blocks/faq/src/types/block-entity.ts delete mode 100644 blocks/heading/.eslintrc.cjs create mode 100644 blocks/heading/eslint.config.js delete mode 100644 blocks/how-to/.eslintrc.cjs create mode 100644 blocks/how-to/eslint.config.js delete mode 100644 blocks/image/.eslintrc.cjs create mode 100644 blocks/image/eslint.config.js delete mode 100644 blocks/kanban-board/.eslintrc.cjs create mode 100644 blocks/kanban-board/eslint.config.js delete mode 100644 blocks/minesweeper/.eslintrc.cjs create mode 100644 blocks/minesweeper/eslint.config.js delete mode 100644 blocks/paragraph/.eslintrc.cjs create mode 100644 blocks/paragraph/eslint.config.js delete mode 100644 blocks/person/.eslintrc.cjs create mode 100644 blocks/person/eslint.config.js delete mode 100644 blocks/shuffle/.eslintrc.cjs create mode 100644 blocks/shuffle/eslint.config.js delete mode 100644 blocks/table/.eslintrc.cjs create mode 100644 blocks/table/eslint.config.js delete mode 100644 blocks/timer/.eslintrc.cjs create mode 100644 blocks/timer/eslint.config.js delete mode 100644 blocks/video/.eslintrc.cjs create mode 100644 blocks/video/eslint.config.js delete mode 100644 libs/@blockprotocol/graph/.eslintrc.cjs create mode 100644 libs/@blockprotocol/graph/eslint.config.js delete mode 100644 libs/@blockprotocol/type-system/typescript/.eslintrc.cjs create mode 100644 libs/@blockprotocol/type-system/typescript/eslint.config.js rename libs/@blockprotocol/type-system/typescript/{vitest.config.js => vitest.config.ts} (91%) delete mode 100644 libs/@hashintel/block-design-system/.eslintrc.cjs create mode 100644 libs/@hashintel/block-design-system/eslint.config.js delete mode 100644 libs/@hashintel/design-system/.eslintrc.cjs create mode 100644 libs/@hashintel/design-system/eslint.config.js delete mode 100644 libs/@hashintel/query-editor/.eslintrc.cjs create mode 100644 libs/@hashintel/query-editor/eslint.config.js delete mode 100644 libs/@hashintel/type-editor/.eslintrc.cjs create mode 100644 libs/@hashintel/type-editor/eslint.config.js delete mode 100644 libs/@local/advanced-types/.eslintrc.cjs create mode 100644 libs/@local/advanced-types/eslint.config.js delete mode 100644 libs/@local/eslint-config/.eslintrc.cjs delete mode 100644 libs/@local/eslint-config/generate-block-config.cjs delete mode 100644 libs/@local/eslint-config/generate-ignore-patterns.cjs delete mode 100644 libs/@local/eslint-config/generate-workspace-config.cjs delete mode 100644 libs/@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs delete mode 100644 libs/@local/eslint-config/legacy-block-eslintrc-to-refactor.cjs delete mode 100644 libs/@local/eslint-config/package.json delete mode 100644 libs/@local/eslint-config/temporarily-disable-rules.cjs delete mode 100644 libs/@local/eslint-config/tsconfig.json rename libs/@local/{eslint-config => eslint}/LICENSE.md (100%) create mode 100644 libs/@local/eslint/eslint.config.js create mode 100644 libs/@local/eslint/package.json create mode 100644 libs/@local/eslint/src/builtIn.ts create mode 100644 libs/@local/eslint/src/constants.ts create mode 100644 libs/@local/eslint/src/deprecated/base.ts create mode 100644 libs/@local/eslint/src/deprecated/block.ts create mode 100644 libs/@local/eslint/src/deprecated/disable.ts create mode 100644 libs/@local/eslint/src/deprecated/index.ts create mode 100644 libs/@local/eslint/src/import.ts create mode 100644 libs/@local/eslint/src/index.ts create mode 100644 libs/@local/eslint/src/react.ts create mode 100644 libs/@local/eslint/src/stylistic.ts create mode 100644 libs/@local/eslint/src/types.ts create mode 100644 libs/@local/eslint/src/typescript.ts create mode 100644 libs/@local/eslint/src/unicorn.ts create mode 100644 libs/@local/eslint/src/utils.ts create mode 100644 libs/@local/eslint/tsconfig.build.json create mode 100644 libs/@local/eslint/tsconfig.json create mode 100644 libs/@local/eslint/turbo.json delete mode 100644 libs/@local/graph/client/typescript/.eslintrc.cjs delete mode 100644 libs/@local/graph/sdk/typescript/.eslintrc.cjs create mode 100644 libs/@local/graph/sdk/typescript/eslint.config.js rename libs/@local/{hash-subgraph/vitest.config.js => graph/sdk/typescript/vitest.config.ts} (92%) delete mode 100644 libs/@local/graph/type-defs/.eslintrc.cjs create mode 100644 libs/@local/graph/type-defs/eslint.config.js delete mode 100644 libs/@local/graph/types/typescript/.eslintrc.cjs create mode 100644 libs/@local/graph/types/typescript/eslint.config.js delete mode 100644 libs/@local/harpc/client/typescript/.eslintrc.cjs create mode 100644 libs/@local/harpc/client/typescript/eslint.config.js rename libs/@local/harpc/client/typescript/{vitest.config.js => vitest.config.ts} (100%) delete mode 100644 libs/@local/hash-backend-utils/.eslintrc.cjs create mode 100644 libs/@local/hash-backend-utils/eslint.config.js rename libs/@local/{hash-isomorphic-utils/vitest.config.js => hash-backend-utils/vitest.config.ts} (91%) delete mode 100644 libs/@local/hash-isomorphic-utils/.eslintrc.cjs create mode 100644 libs/@local/hash-isomorphic-utils/eslint.config.js rename libs/@local/{hash-backend-utils/vitest.config.js => hash-isomorphic-utils/vitest.config.ts} (91%) delete mode 100644 libs/@local/hash-subgraph/.eslintrc.cjs create mode 100644 libs/@local/hash-subgraph/eslint.config.js rename libs/@local/{graph/sdk/typescript/vitest.config.js => hash-subgraph/vitest.config.ts} (100%) delete mode 100644 libs/@local/repo-chores/node/.eslintrc.cjs create mode 100644 libs/@local/repo-chores/node/eslint.config.js delete mode 100644 libs/@local/status/typescript/.eslintrc.cjs create mode 100644 libs/@local/status/typescript/eslint.config.js delete mode 100644 tests/hash-backend-integration/.eslintrc.cjs create mode 100644 tests/hash-backend-integration/eslint.config.js rename tests/hash-backend-integration/{vitest.config.js => vitest.config.ts} (100%) delete mode 100644 tests/hash-backend-load/.eslintrc.cjs create mode 100644 tests/hash-backend-load/eslint.config.js delete mode 100644 tests/hash-playwright/.eslintrc.cjs create mode 100644 tests/hash-playwright/eslint.config.js diff --git a/apps/hash-ai-worker-ts/.eslintrc.cjs b/apps/hash-ai-worker-ts/.eslintrc.cjs deleted file mode 100644 index 75608ba7bba..00000000000 --- a/apps/hash-ai-worker-ts/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - env: { - node: true, - }, -}; diff --git a/apps/hash-ai-worker-ts/eslint.config.js b/apps/hash-ai-worker-ts/eslint.config.js new file mode 100644 index 00000000000..0eac3025266 --- /dev/null +++ b/apps/hash-ai-worker-ts/eslint.config.js @@ -0,0 +1,3 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default createBase(import.meta.dirname); diff --git a/apps/hash-ai-worker-ts/package.json b/apps/hash-ai-worker-ts/package.json index 5681f1fa3c6..e09c5a4e6f7 100644 --- a/apps/hash-ai-worker-ts/package.json +++ b/apps/hash-ai-worker-ts/package.json @@ -94,7 +94,7 @@ "typescript": "5.6.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@sentry/cli": "^2.39.1", "@types/dedent": "0.7.2", @@ -110,7 +110,7 @@ "@types/papaparse": "5.3.15", "@types/sanitize-html": "2.13.0", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3", "vite-tsconfig-paths": "5.1.4", diff --git a/apps/hash-ai-worker-ts/scripts/bundle-workflow-code.ts b/apps/hash-ai-worker-ts/scripts/bundle-workflow-code.ts index ac7c4609a4c..9c37039248c 100644 --- a/apps/hash-ai-worker-ts/scripts/bundle-workflow-code.ts +++ b/apps/hash-ai-worker-ts/scripts/bundle-workflow-code.ts @@ -1,13 +1,12 @@ import { writeFile } from "node:fs/promises"; import { createRequire } from "node:module"; -import * as path from "node:path"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { bundleWorkflowCode } from "@temporalio/worker"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const require = createRequire(import.meta.url); diff --git a/apps/hash-ai-worker-ts/scripts/compare-llm-response.ts b/apps/hash-ai-worker-ts/scripts/compare-llm-response.ts index 10032f5bdeb..1414a1dca19 100644 --- a/apps/hash-ai-worker-ts/scripts/compare-llm-response.ts +++ b/apps/hash-ai-worker-ts/scripts/compare-llm-response.ts @@ -1,5 +1,5 @@ import { mkdirSync, writeFileSync } from "node:fs"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { type OwnedById } from "@local/hash-graph-types/web"; @@ -14,7 +14,7 @@ import { getAliceUserAccountId } from "../src/shared/testing-utilities/get-alice import type { CompareLlmResponseConfig } from "./compare-llm-response/types.js"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const configDirectory = `${__dirname}/compare-llm-response/var/config`; diff --git a/apps/hash-ai-worker-ts/scripts/sanitize-html.ts b/apps/hash-ai-worker-ts/scripts/sanitize-html.ts index 570fa921648..85089d1656f 100644 --- a/apps/hash-ai-worker-ts/scripts/sanitize-html.ts +++ b/apps/hash-ai-worker-ts/scripts/sanitize-html.ts @@ -1,5 +1,5 @@ import { mkdirSync, writeFileSync } from "node:fs"; -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { getWebPageActivity } from "../src/activities/get-web-page-activity.js"; @@ -12,7 +12,7 @@ import { getWebPageActivity } from "../src/activities/get-web-page-activity.js"; */ const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const url = process.argv[2]; diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/answer-question-action.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/answer-question-action.ts index 8c1318e8806..588f6191828 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/answer-question-action.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/answer-question-action.ts @@ -316,7 +316,11 @@ const callModel = async ( : dedent(` The Python code ran successfully. The stdout from your code was: ${stdout} - The following artifacts were generated:\n${artifacts.join("\n")} + The following artifacts were generated:\n${ + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-base-to-string + artifacts.join("\n") + } Please now review the code used and whether it correctly operates on the context data. If you spot errors in how the code attempts to access the code data, submit another code file with the corrections. diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/get-file-from-url-action.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/get-file-from-url-action.ts index 04719a25f30..3c69fd417d6 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/get-file-from-url-action.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/get-file-from-url-action.ts @@ -35,7 +35,7 @@ export const getFileFromUrlAction: FlowActionActivity = async ({ inputs }) => { } // @todo look for an existing file with the same originalUrl in the graph, and update it if found? - const operation = "create" as const; + const operation = "create"; const fileEntity = createFileEntityFromUrlStatus.entity.toJSON(); diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/infer-metadata-from-document-action.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/infer-metadata-from-document-action.ts index 28b445bf670..ab196038dc5 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/infer-metadata-from-document-action.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/infer-metadata-from-document-action.ts @@ -1,6 +1,6 @@ import { createWriteStream } from "node:fs"; import { mkdir, unlink } from "node:fs/promises"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { Readable } from "node:stream"; import { finished } from "node:stream/promises"; import type { ReadableStream } from "node:stream/web"; @@ -47,9 +47,9 @@ import { getLlmAnalysisOfDoc } from "./infer-metadata-from-document-action/get-l import type { FlowActionActivity } from "./types.js"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); -const baseFilePath = join(__dirname, "/var/tmp_files"); +const baseFilePath = path.join(__dirname, "/var/tmp_files"); export const inferMetadataFromDocumentAction: FlowActionActivity = async ({ inputs, @@ -200,6 +200,8 @@ export const inferMetadataFromDocumentAction: FlowActionActivity = async ({ resolve(pdfData); }); + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors pdfParser.loadPDF(filePath).catch((err) => reject(err)); }); diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action.ai.test.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action.ai.test.ts index efce2367b8a..3a6cf71263b 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action.ai.test.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action.ai.test.ts @@ -7,7 +7,7 @@ import { readFileSync, writeFileSync, } from "node:fs"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { expect, test } from "vitest"; @@ -16,9 +16,9 @@ import { researchEntitiesAction } from "./research-entities-action.js"; import type { CoordinatingAgentState } from "./research-entities-action/shared/coordinators.js"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); -const baseDirectoryPath = join(__dirname, "/var/persisted-state"); +const baseDirectoryPath = path.join(__dirname, "/var/persisted-state"); export const retrievePreviousState = (params: { testName: string; diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/choose-relevant-links-from-content.optimize.ai.test.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/choose-relevant-links-from-content.optimize.ai.test.ts index 5b4ca35928e..5db2adeb782 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/choose-relevant-links-from-content.optimize.ai.test.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/choose-relevant-links-from-content.optimize.ai.test.ts @@ -1,6 +1,6 @@ import "../../../../shared/testing-utilities/mock-get-flow-context.js"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import dedent from "dedent"; @@ -32,7 +32,7 @@ const ftse350Metric: MetricDefinition = { The user prompt provided to the LLM is: "${ftse350MetricPrompt}". The text provided to the LLM is the HTML of a web-page containing a table of FTSE350 constituents, paginated across multiple pages. - + The LLM must extract all the paginated links from the FTSE350 constituents page, because the links must be followed to extract the full list of FTSE350 constituents. @@ -118,7 +118,7 @@ const marksAndSpencersAnnualInvestorsReport: MetricDefinition = { The text provided to the LLM is the HTML of the Marks and Spencers investors page, which includes links to a variety of documents, including the annual investor report published by the company every year. - + To satisfy the prompt, the LLM must extract the link to the latest annual investor report PDF published by Marks and Spencers, which is https://corporate.marksandspencer.com/sites/marksandspencer/files/2024-06/M-and-S-2024-Annual-Report.pdf. @@ -201,7 +201,7 @@ const graphicsCardSpecificationMetric: MetricDefinition = { To satisfy the prompt, the LLM must extract the link to the specification page of the NVIDIA GeForce RTX 4090 graphics card, which is https://www.techpowerup.com/gpu-specs/geforce-rtx-4090.c3889. - + The score in this metric is calculated as 1 if the correct link is extracted, and 0 otherwise. `), executeMetric: async (params) => { @@ -267,9 +267,9 @@ const metrics: MetricDefinition[] = [ ]; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); -const baseDirectoryPath = join( +const baseDirectoryPath = path.join( __dirname, "/var/extract-links-from-text-testing", ); diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/get-link-follower-next-tool-calls.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/get-link-follower-next-tool-calls.ts index bcc415d3c43..88f78a01351 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/get-link-follower-next-tool-calls.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/get-link-follower-next-tool-calls.ts @@ -42,11 +42,11 @@ const getLinkFollowerNextToolCallsSystemPrompt = dedent(` - complete: complete the research task if the gathered claims fulfill the task - exploreLinks: call this tool to explore additional links to gather more claims that may fulfill the task - terminate: terminate the research task if it cannot be progressed further - - If you already have enough claims to meet the research brief, call 'complete'. + + If you already have enough claims to meet the research brief, call 'complete'. Don't follow more links unless it is required to meet the goal of the research task. - + Balance any need to gather more claims with the need to complete the task in a timely manner. Consider the research task and the claims already gathered when making your decision. `); @@ -116,9 +116,7 @@ Now decide what to do next. If you have gathered enough information about entiti }; }; -const toolNames = ["exploreLinks", "complete", "terminate"] as const; - -type ToolName = (typeof toolNames)[number]; +type ToolName = "exploreLinks" | "complete" | "terminate"; const suggestionForNextStepsDefinition = { type: "string", diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/llama-index/simple-storage-context.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/llama-index/simple-storage-context.ts index 86c6fdef976..c6df2347809 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/llama-index/simple-storage-context.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/link-follower-agent/llama-index/simple-storage-context.ts @@ -1,5 +1,5 @@ import { access, mkdir } from "node:fs/promises"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import type { Subtype } from "@local/advanced-types/subtype"; @@ -20,9 +20,9 @@ export type SimpleStorageContext = Subtype< >; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); -const baseFilePath = join(__dirname, "/var/tmp_files"); +const baseFilePath = path.join(__dirname, "/var/tmp_files"); export const generateSimpleStorageContextFilePaths = (params: { hash: string; diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/shared/coordinator-tools.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/shared/coordinator-tools.ts index 6f5a40685f7..314c12a3de9 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/shared/coordinator-tools.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/shared/coordinator-tools.ts @@ -56,10 +56,7 @@ export const subCoordinatorOmittedCoordinatorToolNames = [ type SubCoordinatorOmittedCoordinatorToolName = (typeof subCoordinatorOmittedCoordinatorToolNames)[number]; -const subCoordinatingAgentCustomToolNames = ["complete"] as const; - -export type SubCoordinatingAgentCustomToolName = - (typeof subCoordinatingAgentCustomToolNames)[number]; +export type SubCoordinatingAgentCustomToolName = "complete"; export type SubCoordinatingAgentToolName = | Exclude @@ -179,12 +176,12 @@ export const generateToolDefinitions = < description: dedent(` Instruct a colleague to help you with a specific part of the research task. This is useful when the research task is complex and requires multiple people to work on different parts of it. - + Make sure that you take account of any information the user has provided you when instructing your colleague, including the original research brief and any subsequent clarifications. Pass this information on to your colleague as part of the instructions where it would be helpful. - - Where you are seeking additional information on specific entities, make sure to include their ids as relevantEntityIds + + Where you are seeking additional information on specific entities, make sure to include their ids as relevantEntityIds `), inputSchema: { type: "object", @@ -198,7 +195,7 @@ export const generateToolDefinitions = < description: dedent(` The entityId of the proposed entities which the task is relevant to. If none, pass an empty array. - + ${ params.state.entitySummaries.length ? `The possible values are: ${params.state.entitySummaries @@ -217,8 +214,8 @@ export const generateToolDefinitions = < 2. If you are seeking more information on specific entities: a. the names of the entities (their ids should be provided under relevantEntityIds) b. what specific information you are seeking about them - - For example + + For example "Find the technical specifications of product X". "Find the LinkedIn URL for person X" "Find the release date, director and box office takings for movie X" @@ -239,9 +236,9 @@ export const generateToolDefinitions = < webSearch: { name: "webSearch", description: - dedent(`Perform a web search via a web search engine, returning a list of URLs. + dedent(`Perform a web search via a web search engine, returning a list of URLs. For best results, the query should be specific and concise. - Bear in mind that all the information you require may not be available via a single web search + Bear in mind that all the information you require may not be available via a single web search – if you have various attributes to gather about specific entities, it may be worth performing multiple searches for each entity, or for each entity's attribute, until you find suitable results. `), @@ -266,13 +263,13 @@ export const generateToolDefinitions = < name: "inferClaimsFromResource", description: dedent(` Explore a resource in order to discover entities and 'claims' (possible facts) it contains, as well resources linked from it. - + The URLs for the resource must have been provided in messages to you, or as the result of a previous action (e.g. a web search, or in suggestions for next steps). Don't guess URLs! - + If you want additional information about entities you already know about, or to find new entities to link to existing entities, be sure to specify the existing entities under 'relevantEntityIds'. - + You can explore multiple resources at once by making multiple calls, but don't start multiple redundant explorations for the same information. You can always explore another URL if one doesn't return the information you require. `), @@ -288,7 +285,7 @@ export const generateToolDefinitions = < type: "string", description: dedent(` The goal of exploring this specific resource. This will be used to guide what specific entities and claims are discovered. - + DO include: 1. What specifies entities or types of entities you are seeking information on 2. Any guidance from the user, whether in the original instructions or subsequent questions and answers, which is relevant to the task @@ -320,7 +317,7 @@ export const generateToolDefinitions = < The entityIds of already proposed entities which you are seeking further detail on, if any. If you expect new entities you are seeking to be linked to already-discovered entities, specify the already-discovered entities here. If you are unsure if an entity is relevant, just include it – it's better to include too many than too few. - + If there are absolutely no entities relevant, pass an empty array. `), }, @@ -357,7 +354,7 @@ export const generateToolDefinitions = < type: "string", }, description: dedent(` - An array of entityIds to highlight. + An array of entityIds to highlight. The user will receive all entities discovered, with the highlighted entityIds identified for special attention. You must have made an effort to find as many properties and outgoing links for each entity as possible, as long as they relate to the research task in question. @@ -385,12 +382,12 @@ export const generateToolDefinitions = < description: dedent(` Update the plan for the research task. You can call this alongside other tool calls to progress towards completing the task. - + IMPORTANT: the plan should take account of: 1. The research goal 2. The information gathered so far. - - Don't be afraid to deviate from an earlier plan if you've gathered sufficient information to + + Don't be afraid to deviate from an earlier plan if you've gathered sufficient information to meet the research goal, and return the information discovered. `), inputSchema: { @@ -807,10 +804,10 @@ export const generateOutstandingTasksDescription = ( The following tasks are still outstanding. You may decide to do one of the following: 1. Call 'waitForOutstandingTasks' to wait for outstanding tasks, OR 2. Start new tasks. - + You may optionally also call 'stopTasks' to stop specific tasks you think are no longer relevant, whether or not you're creating new tasks or waiting for outstanding tasks, using their 'toolCallId'. - + The outstanding tasks are: ${state.outstandingTasks .map((task) => @@ -822,7 +819,7 @@ export const generateOutstandingTasksDescription = ( `), ) .join("\n")} - + The results of each will be available in due course – but you can stop any now if you think they are no longer relevant. `); }; diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/sub-coordinating-agent.ai.test.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/sub-coordinating-agent.ai.test.ts index cb8a3015ce0..2d42a98e031 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/sub-coordinating-agent.ai.test.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/research-entities-action/sub-coordinating-agent.ai.test.ts @@ -7,7 +7,7 @@ import { readFileSync, writeFileSync, } from "node:fs"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { expect, test } from "vitest"; @@ -19,9 +19,9 @@ import { runSubCoordinatingAgent } from "./sub-coordinating-agent.js"; import type { SubCoordinatingAgentState } from "./sub-coordinating-agent/state.js"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); -const baseDirectoryPath = join( +const baseDirectoryPath = path.join( __dirname, "/var/sub-coordinating-agent/persisted-state", ); diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/create-file-entity-from-url.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/create-file-entity-from-url.ts index ca99565ee2a..d7cdb172454 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/create-file-entity-from-url.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/create-file-entity-from-url.ts @@ -7,7 +7,7 @@ import { import { unlink } from "node:fs/promises"; import * as http from "node:http"; import * as https from "node:https"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { Readable } from "node:stream"; import { finished } from "node:stream/promises"; import type { ReadableStream } from "node:stream/web"; @@ -47,15 +47,15 @@ import { getFlowContext } from "../../shared/get-flow-context.js"; import { graphApiClient } from "../../shared/graph-api-client.js"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); -const baseFilePath = join(__dirname, "/var/tmp_files"); +const baseFilePath = path.join(__dirname, "/var/tmp_files"); const downloadFileToFileSystem = async (fileUrl: string) => { mkdirSync(baseFilePath, { recursive: true }); const tempFileName = generateUuid(); - const filePath = join(baseFilePath, tempFileName); + const filePath = path.join(baseFilePath, tempFileName); const response = await fetch(fileUrl); if (!response.ok || !response.body) { diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/infer-summaries-then-claims-from-text/get-entity-summaries-from-text.optimize.ai.test.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/infer-summaries-then-claims-from-text/get-entity-summaries-from-text.optimize.ai.test.ts index c482f26add2..8d30cca44e6 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/infer-summaries-then-claims-from-text/get-entity-summaries-from-text.optimize.ai.test.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/infer-summaries-then-claims-from-text/get-entity-summaries-from-text.optimize.ai.test.ts @@ -1,6 +1,6 @@ import "../../../../shared/testing-utilities/mock-get-flow-context.js"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { test } from "vitest"; @@ -131,9 +131,9 @@ const metrics: MetricDefinition[] = testData.map((testItem) => { }); const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); -const baseDirectoryPath = join( +const baseDirectoryPath = path.join( __dirname, "/var/get-entity-summaries-from-text-test", ); diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/infer-summaries-then-claims-from-text/infer-summaries-then-claims-from-text.ai.test.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/infer-summaries-then-claims-from-text/infer-summaries-then-claims-from-text.ai.test.ts index f2c5bf73823..39f5a1db218 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/infer-summaries-then-claims-from-text/infer-summaries-then-claims-from-text.ai.test.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/infer-summaries-then-claims-from-text/infer-summaries-then-claims-from-text.ai.test.ts @@ -1,7 +1,7 @@ import "../../../../shared/testing-utilities/mock-get-flow-context.js"; import { readFileSync } from "node:fs"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import type { EntityUuid } from "@local/hash-graph-types/entity"; @@ -322,7 +322,7 @@ const statyaNadellaLinkedInEntitySummaries: LocalEntitySummary[] = [ ]; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); /** * This test requires a local HTML file to be present at the path specified below, @@ -332,7 +332,7 @@ const __dirname = dirname(__filename); test.skip( "Test inferSummariesThenClaimsFromText with Linked In web page", async () => { - const linkedInInnerHtmlPath = join(__dirname, "/var/linkedin.html"); + const linkedInInnerHtmlPath = path.join(__dirname, "/var/linkedin.html"); const innerHtml = readFileSync(linkedInInnerHtmlPath, "utf8"); diff --git a/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/propose-entities-from-claims/propose-entity-from-claims-agent.ts b/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/propose-entities-from-claims/propose-entity-from-claims-agent.ts index d29687f3987..66b5de0d2d8 100644 --- a/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/propose-entities-from-claims/propose-entity-from-claims-agent.ts +++ b/apps/hash-ai-worker-ts/src/activities/flow-activities/shared/propose-entities-from-claims/propose-entity-from-claims-agent.ts @@ -164,9 +164,7 @@ const generatePropertyMetadata = (params: { }; }; -const toolNames = ["proposeEntity", "abandonEntity"] as const; - -type ToolName = (typeof toolNames)[number]; +type ToolName = "proposeEntity" | "abandonEntity"; const generateToolDefinitions = (params: { dereferencedEntityTypes: DereferencedEntityType[]; diff --git a/apps/hash-ai-worker-ts/src/activities/get-ai-assistant-account-id-activity.ts b/apps/hash-ai-worker-ts/src/activities/get-ai-assistant-account-id-activity.ts index 9f3efb96652..caad05fcb7d 100644 --- a/apps/hash-ai-worker-ts/src/activities/get-ai-assistant-account-id-activity.ts +++ b/apps/hash-ai-worker-ts/src/activities/get-ai-assistant-account-id-activity.ts @@ -22,7 +22,7 @@ export const getAiAssistantAccountIdActivity = async (params: { authentication, { identifier: "hash-ai" }, ); - } catch (error) { + } catch { return null; } diff --git a/apps/hash-ai-worker-ts/src/activities/infer-entities/infer-entity-summaries.ts b/apps/hash-ai-worker-ts/src/activities/infer-entities/infer-entity-summaries.ts index 564f2204220..de8eeee14e9 100644 --- a/apps/hash-ai-worker-ts/src/activities/infer-entities/infer-entity-summaries.ts +++ b/apps/hash-ai-worker-ts/src/activities/infer-entities/infer-entity-summaries.ts @@ -302,6 +302,8 @@ export const inferEntitySummaries = async (params: { */ if (typesWithNoSuggestionsToRerequest.length > 0) { logger.info( + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-base-to-string `No suggestions for entity types: ${typesWithNoSuggestionsToRerequest.join( ", ", )}`, diff --git a/apps/hash-ai-worker-ts/src/activities/infer-entities/propose-entities.ts b/apps/hash-ai-worker-ts/src/activities/infer-entities/propose-entities.ts index 0795d544b1c..89a49d61188 100644 --- a/apps/hash-ai-worker-ts/src/activities/infer-entities/propose-entities.ts +++ b/apps/hash-ai-worker-ts/src/activities/infer-entities/propose-entities.ts @@ -371,7 +371,7 @@ export const proposeEntities = async (params: { try { validateProposedEntitiesByType(proposedEntitiesByType, false); - } catch (err) { + } catch { logger.error( `Model provided invalid argument to create_entities function. Argument provided: ${stringify( toolCall.input, diff --git a/apps/hash-ai-worker-ts/src/activities/shared/activity-logger.ts b/apps/hash-ai-worker-ts/src/activities/shared/activity-logger.ts index ff8ff011a83..01457550b08 100644 --- a/apps/hash-ai-worker-ts/src/activities/shared/activity-logger.ts +++ b/apps/hash-ai-worker-ts/src/activities/shared/activity-logger.ts @@ -1,5 +1,5 @@ import fs from "node:fs"; -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { Context } from "@temporalio/activity"; @@ -7,7 +7,7 @@ import { Context } from "@temporalio/activity"; import { logger as baseLogger } from "../../shared/logger.js"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const log = ( message: string, diff --git a/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/anthropic-client.ts b/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/anthropic-client.ts index 22c2f40c685..7ea62b72f1e 100644 --- a/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/anthropic-client.ts +++ b/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/anthropic-client.ts @@ -91,13 +91,10 @@ const anthropicBedrockClient: AnthropicBedrock = new AnthropicBedrock({ awsRegion, }); -const anthropicBedrockModels = [ - "anthropic.claude-3-haiku-20240307-v1:0", - "anthropic.claude-3-opus-20240229-v1:0", - "anthropic.claude-3-5-sonnet-20240620-v1:0", -] as const; - -type AnthropicBedrockModel = (typeof anthropicBedrockModels)[number]; +type AnthropicBedrockModel = + | "anthropic.claude-3-haiku-20240307-v1:0" + | "anthropic.claude-3-opus-20240229-v1:0" + | "anthropic.claude-3-5-sonnet-20240620-v1:0"; /** @see https://docs.anthropic.com/en/api/claude-on-amazon-bedrock#api-model-names */ export const anthropicModelToBedrockModel: Record< @@ -109,9 +106,7 @@ export const anthropicModelToBedrockModel: Record< "claude-3-5-sonnet-20240620": "anthropic.claude-3-5-sonnet-20240620-v1:0", }; -const anthropicApiProviders = ["anthropic", "amazon-bedrock"] as const; - -export type AnthropicApiProvider = (typeof anthropicApiProviders)[number]; +export type AnthropicApiProvider = "anthropic" | "amazon-bedrock"; type AnthropicBedrockMessagesCreateParams = Parameters< typeof anthropicBedrockClient.messages.create diff --git a/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/llm-message.ts b/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/llm-message.ts index a07aef6d803..2289dbb7bb4 100644 --- a/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/llm-message.ts +++ b/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/llm-message.ts @@ -130,6 +130,8 @@ export const mapAnthropicMessageToLlmMessage = (params: { return { type: "tool_result" as const, tool_use_id: block.tool_use_id, + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-base-to-string content: textBlocks?.join("\n") ?? "", } satisfies LlmMessageToolResultContent; } diff --git a/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/log-llm-request.ts b/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/log-llm-request.ts index 0cd63d64d31..1bd4b23edf8 100644 --- a/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/log-llm-request.ts +++ b/apps/hash-ai-worker-ts/src/activities/shared/get-llm-response/log-llm-request.ts @@ -1,5 +1,5 @@ import { existsSync, mkdirSync, writeFileSync } from "node:fs"; -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { Context } from "@temporalio/activity"; @@ -8,7 +8,7 @@ import { logger } from "../activity-logger.js"; import type { LlmLog, LlmServerErrorLog } from "./types.js"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const writeLogToFile = (log: LlmLog | LlmServerErrorLog) => { const logFolderPath = path.join(__dirname, "logs"); diff --git a/apps/hash-ai-worker-ts/src/activities/shared/optimize-system-prompt.ts b/apps/hash-ai-worker-ts/src/activities/shared/optimize-system-prompt.ts index 4d288941350..06514a8afb4 100644 --- a/apps/hash-ai-worker-ts/src/activities/shared/optimize-system-prompt.ts +++ b/apps/hash-ai-worker-ts/src/activities/shared/optimize-system-prompt.ts @@ -1,7 +1,7 @@ import "../../shared/testing-utilities/mock-get-flow-context.js"; import { existsSync, mkdirSync, writeFileSync } from "node:fs"; -import { join } from "node:path"; +import path from "node:path"; import type { LlmParams } from "./get-llm-response/types.js"; import { improveSystemPrompt } from "./optimize-system-prompt/improve-system-prompt.js"; @@ -60,7 +60,7 @@ const saveAllResultsToCSV = (params: { const csvContent = [headers, ...rows].map((row) => row.join(",")).join("\n"); - const filePath = join(directoryPath, `${filePrefix}-metric-results.csv`); + const filePath = path.join(directoryPath, `${filePrefix}-metric-results.csv`); writeFileSync(filePath, csvContent, "utf8"); }; @@ -141,7 +141,7 @@ const saveSummaryToCSV = (params: { const csvContent = [headers, ...rows].map((row) => row.join(",")).join("\n"); - const filePath = join(directoryPath, `${filePrefix}-summary.csv`); + const filePath = path.join(directoryPath, `${filePrefix}-summary.csv`); writeFileSync(filePath, csvContent, "utf8"); }; diff --git a/apps/hash-ai-worker-ts/src/main.ts b/apps/hash-ai-worker-ts/src/main.ts index f1d5ddec316..1e76bd1bc46 100644 --- a/apps/hash-ai-worker-ts/src/main.ts +++ b/apps/hash-ai-worker-ts/src/main.ts @@ -10,8 +10,7 @@ Sentry.init({ import * as http from "node:http"; import { createRequire } from "node:module"; -import * as path from "node:path"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { createGraphClient } from "@local/hash-backend-utils/create-graph-client"; @@ -29,7 +28,7 @@ import { createFlowActivities } from "./activities/flow-activities.js"; import { logger } from "./shared/logger.js"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const require = createRequire(import.meta.url); diff --git a/apps/hash-ai-worker-ts/tsconfig.json b/apps/hash-ai-worker-ts/tsconfig.json index 78fa967946f..0cbdad48d1b 100644 --- a/apps/hash-ai-worker-ts/tsconfig.json +++ b/apps/hash-ai-worker-ts/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["src", "scripts"], + "include": ["src", "scripts", "eslint.config.js", "vitest.config.ts"], "compilerOptions": { "lib": ["ESNext"], "module": "NodeNext", diff --git a/apps/hash-ai-worker-ts/vitest.config.js b/apps/hash-ai-worker-ts/vitest.config.ts similarity index 100% rename from apps/hash-ai-worker-ts/vitest.config.js rename to apps/hash-ai-worker-ts/vitest.config.ts diff --git a/apps/hash-api/.eslintrc.cjs b/apps/hash-api/.eslintrc.cjs deleted file mode 100644 index f843b7007b8..00000000000 --- a/apps/hash-api/.eslintrc.cjs +++ /dev/null @@ -1,22 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - // @todo Re-enable these rules once ESLint config is refactored - "@typescript-eslint/restrict-plus-operands": "off", - "@typescript-eslint/prefer-nullish-coalescing": "off", - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 11 */ "@typescript-eslint/no-unsafe-argument", - /* 2022-11-29: 69 */ "@typescript-eslint/no-unsafe-assignment", - /* 2022-11-29: 37 */ "@typescript-eslint/no-unsafe-call", - /* 2022-11-29: 73 */ "@typescript-eslint/no-unsafe-member-access", - /* 2022-11-29: 45 */ "@typescript-eslint/no-unsafe-return", - /* 2022-11-29: 13 */ "@typescript-eslint/require-await", - /* 2022-11-29: 35 */ "@typescript-eslint/restrict-template-expressions", - "canonical/filename-no-index", - ]), - }, - ignorePatterns: require("@local/eslint-config/generate-ignore-patterns.cjs")( - __dirname, - ), -}; diff --git a/apps/hash-api/eslint.config.js b/apps/hash-api/eslint.config.js new file mode 100644 index 00000000000..0d9b9f6d406 --- /dev/null +++ b/apps/hash-api/eslint.config.js @@ -0,0 +1,25 @@ +import { + createBase, + defineConfig, + disableRules, +} from "@local/eslint/deprecated"; + +export default defineConfig([ + ...createBase(import.meta.dirname), + { + rules: { + "@typescript-eslint/restrict-plus-operands": "off", + "@typescript-eslint/prefer-nullish-coalescing": "off", + }, + }, + ...disableRules([ + /* 2022-11-29: 11 */ "@typescript-eslint/no-unsafe-argument", + /* 2022-11-29: 69 */ "@typescript-eslint/no-unsafe-assignment", + /* 2022-11-29: 37 */ "@typescript-eslint/no-unsafe-call", + /* 2022-11-29: 73 */ "@typescript-eslint/no-unsafe-member-access", + /* 2022-11-29: 45 */ "@typescript-eslint/no-unsafe-return", + /* 2022-11-29: 13 */ "@typescript-eslint/require-await", + /* 2022-11-29: 35 */ "@typescript-eslint/restrict-template-expressions", + "canonical/filename-no-index", + ]), +]); diff --git a/apps/hash-api/package.json b/apps/hash-api/package.json index 6586cb83e87..14e92162fe7 100644 --- a/apps/hash-api/package.json +++ b/apps/hash-api/package.json @@ -111,7 +111,7 @@ "@graphql-codegen/introspection": "2.2.3", "@graphql-codegen/typescript": "2.8.8", "@graphql-codegen/typescript-resolvers": "2.7.13", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/app-root-path": "1.2.8", "@types/dedent": "0.7.2", @@ -124,7 +124,7 @@ "@types/mime-types": "2.1.4", "@types/nodemailer": "6.4.17", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "prettier": "3.4.2", "rimraf": "6.0.1", "typescript": "5.6.3", diff --git a/apps/hash-api/src/ai/gpt/generate-hashgpt-schema.ts b/apps/hash-api/src/ai/gpt/generate-hashgpt-schema.ts index 2765417229a..622c0a0576b 100644 --- a/apps/hash-api/src/ai/gpt/generate-hashgpt-schema.ts +++ b/apps/hash-api/src/ai/gpt/generate-hashgpt-schema.ts @@ -1,19 +1,19 @@ import { writeFileSync } from "node:fs"; -import { dirname, resolve } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { apiOrigin } from "@local/hash-isomorphic-utils/environment"; import * as generator from "ts-json-schema-generator"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const config = { diagnostics: false, noTopRef: true, - path: resolve(__dirname, "gpt-query-entities.ts"), + path: path.resolve(__dirname, "gpt-query-entities.ts"), skipTypeCheck: true, - tsconfig: resolve(__dirname, "../../../tsconfig.json"), + tsconfig: path.resolve(__dirname, "../../../tsconfig.json"), }; const { $ref: queryEntitiesRequestRef, definitions: queryEntitiesRequestDefs } = @@ -30,7 +30,7 @@ const { $ref: queryTypesRequestRef, definitions: queryTypesRequestDefs } = generator .createGenerator({ ...config, - path: resolve(__dirname, "gpt-query-types.ts"), + path: path.resolve(__dirname, "gpt-query-types.ts"), }) .createSchema("GptQueryTypesRequestBody"); @@ -38,7 +38,7 @@ const { $ref: queryTypesResponseRef, definitions: queryTypesResponseDefs } = generator .createGenerator({ ...config, - path: resolve(__dirname, "gpt-query-types.ts"), + path: path.resolve(__dirname, "gpt-query-types.ts"), }) .createSchema("GptQueryTypesResponseBody"); @@ -46,7 +46,7 @@ const { $ref: getUserWebsResponseRef, definitions: getUserWebsResponseDefs } = generator .createGenerator({ ...config, - path: resolve(__dirname, "gpt-get-user-webs.ts"), + path: path.resolve(__dirname, "gpt-get-user-webs.ts"), }) .createSchema("GptGetUserWebsResponseBody"); @@ -153,4 +153,7 @@ const rewrittenSchema = JSON.stringify(openApiSchema, null, 2).replaceAll( "#/components/schemas/", ); -writeFileSync(resolve(__dirname, "openapi-schema.gen.json"), rewrittenSchema); +writeFileSync( + path.resolve(__dirname, "openapi-schema.gen.json"), + rewrittenSchema, +); diff --git a/apps/hash-api/src/generate-ontology-type-ids.ts b/apps/hash-api/src/generate-ontology-type-ids.ts index a7cc35c1206..55f885616c3 100644 --- a/apps/hash-api/src/generate-ontology-type-ids.ts +++ b/apps/hash-api/src/generate-ontology-type-ids.ts @@ -1,6 +1,5 @@ import { writeFile } from "node:fs/promises"; -import * as path from "node:path"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { createGraphClient } from "@local/hash-backend-utils/create-graph-client"; @@ -34,7 +33,7 @@ import { import { getPropertyTypes } from "./graph/ontology/primitive/property-type"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const outputFileName = "ontology-type-ids.ts"; diff --git a/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types.ts b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types.ts index e4ab14a718f..694c659e621 100644 --- a/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types.ts +++ b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types.ts @@ -1,5 +1,5 @@ import { readdir } from "node:fs/promises"; -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import type { Logger } from "@local/hash-backend-utils/logger"; @@ -13,7 +13,7 @@ import type { } from "./migrate-ontology-types/types"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); /** * Migrate the ontology types in the Graph API. diff --git a/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/util.ts b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/util.ts index 4cf0cb634bc..813cf3795c0 100644 --- a/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/util.ts +++ b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/util.ts @@ -1,5 +1,5 @@ /* eslint-disable no-param-reassign */ -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import type { @@ -90,7 +90,7 @@ import { upgradeWebEntities } from "./util/upgrade-entities"; import { upgradeEntityTypeDependencies } from "./util/upgrade-entity-type-dependencies"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const systemTypeDomain = "https://hash.ai"; diff --git a/apps/hash-api/src/graph/knowledge/primitive/entity/after-update-entity-hooks/file-document-after-update-entity-hook-callback.ts b/apps/hash-api/src/graph/knowledge/primitive/entity/after-update-entity-hooks/file-document-after-update-entity-hook-callback.ts index 837ddd4c7dc..514412c5582 100644 --- a/apps/hash-api/src/graph/knowledge/primitive/entity/after-update-entity-hooks/file-document-after-update-entity-hook-callback.ts +++ b/apps/hash-api/src/graph/knowledge/primitive/entity/after-update-entity-hooks/file-document-after-update-entity-hook-callback.ts @@ -116,7 +116,7 @@ export const parseTextFromFileAfterUpdateEntityHookCallback: AfterUpdateEntityHo maximumAttempts: 1, }, }); - } catch (error) { + } catch { /** @todo: figure out whether this should be logged */ return undefined; } diff --git a/apps/hash-api/src/graphql/resolvers/generation/is-generation-available.ts b/apps/hash-api/src/graphql/resolvers/generation/is-generation-available.ts index 7dcb133203f..0adddb4eb59 100644 --- a/apps/hash-api/src/graphql/resolvers/generation/is-generation-available.ts +++ b/apps/hash-api/src/graphql/resolvers/generation/is-generation-available.ts @@ -36,7 +36,7 @@ export const isGenerationAvailableResolver: ResolverFn< return { available: true, }; - } catch (err) { + } catch { return { available: false, reason: "Invalid OpenAI API key or API error", diff --git a/apps/hash-api/src/graphql/resolvers/knowledge/entity/entity.ts b/apps/hash-api/src/graphql/resolvers/knowledge/entity/entity.ts index c0936caa622..0fe4a6c3aca 100644 --- a/apps/hash-api/src/graphql/resolvers/knowledge/entity/entity.ts +++ b/apps/hash-api/src/graphql/resolvers/knowledge/entity/entity.ts @@ -462,7 +462,7 @@ export const archiveEntitiesResolver: ResolverFn< ); archivedEntities.push(entity); - } catch (error) { + } catch { entitiesThatCouldNotBeArchived.push(entityId); } }), diff --git a/apps/hash-api/src/graphql/resolvers/knowledge/user/get-waitlist-position.ts b/apps/hash-api/src/graphql/resolvers/knowledge/user/get-waitlist-position.ts index 50f7eab4f50..e90d31c13e8 100644 --- a/apps/hash-api/src/graphql/resolvers/knowledge/user/get-waitlist-position.ts +++ b/apps/hash-api/src/graphql/resolvers/knowledge/user/get-waitlist-position.ts @@ -28,7 +28,7 @@ export const getWaitlistPositionResolver: ResolverFn< let data: GetWaitlistPosition200Response; try { ({ data } = await internalApiClient.getWaitlistPosition(email)); - } catch (err) { + } catch { throw new Error("Error fetching waitlist position"); } diff --git a/apps/hash-api/src/seed-data/seed-users.ts b/apps/hash-api/src/seed-data/seed-users.ts index 2bd8b0b4227..b42624b70ab 100644 --- a/apps/hash-api/src/seed-data/seed-users.ts +++ b/apps/hash-api/src/seed-data/seed-users.ts @@ -59,7 +59,7 @@ export const ensureUsersAreSeeded = async ({ try { /** @todo validate the JSON parsed from the environment. */ usersToSeed = JSON.parse(process.env.HASH_SEED_USERS) as SeededUser[]; - } catch (error) { + } catch { logger.error( "Could not parse environment variable `HASH_SEED_USERS` as JSON. Make sure it's formatted correctly.", ); diff --git a/apps/hash-api/tsconfig.json b/apps/hash-api/tsconfig.json index deb107101af..fc7cc2a2407 100644 --- a/apps/hash-api/tsconfig.json +++ b/apps/hash-api/tsconfig.json @@ -1,4 +1,4 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["src", "codegen.config.ts"] + "include": ["src", "codegen.config.ts", "vitest.config.ts"] } diff --git a/apps/hash-api/vitest.config.js b/apps/hash-api/vitest.config.ts similarity index 92% rename from apps/hash-api/vitest.config.js rename to apps/hash-api/vitest.config.ts index 35ddc8ed482..1f272d4e188 100644 --- a/apps/hash-api/vitest.config.js +++ b/apps/hash-api/vitest.config.ts @@ -1,4 +1,3 @@ -/// import { defineConfig } from "vitest/config"; export default defineConfig({ diff --git a/apps/hash-frontend/.eslintrc.cjs b/apps/hash-frontend/.eslintrc.cjs deleted file mode 100644 index 8e62f091c00..00000000000 --- a/apps/hash-frontend/.eslintrc.cjs +++ /dev/null @@ -1,89 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 11 */ "@typescript-eslint/no-unsafe-argument", - /* 2022-11-29: 54 */ "@typescript-eslint/no-unsafe-assignment", - /* 2022-11-29: 30 */ "@typescript-eslint/no-unsafe-member-access", - /* 2022-11-29: 11 */ "@typescript-eslint/no-unsafe-return", - /* 2022-11-29: 34 */ "@typescript-eslint/restrict-template-expressions", - ]), - "jsx-a11y/label-has-associated-control": "off", - "import/no-default-export": "error", - "no-restricted-imports": [ - "error", - { - paths: [ - { - name: "next", - importNames: ["Link"], - message: - "Please use the custom wrapper component in src/shared/ui component instead to ensure Next.js and MUI compatibility.", - }, - { - name: "next/link", - message: - "Please use the custom wrapper component in src/shared/ui component instead to ensure Next.js and MUI compatibility.", - }, - { - name: "@mui/material", - importNames: [ - "Avatar", - "IconButton", - "Chip", - "TextField", - "Select", - "Link", - "Button", - "MenuItem", - "Tabs", - ], - message: - "Please use the custom wrapper component from src/shared/ui for Link, Button, Tabs and MenuItem and from '@hashintel/design-system' for every other component.", - }, - { - name: "notistack", - importNames: ["useSnackbar"], - message: - "Please use the custom src/components/hooks/useSnackbar hook instead.", - }, - { - name: "@hashintel/design-system", - importNames: ["Button", "Link", "MenuItem"], - message: - "Please use the custom wrapper component in src/shared/ui component instead", - }, - ], - patterns: [ - { - group: ["@mui/material/*"], - message: "Please import from @mui/material instead", - }, - { - group: [ - "@hashintel/design-system/*", - "!@hashintel/design-system/theme", - "!@hashintel/design-system/constants", - "!@hashintel/design-system/palettes", - ], - message: "Please import from @hashintel/design-system instead", - }, - ], - }, - ], - }, - overrides: [ - { - files: [ - "./src/pages/**/*.api.ts", - "./src/pages/**/*.page.ts", - "./src/pages/**/*.page.tsx", - "**/__mocks__/**", - ], - rules: { - "import/no-default-export": "off", - }, - }, - ], -}; diff --git a/apps/hash-frontend/eslint.config.js b/apps/hash-frontend/eslint.config.js new file mode 100644 index 00000000000..e40c1fc5572 --- /dev/null +++ b/apps/hash-frontend/eslint.config.js @@ -0,0 +1,101 @@ +import { + defineConfig, + createBase, + disableRules, +} from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...disableRules([ + /* 2022-11-29: 11 */ "@typescript-eslint/no-unsafe-argument", + /* 2022-11-29: 54 */ "@typescript-eslint/no-unsafe-assignment", + /* 2022-11-29: 30 */ "@typescript-eslint/no-unsafe-member-access", + /* 2022-11-29: 11 */ "@typescript-eslint/no-unsafe-return", + /* 2022-11-29: 34 */ "@typescript-eslint/restrict-template-expressions", + ]), + ...defineConfig([ + { + rules: { + "jsx-a11y/label-has-associated-control": "off", + "import/no-default-export": "error", + "no-restricted-imports": [ + "error", + { + paths: [ + { + name: "next", + importNames: ["Link"], + message: + "Please use the custom wrapper component in src/shared/ui component instead to ensure Next.js and MUI compatibility.", + }, + { + name: "next/link", + message: + "Please use the custom wrapper component in src/shared/ui component instead to ensure Next.js and MUI compatibility.", + }, + { + name: "@mui/material", + importNames: [ + "Avatar", + "IconButton", + "Chip", + "TextField", + "Select", + "Link", + "Button", + "MenuItem", + "Tabs", + ], + message: + "Please use the custom wrapper component from src/shared/ui for Link, Button, Tabs and MenuItem and from '@hashintel/design-system' for every other component.", + }, + { + name: "notistack", + importNames: ["useSnackbar"], + message: + "Please use the custom src/components/hooks/useSnackbar hook instead.", + }, + { + name: "@hashintel/design-system", + importNames: ["Button", "Link", "MenuItem"], + message: + "Please use the custom wrapper component in src/shared/ui component instead", + }, + ], + patterns: [ + // @ts-expect-error: invalid typing + { + group: ["@mui/material/*"], + message: "Please import from @mui/material instead", + }, + // @ts-expect-error: invalid typing + { + group: [ + "@hashintel/design-system/*", + "!@hashintel/design-system/theme", + "!@hashintel/design-system/constants", + "!@hashintel/design-system/palettes", + ], + message: "Please import from @hashintel/design-system instead", + }, + ], + }, + ], + }, + }, + { + files: [ + "**/src/pages/**/*.api.ts", + "**/src/pages/**/*.page.ts", + "**/src/pages/**/*.page.tsx", + "**/__mocks__/**", + ], + rules: { + "import/no-default-export": "off", + }, + }, + { + ignores: ["buildstamp.js", "next.config.js"], + }, + ]), +]; diff --git a/apps/hash-frontend/package.json b/apps/hash-frontend/package.json index dc8658677d0..6ae5ea31513 100644 --- a/apps/hash-frontend/package.json +++ b/apps/hash-frontend/package.json @@ -131,7 +131,7 @@ "@graphql-codegen/fragment-matcher": "3.3.3", "@graphql-codegen/typescript": "2.8.8", "@graphql-codegen/typescript-operations": "2.5.13", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@next/bundle-analyzer": "12.3.4", "@types/dotenv-flow": "3.3.3", @@ -150,7 +150,7 @@ "@types/url-regex-safe": "1.0.2", "@types/uuid": "10.0.0", "@welldone-software/why-did-you-render": "8.0.3", - "eslint": "8.57.0", + "eslint": "9.16.0", "graphology-types": "0.24.8", "rimraf": "6.0.1", "sass": "1.82.0", diff --git a/apps/hash-frontend/src/components/error-block/error-block.tsx b/apps/hash-frontend/src/components/error-block/error-block.tsx index 601c511af8d..3e0da9a1070 100644 --- a/apps/hash-frontend/src/components/error-block/error-block.tsx +++ b/apps/hash-frontend/src/components/error-block/error-block.tsx @@ -6,7 +6,9 @@ import { Button } from "../../shared/ui"; type FallbackRenderProps = Parameters[0]; export interface ErrorBlockProps extends FallbackRenderProps { - onRetry(): void; + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // before was: onRetry(): void; + onRetry: () => void; } export const ErrorBlock: FunctionComponent = ({ diff --git a/apps/hash-frontend/src/components/remote-block/load-remote-block.ts b/apps/hash-frontend/src/components/remote-block/load-remote-block.ts index 21c1940e681..b05b282907c 100644 --- a/apps/hash-frontend/src/components/remote-block/load-remote-block.ts +++ b/apps/hash-frontend/src/components/remote-block/load-remote-block.ts @@ -11,7 +11,7 @@ export type UnknownBlock = export type FetchSourceFn = ( url: string, - signal?: AbortSignal | undefined, + signal?: AbortSignal, ) => Promise; /** @@ -53,6 +53,8 @@ const fetchAndParseBlock: FetchAndParseFn = (fetchSourceFn) => (url, signal) => const module = { exports }; // eslint-disable-next-line no-new-func,@typescript-eslint/no-implied-eval const func = new Function("require", "module", "exports", source); + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-unsafe-call func(requires, module, exports); /** diff --git a/apps/hash-frontend/src/pages/[shortname].page/edit-user-profile-info-modal/user-profile-info-modal-header.tsx b/apps/hash-frontend/src/pages/[shortname].page/edit-user-profile-info-modal/user-profile-info-modal-header.tsx index 82c56aa0773..3f669bc6934 100644 --- a/apps/hash-frontend/src/pages/[shortname].page/edit-user-profile-info-modal/user-profile-info-modal-header.tsx +++ b/apps/hash-frontend/src/pages/[shortname].page/edit-user-profile-info-modal/user-profile-info-modal-header.tsx @@ -115,6 +115,8 @@ export const UserProfileInfoModalHeader: FunctionComponent<{ const handleAvatarImageFileUpload = useCallback< ChangeEventHandler >( + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-misused-promises async (event) => { const file = event.target.files?.[0]; @@ -132,6 +134,8 @@ export const UserProfileInfoModalHeader: FunctionComponent<{ const handleCoverImageFileUpload = useCallback< ChangeEventHandler >( + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-misused-promises async (event) => { const file = event.target.files?.[0]; diff --git a/apps/hash-frontend/src/pages/[shortname]/[page-slug].page/canvas-page/block-creation-dialog.tsx b/apps/hash-frontend/src/pages/[shortname]/[page-slug].page/canvas-page/block-creation-dialog.tsx index 9da33eb0520..023f18a66de 100644 --- a/apps/hash-frontend/src/pages/[shortname]/[page-slug].page/canvas-page/block-creation-dialog.tsx +++ b/apps/hash-frontend/src/pages/[shortname]/[page-slug].page/canvas-page/block-creation-dialog.tsx @@ -173,7 +173,7 @@ export const BlockCreationDialog = ({ onClose }: DialogProps) => { setCreatingEntity(true); try { await createBlock(blockMeta); - } catch (err) { + } catch { setCreatingEntity(false); } }} diff --git a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/edit-entity-slide-over.tsx b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/edit-entity-slide-over.tsx index aa228c730cd..35b366dbacb 100644 --- a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/edit-entity-slide-over.tsx +++ b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/edit-entity-slide-over.tsx @@ -453,7 +453,7 @@ const EditEntitySlideOver = memo( resetEntityEditor(); onSubmit(); - } catch (err) { + } catch { setSavingChanges(false); } }, [ diff --git a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor-page.tsx b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor-page.tsx index 156361aebdf..152a4789e8d 100644 --- a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor-page.tsx +++ b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor-page.tsx @@ -53,7 +53,7 @@ export const EntityEditorPage = ({ setSelectedEntity({ entityId, }); - } catch (err) { + } catch { setSelectedEntity({ entityId }); } }, []); diff --git a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/history-section/get-history-events.ts b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/history-section/get-history-events.ts index dba4cd30d70..338e4c95145 100644 --- a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/history-section/get-history-events.ts +++ b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/history-section/get-history-events.ts @@ -189,7 +189,7 @@ export const getHistoryEvents = (diffs: EntityDiff[], subgraph: Subgraph) => { type: "property-update", diff: propertyDiff, }); - } catch (err) { + } catch { throw new Error( `Could not find property type with baseUrl ${propertyBaseUrl} among entity types with ids ${firstEntityEdition.metadata.entityTypeIds.join(", ")} in subgraph`, ); diff --git a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/links-section/incoming-links-section/incoming-links-table.tsx b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/links-section/incoming-links-section/incoming-links-table.tsx index f5eb1be2beb..8d45e2f46fc 100644 --- a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/links-section/incoming-links-section/incoming-links-table.tsx +++ b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/links-section/incoming-links-section/incoming-links-table.tsx @@ -52,14 +52,7 @@ import { maxLinksTableHeight, } from "../shared/table-styling"; -const fieldIds = [ - "linkedFrom", - "linkTypes", - "linkedFromTypes", - "link", -] as const; - -type FieldId = (typeof fieldIds)[number]; +type FieldId = "linkedFrom" | "linkTypes" | "linkedFromTypes" | "link"; const staticColumns: VirtualizedTableColumn[] = [ { diff --git a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/links-section/outgoing-links-section/readonly-outgoing-links-table.tsx b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/links-section/outgoing-links-section/readonly-outgoing-links-table.tsx index fa33b541fee..ffd63cfae03 100644 --- a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/links-section/outgoing-links-section/readonly-outgoing-links-table.tsx +++ b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/links-section/outgoing-links-section/readonly-outgoing-links-table.tsx @@ -53,9 +53,7 @@ import { maxLinksTableHeight, } from "../shared/table-styling"; -const fieldIds = ["linkTypes", "linkedTo", "linkedToTypes", "link"] as const; - -type OutgoingLinksFieldId = (typeof fieldIds)[number]; +type OutgoingLinksFieldId = "linkTypes" | "linkedTo" | "linkedToTypes" | "link"; export type OutgoingLinksFilterValues = VirtualizedTableFilterValuesByFieldId; diff --git a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/properties-section/property-table/cells/value-cell/inputs/json-input.tsx b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/properties-section/property-table/cells/value-cell/inputs/json-input.tsx index 8af104eaa94..2b6c6357a65 100644 --- a/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/properties-section/property-table/cells/value-cell/inputs/json-input.tsx +++ b/apps/hash-frontend/src/pages/[shortname]/entities/[entity-uuid].page/entity-editor/properties-section/property-table/cells/value-cell/inputs/json-input.tsx @@ -14,7 +14,7 @@ const isJsonObjectString = (str?: string) => { try { JSON.parse(str); - } catch (err) { + } catch { return false; } return true; diff --git a/apps/hash-frontend/src/pages/_app.page.tsx b/apps/hash-frontend/src/pages/_app.page.tsx index e0c64901c1e..c946c54ee4f 100644 --- a/apps/hash-frontend/src/pages/_app.page.tsx +++ b/apps/hash-frontend/src/pages/_app.page.tsx @@ -2,6 +2,8 @@ import "./_app.page/why-did-you-render"; // @todo have webpack polyfill this +// @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors +// eslint-disable-next-line @typescript-eslint/no-require-imports require("setimmediate"); import "./globals.scss"; diff --git a/apps/hash-frontend/src/pages/_app.page/error-fallback.tsx b/apps/hash-frontend/src/pages/_app.page/error-fallback.tsx index b96390cb8ac..870b1e84ddc 100644 --- a/apps/hash-frontend/src/pages/_app.page/error-fallback.tsx +++ b/apps/hash-frontend/src/pages/_app.page/error-fallback.tsx @@ -57,6 +57,7 @@ const CopyableMonospace = ({ text }: { text: string }) => { export const ErrorFallback: FallbackRender = ({ error, eventId, + // eslint-disable-next-line @typescript-eslint/unbound-method -- sentry issue resetError, }) => { const [showMessage, setShowMessage] = useState(false); diff --git a/apps/hash-frontend/src/pages/shared/block-collection/collab/http.ts b/apps/hash-frontend/src/pages/shared/block-collection/collab/http.ts index 9a08d6a7ede..1e56ca7ce7c 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/collab/http.ts +++ b/apps/hash-frontend/src/pages/shared/block-collection/collab/http.ts @@ -1,6 +1,6 @@ import { StatusError } from "./status-error"; -const makePlain = (html?: string | null | undefined) => { +const makePlain = (html?: string | null) => { const elt = document.createElement("div"); elt.innerHTML = html ?? ""; return elt.textContent?.replace(/\n[^]*|\s+$/g, "") ?? ""; diff --git a/apps/hash-frontend/src/pages/shared/block-collection/collab/use-collab-positions.ts b/apps/hash-frontend/src/pages/shared/block-collection/collab/use-collab-positions.ts index fd1b7cbd064..a7ffa8a8737 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/collab/use-collab-positions.ts +++ b/apps/hash-frontend/src/pages/shared/block-collection/collab/use-collab-positions.ts @@ -78,7 +78,7 @@ export const useCollabPositions = ( setPositionInfo({ accountId, pageEntityId, positions }); } poll = true; - } catch (error) { + } catch { await sleep(requestRetryInterval); } } diff --git a/apps/hash-frontend/src/pages/shared/block-collection/comments/comment-placeholder-plugin.tsx b/apps/hash-frontend/src/pages/shared/block-collection/comments/comment-placeholder-plugin.tsx index 276c60763cb..f7abd2f64e6 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/comments/comment-placeholder-plugin.tsx +++ b/apps/hash-frontend/src/pages/shared/block-collection/comments/comment-placeholder-plugin.tsx @@ -14,10 +14,12 @@ interface CommentPlaceholderState { } export const commentPlaceholderPluginkey = + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error new PluginKey("commentPlaceholder"); // Simplified version of createPlaceholderPlugin to be used in Comments export const commentPlaceholderPlugin = (renderPortal: RenderPortal) => + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error new Plugin({ key: commentPlaceholderPluginkey, state: { diff --git a/apps/hash-frontend/src/pages/shared/block-collection/create-editor-view.ts b/apps/hash-frontend/src/pages/shared/block-collection/create-editor-view.ts index e123e83e56a..2b9455d470e 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/create-editor-view.ts +++ b/apps/hash-frontend/src/pages/shared/block-collection/create-editor-view.ts @@ -41,6 +41,7 @@ const createSavePlugin = ( onError: (message: string) => void, ) => { let saveQueue = Promise.resolve(null); + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing issue const pluginKey = new PluginKey("save"); let view: EditorView; @@ -87,6 +88,7 @@ const createSavePlugin = ( maxWait: maxWaitTime, }); + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing issue return new Plugin({ state: { init: () => null, @@ -172,6 +174,7 @@ export const createEditorView = (params: { const errorSnackbarKey = "editor-saving-error-snackbar"; + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing issue const plugins: Plugin[] = readonly ? [] : [ diff --git a/apps/hash-frontend/src/pages/shared/block-collection/create-error-plugin.tsx b/apps/hash-frontend/src/pages/shared/block-collection/create-error-plugin.tsx index 91f824663b2..aee8a82dc41 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/create-error-plugin.tsx +++ b/apps/hash-frontend/src/pages/shared/block-collection/create-error-plugin.tsx @@ -36,8 +36,11 @@ const ErrorView: FunctionComponent = ({ errored }) => { const defaultErrorProps = { errored: false }; export const createErrorPlugin = (renderPortal: RenderPortal) => { + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error const key = new PluginKey(); + return [ + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error new Plugin({ key, state: { @@ -73,6 +76,7 @@ export const createErrorPlugin = (renderPortal: RenderPortal) => { }, }; }, + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error }) as Plugin, (tr: Transaction) => { // @todo log diff --git a/apps/hash-frontend/src/pages/shared/block-collection/create-format-plugins/index.tsx b/apps/hash-frontend/src/pages/shared/block-collection/create-format-plugins/index.tsx index c212f49b776..391a363647c 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/create-format-plugins/index.tsx +++ b/apps/hash-frontend/src/pages/shared/block-collection/create-format-plugins/index.tsx @@ -30,7 +30,9 @@ interface LinkPluginState { linkUrl: null | string; } +// eslint-disable-next-line no-restricted-syntax -- prosemirror typing error const markPluginKey = new PluginKey("markPlugin"); +// eslint-disable-next-line no-restricted-syntax -- prosemirror typing error const linkPluginKey = new PluginKey("linkPlugin"); export function createFormatPlugins(renderPortal: RenderPortal) { @@ -38,6 +40,7 @@ export function createFormatPlugins(renderPortal: RenderPortal) { const linkModalRef = createRef(); + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error const marksTooltip = new Plugin({ key: markPluginKey, /** @@ -178,6 +181,7 @@ export function createFormatPlugins(renderPortal: RenderPortal) { }, }); + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error const linkPlugin = new Plugin({ key: linkPluginKey, state: { @@ -322,5 +326,6 @@ export function createFormatPlugins(renderPortal: RenderPortal) { inputRules({ rules: [linkInputRule()], }), + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error ] as Plugin[]; } diff --git a/apps/hash-frontend/src/pages/shared/block-collection/create-placeholder-plugin/create-placeholder-plugin.tsx b/apps/hash-frontend/src/pages/shared/block-collection/create-placeholder-plugin/create-placeholder-plugin.tsx index f64ed56352c..cb76c46ee4e 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/create-placeholder-plugin/create-placeholder-plugin.tsx +++ b/apps/hash-frontend/src/pages/shared/block-collection/create-placeholder-plugin/create-placeholder-plugin.tsx @@ -15,11 +15,13 @@ interface PlaceholderPluginState { const defaultState = { focused: false, editable: true }; +// eslint-disable-next-line no-restricted-syntax -- prosemirror typing error const placeholderPluginKey = new PluginKey( "placeholderPlugin", ); export const createPlaceholderPlugin = (renderPortal: RenderPortal) => { + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error return new Plugin({ key: placeholderPluginKey, state: { @@ -123,5 +125,6 @@ export const createPlaceholderPlugin = (renderPortal: RenderPortal) => { }, }, }, + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error }) as Plugin; }; diff --git a/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/block-suggester.tsx b/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/block-suggester.tsx index 90260292490..a38111fbbe3 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/block-suggester.tsx +++ b/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/block-suggester.tsx @@ -12,7 +12,9 @@ import { Suggester } from "./suggester"; export interface BlockSuggesterProps { search?: string; - onChange(variant: BlockVariant, blockMeta: HashBlockMeta): void; + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // before this was: onChange(variant: BlockVariant, blockMeta: HashBlockMeta): void; + onChange: (variant: BlockVariant, blockMeta: HashBlockMeta) => void; sx?: SxProps; } diff --git a/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/create-suggester.tsx b/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/create-suggester.tsx index 236c0fe3713..be70df324b2 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/create-suggester.tsx +++ b/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/create-suggester.tsx @@ -106,6 +106,7 @@ interface SuggesterState { * used to tag the suggester plugin/make it a singleton * @see https://prosemirror.net/docs/ref/#state.PluginKey */ +// eslint-disable-next-line no-restricted-syntax -- prosemirror typing error export const suggesterPluginKey = new PluginKey("suggester"); const docChangedInTransaction = (tr: Transaction) => { @@ -135,6 +136,7 @@ export const createSuggester = ( documentRoot: HTMLElement, getManager?: () => ProsemirrorManager, ) => + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error new Plugin({ key: suggesterPluginKey, state: { @@ -428,4 +430,5 @@ export const createSuggester = ( }, }; }, + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error }) as Plugin; diff --git a/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/suggester.tsx b/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/suggester.tsx index 1d35b6d78d4..1b184728603 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/suggester.tsx +++ b/apps/hash-frontend/src/pages/shared/block-collection/create-suggester/suggester.tsx @@ -8,11 +8,17 @@ import { SpinnerIcon } from "../../../../shared/icons"; export interface SuggesterProps { options: T[]; - renderItem(item: T): ReactElement; + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // before this was: renderItem(item: T): ReactElement; + renderItem: (item: T) => ReactElement; error?: ReactElement | null; - onChange(item: T): void; + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // before this was: onChange(item: T): void; + onChange: (item: T) => void; loading?: boolean; - itemKey(option: T): string; + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // before this was: itemKey(option: T): string; + itemKey: (option: T) => string; sx?: SxProps; } diff --git a/apps/hash-frontend/src/pages/shared/block-collection/focus-page-title-plugin.ts b/apps/hash-frontend/src/pages/shared/block-collection/focus-page-title-plugin.ts index 568ae9b59dd..4a65bb4ef0f 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/focus-page-title-plugin.ts +++ b/apps/hash-frontend/src/pages/shared/block-collection/focus-page-title-plugin.ts @@ -4,6 +4,7 @@ import type { RefObject } from "react"; export const createFocusPageTitlePlugin = ( pageTitleRef: RefObject, ) => + // eslint-disable-next-line no-restricted-syntax -- prosemirror typing error new Plugin({ props: { handleKeyDown: (view, event) => { diff --git a/apps/hash-frontend/src/pages/shared/block-collection/shared/mention-suggester.tsx b/apps/hash-frontend/src/pages/shared/block-collection/shared/mention-suggester.tsx index ee3d4ac816e..0cff91e8918 100644 --- a/apps/hash-frontend/src/pages/shared/block-collection/shared/mention-suggester.tsx +++ b/apps/hash-frontend/src/pages/shared/block-collection/shared/mention-suggester.tsx @@ -91,7 +91,9 @@ export type MentionKind = Mention["kind"]; export interface MentionSuggesterProps { search?: string; - onChange(mention: Mention): void; + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // before this was: onChange(mention: Mention): void; + onChange: (mention: Mention) => void; ownedById: OwnedById; } diff --git a/apps/hash-frontend/src/pages/shared/verify-code.tsx b/apps/hash-frontend/src/pages/shared/verify-code.tsx index eb8959af4bd..cbe2e235e40 100644 --- a/apps/hash-frontend/src/pages/shared/verify-code.tsx +++ b/apps/hash-frontend/src/pages/shared/verify-code.tsx @@ -82,7 +82,7 @@ export const VerifyCode: FunctionComponent = ({ await requestCode(); updateState({ emailResent: true, syntheticLoading: false }); setTimeout(() => updateState({ emailResent: false }), 5000); - } catch (err) { + } catch { updateState({ syntheticLoading: false }); } }, SYNTHETIC_LOADING_TIME_MS); diff --git a/apps/hash-frontend/src/pages/shared/visualizer-views.tsx b/apps/hash-frontend/src/pages/shared/visualizer-views.tsx index 6b64dfeddec..c7181798323 100644 --- a/apps/hash-frontend/src/pages/shared/visualizer-views.tsx +++ b/apps/hash-frontend/src/pages/shared/visualizer-views.tsx @@ -5,9 +5,7 @@ import type { ReactElement } from "react"; import { ChartNetworkRegularIcon } from "../../shared/icons/chart-network-regular-icon"; import { GridSolidIcon } from "../../shared/icons/grid-solid-icon"; -const visualizerViews = ["Table", "Graph", "Grid"] as const; - -export type VisualizerView = (typeof visualizerViews)[number]; +export type VisualizerView = "Table" | "Graph" | "Grid"; export const visualizerViewIcons: Record< VisualizerView, diff --git a/apps/hash-frontend/src/pages/types/[[...type-kind]].page.tsx b/apps/hash-frontend/src/pages/types/[[...type-kind]].page.tsx index f2dc925ed2d..d9c0e3a5381 100644 --- a/apps/hash-frontend/src/pages/types/[[...type-kind]].page.tsx +++ b/apps/hash-frontend/src/pages/types/[[...type-kind]].page.tsx @@ -22,14 +22,11 @@ import { } from "./[[...type-kind]].page/types-page-tabs"; import { TypesTable } from "./[[...type-kind]].page/types-table"; -const parsedQueryParams = [ - "entity-type", - "link-type", - "property-type", - "data-type", -] as const; - -type ParsedQueryKindParam = (typeof parsedQueryParams)[number]; +type ParsedQueryKindParam = + | "entity-type" + | "link-type" + | "property-type" + | "data-type"; type ParsedQueryParams = { ["type-kind"]?: ParsedQueryKindParam[]; diff --git a/apps/hash-frontend/src/pages/types/[[...type-kind]].page/types-table.tsx b/apps/hash-frontend/src/pages/types/[[...type-kind]].page/types-table.tsx index 4b05bad256a..5f9286ffe86 100644 --- a/apps/hash-frontend/src/pages/types/[[...type-kind]].page/types-table.tsx +++ b/apps/hash-frontend/src/pages/types/[[...type-kind]].page/types-table.tsx @@ -51,16 +51,13 @@ import { TypeGraphVisualizer } from "../../shared/type-graph-visualizer"; import type { VisualizerView } from "../../shared/visualizer-views"; import { visualizerViewIcons } from "../../shared/visualizer-views"; -const typesTableColumnIds = [ - "title", - "kind", - "webShortname", - "archived", - "lastEdited", - "lastEditedBy", -] as const; - -type LinkColumnId = (typeof typesTableColumnIds)[number]; +type LinkColumnId = + | "title" + | "kind" + | "webShortname" + | "archived" + | "lastEdited" + | "lastEditedBy"; type TypesTableColumn = { id: LinkColumnId; @@ -86,15 +83,12 @@ const typeNamespaceFromTypeId = (typeId: VersionedUrl): string => { return `${domain}/${firstPathSegment}`; }; -const typeTableKinds = [ - "all", - "entity-type", - "link-type", - "property-type", - "data-type", -] as const; - -type TypeTableKind = (typeof typeTableKinds)[number]; +type TypeTableKind = + | "all" + | "entity-type" + | "link-type" + | "property-type" + | "data-type"; const typesTablesToTitle: Record = { all: "Types", diff --git a/apps/hash-frontend/src/shared/generate-link-parameters.ts b/apps/hash-frontend/src/shared/generate-link-parameters.ts index ffa7d23aa3f..0c731621a30 100644 --- a/apps/hash-frontend/src/shared/generate-link-parameters.ts +++ b/apps/hash-frontend/src/shared/generate-link-parameters.ts @@ -18,7 +18,7 @@ const typeUrlRegExp = * 3. Specifies whether the returned href points to a different site or not */ export const generateLinkParameters = ( - hrefToCheck?: string | Url | undefined, + hrefToCheck?: string | Url, ): { isExternal: boolean; href: string; diff --git a/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar/account-page-list/page-tree-item.tsx b/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar/account-page-list/page-tree-item.tsx index 06bdf1e611f..05ab60ca5e4 100644 --- a/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar/account-page-list/page-tree-item.tsx +++ b/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar/account-page-list/page-tree-item.tsx @@ -17,7 +17,7 @@ import { PageMenu } from "./page-menu"; interface DragProps { isSorting?: boolean; attributes?: DraggableAttributes; - // eslint-disable-next-line @typescript-eslint/ban-types -- this matches the library type we get listeners from + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type -- this matches the library type we get listeners from listeners?: Record; style?: CSSProperties; wrapperRef?(this: void, node: HTMLLIElement): void; diff --git a/apps/hash-integration-worker/.eslintrc.cjs b/apps/hash-integration-worker/.eslintrc.cjs deleted file mode 100644 index 75608ba7bba..00000000000 --- a/apps/hash-integration-worker/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - env: { - node: true, - }, -}; diff --git a/apps/hash-integration-worker/eslint.config.js b/apps/hash-integration-worker/eslint.config.js new file mode 100644 index 00000000000..0eac3025266 --- /dev/null +++ b/apps/hash-integration-worker/eslint.config.js @@ -0,0 +1,3 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default createBase(import.meta.dirname); diff --git a/apps/hash-integration-worker/package.json b/apps/hash-integration-worker/package.json index 9475adc204d..afe35ad96cd 100644 --- a/apps/hash-integration-worker/package.json +++ b/apps/hash-integration-worker/package.json @@ -40,11 +40,11 @@ "typescript": "5.6.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@sentry/cli": "^2.39.1", "@types/dotenv-flow": "3.3.3", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3", "wait-on": "8.0.1" diff --git a/apps/hash-integration-worker/scripts/bundle-workflow-code.ts b/apps/hash-integration-worker/scripts/bundle-workflow-code.ts index ac7c4609a4c..9c37039248c 100644 --- a/apps/hash-integration-worker/scripts/bundle-workflow-code.ts +++ b/apps/hash-integration-worker/scripts/bundle-workflow-code.ts @@ -1,13 +1,12 @@ import { writeFile } from "node:fs/promises"; import { createRequire } from "node:module"; -import * as path from "node:path"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { bundleWorkflowCode } from "@temporalio/worker"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const require = createRequire(import.meta.url); diff --git a/apps/hash-integration-worker/src/main.ts b/apps/hash-integration-worker/src/main.ts index 62360813c69..d1a47cad6ec 100644 --- a/apps/hash-integration-worker/src/main.ts +++ b/apps/hash-integration-worker/src/main.ts @@ -10,8 +10,7 @@ Sentry.init({ import * as http from "node:http"; import { createRequire } from "node:module"; -import * as path from "node:path"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { createGraphClient } from "@local/hash-backend-utils/create-graph-client"; @@ -27,7 +26,7 @@ import * as linearActivities from "./linear-activities"; import * as workflows from "./workflows"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const require = createRequire(import.meta.url); diff --git a/apps/hash-realtime/.eslintrc.cjs b/apps/hash-realtime/.eslintrc.cjs deleted file mode 100644 index 75608ba7bba..00000000000 --- a/apps/hash-realtime/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - env: { - node: true, - }, -}; diff --git a/apps/hash-realtime/eslint.config.js b/apps/hash-realtime/eslint.config.js new file mode 100644 index 00000000000..0eac3025266 --- /dev/null +++ b/apps/hash-realtime/eslint.config.js @@ -0,0 +1,3 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default createBase(import.meta.dirname); diff --git a/apps/hash-realtime/package.json b/apps/hash-realtime/package.json index 9e0637baeda..121c86bf85a 100644 --- a/apps/hash-realtime/package.json +++ b/apps/hash-realtime/package.json @@ -22,11 +22,11 @@ "typescript": "5.6.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/node": "22.10.1", "@types/set-interval-async": "1.0.3", - "eslint": "8.57.0", + "eslint": "9.16.0", "typescript": "5.6.3" } } diff --git a/apps/hash-search-loader/.eslintrc.cjs b/apps/hash-search-loader/.eslintrc.cjs deleted file mode 100644 index 599e1c9ee71..00000000000 --- a/apps/hash-search-loader/.eslintrc.cjs +++ /dev/null @@ -1,13 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - env: { - node: true, - }, - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 25 */ "@typescript-eslint/no-unsafe-assignment", - /* 2022-11-29: 32 */ "@typescript-eslint/no-unsafe-member-access", - ]), - }, -}; diff --git a/apps/hash-search-loader/eslint.config.js b/apps/hash-search-loader/eslint.config.js new file mode 100644 index 00000000000..e67ec295d29 --- /dev/null +++ b/apps/hash-search-loader/eslint.config.js @@ -0,0 +1,9 @@ +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...disableRules([ + /* 2022-11-29: 25 */ "@typescript-eslint/no-unsafe-assignment", + /* 2022-11-29: 32 */ "@typescript-eslint/no-unsafe-member-access", + ]), +]; diff --git a/apps/hash-search-loader/package.json b/apps/hash-search-loader/package.json index bf9f9475a8d..394cba46710 100644 --- a/apps/hash-search-loader/package.json +++ b/apps/hash-search-loader/package.json @@ -22,10 +22,10 @@ "typescript": "5.6.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/node": "22.10.1", - "eslint": "8.57.0", + "eslint": "9.16.0", "typescript": "5.6.3" } } diff --git a/apps/hashdotdesign/package.json b/apps/hashdotdesign/package.json index 136d86a5ec5..ea6bd42e4d7 100644 --- a/apps/hashdotdesign/package.json +++ b/apps/hashdotdesign/package.json @@ -13,7 +13,7 @@ "@babel/preset-typescript": "7.26.0", "@hashintel/block-design-system": "0.0.2", "@hashintel/design-system": "0.0.8", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@storybook/addon-essentials": "7.6.20", "@storybook/addon-interactions": "7.6.20", diff --git a/apps/hashdotdev/.eslintrc.cjs b/apps/hashdotdev/.eslintrc.cjs deleted file mode 100644 index 0a20b8b8c75..00000000000 --- a/apps/hashdotdev/.eslintrc.cjs +++ /dev/null @@ -1,39 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 13 */ "@typescript-eslint/no-unsafe-assignment", - /* 2022-11-29: 13 */ "@typescript-eslint/no-unsafe-member-access", - /* 2022-11-29: 11 */ "@typescript-eslint/restrict-template-expressions", - ]), - "jsx-a11y/label-has-associated-control": "off", - "import/no-default-export": "error", - }, - overrides: [ - { - files: [ - "./src/pages/**/*.page.ts", - "./src/pages/**/*.page.tsx", - "**/__mocks__/**", - "*.stories.ts", - "*.stories.tsx", - ], - rules: { - "import/no-default-export": "off", - }, - }, - { - files: ["./scripts/**/*.ts"], - rules: { - "import/no-extraneous-dependencies": [ - "error", - { - // Allow scripts to be able to import from dev dependencies - devDependencies: true, - }, - ], - }, - }, - ], -}; diff --git a/apps/hashdotdev/eslint.config.js b/apps/hashdotdev/eslint.config.js new file mode 100644 index 00000000000..8b7fc8872f5 --- /dev/null +++ b/apps/hashdotdev/eslint.config.js @@ -0,0 +1,43 @@ +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...disableRules([ + /* 2022-11-29: 13 */ "@typescript-eslint/no-unsafe-assignment", + /* 2022-11-29: 13 */ "@typescript-eslint/no-unsafe-member-access", + /* 2022-11-29: 11 */ "@typescript-eslint/restrict-template-expressions", + ]), + { + rules: { + "jsx-a11y/label-has-associated-control": "off", + "import/no-default-export": "error", + }, + }, + { + files: [ + "**/src/pages/**/*.page.ts", + "**/src/pages/**/*.page.tsx", + "**/__mocks__/**", + "*.stories.ts", + "*.stories.tsx", + ], + rules: { + "import/no-default-export": "off", + }, + }, + { + files: ["**/scripts/**/*.ts"], + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + // Allow scripts to be able to import from dev dependencies + devDependencies: true, + }, + ], + }, + }, + { + ignores: ["buildstamp.js", "next.config.js"], + }, +]; diff --git a/apps/hashdotdev/package.json b/apps/hashdotdev/package.json index 399c25004e0..4c177b02cd2 100644 --- a/apps/hashdotdev/package.json +++ b/apps/hashdotdev/package.json @@ -65,7 +65,7 @@ }, "devDependencies": { "@babel/core": "7.26.0", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/d3": "7.4.3", "@types/fs-extra": "9.0.13", @@ -80,7 +80,7 @@ "@types/unist": "2.0.11", "babel-loader": "9.2.1", "chalk": "5.3.0", - "eslint": "8.57.0", + "eslint": "9.16.0", "execa": "7.2.0", "tsx": "4.19.2", "typescript": "5.6.3" diff --git a/apps/hashdotdev/src/components/calculation-block.tsx b/apps/hashdotdev/src/components/calculation-block.tsx index 57f2e3c089a..aef2b76e61f 100644 --- a/apps/hashdotdev/src/components/calculation-block.tsx +++ b/apps/hashdotdev/src/components/calculation-block.tsx @@ -1,7 +1,7 @@ import { MockBlockDock } from "mock-block-dock"; import type { FunctionComponent } from "react"; -// eslint-disable-next-line @typescript-eslint/no-var-requires -- TODO why was this declared like this +// eslint-disable-next-line @typescript-eslint/no-require-imports -- TODO why was this declared like this const CalcBlock = require("calculation-block").default; export const CalculationBlock: FunctionComponent = () => ( diff --git a/apps/hashdotdev/src/components/link.tsx b/apps/hashdotdev/src/components/link.tsx index b9136243a8e..fe3cb7b4eb7 100644 --- a/apps/hashdotdev/src/components/link.tsx +++ b/apps/hashdotdev/src/components/link.tsx @@ -1,6 +1,8 @@ import type { UrlObject } from "node:url"; import type { LinkProps as MuiLinkProps } from "@mui/material"; +// @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors +// eslint-disable-next-line no-restricted-imports import { Link as MuiLink, styled } from "@mui/material"; import clsx from "clsx"; // eslint-disable-next-line no-restricted-imports diff --git a/apps/hashdotdev/src/components/pre-footer.tsx b/apps/hashdotdev/src/components/pre-footer.tsx index df4874870a1..3dcd0a5e3ac 100644 --- a/apps/hashdotdev/src/components/pre-footer.tsx +++ b/apps/hashdotdev/src/components/pre-footer.tsx @@ -194,7 +194,7 @@ export const Subscribe: FunctionComponent< setError("Something went wrong.️ Please try again later"); } }); - } catch (err) { + } catch { // eslint-disable-next-line no-console console.log(error); unstable_batchedUpdates(() => { diff --git a/apps/hashdotdev/src/pages/blog/[...blog-slug].page.tsx b/apps/hashdotdev/src/pages/blog/[...blog-slug].page.tsx index 4955a0b647b..6f0c7e1632f 100644 --- a/apps/hashdotdev/src/pages/blog/[...blog-slug].page.tsx +++ b/apps/hashdotdev/src/pages/blog/[...blog-slug].page.tsx @@ -121,7 +121,7 @@ export const getStaticProps: GetStaticProps< }, }, }; - } catch (err) { + } catch { // @todo better error when MDX content is broken return { notFound: true, diff --git a/apps/hashdotdev/src/pages/blog/index.page.tsx b/apps/hashdotdev/src/pages/blog/index.page.tsx index f1006f4cbce..4ea496bb3c5 100644 --- a/apps/hashdotdev/src/pages/blog/index.page.tsx +++ b/apps/hashdotdev/src/pages/blog/index.page.tsx @@ -68,7 +68,7 @@ export const getStaticProps: GetStaticProps = async () => { pages, }, }; - } catch (err) { + } catch { // @todo better error when MDX content is broken return { notFound: true, diff --git a/apps/hashdotdev/src/pages/index.page.tsx b/apps/hashdotdev/src/pages/index.page.tsx index 4d573987fe5..f48125e5027 100644 --- a/apps/hashdotdev/src/pages/index.page.tsx +++ b/apps/hashdotdev/src/pages/index.page.tsx @@ -610,7 +610,7 @@ export const getStaticProps: GetStaticProps = async () => { ); return { props: { posts } }; - } catch (err) { + } catch { // @todo better error when MDX content is broken return { notFound: true }; } diff --git a/apps/hashdotdev/src/pages/shared/mdx-utils.ts b/apps/hashdotdev/src/pages/shared/mdx-utils.ts index d7970049b3f..123a36fcafa 100644 --- a/apps/hashdotdev/src/pages/shared/mdx-utils.ts +++ b/apps/hashdotdev/src/pages/shared/mdx-utils.ts @@ -156,6 +156,8 @@ const getFullText = (node: Node): string => // Recursively construct the text from leaf text nodes in an MDX AST const getVisibleText = (node: Node): string => + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-base-to-string [ isTextNode(node) ? isTextNode(node.value) diff --git a/apps/plugin-browser/.eslintrc.cjs b/apps/plugin-browser/.eslintrc.cjs deleted file mode 100644 index 14435b7da9e..00000000000 --- a/apps/plugin-browser/.eslintrc.cjs +++ /dev/null @@ -1,42 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - "no-restricted-imports": [ - "error", - { - paths: [ - { - name: "@local/hash-isomorphic-utils/environment", - message: "Use the API_ORIGIN or FRONTEND_ORIGIN globals instead.", - }, - ], - patterns: [ - { - group: ["*use-user-value"], - message: - "Please useUserContext instead to share state across components", - }, - ], - }, - ], - /** - * Importing the StatusCode enum interferes with Playwright test setup for some reason. - */ - "@typescript-eslint/no-unsafe-enum-comparison": "off", - }, - ignorePatterns: require("@local/eslint-config/generate-ignore-patterns.cjs")( - __dirname, - ), - overrides: [ - { - files: ["utils/*.js"], - rules: { - "import/no-extraneous-dependencies": [ - "error", - { devDependencies: true }, - ], - }, - }, - ], -}; diff --git a/apps/plugin-browser/eslint.config.js b/apps/plugin-browser/eslint.config.js new file mode 100644 index 00000000000..146d840ef01 --- /dev/null +++ b/apps/plugin-browser/eslint.config.js @@ -0,0 +1,40 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { + rules: { + "no-restricted-imports": [ + "error", + { + paths: [ + { + name: "@local/hash-isomorphic-utils/environment", + message: "Use the API_ORIGIN or FRONTEND_ORIGIN globals instead.", + }, + ], + patterns: [ + { + group: ["*use-user-value"], + message: + "Please useUserContext instead to share state across components", + }, + ], + }, + ], + /** + * Importing the StatusCode enum interferes with Playwright test setup for some reason. + */ + "@typescript-eslint/no-unsafe-enum-comparison": "off", + }, + }, + { + files: ["utils/*.js"], + rules: { + "import/no-extraneous-dependencies": ["error", { devDependencies: true }], + }, + }, + { + ignores: ["webpack.config.js", "utils/webserver.js", "utils/build.js"], + }, +]; diff --git a/apps/plugin-browser/package.json b/apps/plugin-browser/package.json index 95c3205b499..482caf28bd6 100755 --- a/apps/plugin-browser/package.json +++ b/apps/plugin-browser/package.json @@ -50,13 +50,12 @@ }, "devDependencies": { "@babel/core": "7.26.0", - "@babel/eslint-parser": "7.25.9", "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/preset-env": "7.26.0", "@babel/preset-react": "7.26.3", "@blockprotocol/core": "0.1.3", "@graphql-codegen/cli": "^5.0.3", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/hash-graph-client": "0.0.0-private", "@local/hash-isomorphic-utils": "0.0.0-private", "@local/hash-subgraph": "0.0.0-private", @@ -74,7 +73,7 @@ "copy-webpack-plugin": "11.0.0", "css-loader": "6.11.0", "dotenv-flow": "3.3.0", - "eslint": "8.57.0", + "eslint": "9.16.0", "file-loader": "6.2.0", "fs-extra": "11.1.0", "html-loader": "4.2.0", diff --git a/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx b/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx index dfdeccdfff4..dd487e0024a 100644 --- a/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx +++ b/apps/plugin-browser/src/pages/popup/popup-contents/action-center/one-off/infer-entities-action.tsx @@ -75,7 +75,7 @@ export const InferEntitiesAction = ({ sourceWebPage, type: "infer-entities", }); - } catch (err) { + } catch { // eslint-disable-next-line no-alert alert( "Could not access page content – you may need to reload the tab if you just installed the extension, or it may be a page which your browser does not allow extensions to access.", diff --git a/apps/plugin-browser/tsconfig.json b/apps/plugin-browser/tsconfig.json index 3555429663a..d414625a634 100644 --- a/apps/plugin-browser/tsconfig.json +++ b/apps/plugin-browser/tsconfig.json @@ -13,7 +13,8 @@ "src", "theme-override.d.ts", "webpack-injected-env.d.ts", - "codegen.config.ts" + "codegen.config.ts", + "eslint.config.js" ], "exclude": ["build", "node_modules"] } diff --git a/blocks/address/.eslintrc.cjs b/blocks/address/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/address/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/address/eslint.config.js b/blocks/address/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/address/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/address/package.json b/blocks/address/package.json index 761dd1fa90a..4facaa5682c 100644 --- a/blocks/address/package.json +++ b/blocks/address/package.json @@ -44,12 +44,12 @@ "uuid": "9.0.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@types/lodash.debounce": "4.0.9", "@types/react-dom": "18.2.25", "@types/uuid": "10.0.0", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/address/src/address-card.tsx b/blocks/address/src/address-card.tsx index 11303a2c148..327e1b7bb0b 100644 --- a/blocks/address/src/address-card.tsx +++ b/blocks/address/src/address-card.tsx @@ -10,6 +10,8 @@ import { Box, CircularProgress, Fade, + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line no-restricted-imports Link, Stack, Typography, diff --git a/blocks/address/src/map-button.tsx b/blocks/address/src/map-button.tsx index 538726e5206..3ac64624177 100644 --- a/blocks/address/src/map-button.tsx +++ b/blocks/address/src/map-button.tsx @@ -1,5 +1,7 @@ import type { ButtonProps } from "@hashintel/design-system"; import { Button } from "@hashintel/design-system"; +// @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors +// eslint-disable-next-line no-restricted-imports import { Link } from "@mui/material"; export const MapButton = ({ children, href, sx, ...props }: ButtonProps) => { diff --git a/blocks/ai-chat/.eslintrc.cjs b/blocks/ai-chat/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/ai-chat/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/ai-chat/eslint.config.js b/blocks/ai-chat/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/ai-chat/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/ai-chat/package.json b/blocks/ai-chat/package.json index a42a407d18b..5e461299ab4 100644 --- a/blocks/ai-chat/package.json +++ b/blocks/ai-chat/package.json @@ -39,12 +39,12 @@ "uuid": "9.0.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "@types/uuid": "10.0.0", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/ai-image/.eslintrc.cjs b/blocks/ai-image/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/ai-image/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/ai-image/eslint.config.js b/blocks/ai-image/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/ai-image/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/ai-image/package.json b/blocks/ai-image/package.json index 185df1b8442..6ba2d49151a 100644 --- a/blocks/ai-image/package.json +++ b/blocks/ai-image/package.json @@ -40,12 +40,12 @@ "uuid": "9.0.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "@types/uuid": "10.0.0", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/ai-text/.eslintrc.cjs b/blocks/ai-text/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/ai-text/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/ai-text/eslint.config.js b/blocks/ai-text/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/ai-text/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/ai-text/package.json b/blocks/ai-text/package.json index 4e7a096ff57..a5eabbee0a4 100644 --- a/blocks/ai-text/package.json +++ b/blocks/ai-text/package.json @@ -34,11 +34,11 @@ "@mui/material": "5.16.9" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/callout/.eslintrc.cjs b/blocks/callout/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/callout/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/callout/eslint.config.js b/blocks/callout/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/callout/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/callout/package.json b/blocks/callout/package.json index ed3bd3985ad..6290f1b96dd 100644 --- a/blocks/callout/package.json +++ b/blocks/callout/package.json @@ -31,11 +31,11 @@ "@blockprotocol/hook": "0.1.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/chart/.eslintrc.cjs b/blocks/chart/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/chart/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/chart/eslint.config.js b/blocks/chart/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/chart/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/chart/package.json b/blocks/chart/package.json index 21c16940e7c..c887b534245 100644 --- a/blocks/chart/package.json +++ b/blocks/chart/package.json @@ -30,6 +30,7 @@ "@blockprotocol/graph": "0.3.4", "@hashintel/block-design-system": "0.0.2", "@hashintel/design-system": "0.0.8", + "@local/hash-isomorphic-utils": "0.0.0-private", "@mui/material": "5.16.9", "echarts": "5.5.1", "lodash.debounce": "4.0.8", @@ -38,13 +39,13 @@ "devDependencies": { "@emotion/react": "11.13.5", "@emotion/styled": "11.13.5", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/lodash.debounce": "4.0.9", "@types/react-dom": "18.2.25", "@types/react-is": "18.3.0", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/chart/src/bar-chart.tsx b/blocks/chart/src/bar-chart.tsx index caf3ba71e88..5093be86ba8 100644 --- a/blocks/chart/src/bar-chart.tsx +++ b/blocks/chart/src/bar-chart.tsx @@ -101,6 +101,8 @@ export const BarChart: FunctionComponent<{ ); const label = String( + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-base-to-string entity.properties[extractBaseUrl(labelPropertyTypeId)] ?? "Unknown", ); diff --git a/blocks/code/.eslintrc.cjs b/blocks/code/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/code/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/code/eslint.config.js b/blocks/code/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/code/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/code/package.json b/blocks/code/package.json index 53b90d1fcc4..581b181a102 100644 --- a/blocks/code/package.json +++ b/blocks/code/package.json @@ -31,12 +31,12 @@ "prismjs": "1.29.0" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/prismjs": "1.26.5", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/countdown/.eslintrc.cjs b/blocks/countdown/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/countdown/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/countdown/eslint.config.js b/blocks/countdown/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/countdown/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/countdown/package.json b/blocks/countdown/package.json index b2b4fc44b4e..371fc377d26 100644 --- a/blocks/countdown/package.json +++ b/blocks/countdown/package.json @@ -32,12 +32,12 @@ "react-datepicker": "4.25.0" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-datepicker": "4.19.6", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/divider/.eslintrc.cjs b/blocks/divider/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/divider/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/divider/eslint.config.js b/blocks/divider/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/divider/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/divider/package.json b/blocks/divider/package.json index d9edec79235..88dcaf535e9 100644 --- a/blocks/divider/package.json +++ b/blocks/divider/package.json @@ -31,11 +31,11 @@ "@blockprotocol/graph": "0.3.4" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/embed/.eslintrc.cjs b/blocks/embed/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/embed/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/embed/eslint.config.js b/blocks/embed/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/embed/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/embed/package.json b/blocks/embed/package.json index ec9b1fab9ba..660e67a97d0 100644 --- a/blocks/embed/package.json +++ b/blocks/embed/package.json @@ -30,12 +30,12 @@ "twind": "0.16.19" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/lodash": "4.17.13", "@types/react-dom": "18.0.9", "block-scripts": "0.0.14", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.0.10", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/blocks/embed/turbo.json b/blocks/embed/turbo.json index a127d67087c..2815ced6012 100644 --- a/blocks/embed/turbo.json +++ b/blocks/embed/turbo.json @@ -14,7 +14,7 @@ }, "lint:eslint": { "env": ["CHECK_TEMPORARILY_DISABLED_RULES"], - "dependsOn": ["schema"] + "dependsOn": ["schema", "@local/eslint#build"] }, "fix:eslint": { "cache": false, diff --git a/blocks/faq/.eslintrc.cjs b/blocks/faq/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/faq/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/faq/eslint.config.js b/blocks/faq/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/faq/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/faq/package.json b/blocks/faq/package.json index c84a62b8767..1841e937991 100644 --- a/blocks/faq/package.json +++ b/blocks/faq/package.json @@ -38,11 +38,11 @@ "uuid": "9.0.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@types/react-dom": "18.2.25", "@types/uuid": "10.0.0", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/faq/src/app.tsx b/blocks/faq/src/app.tsx index a58f4566114..3d8bfbab106 100644 --- a/blocks/faq/src/app.tsx +++ b/blocks/faq/src/app.tsx @@ -26,7 +26,7 @@ import type { FAQBlockOutgoingLinksByLinkEntityTypeId, FrequentlyAskedQuestion, FrequentlyAskedQuestionProperties, -} from "./types/block-entity"; +} from "./types/generated/block-entity"; type RootEntityKey = keyof BlockEntity["properties"]; type QuestionEntityKey = keyof FrequentlyAskedQuestionProperties; diff --git a/blocks/faq/src/dev.tsx b/blocks/faq/src/dev.tsx index 79d2ee5beb1..031ca870b38 100644 --- a/blocks/faq/src/dev.tsx +++ b/blocks/faq/src/dev.tsx @@ -4,7 +4,7 @@ import { createRoot } from "react-dom/client"; import packageJson from "../package.json"; import Component from "./index"; -import type { BlockEntity } from "./types/block-entity"; +import type { BlockEntity } from "./types/generated/block-entity"; const node = document.getElementById("app"); diff --git a/blocks/faq/src/types/block-entity.ts b/blocks/faq/src/types/block-entity.ts deleted file mode 100644 index c16a4945c19..00000000000 --- a/blocks/faq/src/types/block-entity.ts +++ /dev/null @@ -1,105 +0,0 @@ -/** - * This file was automatically generated – do not edit it. - */ - -import type { Entity, LinkData } from "@blockprotocol/graph"; - -/** - * A response to a question that provides information, clarification, or confirmation. - */ -export type AnswerPropertyValue = Text; - -/** - * Defines whether or not toggles should be displayed on questions to show/hide their respective answer. - */ -export type AnswerVisibilityIsConfigurablePropertyValue = boolean; - -export type BlockEntity = FAQBlock; - -export type BlockEntityOutgoingLinkAndTarget = FAQBlockOutgoingLinkAndTarget; - -/** - * A True or False value - */ -export type Boolean = boolean; - -/** - * A piece of text that tells you about something or someone. This can include explaining what they look like, what its purpose is for, what they’re like, etc. - */ -export type DescriptionPropertyValue = Text; - -export type FAQBlock = Entity; - -export type FAQBlockHasFrequentlyAskedQuestionLinks = { - linkEntity: HasFrequentlyAskedQuestion; - rightEntity: FrequentlyAskedQuestion; -}; - -export type FAQBlockOutgoingLinkAndTarget = - FAQBlockHasFrequentlyAskedQuestionLinks; - -export type FAQBlockOutgoingLinksByLinkEntityTypeId = { - "https://blockprotocol.org/@hash/types/entity-type/has-frequently-asked-question/v/1": FAQBlockHasFrequentlyAskedQuestionLinks; -}; - -export type FAQBlockProperties = { - "https://blockprotocol.org/@blockprotocol/types/property-type/description/"?: DescriptionPropertyValue; - "https://blockprotocol.org/@blockprotocol/types/property-type/title/"?: TitlePropertyValue; - "https://blockprotocol.org/@hash/types/property-type/sections-should-be-numbered/"?: SectionsShouldBeNumberedPropertyValue; - "https://blockprotocol.org/@hash/types/property-type/answer-visibility-is-configurable/"?: AnswerVisibilityIsConfigurablePropertyValue; -}; - -export type FrequentlyAskedQuestion = Entity; - -export type FrequentlyAskedQuestionOutgoingLinkAndTarget = never; - -export type FrequentlyAskedQuestionOutgoingLinksByLinkEntityTypeId = {}; - -export type FrequentlyAskedQuestionProperties = { - "https://blockprotocol.org/@blockprotocol/types/property-type/question/"?: QuestionPropertyValue; - "https://blockprotocol.org/@blockprotocol/types/property-type/answer/"?: AnswerPropertyValue; -}; - -export type HasFrequentlyAskedQuestion = - Entity & { linkData: LinkData }; - -export type HasFrequentlyAskedQuestionOutgoingLinkAndTarget = never; - -export type HasFrequentlyAskedQuestionOutgoingLinksByLinkEntityTypeId = {}; - -/** - * Contains a frequently asked question defined by a [Frequently Asked Question] entity. - */ -export type HasFrequentlyAskedQuestionProperties = - HasFrequentlyAskedQuestionProperties1 & HasFrequentlyAskedQuestionProperties2; -export type HasFrequentlyAskedQuestionProperties1 = LinkProperties; - -export type HasFrequentlyAskedQuestionProperties2 = {}; - -export type Link = Entity; - -export type LinkOutgoingLinkAndTarget = never; - -export type LinkOutgoingLinksByLinkEntityTypeId = {}; - -export type LinkProperties = {}; - -/** - * A sentence that is used to request information, clarification, or confirmation about something. - */ -export type QuestionPropertyValue = Text; - -/** - * Defines whether or not sections should be numbered. - */ -export type SectionsShouldBeNumberedPropertyValue = boolean; - -/** - * An ordered sequence of characters - */ -export type Text = string; - -/** - * The name given to something to identify it, generally associated with objects or inanimate things such as books, websites, songs, etc. - */ -export type TitlePropertyValue = Text; diff --git a/blocks/heading/.eslintrc.cjs b/blocks/heading/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/heading/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/heading/eslint.config.js b/blocks/heading/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/heading/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/heading/package.json b/blocks/heading/package.json index be040d7dcdc..cb1b746a2c8 100644 --- a/blocks/heading/package.json +++ b/blocks/heading/package.json @@ -31,11 +31,11 @@ "@blockprotocol/hook": "0.1.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/how-to/.eslintrc.cjs b/blocks/how-to/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/how-to/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/how-to/eslint.config.js b/blocks/how-to/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/how-to/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/how-to/package.json b/blocks/how-to/package.json index ee0fb2fe4ff..83341482f03 100644 --- a/blocks/how-to/package.json +++ b/blocks/how-to/package.json @@ -39,11 +39,11 @@ "uuid": "9.0.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@types/react-dom": "18.2.25", "@types/uuid": "10.0.0", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/how-to/src/app.tsx b/blocks/how-to/src/app.tsx index f9d549c6373..da56aea82f2 100644 --- a/blocks/how-to/src/app.tsx +++ b/blocks/how-to/src/app.tsx @@ -330,65 +330,59 @@ export const App: BlockComponent = ({ }), }} > - { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we don't want an empty string - title || description || !readonly ? ( - + { + if (!readonly) { + setTitleValue(event.target.value); + } + }} + onBlur={(event) => + updateField(event.target.value, titleKey) + } sx={{ - gap: 1.5, + fontWeight: 700, + fontSize: 21, + lineHeight: 1, + letterSpacing: "-0.02em", + color: theme.palette.common.black, }} - > - { - if (!readonly) { - setTitleValue(event.target.value); - } - }} - onBlur={(event) => - updateField(event.target.value, titleKey) + placeholder="Enter a how-to guide name" + readonly={readonly} + /> + + { + if (!readonly) { + setDescriptionValue(event.target.value); } - sx={{ - fontWeight: 700, - fontSize: 21, - lineHeight: 1, - letterSpacing: "-0.02em", - color: theme.palette.common.black, - }} - placeholder="Enter a how-to guide name" - readonly={readonly} - /> - - { - if (!readonly) { - setDescriptionValue(event.target.value); - } - }} - onBlur={(event) => { - void updateField( - event.target.value, - descriptionKey, - ); - }} - sx={{ - fontWeight: 500, - fontSize: 14, - lineHeight: 1.3, - letterSpacing: "-0.02em", - color: theme.palette.gray[90], - }} - placeholder="Click here to add a description of the how-to process" - placeholderSx={{ - fontStyle: "italic", - }} - readonly={readonly} - /> - - ) : null - } + }} + onBlur={(event) => { + void updateField(event.target.value, descriptionKey); + }} + sx={{ + fontWeight: 500, + fontSize: 14, + lineHeight: 1.3, + letterSpacing: "-0.02em", + color: theme.palette.gray[90], + }} + placeholder="Click here to add a description of the how-to process" + placeholderSx={{ + fontStyle: "italic", + }} + readonly={readonly} + /> + + ) : null} {(introEntity ?? !readonly) ? ( diff --git a/blocks/image/.eslintrc.cjs b/blocks/image/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/image/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/image/eslint.config.js b/blocks/image/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/image/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/image/package.json b/blocks/image/package.json index d933497f7ea..e45ddc8c99e 100644 --- a/blocks/image/package.json +++ b/blocks/image/package.json @@ -32,11 +32,11 @@ "twind": "0.16.19" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/kanban-board/.eslintrc.cjs b/blocks/kanban-board/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/kanban-board/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/kanban-board/eslint.config.js b/blocks/kanban-board/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/kanban-board/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/kanban-board/package.json b/blocks/kanban-board/package.json index 9dcd7b06283..b375ee75318 100644 --- a/blocks/kanban-board/package.json +++ b/blocks/kanban-board/package.json @@ -36,6 +36,7 @@ "@dnd-kit/sortable": "7.0.2", "@dnd-kit/utilities": "3.2.2", "@hashintel/block-design-system": "0.0.2", + "@hashintel/design-system": "0.0.8", "@mui/material": "5.16.9", "clsx": "1.2.1", "lodash.clonedeep": "4.5.0", @@ -44,14 +45,14 @@ "react-textarea-autosize": "8.5.6" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/lodash.clonedeep": "4.5.9", "@types/lodash.debounce": "4.0.9", "@types/lodash.isequal": "4.5.8", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/minesweeper/.eslintrc.cjs b/blocks/minesweeper/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/minesweeper/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/minesweeper/eslint.config.js b/blocks/minesweeper/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/minesweeper/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/minesweeper/package.json b/blocks/minesweeper/package.json index 0a3619a981a..07e15c3e4e5 100644 --- a/blocks/minesweeper/package.json +++ b/blocks/minesweeper/package.json @@ -26,11 +26,11 @@ "mine-sweeper-tag": "1.0.6" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/minesweeper/src/app.ts b/blocks/minesweeper/src/app.ts index 6fe622ed001..cfb6c8ee863 100644 --- a/blocks/minesweeper/src/app.ts +++ b/blocks/minesweeper/src/app.ts @@ -1,7 +1,6 @@ import { BlockElementBase } from "@blockprotocol/graph/custom-element"; import { getRoots } from "@blockprotocol/graph/stdlib"; import type { PropertyValues } from "lit"; -// eslint-disable-next-line import/extensions import { unsafeHTML } from "lit/directives/unsafe-html.js"; import { mine_sweeper } from "mine-sweeper-tag"; diff --git a/blocks/paragraph/.eslintrc.cjs b/blocks/paragraph/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/paragraph/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/paragraph/eslint.config.js b/blocks/paragraph/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/paragraph/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/paragraph/package.json b/blocks/paragraph/package.json index 36919101633..bb81b089128 100644 --- a/blocks/paragraph/package.json +++ b/blocks/paragraph/package.json @@ -31,11 +31,11 @@ "@blockprotocol/hook": "0.1.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/person/.eslintrc.cjs b/blocks/person/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/person/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/person/eslint.config.js b/blocks/person/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/person/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/person/package.json b/blocks/person/package.json index bb2faaa1e37..0774c0cacd2 100644 --- a/blocks/person/package.json +++ b/blocks/person/package.json @@ -29,12 +29,12 @@ "dompurify": "2.5.8" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/dompurify": "2.4.0", "@types/react-dom": "18.0.9", "block-scripts": "0.0.14", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.0.38", "react": "18.2.0", "react-dom": "18.2.0", diff --git a/blocks/shuffle/.eslintrc.cjs b/blocks/shuffle/.eslintrc.cjs deleted file mode 100644 index 9e5c261e5d9..00000000000 --- a/blocks/shuffle/.eslintrc.cjs +++ /dev/null @@ -1,14 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), - rules: { - "unicorn/import-style": [ - "error", - { - styles: { - react: { named: false }, - }, - }, - ], - }, -}; diff --git a/blocks/shuffle/eslint.config.js b/blocks/shuffle/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/shuffle/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/shuffle/package.json b/blocks/shuffle/package.json index c9693b5dc42..2fac53c0c7c 100644 --- a/blocks/shuffle/package.json +++ b/blocks/shuffle/package.json @@ -39,12 +39,12 @@ "uuid": "9.0.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/lodash.isequal": "4.5.8", "@types/uuid": "10.0.0", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/shuffle/src/components/item-list.tsx b/blocks/shuffle/src/components/item-list.tsx index 2bbdbb52258..b6a41c8c28b 100644 --- a/blocks/shuffle/src/components/item-list.tsx +++ b/blocks/shuffle/src/components/item-list.tsx @@ -15,7 +15,9 @@ import { import { CSS } from "@dnd-kit/utilities"; import { List } from "@mui/material"; import type { FunctionComponent } from "react"; -import React, { useMemo, useRef, useState } from "react"; +// @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors +// removed React import +import { useMemo, useRef, useState } from "react"; import { propertyIds } from "../property-ids"; import type { ShuffleBlockItemPropertyValue } from "../types/generated/block-entity"; diff --git a/blocks/shuffle/src/components/item.tsx b/blocks/shuffle/src/components/item.tsx index 5b98053faf7..a69deba73fe 100644 --- a/blocks/shuffle/src/components/item.tsx +++ b/blocks/shuffle/src/components/item.tsx @@ -5,7 +5,9 @@ import LinkIcon from "@mui/icons-material/Link"; import type { SxProps } from "@mui/material"; import { Tooltip } from "@mui/material"; import type { CSSProperties, RefObject } from "react"; -import React, { forwardRef, useState } from "react"; +// @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors +// removed React import +import { forwardRef, useState } from "react"; import { SButtonsWrapper, @@ -25,7 +27,7 @@ export type ItemProps = { onDelete?: () => void; paperStyle?: SxProps; attributes?: DraggableAttributes; - // eslint-disable-next-line @typescript-eslint/ban-types -- this matches the library type we get listeners from + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type -- this matches the library type we get listeners from listeners?: Record; style?: CSSProperties; dragOverlay?: RefObject; diff --git a/blocks/shuffle/src/components/sortable-item.tsx b/blocks/shuffle/src/components/sortable-item.tsx index f87aa374f88..df077fca050 100644 --- a/blocks/shuffle/src/components/sortable-item.tsx +++ b/blocks/shuffle/src/components/sortable-item.tsx @@ -1,8 +1,9 @@ import type { AnimateLayoutChanges } from "@dnd-kit/sortable"; import { defaultAnimateLayoutChanges, useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; +// @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors +// removed React import import type { FunctionComponent } from "react"; -import React from "react"; import type { ItemProps } from "./item"; import { Item } from "./item"; diff --git a/blocks/shuffle/src/shuffle.tsx b/blocks/shuffle/src/shuffle.tsx index 44a328de3e8..980f5a32218 100644 --- a/blocks/shuffle/src/shuffle.tsx +++ b/blocks/shuffle/src/shuffle.tsx @@ -14,7 +14,9 @@ import ShuffleIcon from "@mui/icons-material/Shuffle"; import Box from "@mui/material/Box"; import produce from "immer"; import isEqual from "lodash.isequal"; -import React, { useMemo, useRef, useState } from "react"; +// @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors +// removed React import +import { useMemo, useRef, useState } from "react"; import { v4 as uuid } from "uuid"; import { ItemList } from "./components/item-list"; diff --git a/blocks/table/.eslintrc.cjs b/blocks/table/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/table/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/table/eslint.config.js b/blocks/table/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/table/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/table/package.json b/blocks/table/package.json index 129d73fee04..8d394308615 100644 --- a/blocks/table/package.json +++ b/blocks/table/package.json @@ -34,6 +34,8 @@ "@blockprotocol/graph": "0.3.4", "@glideapps/glide-data-grid": "patch:@glideapps/glide-data-grid@npm%3A6.0.3#~/.yarn/patches/@glideapps-glide-data-grid-npm-6.0.3-f71d586425.patch", "@hashintel/block-design-system": "0.0.2", + "@hashintel/design-system": "0.0.8", + "@local/hash-isomorphic-utils": "0.0.0-private", "@mui/material": "5.16.9", "clsx": "1.2.1", "immer": "9.0.21", @@ -46,14 +48,14 @@ "rooks": "7.14.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/lodash.debounce": "4.0.9", "@types/lodash.isequal": "4.5.8", "@types/lodash.uniqueid": "4.0.9", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/timer/.eslintrc.cjs b/blocks/timer/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/timer/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/timer/eslint.config.js b/blocks/timer/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/timer/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/timer/package.json b/blocks/timer/package.json index c3212c8cc35..78894682b86 100644 --- a/blocks/timer/package.json +++ b/blocks/timer/package.json @@ -32,11 +32,11 @@ "duration-fns": "3.0.2" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/blocks/video/.eslintrc.cjs b/blocks/video/.eslintrc.cjs deleted file mode 100644 index ee8314fefb0..00000000000 --- a/blocks/video/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-block-config.cjs")(__dirname), -}; diff --git a/blocks/video/eslint.config.js b/blocks/video/eslint.config.js new file mode 100644 index 00000000000..5b6bb9d538e --- /dev/null +++ b/blocks/video/eslint.config.js @@ -0,0 +1,3 @@ +import { createBlock } from "@local/eslint/deprecated"; + +export default createBlock(import.meta.dirname); diff --git a/blocks/video/package.json b/blocks/video/package.json index 80e99788935..1c490077617 100644 --- a/blocks/video/package.json +++ b/blocks/video/package.json @@ -31,11 +31,11 @@ "twind": "0.16.19" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/react-dom": "18.2.25", "block-scripts": "0.3.4", - "eslint": "8.57.0", + "eslint": "9.16.0", "mock-block-dock": "0.1.9", "prettier": "3.4.2", "react": "18.2.0", diff --git a/libs/@blockprotocol/graph/.eslintrc.cjs b/libs/@blockprotocol/graph/.eslintrc.cjs deleted file mode 100644 index 3cb37833d62..00000000000 --- a/libs/@blockprotocol/graph/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - "@typescript-eslint/no-explicit-any": "off", - }, -}; diff --git a/libs/@blockprotocol/graph/eslint.config.js b/libs/@blockprotocol/graph/eslint.config.js new file mode 100644 index 00000000000..6e9ea6a4789 --- /dev/null +++ b/libs/@blockprotocol/graph/eslint.config.js @@ -0,0 +1,10 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { + rules: { + "@typescript-eslint/no-explicit-any": "off", + }, + }, +]; diff --git a/libs/@blockprotocol/graph/package.json b/libs/@blockprotocol/graph/package.json index 75e9df23b69..c3d0d399f5f 100644 --- a/libs/@blockprotocol/graph/package.json +++ b/libs/@blockprotocol/graph/package.json @@ -75,12 +75,12 @@ "typescript": "5.6.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/lodash.isequal": "4.5.8", "@types/node": "22.10.1", "@types/react": "18.2.68", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3" }, diff --git a/libs/@blockprotocol/graph/src/codegen.ts b/libs/@blockprotocol/graph/src/codegen.ts index a9a57b19a91..d0f07222a7b 100644 --- a/libs/@blockprotocol/graph/src/codegen.ts +++ b/libs/@blockprotocol/graph/src/codegen.ts @@ -1,7 +1,7 @@ /** * Defines utilities for generating TypeScript types from elements of the Block Protocol Type System. */ -import * as path from "node:path"; +import path from "node:path"; import { compile } from "./codegen/compile.js"; import { diff --git a/libs/@blockprotocol/graph/src/codegen/initialize/clean-output-dir.ts b/libs/@blockprotocol/graph/src/codegen/initialize/clean-output-dir.ts index 6ceab05789f..bf35f2cb540 100644 --- a/libs/@blockprotocol/graph/src/codegen/initialize/clean-output-dir.ts +++ b/libs/@blockprotocol/graph/src/codegen/initialize/clean-output-dir.ts @@ -1,5 +1,5 @@ -import * as fs from "node:fs/promises"; -import * as path from "node:path"; +import fs from "node:fs/promises"; +import path from "node:path"; import type { InitializeContext } from "../context/initialize.js"; diff --git a/libs/@blockprotocol/graph/src/codegen/initialize/ensure-output-dir-exists.ts b/libs/@blockprotocol/graph/src/codegen/initialize/ensure-output-dir-exists.ts index fa0d0951e08..e561add6278 100644 --- a/libs/@blockprotocol/graph/src/codegen/initialize/ensure-output-dir-exists.ts +++ b/libs/@blockprotocol/graph/src/codegen/initialize/ensure-output-dir-exists.ts @@ -1,5 +1,5 @@ -import * as fs from "node:fs/promises"; -import * as path from "node:path"; +import fs from "node:fs/promises"; +import path from "node:path"; import type { InitializeContext } from "../context/initialize.js"; @@ -14,7 +14,7 @@ export const ensureOutputDirExists = async ( // Check the file exists await fs.stat(resolvedTargetDir); context.logTrace(`Target directory ${resolvedTargetDir} already existed`); - } catch (_) { + } catch { context.logTrace( `Target directory ${resolvedTargetDir} didn't exist, creating..`, ); diff --git a/libs/@blockprotocol/graph/src/codegen/postprocess/prepend-imports-and-exports.ts b/libs/@blockprotocol/graph/src/codegen/postprocess/prepend-imports-and-exports.ts index 2f2dc614f47..7971d64adc5 100644 --- a/libs/@blockprotocol/graph/src/codegen/postprocess/prepend-imports-and-exports.ts +++ b/libs/@blockprotocol/graph/src/codegen/postprocess/prepend-imports-and-exports.ts @@ -1,4 +1,4 @@ -import * as path from "node:path"; +import path from "node:path"; import { mustBeDefined } from "../../util/must-be-defined.js"; import type { PostprocessContext } from "../context/postprocess.js"; diff --git a/libs/@blockprotocol/graph/src/codegen/postprocess/write-to-files.ts b/libs/@blockprotocol/graph/src/codegen/postprocess/write-to-files.ts index 36e3ec2b50c..563984cd09d 100644 --- a/libs/@blockprotocol/graph/src/codegen/postprocess/write-to-files.ts +++ b/libs/@blockprotocol/graph/src/codegen/postprocess/write-to-files.ts @@ -1,5 +1,5 @@ import { writeFile } from "node:fs/promises"; -import * as path from "node:path"; +import path from "node:path"; import type { PostprocessContext } from "../context/postprocess.js"; diff --git a/libs/@blockprotocol/graph/src/stdlib/subgraph/builder.ts b/libs/@blockprotocol/graph/src/stdlib/subgraph/builder.ts index a08838d44ed..403345d3e6d 100644 --- a/libs/@blockprotocol/graph/src/stdlib/subgraph/builder.ts +++ b/libs/@blockprotocol/graph/src/stdlib/subgraph/builder.ts @@ -133,13 +133,15 @@ export const buildSubgraph = ( try { const vertexId = getVertexIdForRecordId(subgraph, rootRecordId); subgraph.roots.push(vertexId); - } catch (error) { + } catch { missingRootVertexIds.push(rootRecordId); } } if (missingRootVertexIds.length > 0) { throw new Error( + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-base-to-string `Internal implementation error, could not find VertexId for root RecordId(s): ${missingRootVertexIds.join( ", ", )}`, diff --git a/libs/@blockprotocol/graph/tsconfig.build.json b/libs/@blockprotocol/graph/tsconfig.build.json index 85f5f1162d1..19340e844f2 100644 --- a/libs/@blockprotocol/graph/tsconfig.build.json +++ b/libs/@blockprotocol/graph/tsconfig.build.json @@ -1,5 +1,6 @@ { "extends": "./tsconfig.json", + "exclude": ["eslint.config.js"], "compilerOptions": { "declaration": true, "outDir": "dist", diff --git a/libs/@blockprotocol/graph/tsconfig.json b/libs/@blockprotocol/graph/tsconfig.json index 79cb84da404..ae679cd7b6a 100644 --- a/libs/@blockprotocol/graph/tsconfig.json +++ b/libs/@blockprotocol/graph/tsconfig.json @@ -5,5 +5,5 @@ "module": "NodeNext", "moduleResolution": "NodeNext" }, - "include": ["src"] + "include": ["src", "eslint.config.js"] } diff --git a/libs/@blockprotocol/type-system/typescript/.eslintrc.cjs b/libs/@blockprotocol/type-system/typescript/.eslintrc.cjs deleted file mode 100644 index 568c500804e..00000000000 --- a/libs/@blockprotocol/type-system/typescript/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), -}; diff --git a/libs/@blockprotocol/type-system/typescript/eslint.config.js b/libs/@blockprotocol/type-system/typescript/eslint.config.js new file mode 100644 index 00000000000..3ee9e76d8c7 --- /dev/null +++ b/libs/@blockprotocol/type-system/typescript/eslint.config.js @@ -0,0 +1,6 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { ignores: ["rollup.config.js"] }, +]; diff --git a/libs/@blockprotocol/type-system/typescript/package.json b/libs/@blockprotocol/type-system/typescript/package.json index a0ec27ec541..1a59bc9b8b0 100644 --- a/libs/@blockprotocol/type-system/typescript/package.json +++ b/libs/@blockprotocol/type-system/typescript/package.json @@ -54,7 +54,7 @@ "@blockprotocol/type-system-rs": "0.0.0-private" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@rollup/plugin-node-resolve": "15.3.0", "@rollup/plugin-typescript": "12.1.1", @@ -62,7 +62,7 @@ "@types/node": "22.10.1", "@types/react": "18.2.68", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "react": "18.2.0", "rimraf": "6.0.1", "rollup": "4.28.1", diff --git a/libs/@blockprotocol/type-system/typescript/tsconfig.json b/libs/@blockprotocol/type-system/typescript/tsconfig.json index 5418423ff93..9fc31a8f747 100644 --- a/libs/@blockprotocol/type-system/typescript/tsconfig.json +++ b/libs/@blockprotocol/type-system/typescript/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["scripts", "src", "test"], + "include": ["scripts", "src", "test", "eslint.config.js", "vitest.config.ts"], "exclude": ["dist"], "compilerOptions": { /** diff --git a/libs/@blockprotocol/type-system/typescript/vitest.config.js b/libs/@blockprotocol/type-system/typescript/vitest.config.ts similarity index 91% rename from libs/@blockprotocol/type-system/typescript/vitest.config.js rename to libs/@blockprotocol/type-system/typescript/vitest.config.ts index 206abacceb8..bc34d2671b1 100644 --- a/libs/@blockprotocol/type-system/typescript/vitest.config.js +++ b/libs/@blockprotocol/type-system/typescript/vitest.config.ts @@ -1,4 +1,3 @@ -/// import { defineConfig } from "vitest/config"; // This is super hacky, but basically adds the `?url` suffix to any wasm import @@ -12,14 +11,15 @@ import { defineConfig } from "vitest/config"; const rewriteWasmToUrl = { name: "vite-replace-wasm-import", enforce: "pre", - async load(id) { + // eslint-disable-next-line @typescript-eslint/require-await + async load(id: string) { if (!id.endsWith(".wasm")) { return null; } return `export * from "${id}?url"`; }, -}; +} as const; export default defineConfig({ plugins: [rewriteWasmToUrl], diff --git a/libs/@hashintel/block-design-system/.eslintrc.cjs b/libs/@hashintel/block-design-system/.eslintrc.cjs deleted file mode 100644 index 20fa50cb13a..00000000000 --- a/libs/@hashintel/block-design-system/.eslintrc.cjs +++ /dev/null @@ -1,48 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - extends: [ - "plugin:storybook/recommended", - "@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs", - ], - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 14 */ "@typescript-eslint/no-unsafe-assignment", - ]), - "jsx-a11y/label-has-associated-control": "off", - "import/no-default-export": "error", - "no-restricted-imports": [ - "error", - { - patterns: [ - { - group: ["*/main"], - message: - "Please import from the component file directly, not main.ts", - }, - { - group: ["@mui/material/*"], - message: "Please import from @mui/material instead", - }, - { - group: ["@local/*"], - message: - "You cannot use unpublished local packages in a published package.", - }, - ], - }, - ], - "storybook/no-uninstalled-addons": [ - "error", - { packageJsonLocation: `${__dirname}/package.json` }, - ], - }, - overrides: [ - { - files: ["*.stories.{j,t}s{x,}"], - rules: { - "import/no-default-export": "off", - }, - }, - ], -}; diff --git a/libs/@hashintel/block-design-system/eslint.config.js b/libs/@hashintel/block-design-system/eslint.config.js new file mode 100644 index 00000000000..e2197285d21 --- /dev/null +++ b/libs/@hashintel/block-design-system/eslint.config.js @@ -0,0 +1,47 @@ +import storybook from "eslint-plugin-storybook"; +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...storybook.configs["flat/recommended"], + ...disableRules([ + /* 2022-11-29: 14 */ "@typescript-eslint/no-unsafe-assignment", + ]), + { + rules: { + "jsx-a11y/label-has-associated-control": "off", + "import/no-default-export": "error", + "no-restricted-imports": [ + "error", + { + patterns: [ + { + group: ["*/main"], + message: + "Please import from the component file directly, not main.ts", + }, + { + group: ["@mui/material/*"], + message: "Please import from @mui/material instead", + }, + { + group: ["@local/*"], + message: + "You cannot use unpublished local packages in a published package.", + }, + ], + }, + ], + "storybook/no-uninstalled-addons": [ + "error", + { packageJsonLocation: `${import.meta.dirname}/package.json` }, + ], + }, + }, + { + files: ["**/*.stories.{j,t}s{x,}"], + rules: { + "import/no-default-export": "off", + }, + }, +]; diff --git a/libs/@hashintel/block-design-system/package.json b/libs/@hashintel/block-design-system/package.json index 51498866791..3b756c4f08e 100644 --- a/libs/@hashintel/block-design-system/package.json +++ b/libs/@hashintel/block-design-system/package.json @@ -39,15 +39,15 @@ "devDependencies": { "@emotion/react": "11.13.5", "@emotion/styled": "11.13.5", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@mui/material": "5.16.9", "@mui/system": "5.16.8", "@types/react": "18.2.68", "@types/react-dom": "18.2.25", "@types/react-syntax-highlighter": "15.5.13", - "eslint": "8.57.0", - "eslint-plugin-storybook": "0.8.0", + "eslint": "9.16.0", + "eslint-plugin-storybook": "0.11.1", "react": "18.2.0", "react-dom": "18.2.0", "typescript": "5.6.3" diff --git a/libs/@hashintel/design-system/.eslintrc.cjs b/libs/@hashintel/design-system/.eslintrc.cjs deleted file mode 100644 index fdb0b0c242a..00000000000 --- a/libs/@hashintel/design-system/.eslintrc.cjs +++ /dev/null @@ -1,48 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - extends: [ - "plugin:storybook/recommended", - "@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs", - ], - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 14 */ "@typescript-eslint/no-unsafe-assignment", - ]), - "jsx-a11y/label-has-associated-control": "off", - "import/no-default-export": "error", - "no-restricted-imports": [ - "error", - { - patterns: [ - { - group: ["components", "!./theme/components", "!components/"], - message: - "Please import from the component's file directly, not components.ts", - }, - { - group: ["@mui/material/*"], - message: "Please import from @mui/material instead", - }, - { - group: ["@local/*"], - message: - "You cannot use unpublished local packages in a published package.", - }, - ], - }, - ], - "storybook/no-uninstalled-addons": [ - "error", - { packageJsonLocation: `${__dirname}/package.json` }, - ], - }, - overrides: [ - { - files: ["*.stories.{j,t}s{x,}"], - rules: { - "import/no-default-export": "off", - }, - }, - ], -}; diff --git a/libs/@hashintel/design-system/eslint.config.js b/libs/@hashintel/design-system/eslint.config.js new file mode 100644 index 00000000000..4783568319d --- /dev/null +++ b/libs/@hashintel/design-system/eslint.config.js @@ -0,0 +1,47 @@ +import storybook from "eslint-plugin-storybook"; +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...storybook.configs["flat/recommended"], + ...disableRules([ + /* 2022-11-29: 14 */ "@typescript-eslint/no-unsafe-assignment", + ]), + { + rules: { + "jsx-a11y/label-has-associated-control": "off", + "import/no-default-export": "error", + "no-restricted-imports": [ + "error", + { + patterns: [ + { + group: ["components", "!./theme/components", "!components/"], + message: + "Please import from the component's file directly, not components.ts", + }, + { + group: ["@mui/material/*"], + message: "Please import from @mui/material instead", + }, + { + group: ["@local/*"], + message: + "You cannot use unpublished local packages in a published package.", + }, + ], + }, + ], + "storybook/no-uninstalled-addons": [ + "error", + { packageJsonLocation: `${import.meta.dirname}/package.json` }, + ], + }, + }, + { + files: ["**/*.stories.{j,t}s{x,}"], + rules: { + "import/no-default-export": "off", + }, + }, +]; diff --git a/libs/@hashintel/design-system/package.json b/libs/@hashintel/design-system/package.json index 67e9ba71543..cd2067fee34 100644 --- a/libs/@hashintel/design-system/package.json +++ b/libs/@hashintel/design-system/package.json @@ -54,15 +54,15 @@ "@emotion/cache": "11.13.5", "@emotion/react": "11.13.5", "@emotion/styled": "11.13.5", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@mui/material": "5.16.9", "@mui/system": "5.16.8", "@storybook/react": "7.6.20", "@types/react": "18.2.68", "@types/react-dom": "18.2.25", - "eslint": "8.57.0", - "eslint-plugin-storybook": "0.8.0", + "eslint": "9.16.0", + "eslint-plugin-storybook": "0.11.1", "react": "18.2.0", "react-dom": "18.2.0", "typescript": "5.6.3" diff --git a/libs/@hashintel/design-system/src/autocomplete-dropdown.tsx b/libs/@hashintel/design-system/src/autocomplete-dropdown.tsx index c2223e69811..e6c4c641367 100644 --- a/libs/@hashintel/design-system/src/autocomplete-dropdown.tsx +++ b/libs/@hashintel/design-system/src/autocomplete-dropdown.tsx @@ -25,16 +25,16 @@ export const AutocompleteDropdown = ({ pointerEvents: "none", borderRadius: `${textFieldBorderRadius}px`, [`${popperPlacementSelectors.top} &`]: { - bottom: -inputHeight, + bottom: -Number(inputHeight), }, [`${popperPlacementSelectors.topStart} &`]: { - bottom: -inputHeight, + bottom: -Number(inputHeight), }, [`${popperPlacementSelectors.bottom} &`]: { - top: -inputHeight, + top: -Number(inputHeight), }, [`${popperPlacementSelectors.bottomStart} &`]: { - top: -inputHeight, + top: -Number(inputHeight), }, })} aria-hidden diff --git a/libs/@hashintel/design-system/src/popper-placement-modifier.ts b/libs/@hashintel/design-system/src/popper-placement-modifier.ts index 883bab5df39..76418422ba6 100644 --- a/libs/@hashintel/design-system/src/popper-placement-modifier.ts +++ b/libs/@hashintel/design-system/src/popper-placement-modifier.ts @@ -33,6 +33,7 @@ export const addPopperPositionClassPopperModifier: NonNullable< // This allows a consumer to be notified when the placement has changed const { update } = options as { update?: unknown }; if (typeof update === "function") { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call update(state.placement); } }, diff --git a/libs/@hashintel/query-editor/.eslintrc.cjs b/libs/@hashintel/query-editor/.eslintrc.cjs deleted file mode 100644 index f51a4752b12..00000000000 --- a/libs/@hashintel/query-editor/.eslintrc.cjs +++ /dev/null @@ -1,43 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - extends: [ - "plugin:storybook/recommended", - "@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs", - ], - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 14 */ "@typescript-eslint/no-unsafe-assignment", - ]), - "jsx-a11y/label-has-associated-control": "off", - "import/no-default-export": "error", - "no-restricted-imports": [ - "error", - { - patterns: [ - { - group: ["@mui/material/*"], - message: "Please import from @mui/material instead", - }, - { - group: ["@local/*"], - message: - "You cannot use unpublished local packages in a published package.", - }, - ], - }, - ], - "storybook/no-uninstalled-addons": [ - "error", - { packageJsonLocation: `${__dirname}/package.json` }, - ], - }, - overrides: [ - { - files: ["*.stories.{j,t}s{x,}"], - rules: { - "import/no-default-export": "off", - }, - }, - ], -}; diff --git a/libs/@hashintel/query-editor/eslint.config.js b/libs/@hashintel/query-editor/eslint.config.js new file mode 100644 index 00000000000..d350c93c502 --- /dev/null +++ b/libs/@hashintel/query-editor/eslint.config.js @@ -0,0 +1,42 @@ +import storybook from "eslint-plugin-storybook"; +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...storybook.configs["flat/recommended"], + ...disableRules([ + /* 2022-11-29: 14 */ "@typescript-eslint/no-unsafe-assignment", + ]), + { + rules: { + "jsx-a11y/label-has-associated-control": "off", + "import/no-default-export": "error", + "no-restricted-imports": [ + "error", + { + patterns: [ + { + group: ["@mui/material/*"], + message: "Please import from @mui/material instead", + }, + { + group: ["@local/*"], + message: + "You cannot use unpublished local packages in a published package.", + }, + ], + }, + ], + "storybook/no-uninstalled-addons": [ + "error", + { packageJsonLocation: `${import.meta.dirname}/package.json` }, + ], + }, + }, + { + files: ["**/*.stories.{j,t}s{x,}"], + rules: { + "import/no-default-export": "off", + }, + }, +]; diff --git a/libs/@hashintel/query-editor/package.json b/libs/@hashintel/query-editor/package.json index c596b0243a9..aa98894d017 100644 --- a/libs/@hashintel/query-editor/package.json +++ b/libs/@hashintel/query-editor/package.json @@ -28,10 +28,11 @@ "clsx": "1.2.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@mui/material": "5.16.9", "@mui/system": "5.16.8", - "eslint": "8.57.0", + "eslint": "9.16.0", + "eslint-plugin-storybook": "0.11.1", "react": "18.2.0", "react-dom": "18.2.0", "react-hook-form": "7.54.0", diff --git a/libs/@hashintel/type-editor/.eslintrc.cjs b/libs/@hashintel/type-editor/.eslintrc.cjs deleted file mode 100644 index f51a4752b12..00000000000 --- a/libs/@hashintel/type-editor/.eslintrc.cjs +++ /dev/null @@ -1,43 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - extends: [ - "plugin:storybook/recommended", - "@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs", - ], - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 14 */ "@typescript-eslint/no-unsafe-assignment", - ]), - "jsx-a11y/label-has-associated-control": "off", - "import/no-default-export": "error", - "no-restricted-imports": [ - "error", - { - patterns: [ - { - group: ["@mui/material/*"], - message: "Please import from @mui/material instead", - }, - { - group: ["@local/*"], - message: - "You cannot use unpublished local packages in a published package.", - }, - ], - }, - ], - "storybook/no-uninstalled-addons": [ - "error", - { packageJsonLocation: `${__dirname}/package.json` }, - ], - }, - overrides: [ - { - files: ["*.stories.{j,t}s{x,}"], - rules: { - "import/no-default-export": "off", - }, - }, - ], -}; diff --git a/libs/@hashintel/type-editor/eslint.config.js b/libs/@hashintel/type-editor/eslint.config.js new file mode 100644 index 00000000000..d350c93c502 --- /dev/null +++ b/libs/@hashintel/type-editor/eslint.config.js @@ -0,0 +1,42 @@ +import storybook from "eslint-plugin-storybook"; +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...storybook.configs["flat/recommended"], + ...disableRules([ + /* 2022-11-29: 14 */ "@typescript-eslint/no-unsafe-assignment", + ]), + { + rules: { + "jsx-a11y/label-has-associated-control": "off", + "import/no-default-export": "error", + "no-restricted-imports": [ + "error", + { + patterns: [ + { + group: ["@mui/material/*"], + message: "Please import from @mui/material instead", + }, + { + group: ["@local/*"], + message: + "You cannot use unpublished local packages in a published package.", + }, + ], + }, + ], + "storybook/no-uninstalled-addons": [ + "error", + { packageJsonLocation: `${import.meta.dirname}/package.json` }, + ], + }, + }, + { + files: ["**/*.stories.{j,t}s{x,}"], + rules: { + "import/no-default-export": "off", + }, + }, +]; diff --git a/libs/@hashintel/type-editor/package.json b/libs/@hashintel/type-editor/package.json index b77d98d97b9..6afc8de43b0 100644 --- a/libs/@hashintel/type-editor/package.json +++ b/libs/@hashintel/type-editor/package.json @@ -34,12 +34,13 @@ "setimmediate": "1.0.5" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@mui/material": "5.16.9", "@mui/system": "5.16.8", "@types/lodash.memoize": "4.1.9", "@types/lodash.uniqueid": "4.0.9", - "eslint": "8.57.0", + "eslint": "9.16.0", + "eslint-plugin-storybook": "0.11.1", "react": "18.2.0", "react-dom": "18.2.0", "react-hook-form": "7.54.0", diff --git a/libs/@hashintel/type-editor/src/entity-type-editor.tsx b/libs/@hashintel/type-editor/src/entity-type-editor.tsx index 1e8fd1a4939..84c333c8707 100644 --- a/libs/@hashintel/type-editor/src/entity-type-editor.tsx +++ b/libs/@hashintel/type-editor/src/entity-type-editor.tsx @@ -1,4 +1,5 @@ /* eslint-disable import/first */ +// eslint-disable-next-line @typescript-eslint/no-require-imports require("setimmediate"); import type { diff --git a/libs/@hashintel/type-editor/src/entity-type-editor/shared/type-menu-cell.tsx b/libs/@hashintel/type-editor/src/entity-type-editor/shared/type-menu-cell.tsx index 04b1846179e..dc888f8498b 100644 --- a/libs/@hashintel/type-editor/src/entity-type-editor/shared/type-menu-cell.tsx +++ b/libs/@hashintel/type-editor/src/entity-type-editor/shared/type-menu-cell.tsx @@ -122,7 +122,7 @@ export const TypeMenuCell = ({ event.preventDefault(); setHasCopied(true); - return navigator.clipboard.writeText(typeId); + void navigator.clipboard.writeText(typeId); }, [typeId, setHasCopied], ); diff --git a/libs/@local/advanced-types/.eslintrc.cjs b/libs/@local/advanced-types/.eslintrc.cjs deleted file mode 100644 index 35a9798690a..00000000000 --- a/libs/@local/advanced-types/.eslintrc.cjs +++ /dev/null @@ -1,14 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 6 */ "@typescript-eslint/no-unsafe-argument", - /* 2022-11-29: 15 */ "@typescript-eslint/no-unsafe-assignment", - /* 2022-11-29: 5 */ "@typescript-eslint/no-unsafe-call", - /* 2022-11-29: 7 */ "@typescript-eslint/no-unsafe-member-access", - /* 2022-11-29: 7 */ "@typescript-eslint/no-unsafe-return", - ]), - "import/no-extraneous-dependencies": ["error", { devDependencies: true }], - }, -}; diff --git a/libs/@local/advanced-types/eslint.config.js b/libs/@local/advanced-types/eslint.config.js new file mode 100644 index 00000000000..37363e709d2 --- /dev/null +++ b/libs/@local/advanced-types/eslint.config.js @@ -0,0 +1,17 @@ +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...disableRules([ + /* 2022-11-29: 6 */ "@typescript-eslint/no-unsafe-argument", + /* 2022-11-29: 15 */ "@typescript-eslint/no-unsafe-assignment", + /* 2022-11-29: 5 */ "@typescript-eslint/no-unsafe-call", + /* 2022-11-29: 7 */ "@typescript-eslint/no-unsafe-member-access", + /* 2022-11-29: 7 */ "@typescript-eslint/no-unsafe-return", + ]), + { + rules: { + "import/no-extraneous-dependencies": ["error", { devDependencies: true }], + }, + }, +]; diff --git a/libs/@local/advanced-types/package.json b/libs/@local/advanced-types/package.json index 80fd7ca2bb7..25ee10f72c6 100644 --- a/libs/@local/advanced-types/package.json +++ b/libs/@local/advanced-types/package.json @@ -22,9 +22,9 @@ "lint:tsc": "tsc --noEmit" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", - "eslint": "8.57.0", + "eslint": "9.16.0", "react": "18.2.0", "rimraf": "6.0.1", "typescript": "5.6.3" diff --git a/libs/@local/advanced-types/tsconfig.build.json b/libs/@local/advanced-types/tsconfig.build.json index 85f5f1162d1..19340e844f2 100644 --- a/libs/@local/advanced-types/tsconfig.build.json +++ b/libs/@local/advanced-types/tsconfig.build.json @@ -1,5 +1,6 @@ { "extends": "./tsconfig.json", + "exclude": ["eslint.config.js"], "compilerOptions": { "declaration": true, "outDir": "dist", diff --git a/libs/@local/advanced-types/tsconfig.json b/libs/@local/advanced-types/tsconfig.json index 08fd9785690..e9e22172e63 100644 --- a/libs/@local/advanced-types/tsconfig.json +++ b/libs/@local/advanced-types/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["./src/", "codegen.config.ts"], + "include": ["./src/", "codegen.config.ts", "eslint.config.js"], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" diff --git a/libs/@local/eslint-config/.eslintrc.cjs b/libs/@local/eslint-config/.eslintrc.cjs deleted file mode 100644 index 4c445f95541..00000000000 --- a/libs/@local/eslint-config/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("./generate-workspace-config.cjs")(__dirname), - rules: { - "global-require": "off", - }, -}; diff --git a/libs/@local/eslint-config/generate-block-config.cjs b/libs/@local/eslint-config/generate-block-config.cjs deleted file mode 100644 index c38456ae84f..00000000000 --- a/libs/@local/eslint-config/generate-block-config.cjs +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @param {string} workspaceDirPath - * @returns {import("eslint").Linter.Config} - */ -module.exports = (workspaceDirPath) => ({ - root: true, - extends: [ - "@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs", - "@local/eslint-config/legacy-block-eslintrc-to-refactor.cjs", - ], - ignorePatterns: require("./generate-ignore-patterns.cjs")(workspaceDirPath), - parserOptions: { - tsconfigRootDir: workspaceDirPath, - project: `${workspaceDirPath}/tsconfig.json`, - }, - overrides: [ - { - files: ["**/src/types/**"], - rules: { - "@typescript-eslint/ban-types": [ - "error", - { - types: { - /** - * @todo update the codegen utility in @blockprotocol/graph to generate Object as Record, not {} - */ - "{}": false, - }, - extendDefaults: true, - }, - ], - }, - }, - ], -}); diff --git a/libs/@local/eslint-config/generate-ignore-patterns.cjs b/libs/@local/eslint-config/generate-ignore-patterns.cjs deleted file mode 100644 index f5acc672f9d..00000000000 --- a/libs/@local/eslint-config/generate-ignore-patterns.cjs +++ /dev/null @@ -1,181 +0,0 @@ -const path = require("node:path"); -const fs = require("node:fs"); - -const monorepoRoot = path.resolve(__dirname, "../../.."); - -// Check if the line's glob affects this workspace e.g. -// say the path to this workspace is `path/to/workspace/foo` -// - if the line is `path/to/**/bar` -// then we want patterns equivalent to `**/bar` -// as `path/to/**` overlaps the current path -// - if the line is `**/bar` -// then we want patterns equivalent to `**/bar` -// as `**` overlaps the current path -// - if the line is `path/to/**/foo/bar**` -// then we want patterns equivalent to [`bar**`, `**/foo/bar/**`] -// as both `path/to/**/foo` and `path/to/**` overlaps the current path -/** - * Given a path from a .gitignore in a parent directory, this returns the equivalent paths if written in the current - * directory - * - * @param {string} pattern - * @param {string} workspaceDirPrefix - * @returns {string[]} - */ -const getEquivalentIgnorePaths = (pattern, workspaceDirPrefix) => { - // We want to traverse the components of the workspaceDirPrefix, and consume wild cards whenever they match. - // On some wildcards there may be a branch of equivalent paths, e.g. for a "**" wildcard - /** - * @param {string[]} pathComponents - * @param {string[]} patternComponents - * @returns {Set} - */ - const getEquivalentPaths = (pathComponents, patternComponents) => { - const equivalentPaths = new Set(); - - let i = 0; - for (; i < patternComponents.length; i++) { - const patternComponent = patternComponents[i]; - const pathComponent = pathComponents[i]; - - // This could happen if the pattern started or ended with `/` - if (patternComponent === "") { - break; - } - - if (!pathComponent) { - // We have reached the end of the path components - equivalentPaths.add(patternComponents.slice(i).join("/")); - break; - } - - if (patternComponent === "**") { - // We can choose to use ** once, or multiple times, or never - - // we use and consume **, so we advance both sets of components - for (const equivalentPath of getEquivalentPaths( - pathComponents.slice(i + 1), - patternComponents.slice(i + 1), - )) { - equivalentPaths.add(equivalentPath); - } - // we use ** but don't consume it, so we advance the path components by one but leave the pattern as is - for (const equivalentPath of getEquivalentPaths( - pathComponents.slice(i + 1), - patternComponents.slice(i), - )) { - equivalentPaths.add(equivalentPath); - } - - // we don't use but consume **, so we advance the pattern components by one but leave the path as is - for (const equivalentPath of getEquivalentPaths( - pathComponents.slice(i), - patternComponents.slice(i + 1), - )) { - equivalentPaths.add(equivalentPath); - } - } else if (patternComponent === "*") { - // We must consume "*" if it is present - for (const equivalentPath of getEquivalentPaths( - pathComponents.slice(i + 1), - patternComponents.slice(i + 1), - )) { - equivalentPaths.add(equivalentPath); - } - } - } - - return equivalentPaths; - }; - - return [ - ...getEquivalentPaths(workspaceDirPrefix.split("/"), pattern.split("/")), - ]; -}; - -/** - * ESlint requires .eslintignore file to be placed next to .eslintrc.cjs file. - * Because .*ignore files are not composable, we cannot import or otherwise reuse - * a top-level .eslintignore. To avoid repetition and to maintain a coherent behavior - * of ESLint CLI and IDE extensions, we generate ignore patterns for each workspace - * based from .prettierignore. This is done via ignorePatterns option in ESLint config. - * - * @param {string} workspaceDirPath - * @returns {string[]} - */ -module.exports = (workspaceDirPath) => { - const [, match] = - fs - .readFileSync(`${monorepoRoot}/.prettierignore`, "utf8") - .match(/Same as in .gitignore([^\0]*?)$/) ?? []; - - if (!match) { - throw new Error( - "Could not find shared .prettierignore patterns. Please update .prettierignore or the regexp in this file.", - ); - } - - const workspaceDirPrefix = `/${path - .relative(monorepoRoot, workspaceDirPath) - .replace(/\\/g, "/")}/`; - - const sharedPatternsFromPrettierIgnore = match - .split("\n") - .map((line) => { - // Ignore empty lines and comments - if (!line || line.startsWith("#")) { - return []; - } - - if (line.includes("**")) { - // remove the leading "/" from the workspaceDirPrefix as we need to check it as a relative path - const relativePrefix = workspaceDirPrefix.slice(1); - - const overlappingPatterns = getEquivalentIgnorePaths( - line.startsWith("/") ? line.slice(1) : line, - relativePrefix, - ); - - if (overlappingPatterns.length > 0) { - return overlappingPatterns; - } - } - - // Ignore patterns specific to other workspaces - if ( - line.includes("/") && - !line.match(/^[^/]+\/$/) && - !line.startsWith(workspaceDirPrefix) && - !line.startsWith("**") - ) { - return []; - } - - // Remove workspace-specific prefix (path/to/workspace/foo/**/bar => foo/**/bar) - if (line.startsWith(workspaceDirPrefix)) { - return [line.replace(workspaceDirPrefix, "")]; - } - - // Keep other patterns as is - return [line]; - }) - .flat(); - - return [ - // Ignore all files (but still allow sub-folder scanning) - "*", - "!*/", - - // Allow certain file types - "!*.cjs", - "!*.js", - "!*.json", - "!*.jsx", - "!*.mjs", - "!*.ts", - "!*.tsx", - - // Add patterns extracted from .prettierignore - ...sharedPatternsFromPrettierIgnore, - ]; -}; diff --git a/libs/@local/eslint-config/generate-workspace-config.cjs b/libs/@local/eslint-config/generate-workspace-config.cjs deleted file mode 100644 index 399e1d1446e..00000000000 --- a/libs/@local/eslint-config/generate-workspace-config.cjs +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @param {string} workspaceDirPath - * @returns {import("eslint").Linter.Config} - */ -module.exports = (workspaceDirPath) => ({ - root: true, - extends: ["@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs"], - ignorePatterns: require("./generate-ignore-patterns.cjs")(workspaceDirPath), - parserOptions: { - tsconfigRootDir: workspaceDirPath, - project: `${workspaceDirPath}/tsconfig.json`, - }, - settings: { - "import/resolver": { - typescript: { - alwaysTryTypes: true, - project: `${workspaceDirPath}}/tsconfig.json`, - }, - }, - }, -}); diff --git a/libs/@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs b/libs/@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs deleted file mode 100644 index 6c692a3b853..00000000000 --- a/libs/@local/eslint-config/legacy-base-eslintrc-to-refactor.cjs +++ /dev/null @@ -1,373 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - // this is the highest config lower ones will automatically extend - parser: "@typescript-eslint/parser", - plugins: [ - "@typescript-eslint", - "canonical", - "react-hooks", - "simple-import-sort", - "unicorn", - ], - extends: [ - "airbnb", - "prettier", - // mutes eslint rules conflicting w/ prettier (requires eslint-config-prettier) - ], - globals: { - NodeJS: true, - FixMeLater: "readonly", - globalThis: "readonly", - }, - env: { - browser: true, - node: true, - }, - reportUnusedDisableDirectives: true, - rules: { - "canonical/filename-no-index": "error", - "@typescript-eslint/consistent-type-imports": "error", - // overridden airbnb rules (if you wish to add to this list, please outline your reasoning here: https://www.notion.so/hashintel/HASH-dev-eslint-configuration-60c52c127d13478fbce6bb5579a6b7be) - "no-undef-init": "off", - "no-underscore-dangle": "off", - "no-nested-ternary": "off", - "no-restricted-syntax": [ - "error", - { - selector: - "TSTypeReference[typeName.name=/^(Plugin|PluginKey)$/]:not([typeParameters])", - message: "Please provide a generic to avoid implicit `any`", - }, - { - selector: - "TSTypeReference[typeName.name=/^(Plugin|PluginKey)$/][typeParameters.params.0.type=TSAnyKeyword]", - message: "Please replace `any` with a specific type", - }, - { - selector: - "NewExpression[callee.name=/^(Plugin|PluginKey)$/]:not([typeParameters])", - message: "Please provide a generic to avoid implicit `any`", - }, - { - selector: - "NewExpression[callee.name=/^(Plugin|PluginKey)$/][typeParameters.params.0.type=TSAnyKeyword]", - message: "Please replace `any` with a specific type", - }, - ], - camelcase: "off", - "default-param-last": "off", // using @typescript-eslint/default-param-last instead - "import/no-cycle": "error", - "import/named": "off", // redundant for TypeScript code, leads to false positives with @blockprotocol/type-system - "import/prefer-default-export": "off", - "no-await-in-loop": "off", - "no-console": "error", - "no-dupe-class-members": "off", - "import/no-unresolved": [ - 2, - { - // graph uses 'exports' field in package.json https://github.com/import-js/eslint-plugin-import/issues/1810 - ignore: [ - "^@apps/", - "^@blockprotocol/graph", - "^@blockprotocol/hook", - "^@blockprotocol/service", - "^@blockprotocol/type-system", - "^@hashintel/", - "^@local/", - ], - }, - ], - "react/prop-types": "off", - // because we are using typescript this is redundant - "jsx-a11y/anchor-is-valid": "off", - // because we use next.js empty anchor tags should be used when using the Link component - "react/jsx-filename-extension": [ - 2, - { - extensions: [".js", ".jsx", ".ts", ".tsx"], - }, - ], - "react/jsx-props-no-spreading": "off", - "no-void": [ - "error", - { - allowAsStatement: true, - }, - ], - "no-continue": "off", - "react/react-in-jsx-scope": "off", - "no-return-await": "off", - "max-classes-per-file": "off", - "lines-between-class-members": [ - "error", - "always", - { - exceptAfterSingleLine: true, - }, - ], - "consistent-return": "off", - "default-case": "off", - "class-methods-use-this": "off", - "react/no-unescapted-entities": "off", - "jsx-a11y/no-autofocus": "off", - "no-plusplus": "off", - "prefer-destructuring": "off", - "no-else-return": "off", - "arrow-body-style": "off", - "react/no-unescaped-entities": "off", - // Other rule changes - "react-hooks/rules-of-hooks": "error", - "react-hooks/exhaustive-deps": [ - "error", - { - additionalHooks: "^(useModal|useUserGatedEffect)$", - }, - ], - "react/function-component-definition": [ - "error", - { - namedComponents: "arrow-function", - unnamedComponents: "arrow-function", - }, - ], - "react/jsx-key": "error", - "react/jsx-no-useless-fragment": "error", - "react/self-closing-comp": "error", - "no-restricted-imports": [ - "error", - { - paths: [ - { - name: "react", - importNames: ["FC", "VFC", "VoidFunctionComponent"], - message: "Please use FunctionComponent instead", - }, - { - name: "@testing-library/react", - importNames: ["render"], - message: "Please use ./src/tests/testUtils.tsx#render instead", - }, - { - name: "@mui/material", - importNames: ["Link"], - message: - "Please use the custom src/components/Link component instead to ensure Next.js and MUI compatibility.", - }, - { - name: "@mui/material/Link", - message: - "Please use the custom src/components/Link component instead to ensure Next.js and MUI compatibility.", - }, - { - name: "next", - importNames: ["Link"], - message: - "Please use the custom src/components/Link component instead to ensure Next.js and MUI compatibility.", - }, - { - name: "next/link", - message: - "Please use the custom src/components/Link component instead to ensure Next.js and MUI compatibility.", - }, - { - name: "@mui/material", - importNames: ["Button"], - message: - "Please use the custom wrapper component in src/component instead.", - }, - { - name: "@mui/material/Button", - importNames: ["default"], - message: - "Please use the custom src/components/Button component instead.", - }, - ], - patterns: [ - { - group: [ - "@hashintel/design-system/*", - "!@hashintel/design-system/theme", - "!@hashintel/design-system/constants", - "!@hashintel/design-system/palettes", - ], - message: "Please import from @hashintel/design-system instead.", - }, - ], - }, - ], - "react/require-default-props": "off", - "no-shadow": "off", - "@typescript-eslint/default-param-last": "error", - // see https://github.com/typescript-eslint/typescript-eslint/issues/2483 - "@typescript-eslint/no-shadow": "error", - "no-use-before-define": "off", - "@typescript-eslint/no-use-before-define": ["error"], - "no-redeclare": "off", - "@typescript-eslint/no-redeclare": ["error"], - - eqeqeq: [ - "error", - "always", - { - null: "ignore", - }, - ], - "id-length": [ - "error", - { - min: 2, - exceptions: ["_", "x", "y", "z", "a", "b", "i"], - properties: "never", - }, - ], - "no-unused-expressions": "error", - curly: ["error", "all"], - "import/extensions": [ - "error", - "ignorePackages", - { - js: "never", - jsx: "never", - ts: "never", - tsx: "never", - }, - ], - "no-useless-constructor": "off", - "@typescript-eslint/no-useless-constructor": ["error"], - "@typescript-eslint/ban-ts-comment": [ - "error", - { - "ts-expect-error": "allow-with-description", - minimumDescriptionLength: 10, - }, - ], - "no-empty-function": "off", - "no-param-reassign": [ - "error", - { - props: true, - ignorePropertyModificationsForRegex: ["^draft"], - ignorePropertyModificationsFor: [ - "acc", - "accumulator", - "e", - "ctx", - "context", - "req", - "request", - "res", - "response", - "$scope", - "staticContext", - ], - }, - ], - "simple-import-sort/exports": "error", - "simple-import-sort/imports": "error", - "unicorn/filename-case": "error", - "unicorn/import-style": [ - "error", - { - styles: { - react: { named: true }, - "react-dom": { named: true }, - }, - }, - ], - "unicorn/no-array-for-each": "error", - "unicorn/prefer-node-protocol": "error", - }, - settings: { - "import/resolver": { - node: { - extensions: [".js", ".jsx", ".ts", ".tsx"], - }, - }, - }, - overrides: [ - { - files: ["**/*.{c,m,}js"], - parser: "@babel/eslint-parser", // disables typescript rules - parserOptions: { - requireConfigFile: false, - extraFileExtensions: [".cjs"], - babelOptions: { - presets: ["@babel/preset-react"], // allows jsx - }, - }, - }, - { - files: [ - "**/tests/**", - "**/__mocks__/**", - "**/testUtils/**", - "*.test.{j,t}s{x,}", - ], - env: { - node: true, - }, - rules: { - "import/no-extraneous-dependencies": [ - "error", - { devDependencies: true }, - ], - }, - }, - { - files: [".storybook/*", "**/*.stories.{j,t}s{x,}"], - rules: { - "import/no-extraneous-dependencies": [ - "error", - { devDependencies: true }, - ], - }, - }, - { - files: ["*.config.{c,m,}{j,t}s", "*.d.ts", "*rc.{c,m,}js"], - rules: { - "global-require": "off", - "import/no-extraneous-dependencies": [ - "error", - { devDependencies: true }, - ], - }, - }, - { - files: ["*.ts", "*.tsx"], - extends: [ - "plugin:@typescript-eslint/recommended-requiring-type-checking", - ], - rules: { - "no-unused-vars": "off", - "@typescript-eslint/prefer-nullish-coalescing": [ - "error", - { - ignoreMixedLogicalExpressions: true, - }, - ], - "@typescript-eslint/no-meaningless-void-operator": "error", - "@typescript-eslint/no-misused-promises": [ - "error", // https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-misused-promises.md#checksvoidreturn - { checksVoidReturn: { attributes: false, properties: false } }, - ], - "no-constant-condition": "off", // replaced by @typescript-eslint/no-unnecessary-condition - "@typescript-eslint/no-unnecessary-condition": "error", - "@typescript-eslint/no-unused-vars": [ - "error", - { - args: "all", // check all args, not just those after-used - argsIgnorePattern: "^_+", - varsIgnorePattern: "^_+", - }, - ], - }, - }, - { - files: ["**/scripts/**"], - rules: { - "no-console": "off", - }, - }, - ], -}; diff --git a/libs/@local/eslint-config/legacy-block-eslintrc-to-refactor.cjs b/libs/@local/eslint-config/legacy-block-eslintrc-to-refactor.cjs deleted file mode 100644 index 98d47913605..00000000000 --- a/libs/@local/eslint-config/legacy-block-eslintrc-to-refactor.cjs +++ /dev/null @@ -1,15 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - plugins: ["@typescript-eslint", "react-hooks", "react", "unicorn"], - rules: { - curly: ["error", "multi-line"], - "import/no-extraneous-dependencies": ["error", { devDependencies: true }], - "jsx-a11y/label-has-associated-control": "off", - "react-hooks/exhaustive-deps": "error", - "react-hooks/rules-of-hooks": "error", - "react/jsx-key": "error", - "react/jsx-no-useless-fragment": "error", - "react/no-danger": "error", - "react/self-closing-comp": "error", - }, -}; diff --git a/libs/@local/eslint-config/package.json b/libs/@local/eslint-config/package.json deleted file mode 100644 index 9168dc73747..00000000000 --- a/libs/@local/eslint-config/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "@local/eslint-config", - "version": "0.0.0-private", - "private": true, - "scripts": { - "fix:eslint": "eslint --fix .", - "lint:eslint": "eslint --report-unused-disable-directives .", - "lint:tsc": "tsc --noEmit" - }, - "dependencies": { - "@babel/core": "7.26.0", - "@babel/eslint-parser": "7.25.9", - "@babel/preset-react": "7.26.3", - "@typescript-eslint/eslint-plugin": "7.2.0", - "@typescript-eslint/parser": "7.2.0", - "eslint": "8.57.0", - "eslint-config-airbnb": "19.0.4", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-canonical": "4.18.0", - "eslint-plugin-import": "2.29.1", - "eslint-plugin-jsx-a11y": "6.8.0", - "eslint-plugin-react": "7.34.1", - "eslint-plugin-react-hooks": "4.6.0", - "eslint-plugin-simple-import-sort": "12.0.0", - "eslint-plugin-typescript-sort-keys": "3.2.0", - "eslint-plugin-unicorn": "51.0.1", - "typescript": "5.6.3" - }, - "devDependencies": { - "@local/tsconfig": "0.0.0-private", - "@types/eslint": "8.56.12", - "@types/node": "22.10.1", - "eslint": "8.57.0", - "typescript": "5.6.3" - } -} diff --git a/libs/@local/eslint-config/temporarily-disable-rules.cjs b/libs/@local/eslint-config/temporarily-disable-rules.cjs deleted file mode 100644 index 9cd480bc28d..00000000000 --- a/libs/@local/eslint-config/temporarily-disable-rules.cjs +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @param {string[]} ruleNames - * @returns {import("eslint").Linter.RulesRecord} - * @see https://github.com/hashintel/hash/pull/1384 - */ -module.exports = (ruleNames) => { - /** @type {import("eslint").Linter.RulesRecord} */ - const result = {}; - - if (process.env.CHECK_TEMPORARILY_DISABLED_RULES === "true") { - return result; - } - - for (const ruleName of ruleNames) { - result[ruleName] = "off"; - } - return result; -}; diff --git a/libs/@local/eslint-config/tsconfig.json b/libs/@local/eslint-config/tsconfig.json deleted file mode 100644 index b2aa2356617..00000000000 --- a/libs/@local/eslint-config/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json" -} diff --git a/libs/@local/eslint-config/LICENSE.md b/libs/@local/eslint/LICENSE.md similarity index 100% rename from libs/@local/eslint-config/LICENSE.md rename to libs/@local/eslint/LICENSE.md diff --git a/libs/@local/eslint/eslint.config.js b/libs/@local/eslint/eslint.config.js new file mode 100644 index 00000000000..6aff3b50988 --- /dev/null +++ b/libs/@local/eslint/eslint.config.js @@ -0,0 +1,3 @@ +import { create } from "@local/eslint"; + +export default create(import.meta.dirname); diff --git a/libs/@local/eslint/package.json b/libs/@local/eslint/package.json new file mode 100644 index 00000000000..51438dd5584 --- /dev/null +++ b/libs/@local/eslint/package.json @@ -0,0 +1,50 @@ +{ + "name": "@local/eslint", + "version": "0.0.0-private", + "private": true, + "description": "Shared ESLint configuration", + "type": "module", + "exports": { + ".": { + "default": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./deprecated": { + "default": "./dist/deprecated/index.js", + "types": "./dist/deprecated/index.d.ts" + } + }, + "scripts": { + "build": "rimraf dist && tsc --build tsconfig.build.json", + "fix:eslint": "eslint --report-unused-disable-directives --flag unstable_ts_config --fix .", + "lint:eslint": "eslint --report-unused-disable-directives --flag unstable_ts_config ." + }, + "dependencies": { + "@babel/core": "7.26.0", + "@babel/eslint-parser": "7.25.9", + "@eslint/compat": "1.2.4", + "@eslint/eslintrc": "3.2.0", + "effect": "3.11.3", + "eslint": "9.16.0", + "eslint-config-airbnb": "19.0.4", + "eslint-config-flat-gitignore": "0.3.0", + "eslint-config-prettier": "9.1.0", + "eslint-config-sheriff": "25.3.0", + "eslint-import-resolver-node": "0.3.9", + "eslint-import-resolver-typescript": "3.7.0", + "eslint-plugin-canonical": "5.0.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-react-hooks": "5.1.0", + "eslint-plugin-storybook": "0.11.1", + "eslint-unicorn": "55.0.0", + "globals": "15.13.0" + }, + "devDependencies": { + "@local/tsconfig": "0.0.0-private", + "@types/babel__core": "^7", + "@types/eslint__eslintrc": "2.1.2", + "@types/node": "22.10.1", + "rimraf": "6.0.1", + "typescript": "5.6.3" + } +} diff --git a/libs/@local/eslint/src/builtIn.ts b/libs/@local/eslint/src/builtIn.ts new file mode 100644 index 00000000000..01b0ff48bf9 --- /dev/null +++ b/libs/@local/eslint/src/builtIn.ts @@ -0,0 +1,95 @@ +import { Array as ReadonlyArray, Option, pipe, Predicate } from "effect"; +import type { PartialDeep } from "type-fest"; + +import type { NoRestrictedImportsRule } from "./types.js"; +import { defineConfig, type ESConfig } from "./utils.js"; + +import type { Options } from "./index.js"; + +const mergeRestrictedImports = ( + current: NoRestrictedImportsRule, + override: NoRestrictedImportsRule, +): NoRestrictedImportsRule => ({ + paths: [...current.paths, ...override.paths], + patterns: [...current.patterns, ...override.patterns], +}); + +const noRestrictedImports = ( + config: readonly ESConfig[], + overrides: () => NoRestrictedImportsRule[], +): readonly ESConfig[] => { + // get the latest current `no-restricted-imports` rule value and merge with the + // overrides + const candidates = pipe( + config, + ReadonlyArray.map((entry) => entry.rules?.["no-restricted-imports"]), + ReadonlyArray.filter(Predicate.isNotUndefined), + ReadonlyArray.filterMap((entry) => + Array.isArray(entry) && entry.length === 2 + ? Option.some(entry[1]) + : Option.none(), + ), + ); + + const current = candidates.at(-1); + + // the value should be a dictionary with `paths` and `patterns` keys + if (!Predicate.isRecord(current) || Predicate.hasProperty(current, "name")) { + throw new Error( + "expected no-restricted-imports to follow the `paths` and `patterns` structure", + ); + } + + if (current.patterns?.some((pattern) => typeof pattern === "string")) { + throw new Error("expected patterns to be an array of objects"); + } + + const currentRule = current as NoRestrictedImportsRule; + + return defineConfig([ + { + rules: { + "no-restricted-imports": [ + "error", + overrides().reduce(mergeRestrictedImports, currentRule), + ], + }, + } satisfies ESConfig, + ]); +}; + +export const builtIn = + (options: PartialDeep) => + (config: readonly ESConfig[]): readonly ESConfig[] => + defineConfig([ + ...config, + { + rules: { + // Reason: Nesting ternary expressions can make code more difficult to understand. + // While true they are a staple of JS and too integrated into our codebase to remove. + // furthermore, `prettier` removes this concern by formatting them in a way that is easy to read. + "no-nested-ternary": "off", + // We always prefer arrow functions over function declarations. + // Generators cannot be written as arrow functions, therefore are + // allowed to be anonymous to accommodate effect. + "func-names": ["error", "always", { generators: "never" }], + // This is the same as sheriff's rule but allows for drafts to be modified + "no-param-reassign": [ + "error", + { + props: true, + ignorePropertyModificationsForRegex: + options.mutableParametersRegex?.() ?? [], + }, + ], + // Clashes with `@typescript-eslint/no-floating-promises` + "no-void": [ + "error", + { + allowAsStatement: true, + }, + ], + }, + }, + ...noRestrictedImports(config, options.noRestrictedImports ?? (() => [])), + ]); diff --git a/libs/@local/eslint/src/constants.ts b/libs/@local/eslint/src/constants.ts new file mode 100644 index 00000000000..0dc51ea13da --- /dev/null +++ b/libs/@local/eslint/src/constants.ts @@ -0,0 +1,2 @@ +export const JS_EXTENSIONS = "js,mjs,cjs,ts,mts,cts"; +export const JSX_EXTENSIONS = "jsx,tsx,mtsx,mjsx"; diff --git a/libs/@local/eslint/src/deprecated/base.ts b/libs/@local/eslint/src/deprecated/base.ts new file mode 100644 index 00000000000..638b5bfc290 --- /dev/null +++ b/libs/@local/eslint/src/deprecated/base.ts @@ -0,0 +1,500 @@ +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +import getGitignorePatterns from "eslint-config-flat-gitignore"; +// @ts-expect-error - eslint-plugin-import does not expose types +import importPlugin from "eslint-plugin-import"; +import { ignores } from "eslint-config-sheriff"; +// @ts-expect-error - react-hooks does not expose types +import canonical from "eslint-plugin-canonical"; +// @ts-expect-error - react-hooks does not expose types +import reactHooks from "eslint-plugin-react-hooks"; +import simpleImportSort from "eslint-plugin-simple-import-sort"; +import unicorn from "eslint-plugin-unicorn"; +import globals from "globals"; +import babelParser from "@babel/eslint-parser"; +import { fixupPluginRules } from "@eslint/compat"; +import { FlatCompat } from "@eslint/eslintrc"; +import js from "@eslint/js"; +import typescriptEslint from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import { Array, pipe, Record, Struct } from "effect"; + +import { projectIgnoreFiles, type ESConfig } from "../utils.js"; + +const filename = fileURLToPath(import.meta.url); +const dirname = path.dirname(filename); +const compat = new FlatCompat({ + baseDirectory: dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +const removeImportPlugin = ( + configs: readonly ESConfig[], +): readonly ESConfig[] => + pipe( + configs, + Array.map( + Struct.evolve({ + plugins: (plugins) => + plugins === undefined ? undefined : Record.remove(plugins, "import"), + }), + ), + ); + +export const create = (projectDirectory: string) => + [ + ...removeImportPlugin(compat.extends("airbnb", "prettier")), + { + languageOptions: { + parserOptions: { + projectService: true, + // eslint-disable-next-line unicorn/prevent-abbreviations + tsconfigRootDir: projectDirectory, + }, + }, + }, + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + importPlugin.flatConfigs.recommended, + { + plugins: { + "@typescript-eslint": typescriptEslint, + canonical, + /* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */ + "react-hooks": fixupPluginRules(reactHooks), + "simple-import-sort": simpleImportSort, + unicorn, + }, + + linterOptions: { + reportUnusedDisableDirectives: true, + }, + + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + NodeJS: true, + FixMeLater: "readonly", + globalThis: "readonly", + }, + + parser: tsParser, + + ecmaVersion: "latest", + sourceType: "module", + }, + + settings: { + "import/resolver": { + typescript: { + alwaysTryTypes: true, + project: projectDirectory, + extensions: [".js", ".jsx", ".ts", ".tsx"], + }, + }, + }, + + rules: { + "canonical/filename-no-index": "error", + "@typescript-eslint/consistent-type-imports": "error", + "no-undef-init": "off", + "no-underscore-dangle": "off", + "no-nested-ternary": "off", + + "no-restricted-syntax": [ + "error", + { + selector: + "TSTypeReference[typeName.name=/^(Plugin|PluginKey)$/]:not([typeParameters])", + message: "Please provide a generic to avoid implicit `any`", + }, + { + selector: + "TSTypeReference[typeName.name=/^(Plugin|PluginKey)$/][typeParameters.params.0.type=TSAnyKeyword]", + message: "Please replace `any` with a specific type", + }, + { + selector: + "NewExpression[callee.name=/^(Plugin|PluginKey)$/]:not([typeParameters])", + message: "Please provide a generic to avoid implicit `any`", + }, + { + selector: + "NewExpression[callee.name=/^(Plugin|PluginKey)$/][typeParameters.params.0.type=TSAnyKeyword]", + message: "Please replace `any` with a specific type", + }, + ], + + camelcase: "off", + "default-param-last": "off", + "import/no-cycle": "error", + "import/named": "off", + "import/prefer-default-export": "off", + "no-await-in-loop": "off", + "no-console": "error", + "no-dupe-class-members": "off", + + "import/no-unresolved": [ + 2, + { + ignore: [ + "^@apps/", + "^@blockprotocol/graph", + "^@blockprotocol/hook", + "^@blockprotocol/service", + "^@blockprotocol/type-system", + "^@hashintel/", + "^@local/", + ], + }, + ], + + "react/prop-types": "off", + "jsx-a11y/anchor-is-valid": "off", + + "react/jsx-filename-extension": [ + 2, + { + extensions: [".js", ".jsx", ".ts", ".tsx"], + }, + ], + + "react/jsx-props-no-spreading": "off", + + "no-void": [ + "error", + { + allowAsStatement: true, + }, + ], + + "no-continue": "off", + "react/react-in-jsx-scope": "off", + "no-return-await": "off", + "max-classes-per-file": "off", + + "lines-between-class-members": [ + "error", + "always", + { + exceptAfterSingleLine: true, + }, + ], + + "consistent-return": "off", + "default-case": "off", + "class-methods-use-this": "off", + "react/no-unescapted-entities": "off", + "jsx-a11y/no-autofocus": "off", + "no-plusplus": "off", + "prefer-destructuring": "off", + "no-else-return": "off", + "arrow-body-style": "off", + "react/no-unescaped-entities": "off", + "react-hooks/rules-of-hooks": "error", + + "react-hooks/exhaustive-deps": [ + "error", + { + additionalHooks: "^(useModal|useUserGatedEffect)$", + }, + ], + + "react/function-component-definition": [ + "error", + { + namedComponents: "arrow-function", + unnamedComponents: "arrow-function", + }, + ], + + "react/jsx-key": "error", + "react/jsx-no-useless-fragment": "error", + "react/self-closing-comp": "error", + + "no-restricted-imports": [ + "error", + { + paths: [ + { + name: "react", + importNames: ["FC", "VFC", "VoidFunctionComponent"], + message: "Please use FunctionComponent instead", + }, + { + name: "@testing-library/react", + importNames: ["render"], + message: "Please use ./src/tests/testUtils.tsx#render instead", + }, + { + name: "@mui/material", + importNames: ["Link"], + message: + /* eslint-disable-next-line sonarjs/no-duplicate-string */ + "Please use the custom src/components/Link component instead to ensure Next.js and MUI compatibility.", + }, + { + name: "@mui/material/Link", + message: + "Please use the custom src/components/Link component instead to ensure Next.js and MUI compatibility.", + }, + { + name: "next", + importNames: ["Link"], + message: + "Please use the custom src/components/Link component instead to ensure Next.js and MUI compatibility.", + }, + { + name: "next/link", + message: + "Please use the custom src/components/Link component instead to ensure Next.js and MUI compatibility.", + }, + { + name: "@mui/material", + importNames: ["Button"], + message: + "Please use the custom wrapper component in src/component instead.", + }, + { + name: "@mui/material/Button", + importNames: ["default"], + message: + "Please use the custom src/components/Button component instead.", + }, + ], + + patterns: [ + { + group: [ + "@hashintel/design-system/*", + "!@hashintel/design-system/theme", + "!@hashintel/design-system/constants", + "!@hashintel/design-system/palettes", + ], + + message: "Please import from @hashintel/design-system instead.", + }, + ], + }, + ], + + "react/require-default-props": "off", + "no-shadow": "off", + "@typescript-eslint/default-param-last": "error", + "@typescript-eslint/no-shadow": "error", + "no-use-before-define": "off", + "@typescript-eslint/no-use-before-define": ["error"], + "no-redeclare": "off", + "@typescript-eslint/no-redeclare": ["error"], + + eqeqeq: [ + "error", + "always", + { + null: "ignore", + }, + ], + + "id-length": [ + "error", + { + min: 2, + exceptions: ["_", "x", "y", "z", "a", "b", "i"], + properties: "never", + }, + ], + + "no-unused-expressions": "error", + curly: ["error", "all"], + + // needs to be disabled because it can't map `.js` -> `.ts` correctly + // see: https://github.com/import-js/eslint-plugin-import/issues/2776 + "import/extensions": "off", + + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": ["error"], + + "@typescript-eslint/ban-ts-comment": [ + "error", + { + "ts-expect-error": "allow-with-description", + minimumDescriptionLength: 10, + }, + ], + + "no-empty-function": "off", + + "no-param-reassign": [ + "error", + { + props: true, + ignorePropertyModificationsForRegex: ["^draft"], + + ignorePropertyModificationsFor: [ + "acc", + "accumulator", + "e", + "ctx", + "context", + "req", + "request", + "res", + "response", + "$scope", + "staticContext", + ], + }, + ], + + "simple-import-sort/exports": "error", + "simple-import-sort/imports": "error", + "unicorn/filename-case": "error", + + "unicorn/import-style": [ + "error", + { + styles: { + react: { + named: true, + }, + + "react-dom": { + named: true, + }, + }, + }, + ], + + "unicorn/no-array-for-each": "error", + "unicorn/prefer-node-protocol": "error", + }, + }, + { + files: ["**/*.{c,m,}js"], + + languageOptions: { + parser: babelParser, + ecmaVersion: 5, + sourceType: "script", + + parserOptions: { + requireConfigFile: false, + extraFileExtensions: [".cjs"], + + babelOptions: { + presets: ["@babel/preset-react"], + }, + }, + }, + }, + { + files: [ + "**/tests/**", + "**/__mocks__/**", + "**/testUtils/**", + "**/*.test.{j,t}s{x,}", + ], + + languageOptions: { + globals: { + ...globals.node, + }, + }, + + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, + }, + { + files: [".storybook/*", "**/*.stories.{j,t}s{x,}"], + + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, + }, + { + files: ["**/*.config.{c,m,}{j,t}s", "**/*.d.ts", "**/*rc.{c,m,}js"], + + rules: { + "global-require": "off", + + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, + }, + ...compat + .extends("plugin:@typescript-eslint/recommended-requiring-type-checking") + .map((config) => ({ + ...config, + files: ["**/*.ts", "**/*.tsx"], + })), + { + files: ["**/*.ts", "**/*.tsx"], + + rules: { + "no-unused-vars": "off", + + "@typescript-eslint/prefer-nullish-coalescing": [ + "error", + { + ignoreMixedLogicalExpressions: true, + }, + ], + + "@typescript-eslint/no-meaningless-void-operator": "error", + + "@typescript-eslint/no-misused-promises": [ + "error", + { + checksVoidReturn: { + attributes: false, + properties: false, + }, + }, + ], + + "no-constant-condition": "off", + "@typescript-eslint/no-unnecessary-condition": "error", + + "@typescript-eslint/no-unused-vars": [ + "error", + { + args: "all", + argsIgnorePattern: "^_+", + /* eslint-disable-next-line unicorn/prevent-abbreviations */ + varsIgnorePattern: "^_+", + }, + ], + }, + }, + { + files: ["**/scripts/**"], + + rules: { + "no-console": "off", + }, + }, + getGitignorePatterns({ + strict: false, + files: projectIgnoreFiles(projectDirectory), + }), + { + ignores, + }, + ] as readonly ESConfig[]; diff --git a/libs/@local/eslint/src/deprecated/block.ts b/libs/@local/eslint/src/deprecated/block.ts new file mode 100644 index 00000000000..38eafc53125 --- /dev/null +++ b/libs/@local/eslint/src/deprecated/block.ts @@ -0,0 +1,46 @@ +import react from "eslint-plugin-react"; +// @ts-expect-error - react-hooks does not expose types +import reactHooks from "eslint-plugin-react-hooks"; +import unicorn from "eslint-plugin-unicorn"; +import { fixupPluginRules } from "@eslint/compat"; +import typescriptEslint from "@typescript-eslint/eslint-plugin"; + +import type { ESConfig } from "../utils.js"; + +import { create as createBase } from "./base.js"; + +export const create = (projectDirectory: string) => + [ + ...createBase(projectDirectory), + { + plugins: { + "@typescript-eslint": typescriptEslint, + /* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */ + "react-hooks": fixupPluginRules(reactHooks), + react, + unicorn, + }, + + rules: { + curly: ["error", "multi-line"], + + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + + "jsx-a11y/label-has-associated-control": "off", + "react-hooks/exhaustive-deps": "error", + "react-hooks/rules-of-hooks": "error", + "react/jsx-key": "error", + "react/jsx-no-useless-fragment": "error", + "react/no-danger": "error", + "react/self-closing-comp": "error", + }, + }, + { + ignores: ["**/types/generated/*.ts"], + }, + ] as readonly ESConfig[]; diff --git a/libs/@local/eslint/src/deprecated/disable.ts b/libs/@local/eslint/src/deprecated/disable.ts new file mode 100644 index 00000000000..2f0196314bb --- /dev/null +++ b/libs/@local/eslint/src/deprecated/disable.ts @@ -0,0 +1,13 @@ +import { Array, pipe, Record } from "effect"; + +import type { ESConfig } from "../utils.js"; + +export const disableRules = (rules: readonly string[]): readonly ESConfig[] => + process.env.CHECK_TEMPORARILY_DISABLED_RULES === "true" + ? [] + : pipe( + rules, + Array.map((rule) => [rule, "off"] as const), + Record.fromEntries, + (record) => [{ rules: record }], + ); diff --git a/libs/@local/eslint/src/deprecated/index.ts b/libs/@local/eslint/src/deprecated/index.ts new file mode 100644 index 00000000000..e6a566cd1ba --- /dev/null +++ b/libs/@local/eslint/src/deprecated/index.ts @@ -0,0 +1,9 @@ +import type { ESLintRules } from "eslint/rules"; + +import { defineConfig as defineConfig$ } from "../utils.js"; + +export { create as createBase } from "./base.js"; +export { create as createBlock } from "./block.js"; +export { disableRules } from "./disable.js"; + +export const defineConfig = defineConfig$; diff --git a/libs/@local/eslint/src/import.ts b/libs/@local/eslint/src/import.ts new file mode 100644 index 00000000000..7be43759235 --- /dev/null +++ b/libs/@local/eslint/src/import.ts @@ -0,0 +1,36 @@ +import { defineConfig, type ESConfig } from "./utils.js"; + +export const importPlugin = ( + config: readonly ESConfig[], +): readonly ESConfig[] => + defineConfig([ + ...config, + { + rules: { + "import/order": [ + "error", + { + "newlines-between": "always", + // This is the same as the default, but with `internal` added + groups: [ + "builtin", + "external", + "internal", + "parent", + "sibling", + "index", + ], + }, + ], + // This clashes directly with file name endings as `./index.js` is required + "import/no-useless-path-segments": ["error", { noUselessIndex: false }], + // We no longer want to use CommonJS or AMD + "import/no-commonjs": "error", + "import/no-amd": "error", + // We want to avoid circular dependencies + "import/no-cycle": "error", + // We have custom import/order rules that clash with `simple-import-sort` + "simple-import-sort/imports": "off", + }, + }, + ]); diff --git a/libs/@local/eslint/src/index.ts b/libs/@local/eslint/src/index.ts new file mode 100644 index 00000000000..c7201dcc325 --- /dev/null +++ b/libs/@local/eslint/src/index.ts @@ -0,0 +1,64 @@ +import getGitignorePatterns from "eslint-config-flat-gitignore"; +import { Array, pipe } from "effect"; +import { sheriff, type SheriffSettings } from "eslint-config-sheriff"; +import type { PartialDeep } from "type-fest"; + +import { builtIn } from "./builtIn.js"; +import { importPlugin } from "./import.js"; +import { react } from "./react.js"; +import { stylistic } from "./stylistic.js"; +import type { NoRestrictedImportsRule } from "./types.js"; +import { typescript } from "./typescript.js"; +import { unicorn } from "./unicorn.js"; +import { projectIgnoreFiles, type ESConfig } from "./utils.js"; + +export type * from "./types.js"; + +export interface Modules { + frontend: "next" | "react" | false; + playwright: boolean; + tests: boolean; + storybook: boolean; +} + +export interface Options { + enabled: Modules; + noRestrictedImports: () => NoRestrictedImportsRule[]; + mutableParametersRegex: () => string[]; +} + +export const create = ( + projectDirectory: string, + // eslint-disable-next-line fsecond/prefer-destructured-optionals + options?: PartialDeep, +): readonly ESConfig[] => { + const sheriffOptions: SheriffSettings = { + react: options?.enabled?.frontend === "react", + next: options?.enabled?.frontend === "next", + // I want to move away from lodash, not add more of it + lodash: false, + playwright: options?.enabled?.playwright ?? false, + jest: false, + vitest: options?.enabled?.tests ?? false, + ignores: { + recommended: true, + inheritedFromGitignore: false, + }, + }; + + return pipe( + sheriff(sheriffOptions) as readonly ESConfig[], + Array.append( + getGitignorePatterns({ + strict: false, + files: projectIgnoreFiles(projectDirectory), + }), + ), + builtIn(options ?? {}), + importPlugin, + unicorn, + react(options ?? {}), + typescript, + stylistic, + ); +}; diff --git a/libs/@local/eslint/src/react.ts b/libs/@local/eslint/src/react.ts new file mode 100644 index 00000000000..4e9c6f9341e --- /dev/null +++ b/libs/@local/eslint/src/react.ts @@ -0,0 +1,42 @@ +import type { PartialDeep } from "type-fest"; + +import { defineConfig, type ESConfig } from "./utils.js"; + +import type { Options } from "./index.js"; + +export const react = + (options: PartialDeep) => + (config: readonly ESConfig[]): readonly ESConfig[] => { + if (!options.enabled?.frontend) { + return config; + } + + return defineConfig([ + ...config, + { + rules: { + // disallows the use of `dangerouslySetInnerHTML` + "react/no-danger": "error", + // We make use of quite a few HOCs + // Typescript ensures that the props are passed correctly + // TODO: investigate if we want to enable this in the future + "react/jsx-props-no-spreading": "off", + // Personal preference + "react/no-multi-comp": "off", + // Personal preference, ensures that the code is more readable + "react/jsx-boolean-value": "error", + // Non-curly braces can lead to confusion and ambiguity + // N.B. This is a quite subjective rule + "react/jsx-curly-brace-presence": [ + "error", + { + props: "always", + children: "never", + // eslint-disable-next-line unicorn/prevent-abbreviations + propElementValues: "always", + }, + ], + }, + }, + ]); + }; diff --git a/libs/@local/eslint/src/stylistic.ts b/libs/@local/eslint/src/stylistic.ts new file mode 100644 index 00000000000..cb64723357d --- /dev/null +++ b/libs/@local/eslint/src/stylistic.ts @@ -0,0 +1,17 @@ +import { defineConfig, type ESConfig } from "./utils.js"; + +export const stylistic = (config: readonly ESConfig[]): readonly ESConfig[] => + defineConfig([ + ...config, + { + rules: { + // Personal preference + "@stylistic/yield-star-spacing": ["error", "after"], + "@stylistic/generator-star-spacing": ["error", "after"], + // Forces multiline constructs to use an explicit return. + // This creates additional noise in the code, especially when + // using constructs such as `pipe` or `Effect.gen` + "arrow-return-style/arrow-return-style": "off", + }, + }, + ]); diff --git a/libs/@local/eslint/src/types.ts b/libs/@local/eslint/src/types.ts new file mode 100644 index 00000000000..222d276663c --- /dev/null +++ b/libs/@local/eslint/src/types.ts @@ -0,0 +1,59 @@ +export interface NoRestrictedImportsRule { + paths: (string | ValidNoRestrictedImportPathOptions)[]; + patterns: (string | ValidNoRestrictedImportPatternOptions)[]; +} + +export interface NoRestrictedImportPathCommonOptions { + name: string; + message?: string; +} + +export type EitherImportNamesOrAllowImportName = + | { importNames?: string[]; allowImportNames?: never } + | { allowImportNames?: string[]; importNames?: never }; + +export type ValidNoRestrictedImportPathOptions = + NoRestrictedImportPathCommonOptions & EitherImportNamesOrAllowImportName; + +export interface NoRestrictedImportPatternCommonOptions { + message?: string; + caseSensitive?: boolean; +} + +// Base type for group or regex constraint, ensuring mutual exclusivity +export type EitherGroupOrRegEx = + | { group: string[]; regex?: never } + | { regex: string; group?: never }; + +// Base type for import name specifiers, ensuring mutual exclusivity +export type EitherNameSpecifiers = + | { + importNames: string[]; + allowImportNames?: never; + importNamePattern?: never; + allowImportNamePattern?: never; + } + | { + importNamePattern: string; + allowImportNames?: never; + importNames?: never; + allowImportNamePattern?: never; + } + | { + allowImportNames: string[]; + importNames?: never; + importNamePattern?: never; + allowImportNamePattern?: never; + } + | { + allowImportNamePattern: string; + importNames?: never; + allowImportNames?: never; + importNamePattern?: never; + }; + +// Adds oneOf and not constraints, ensuring group or regex are present and mutually exclusive sets for importNames, allowImportNames, etc., as per the schema. +export type ValidNoRestrictedImportPatternOptions = + NoRestrictedImportPatternCommonOptions & + EitherGroupOrRegEx & + EitherNameSpecifiers; diff --git a/libs/@local/eslint/src/typescript.ts b/libs/@local/eslint/src/typescript.ts new file mode 100644 index 00000000000..62270de9074 --- /dev/null +++ b/libs/@local/eslint/src/typescript.ts @@ -0,0 +1,145 @@ +import { Predicate } from "effect"; +import type { Linter } from "eslint"; + +import { JS_EXTENSIONS, JSX_EXTENSIONS } from "./constants.js"; +import { defineConfig, type ESConfig } from "./utils.js"; + +const namingConvention = ({ tsx }: { tsx: boolean }): Linter.RuleEntry => [ + "error", + // adapted from https://github.com/AndreaPontrandolfo/sheriff/blob/3a6e3c9873c4b8fbbfbd01b6051c55fd1e57609a/packages/eslint-config-sheriff/src/getTsNamingConventionRule.ts#L9 + { + selector: "default", + format: ["camelCase", tsx && "StrictPascalCase"].filter(Predicate.isString), + leadingUnderscore: "allow", + trailingUnderscore: "forbid", + }, + { + selector: "import", + format: ["camelCase", "StrictPascalCase"], + leadingUnderscore: "forbid", + trailingUnderscore: "forbid", + }, + { + selector: "variable", + format: ["camelCase", "UPPER_CASE"], + modifiers: ["const"], + types: ["string", "number"], + leadingUnderscore: "allow", + trailingUnderscore: "forbid", + }, + // allow constant variables in the global scope to be in UPPER_CASE, + // but they cannot be unused. + { + selector: "variable", + format: ["camelCase", "UPPER_CASE", "StrictPascalCase"], + modifiers: ["const", "global"], + leadingUnderscore: "forbid", + trailingUnderscore: "forbid", + }, + { + selector: "objectLiteralProperty", + format: null, + leadingUnderscore: "allowSingleOrDouble", + trailingUnderscore: "forbid", + }, + { + selector: "typeLike", + format: ["PascalCase"], + leadingUnderscore: "forbid", + trailingUnderscore: "forbid", + }, + // TODO: consider enabling this rule in the future: + // https://typescript-eslint.io/rules/naming-convention/#enforce-that-boolean-variables-are-prefixed-with-an-allowed-verb + { + selector: "variable", + modifiers: ["destructured"], + format: null, + }, + { + selector: "typeProperty", + format: null, + }, + // forbid common type prefixes/suffixes + { + selector: "interface", + format: ["PascalCase"], + custom: { + regex: "^I[A-Z]", + match: false, + }, + }, + { + selector: "typeAlias", + format: ["PascalCase"], + custom: { + regex: "^T[A-Z]", + match: false, + }, + }, + { + selector: "enum", + format: ["PascalCase"], + custom: { + regex: "^E[A-Z]", + match: false, + }, + }, +]; + +export const typescript = (config: readonly ESConfig[]): readonly ESConfig[] => + defineConfig([ + ...config, + { + rules: { + // While a good idea, there are just too many places where this isn't the case yet + // TODO: consider introducing this rule in the future + "@typescript-eslint/explicit-module-boundary-types": "off", + // Allow unused variables that start with an underscore (goes hand in hand with + // the naming convention) + "@typescript-eslint/no-unused-vars": [ + "error", + { + args: "all", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + // eslint-disable-next-line unicorn/prevent-abbreviations + varsIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + "@typescript-eslint/no-shadow": [ + "error", + { + hoist: "all", + allow: ["resolve", "reject", "done", "next", "err", "error", "_"], + ignoreTypeValueShadow: true, + ignoreFunctionTypeParameterNameValueShadow: true, + }, + ], + // Allow numbers in template expressions, as they are used quite frequently + // and do not really suffer from the reasons described in the rule documentation + "@typescript-eslint/restrict-template-expressions": [ + "error", + { allowNumber: true }, + ], + }, + }, + { + files: [`**/*{${JS_EXTENSIONS}}`], + rules: { + "@typescript-eslint/naming-convention": namingConvention({ + tsx: false, + }), + }, + }, + { + files: [`**/*{${JSX_EXTENSIONS}}`], + rules: { + "@typescript-eslint/naming-convention": namingConvention({ + tsx: true, + }), + }, + }, + ]); diff --git a/libs/@local/eslint/src/unicorn.ts b/libs/@local/eslint/src/unicorn.ts new file mode 100644 index 00000000000..b6356b5c44f --- /dev/null +++ b/libs/@local/eslint/src/unicorn.ts @@ -0,0 +1,160 @@ +/* eslint-disable unicorn/prevent-abbreviations */ +import { defineConfig, type ESConfig } from "./utils.js"; + +const preventAbbreviations = (): ESConfig => ({ + rules: { + "unicorn/prevent-abbreviations": [ + "error", + { + checkFilenames: true, + checkProperties: true, + checkDefaultAndNamespaceImports: true, + checkShorthandImports: "internal", + extendDefaultReplacements: true, + replacements: { + // Offensive terms + whitelist: { + include: true, + allowList: true, + permitList: true, + passList: true, + }, + blacklist: { + exclude: true, + denyList: true, + blockList: true, + rejectList: true, + }, + master: { + primary: true, + host: true, + leader: true, + main: true, + trunk: true, + }, + slave: { + secondary: true, + guest: true, + follower: true, + replica: true, + branch: true, + }, + + // Gendered terms + man: { + person: true, + human: true, + individual: true, + being: true, + user: true, + }, + + // Reverse (some abbreviations are very well understood) + application: { + app: true, + }, + applications: { + apps: true, + }, + + // Disable some default replacements that are well understood + // and commonly used (or from other languages) + env: false, + impl: false, // <- `rust` + iter: false, // <- `rust` + temp: false, + tmp: { + temp: true, + }, + gen: false, // <- `rust` + `effect` + ctx: false, // <- `rust` + `effect` + dev: false, + prod: false, + fn: false, + func: { + fn: true, // mimic `rust` + }, + ref: false, // <- `rust` + `effect` + refs: false, // <- `rust` + `effect` + arg: false, + args: false, + param: false, + params: false, + props: false, + docs: false, + db: false, + + // Look in the future: + // really want to remove this, but it's too ingrained in our codebase + i: false, + nav: false, + + // Not part of `eslint-plugin-unicorn`, copied from `xo` + // with some modifications + bin: { + binary: true, + }, + eof: { + endOfFile: true, + }, + anim: { + animation: true, + }, + calc: { + calculate: true, + }, + dict: { + dictionary: true, + }, + dup: { + duplicate: true, + }, + enc: { + encode: true, + encryption: true, + }, + gfx: { + graphics: true, + }, + inc: { + increment: true, + }, + norm: { + normalize: true, + }, + notif: { + notification: true, + }, + perf: { + performance: true, + }, + proc: { + process: true, + }, + rand: { + random: true, + }, + sys: { + system: true, + }, + }, + }, + ], + }, +}); + +export const unicorn = (config: readonly ESConfig[]): readonly ESConfig[] => + defineConfig([ + ...config, + { + rules: { + // I disagree why this is a bad idea, the documentation describes + // reduce as hard-to-read and less-performant. + // `Array#reduce()` is only less performant if used with an internal + // spread operator. It's also a very common pattern in functional + // programming. + "unicorn/no-array-reduce": "off", + }, + }, + preventAbbreviations(), + ]); diff --git a/libs/@local/eslint/src/utils.ts b/libs/@local/eslint/src/utils.ts new file mode 100644 index 00000000000..d4247dd0e02 --- /dev/null +++ b/libs/@local/eslint/src/utils.ts @@ -0,0 +1,38 @@ +import fs from "node:fs"; +import path from "node:path"; + +import type { Linter } from "eslint"; +import type { ESLintRules } from "eslint/rules"; + +export type ESConfig = Linter.Config; + +export const defineConfig = ( + config: readonly Linter.Config[], +): readonly Linter.Config[] => config; + +/** Version of findUp that only considers the git repository and searches for `.gitignore`. */ +export const projectIgnoreFiles = (directory: string): string[] => { + // traverses the directory tree to find all `.gitignore` files, stops at the .git directory + + const gitignoreFiles: string[] = []; + let currentDirectory = directory; + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- termination is handled by the break statement + while (true) { + const parent = path.dirname(currentDirectory); + const files = fs.readdirSync(currentDirectory); + + if (files.includes(".gitignore")) { + gitignoreFiles.push(path.join(currentDirectory, ".gitignore")); + } + + if (files.includes(".git")) { + // we have reached the .git directory, stop traversing + break; + } + + currentDirectory = parent; + } + + return gitignoreFiles; +}; diff --git a/libs/@local/eslint/tsconfig.build.json b/libs/@local/eslint/tsconfig.build.json new file mode 100644 index 00000000000..f57633edc28 --- /dev/null +++ b/libs/@local/eslint/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src"], + "compilerOptions": { + "declaration": true, + "outDir": "dist", + "paths": {} + } +} diff --git a/libs/@local/eslint/tsconfig.json b/libs/@local/eslint/tsconfig.json new file mode 100644 index 00000000000..1d8fe2a0680 --- /dev/null +++ b/libs/@local/eslint/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", + "compilerOptions": { + "module": "NodeNext", + "moduleResolution": "NodeNext" + }, + "include": ["src", "eslint.config.js"], + "exclude": ["node-modules", "dist"] +} diff --git a/libs/@local/eslint/turbo.json b/libs/@local/eslint/turbo.json new file mode 100644 index 00000000000..5e4a1571375 --- /dev/null +++ b/libs/@local/eslint/turbo.json @@ -0,0 +1,8 @@ +{ + "extends": ["//"], + "tasks": { + "build": { + "outputs": ["./dist/**"] + } + } +} diff --git a/libs/@local/graph/client/typescript/.eslintrc.cjs b/libs/@local/graph/client/typescript/.eslintrc.cjs deleted file mode 100644 index 7214645fa15..00000000000 --- a/libs/@local/graph/client/typescript/.eslintrc.cjs +++ /dev/null @@ -1,9 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - plugins: ["typescript-sort-keys"], - rules: { - "typescript-sort-keys/interface": "error", - }, - reportUnusedDisableDirectives: false, -}; diff --git a/libs/@local/graph/client/typescript/package.json b/libs/@local/graph/client/typescript/package.json index d2c4ad0476b..fe819742e19 100644 --- a/libs/@local/graph/client/typescript/package.json +++ b/libs/@local/graph/client/typescript/package.json @@ -16,7 +16,6 @@ "axios": "1.7.9" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@redocly/cli": "1.26.0", "@rust/hash-graph-api": "0.0.0-private", diff --git a/libs/@local/graph/sdk/typescript/.eslintrc.cjs b/libs/@local/graph/sdk/typescript/.eslintrc.cjs deleted file mode 100644 index ae0bc9befab..00000000000 --- a/libs/@local/graph/sdk/typescript/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - "global-require": "off", - }, -}; diff --git a/libs/@local/graph/sdk/typescript/eslint.config.js b/libs/@local/graph/sdk/typescript/eslint.config.js new file mode 100644 index 00000000000..1259c362459 --- /dev/null +++ b/libs/@local/graph/sdk/typescript/eslint.config.js @@ -0,0 +1,6 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { rules: { "global-require": "off" } }, +]; diff --git a/libs/@local/graph/sdk/typescript/package.json b/libs/@local/graph/sdk/typescript/package.json index 6a6291af14b..2165a2b35e4 100644 --- a/libs/@local/graph/sdk/typescript/package.json +++ b/libs/@local/graph/sdk/typescript/package.json @@ -31,10 +31,10 @@ "effect": "3.11.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3", "vitest": "2.1.8" diff --git a/libs/@local/graph/sdk/typescript/src/entity.ts b/libs/@local/graph/sdk/typescript/src/entity.ts index dfb00dbb132..3ced7a7c386 100644 --- a/libs/@local/graph/sdk/typescript/src/entity.ts +++ b/libs/@local/graph/sdk/typescript/src/entity.ts @@ -985,6 +985,8 @@ export class Entity { ) .then( ({ data: entities }) => + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-unused-vars entities.map((entity, index) => { return new Entity(entity); }) as { [I in keyof T]: Entity }, diff --git a/libs/@local/graph/sdk/typescript/tsconfig.json b/libs/@local/graph/sdk/typescript/tsconfig.json index b60fa3ed434..35a36985b1e 100644 --- a/libs/@local/graph/sdk/typescript/tsconfig.json +++ b/libs/@local/graph/sdk/typescript/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["src", "tests"], + "include": ["src", "tests", "eslint.config.js", "vitest.config.ts"], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" diff --git a/libs/@local/hash-subgraph/vitest.config.js b/libs/@local/graph/sdk/typescript/vitest.config.ts similarity index 92% rename from libs/@local/hash-subgraph/vitest.config.js rename to libs/@local/graph/sdk/typescript/vitest.config.ts index d4519b2e7db..474acf4f1ac 100644 --- a/libs/@local/hash-subgraph/vitest.config.js +++ b/libs/@local/graph/sdk/typescript/vitest.config.ts @@ -1,4 +1,3 @@ -/// import { defineConfig } from "vitest/config"; export default defineConfig({ diff --git a/libs/@local/graph/type-defs/.eslintrc.cjs b/libs/@local/graph/type-defs/.eslintrc.cjs deleted file mode 100644 index 9a9cd07da3c..00000000000 --- a/libs/@local/graph/type-defs/.eslintrc.cjs +++ /dev/null @@ -1,11 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - env: { - node: true, - }, - rules: { - "no-console": "off", - "@typescript-eslint/consistent-type-imports": "off", - }, -}; diff --git a/libs/@local/graph/type-defs/Cargo.toml b/libs/@local/graph/type-defs/Cargo.toml index 01355cc1e0d..7454ac4d3c7 100644 --- a/libs/@local/graph/type-defs/Cargo.toml +++ b/libs/@local/graph/type-defs/Cargo.toml @@ -12,7 +12,7 @@ extra-dependencies = [ { name = "@local/status", version = "0.0.0-private" }, ] extra-dev-dependencies = [ - { name = "@local/eslint-config", version = "0.0.0-private" }, + { name = "@local/eslint", version = "0.0.0-private" }, ] [dependencies] diff --git a/libs/@local/graph/type-defs/eslint.config.js b/libs/@local/graph/type-defs/eslint.config.js new file mode 100644 index 00000000000..cd8f2aa7fa7 --- /dev/null +++ b/libs/@local/graph/type-defs/eslint.config.js @@ -0,0 +1,11 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { + rules: { + "no-console": "off", + "@typescript-eslint/consistent-type-imports": "off", + }, + }, +]; diff --git a/libs/@local/graph/type-defs/package.json b/libs/@local/graph/type-defs/package.json index 6f93e207440..7732077d815 100644 --- a/libs/@local/graph/type-defs/package.json +++ b/libs/@local/graph/type-defs/package.json @@ -14,8 +14,8 @@ "@rust/hash-status": "0.0.0-private" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", - "eslint": "8.57.0", + "@local/eslint": "0.0.0-private", + "eslint": "9.16.0", "quicktype": "16.0.43", "tsx": "4.19.2", "typescript": "5.6.3" diff --git a/libs/@local/graph/type-defs/tsconfig.json b/libs/@local/graph/type-defs/tsconfig.json index 82d2d9acf04..618780e98b9 100644 --- a/libs/@local/graph/type-defs/tsconfig.json +++ b/libs/@local/graph/type-defs/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["typescript"], + "include": ["typescript", "eslint.config.js"], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" diff --git a/libs/@local/graph/types/typescript/.eslintrc.cjs b/libs/@local/graph/types/typescript/.eslintrc.cjs deleted file mode 100644 index ae0bc9befab..00000000000 --- a/libs/@local/graph/types/typescript/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - "global-require": "off", - }, -}; diff --git a/libs/@local/graph/types/typescript/eslint.config.js b/libs/@local/graph/types/typescript/eslint.config.js new file mode 100644 index 00000000000..2a4de1a5fc4 --- /dev/null +++ b/libs/@local/graph/types/typescript/eslint.config.js @@ -0,0 +1,10 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { + rules: { + "global-require": "off", + }, + }, +]; diff --git a/libs/@local/graph/types/typescript/package.json b/libs/@local/graph/types/typescript/package.json index d889ef2e4f0..7b9ab43713d 100644 --- a/libs/@local/graph/types/typescript/package.json +++ b/libs/@local/graph/types/typescript/package.json @@ -28,9 +28,9 @@ "@local/hash-graph-client": "0.0.0-private" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3" } diff --git a/libs/@local/graph/types/typescript/tsconfig.build.json b/libs/@local/graph/types/typescript/tsconfig.build.json index 85f5f1162d1..19340e844f2 100644 --- a/libs/@local/graph/types/typescript/tsconfig.build.json +++ b/libs/@local/graph/types/typescript/tsconfig.build.json @@ -1,5 +1,6 @@ { "extends": "./tsconfig.json", + "exclude": ["eslint.config.js"], "compilerOptions": { "declaration": true, "outDir": "dist", diff --git a/libs/@local/graph/types/typescript/tsconfig.json b/libs/@local/graph/types/typescript/tsconfig.json index 5ab74b4e710..9d1658f15e2 100644 --- a/libs/@local/graph/types/typescript/tsconfig.json +++ b/libs/@local/graph/types/typescript/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["src"], + "include": ["src", "eslint.config.js"], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" diff --git a/libs/@local/graph/types/typescript/turbo.json b/libs/@local/graph/types/typescript/turbo.json index 35be9c68fa8..12a44b35146 100644 --- a/libs/@local/graph/types/typescript/turbo.json +++ b/libs/@local/graph/types/typescript/turbo.json @@ -2,7 +2,8 @@ "extends": ["//"], "tasks": { "build": { - "outputs": ["dist/**"] + "outputs": ["dist/**"], + "dependsOn": ["^build"] } } } diff --git a/libs/@local/harpc/client/typescript/.eslintrc.cjs b/libs/@local/harpc/client/typescript/.eslintrc.cjs deleted file mode 100644 index a4d15fbdaec..00000000000 --- a/libs/@local/harpc/client/typescript/.eslintrc.cjs +++ /dev/null @@ -1,13 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - "@typescript-eslint/no-redeclare": "off", - "unicorn/filename-case": "off", - "func-names": "off", - "canonical/filename-no-index": "off", - }, - ignorePatterns: require("@local/eslint-config/generate-ignore-patterns.cjs")( - __dirname, - ), -}; diff --git a/libs/@local/harpc/client/typescript/eslint.config.js b/libs/@local/harpc/client/typescript/eslint.config.js new file mode 100644 index 00000000000..9b68b9bc5bd --- /dev/null +++ b/libs/@local/harpc/client/typescript/eslint.config.js @@ -0,0 +1,17 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { + rules: { + "@typescript-eslint/no-redeclare": "off", + "unicorn/filename-case": "off", + "func-names": "off", + "canonical/filename-no-index": "off", + "@typescript-eslint/no-empty-object-type": [ + "error", + { allowInterfaces: "with-single-extends" }, + ], + }, + }, +]; diff --git a/libs/@local/harpc/client/typescript/package.json b/libs/@local/harpc/client/typescript/package.json index 356fdeccb26..d6de02e83a3 100644 --- a/libs/@local/harpc/client/typescript/package.json +++ b/libs/@local/harpc/client/typescript/package.json @@ -41,12 +41,12 @@ "@effect/platform": "0.70.4", "@effect/platform-node": "0.65.4", "@effect/vitest": "0.14.3", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@rust/harpc-wire-protocol": "0.0.0-private", "@types/node": "22.10.1", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3", "vitest": "2.1.8" diff --git a/libs/@local/harpc/client/typescript/src/codec/Decoder.ts b/libs/@local/harpc/client/typescript/src/codec/Decoder.ts index 998824a9d2e..7d601715b58 100644 --- a/libs/@local/harpc/client/typescript/src/codec/Decoder.ts +++ b/libs/@local/harpc/client/typescript/src/codec/Decoder.ts @@ -57,7 +57,7 @@ const DecoderProto: Omit = { }; }, - [Inspectable.NodeInspectSymbol]() { + [Inspectable.NodeInspectSymbol](this: DecoderImpl) { return this.toJSON(); }, diff --git a/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts b/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts index b3098dbd03e..aa783136b52 100644 --- a/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts +++ b/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts @@ -2,7 +2,10 @@ import { describe, it } from "@effect/vitest"; import { Chunk, Effect, pipe, Schema, Stream } from "effect"; +import type { ParseError } from "effect/ParseResult"; +import type { ReadonlyRecord } from "effect/Record"; +import type { DecodingError } from "../../src/codec/Decoder.js"; import { Decoder, JsonDecoder } from "../../src/codec/index.js"; const decode = (text: readonly string[]) => @@ -12,13 +15,15 @@ const decode = (text: readonly string[]) => const schema = Schema.Record({ key: Schema.String, value: Schema.String }); - return yield* pipe( - Stream.fromIterable(text), + const effect = Stream.fromChunk(Chunk.fromIterable(text)).pipe( Stream.map((input) => textEncoder.encode(input).buffer), decoder.decode(schema), Stream.runCollect, Effect.map(Chunk.toReadonlyArray), ); + + // explicit type annotation needed for eslint + return (yield* effect) as readonly ReadonlyRecord[]; }); describe.concurrent("JsonDecoder", () => { @@ -73,7 +78,12 @@ describe.concurrent("JsonDecoder", () => { Effect.gen(function* () { const textPayload = '{"key": "valu\x1E'; - const error = yield* pipe(decode([textPayload]), Effect.flip); + // explicit type annotation needed for eslint + const error: DecodingError | ParseError = yield* pipe( + decode([textPayload]), + Effect.flip, + ); + cx.expect(error.toString()).toMatch( /Unterminated string in JSON at position 13/, ); diff --git a/libs/@local/harpc/client/typescript/tests/net/Request.test.ts b/libs/@local/harpc/client/typescript/tests/net/Request.test.ts index faf1e8bc25d..af3d0d8696e 100644 --- a/libs/@local/harpc/client/typescript/tests/net/Request.test.ts +++ b/libs/@local/harpc/client/typescript/tests/net/Request.test.ts @@ -1,6 +1,6 @@ import { describe, it } from "@effect/vitest"; import { Chunk, Effect, pipe, Predicate, Stream } from "effect"; -import type * as V from "vitest"; +import type * as vitest from "vitest"; import { Request } from "../../src/net/index.js"; import { @@ -31,7 +31,7 @@ const makeRequest = (stream: Stream.Stream) => }); const assertBody = ( - cx: V.TaskContext> & V.TestContext, + cx: vitest.TaskContext> & vitest.TestContext, request: WireRequest.Request, bodyIs: (request: RequestBody.RequestBody) => boolean, body: string | number, diff --git a/libs/@local/harpc/client/typescript/tsconfig.json b/libs/@local/harpc/client/typescript/tsconfig.json index d388501d083..7fff5ad2cd1 100644 --- a/libs/@local/harpc/client/typescript/tsconfig.json +++ b/libs/@local/harpc/client/typescript/tsconfig.json @@ -6,5 +6,5 @@ "moduleResolution": "NodeNext", "types": ["vitest/importMeta"] }, - "include": ["src", "tests"] + "include": ["src", "tests", "eslint.config.js", "vitest.config.ts"] } diff --git a/libs/@local/harpc/client/typescript/vitest.config.js b/libs/@local/harpc/client/typescript/vitest.config.ts similarity index 100% rename from libs/@local/harpc/client/typescript/vitest.config.js rename to libs/@local/harpc/client/typescript/vitest.config.ts diff --git a/libs/@local/hash-backend-utils/.eslintrc.cjs b/libs/@local/hash-backend-utils/.eslintrc.cjs deleted file mode 100644 index f35065da60c..00000000000 --- a/libs/@local/hash-backend-utils/.eslintrc.cjs +++ /dev/null @@ -1,10 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 15 */ "@typescript-eslint/no-unsafe-member-access", - /* 2022-11-29: 11 */ "@typescript-eslint/unbound-method", - ]), - }, -}; diff --git a/libs/@local/hash-backend-utils/eslint.config.js b/libs/@local/hash-backend-utils/eslint.config.js new file mode 100644 index 00000000000..9c2d440037c --- /dev/null +++ b/libs/@local/hash-backend-utils/eslint.config.js @@ -0,0 +1,9 @@ +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...disableRules([ + /* 2022-11-29: 15 */ "@typescript-eslint/no-unsafe-member-access", + /* 2022-11-29: 11 */ "@typescript-eslint/unbound-method", + ]), +]; diff --git a/libs/@local/hash-backend-utils/package.json b/libs/@local/hash-backend-utils/package.json index 47837381790..6ecfbb0cffd 100644 --- a/libs/@local/hash-backend-utils/package.json +++ b/libs/@local/hash-backend-utils/package.json @@ -56,13 +56,13 @@ "winston": "3.17.0" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/dotenv-flow": "3.3.3", "@types/node": "22.10.1", "@types/wait-on": "5.3.4", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3", "vitest": "2.1.8" diff --git a/libs/@local/hash-backend-utils/src/environment.ts b/libs/@local/hash-backend-utils/src/environment.ts index baa8f115300..a8c5a7af0c6 100644 --- a/libs/@local/hash-backend-utils/src/environment.ts +++ b/libs/@local/hash-backend-utils/src/environment.ts @@ -1,11 +1,11 @@ -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { config } from "dotenv-flow"; import waitOn from "wait-on"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); export const monorepoRootDir = path.resolve(__dirname, "../../../.."); diff --git a/libs/@local/hash-backend-utils/src/google.ts b/libs/@local/hash-backend-utils/src/google.ts index 56dc09bef1d..e4094969885 100644 --- a/libs/@local/hash-backend-utils/src/google.ts +++ b/libs/@local/hash-backend-utils/src/google.ts @@ -136,7 +136,7 @@ export const getTokensForGoogleAccount = async ({ userAccountId, }); return vaultResponse.data; - } catch (err) { + } catch { return null; } }; diff --git a/libs/@local/hash-backend-utils/src/machine-actors.ts b/libs/@local/hash-backend-utils/src/machine-actors.ts index d7ff8a7c67a..c5934e87c13 100644 --- a/libs/@local/hash-backend-utils/src/machine-actors.ts +++ b/libs/@local/hash-backend-utils/src/machine-actors.ts @@ -9,7 +9,7 @@ import { systemEntityTypes, systemPropertyTypes, } from "@local/hash-isomorphic-utils/ontology-type-ids"; -import { systemTypeWebShortnames } from "@local/hash-isomorphic-utils/ontology-types"; +import type { SystemTypeWebShortname } from "@local/hash-isomorphic-utils/ontology-types"; import { mapGraphApiEntityToEntity } from "@local/hash-isomorphic-utils/subgraph-mapping"; import type { Machine } from "@local/hash-isomorphic-utils/system-types/machine"; import { backOff } from "exponential-backoff"; @@ -18,13 +18,7 @@ import { NotFoundError } from "./error.js"; export type WebMachineActorIdentifier = `system-${OwnedById}`; -const globalMachineActorIdentifiers = [ - ...systemTypeWebShortnames, - "hash-ai", -] as const; - -export type GlobalMachineActorIdentifier = - (typeof globalMachineActorIdentifiers)[number]; +export type GlobalMachineActorIdentifier = SystemTypeWebShortname | "hash-ai"; export type MachineActorIdentifier = | GlobalMachineActorIdentifier diff --git a/libs/@local/hash-backend-utils/tsconfig.build.json b/libs/@local/hash-backend-utils/tsconfig.build.json index 85f5f1162d1..d6484184671 100644 --- a/libs/@local/hash-backend-utils/tsconfig.build.json +++ b/libs/@local/hash-backend-utils/tsconfig.build.json @@ -1,5 +1,6 @@ { "extends": "./tsconfig.json", + "exclude": ["eslint.config.js", "vitest.config.ts"], "compilerOptions": { "declaration": true, "outDir": "dist", diff --git a/libs/@local/hash-backend-utils/tsconfig.json b/libs/@local/hash-backend-utils/tsconfig.json index 5ab74b4e710..7cb93887c0c 100644 --- a/libs/@local/hash-backend-utils/tsconfig.json +++ b/libs/@local/hash-backend-utils/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["src"], + "include": ["src", "eslint.config.js", "vitest.config.ts"], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" diff --git a/libs/@local/hash-isomorphic-utils/vitest.config.js b/libs/@local/hash-backend-utils/vitest.config.ts similarity index 91% rename from libs/@local/hash-isomorphic-utils/vitest.config.js rename to libs/@local/hash-backend-utils/vitest.config.ts index f19ca5fb70a..1feb2e96bcd 100644 --- a/libs/@local/hash-isomorphic-utils/vitest.config.js +++ b/libs/@local/hash-backend-utils/vitest.config.ts @@ -1,4 +1,3 @@ -/// import { defineConfig } from "vitest/config"; export default defineConfig({ diff --git a/libs/@local/hash-isomorphic-utils/.eslintrc.cjs b/libs/@local/hash-isomorphic-utils/.eslintrc.cjs deleted file mode 100644 index f0383c86073..00000000000 --- a/libs/@local/hash-isomorphic-utils/.eslintrc.cjs +++ /dev/null @@ -1,50 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 6 */ "@typescript-eslint/no-unsafe-argument", - /* 2022-11-29: 15 */ "@typescript-eslint/no-unsafe-assignment", - /* 2022-11-29: 5 */ "@typescript-eslint/no-unsafe-call", - /* 2022-11-29: 7 */ "@typescript-eslint/no-unsafe-member-access", - /* 2022-11-29: 7 */ "@typescript-eslint/no-unsafe-return", - ]), - "import/no-extraneous-dependencies": ["error", { devDependencies: true }], - }, - overrides: [ - { - files: ["./src/**/*.ts"], - rules: { - "no-restricted-imports": [ - "error", - { - patterns: [ - { - group: ["@local/hash-backend-utils/*"], - message: - "This package is shared by FE and BE, move backend utils here if both need them.", - }, - ], - }, - ], - }, - }, - { - files: ["src/system-types/**"], - rules: { - "@typescript-eslint/ban-types": [ - "error", - { - types: { - /** - * @todo update the codegen utility in @blockprotocol/graph to generate Object as Record, not {} - */ - "{}": false, - }, - extendDefaults: true, - }, - ], - }, - }, - ], -}; diff --git a/libs/@local/hash-isomorphic-utils/eslint.config.js b/libs/@local/hash-isomorphic-utils/eslint.config.js new file mode 100644 index 00000000000..d6ac75c7ec6 --- /dev/null +++ b/libs/@local/hash-isomorphic-utils/eslint.config.js @@ -0,0 +1,40 @@ +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...disableRules([ + /* 2022-11-29: 6 */ "@typescript-eslint/no-unsafe-argument", + /* 2022-11-29: 15 */ "@typescript-eslint/no-unsafe-assignment", + /* 2022-11-29: 5 */ "@typescript-eslint/no-unsafe-call", + /* 2022-11-29: 7 */ "@typescript-eslint/no-unsafe-member-access", + /* 2022-11-29: 7 */ "@typescript-eslint/no-unsafe-return", + ]), + { + rules: { + "import/no-extraneous-dependencies": ["error", { devDependencies: true }], + }, + }, + { + files: ["**/src/**/*.ts"], + rules: { + "no-restricted-imports": [ + "error", + { + patterns: [ + { + group: ["@local/hash-backend-utils/*"], + message: + "This package is shared by FE and BE, move backend utils here if both need them.", + }, + ], + }, + ], + }, + }, + { + files: ["**/src/system-types/**"], + rules: { + "@typescript-eslint/no-empty-object-type": "off", + }, + }, +]; diff --git a/libs/@local/hash-isomorphic-utils/package.json b/libs/@local/hash-isomorphic-utils/package.json index 5fa480e7069..a1dccf0b42a 100644 --- a/libs/@local/hash-isomorphic-utils/package.json +++ b/libs/@local/hash-isomorphic-utils/package.json @@ -60,14 +60,14 @@ "@graphql-codegen/fragment-matcher": "3.3.3", "@graphql-codegen/typescript": "2.8.8", "@graphql-codegen/typescript-operations": "2.5.13", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@temporalio/workflow": "1.11.5", "@types/lodash-es": "4.17.12", "@types/node": "22.10.1", "@types/pluralize": "0.0.33", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "graphql": "16.9.0", "next": "13.5.5", "prettier": "3.4.2", diff --git a/libs/@local/hash-isomorphic-utils/src/create-prose-mirror-state.ts b/libs/@local/hash-isomorphic-utils/src/create-prose-mirror-state.ts index 4cd9c8d6ca7..f96bb8c7bdd 100644 --- a/libs/@local/hash-isomorphic-utils/src/create-prose-mirror-state.ts +++ b/libs/@local/hash-isomorphic-utils/src/create-prose-mirror-state.ts @@ -26,6 +26,7 @@ const nodes = { const createInitialDoc = (schema: Schema = createSchema(cloneDeep(nodes))) => schema.node("doc", {}, [schema.node("loading")]); +// eslint-disable-next-line no-restricted-syntax -- prosemirror issue const defaultPlugins: Plugin[] = [ ...wrapEntitiesPlugin(baseKeymap), // This enables an indicator to appear when drag and dropping blocks @@ -39,6 +40,7 @@ export const createProseMirrorState = ({ }: { ownedById: OwnedById; doc?: Node; + // eslint-disable-next-line no-restricted-syntax -- prosemirror issue plugins?: Plugin[]; }) => { return EditorState.create({ diff --git a/libs/@local/hash-isomorphic-utils/src/entity-store-plugin.ts b/libs/@local/hash-isomorphic-utils/src/entity-store-plugin.ts index dc91966eb53..ba962c46384 100644 --- a/libs/@local/hash-isomorphic-utils/src/entity-store-plugin.ts +++ b/libs/@local/hash-isomorphic-utils/src/entity-store-plugin.ts @@ -94,10 +94,12 @@ export type EntityStorePluginAction = { received?: boolean } & ( ); const EntityStoreListeners = new WeakMap< + // eslint-disable-next-line no-restricted-syntax -- prosemirror issue Plugin, Set >(); +// eslint-disable-next-line no-restricted-syntax -- prosemirror issue const entityStorePluginKey = new PluginKey( "entityStore", ); @@ -757,6 +759,7 @@ const scheduleNotifyEntityStoreSubscribers = collect< [ view: EditorView, prevState: EditorState, + // eslint-disable-next-line no-restricted-syntax -- prosemirror issue entityStorePlugin: Plugin, ] >((calls) => { @@ -782,6 +785,7 @@ export const createEntityStorePlugin = ({ }: { ownedById: OwnedById; }) => { + // eslint-disable-next-line no-restricted-syntax -- prosemirror issue const entityStorePlugin = new Plugin({ key: entityStorePluginKey, state: { diff --git a/libs/@local/hash-isomorphic-utils/src/flows/action-definitions.ts b/libs/@local/hash-isomorphic-utils/src/flows/action-definitions.ts index d4a9842d4fd..45910a2ee65 100644 --- a/libs/@local/hash-isomorphic-utils/src/flows/action-definitions.ts +++ b/libs/@local/hash-isomorphic-utils/src/flows/action-definitions.ts @@ -6,23 +6,20 @@ import type { StepInput, } from "./types.js"; -const actionDefinitionIds = [ - "answerQuestion", - "generateWebQueries", - "getFileFromUrl", - "getWebPageByUrl", - "getWebPageSummary", - "inferMetadataFromDocument", - "inferEntitiesFromContent", - "processAutomaticBrowsingSettings", - "persistEntities", - "persistEntity", - "researchEntities", - "webSearch", - "writeGoogleSheet", -] as const; - -export type ActionDefinitionId = (typeof actionDefinitionIds)[number]; +export type ActionDefinitionId = + | "answerQuestion" + | "generateWebQueries" + | "getFileFromUrl" + | "getWebPageByUrl" + | "getWebPageSummary" + | "inferMetadataFromDocument" + | "inferEntitiesFromContent" + | "processAutomaticBrowsingSettings" + | "persistEntities" + | "persistEntity" + | "researchEntities" + | "webSearch" + | "writeGoogleSheet"; const actionDefinitionsAsConst = { generateWebQueries: { diff --git a/libs/@local/hash-isomorphic-utils/src/flows/trigger-definitions.ts b/libs/@local/hash-isomorphic-utils/src/flows/trigger-definitions.ts index bdd937a98fd..537655a3779 100644 --- a/libs/@local/hash-isomorphic-utils/src/flows/trigger-definitions.ts +++ b/libs/@local/hash-isomorphic-utils/src/flows/trigger-definitions.ts @@ -1,13 +1,10 @@ import type { DeepReadOnly, TriggerDefinition } from "./types.js"; -const triggerIds = [ - "onFileUpload", - "userTrigger", - "userVisitedWebPageTrigger", - "scheduledTrigger", -] as const; - -export type TriggerDefinitionId = (typeof triggerIds)[number]; +export type TriggerDefinitionId = + | "onFileUpload" + | "userTrigger" + | "userVisitedWebPageTrigger" + | "scheduledTrigger"; const triggerDefinitionsAsConst = { onFileUpload: { diff --git a/libs/@local/hash-isomorphic-utils/src/flows/types.ts b/libs/@local/hash-isomorphic-utils/src/flows/types.ts index b05a642ec70..d0c51b25af3 100644 --- a/libs/@local/hash-isomorphic-utils/src/flows/types.ts +++ b/libs/@local/hash-isomorphic-utils/src/flows/types.ts @@ -594,15 +594,12 @@ export type StepProgressLog = | ViewedFile | VisitedWebPageLog; -const flowSignalTypes = [ - "externalInputRequest", - "externalInputResponse", - "logProgress", - "researchActionCheckpoint", - "stopWorker", -] as const; - -export type FlowSignalType = (typeof flowSignalTypes)[number]; +export type FlowSignalType = + | "externalInputRequest" + | "externalInputResponse" + | "logProgress" + | "researchActionCheckpoint" + | "stopWorker"; export type ProgressLogSignal = { attempt: number; diff --git a/libs/@local/hash-isomorphic-utils/src/sanitize.ts b/libs/@local/hash-isomorphic-utils/src/sanitize.ts index 5db031d7d3f..d0d0fec8c4d 100644 --- a/libs/@local/hash-isomorphic-utils/src/sanitize.ts +++ b/libs/@local/hash-isomorphic-utils/src/sanitize.ts @@ -17,7 +17,7 @@ export const sanitizeHref = (url?: string) => { } return href; - } catch (err) { + } catch { // eslint-disable-next-line no-console console.error(`Could not construct URL from ${url}`); return ""; diff --git a/libs/@local/hash-isomorphic-utils/src/stringify-property-value.ts b/libs/@local/hash-isomorphic-utils/src/stringify-property-value.ts index cda96c61490..a5627942add 100644 --- a/libs/@local/hash-isomorphic-utils/src/stringify-property-value.ts +++ b/libs/@local/hash-isomorphic-utils/src/stringify-property-value.ts @@ -40,5 +40,7 @@ export const stringifyPropertyValue = (propertyValue: unknown): string => { } // Otherwise directly stringify the property value (for example if it's a number) + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line @typescript-eslint/no-base-to-string return String(propertyValue); }; diff --git a/libs/@local/hash-isomorphic-utils/src/wrap-entities-plugin.ts b/libs/@local/hash-isomorphic-utils/src/wrap-entities-plugin.ts index 52a491f5ae3..04bf7265848 100644 --- a/libs/@local/hash-isomorphic-utils/src/wrap-entities-plugin.ts +++ b/libs/@local/hash-isomorphic-utils/src/wrap-entities-plugin.ts @@ -257,6 +257,7 @@ export const wrapEntitiesPlugin = (baseKeymap: Record) => { * This plugin ensures at the end of every transaction all necessary nodes * are wrapped with block nodeviews */ + // eslint-disable-next-line no-restricted-syntax -- prosemirror issue const ensureWrappedPlugin = new Plugin({ appendTransaction: (_, __, newState) => ensureEntitiesAreWrapped(newState), }); diff --git a/libs/@local/hash-isomorphic-utils/tsconfig.json b/libs/@local/hash-isomorphic-utils/tsconfig.json index 83c9cf7fefb..57db930a6b8 100644 --- a/libs/@local/hash-isomorphic-utils/tsconfig.json +++ b/libs/@local/hash-isomorphic-utils/tsconfig.json @@ -1,6 +1,12 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["src", "codegen.config.ts", "/**/*.gen.json"], + "include": [ + "src", + "codegen.config.ts", + "/**/*.gen.json", + "eslint.config.js", + "vitest.config.ts" + ], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext", diff --git a/libs/@local/hash-backend-utils/vitest.config.js b/libs/@local/hash-isomorphic-utils/vitest.config.ts similarity index 91% rename from libs/@local/hash-backend-utils/vitest.config.js rename to libs/@local/hash-isomorphic-utils/vitest.config.ts index f19ca5fb70a..1feb2e96bcd 100644 --- a/libs/@local/hash-backend-utils/vitest.config.js +++ b/libs/@local/hash-isomorphic-utils/vitest.config.ts @@ -1,4 +1,3 @@ -/// import { defineConfig } from "vitest/config"; export default defineConfig({ diff --git a/libs/@local/hash-subgraph/.eslintrc.cjs b/libs/@local/hash-subgraph/.eslintrc.cjs deleted file mode 100644 index 568c500804e..00000000000 --- a/libs/@local/hash-subgraph/.eslintrc.cjs +++ /dev/null @@ -1,4 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), -}; diff --git a/libs/@local/hash-subgraph/eslint.config.js b/libs/@local/hash-subgraph/eslint.config.js new file mode 100644 index 00000000000..0eac3025266 --- /dev/null +++ b/libs/@local/hash-subgraph/eslint.config.js @@ -0,0 +1,3 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default createBase(import.meta.dirname); diff --git a/libs/@local/hash-subgraph/package.json b/libs/@local/hash-subgraph/package.json index fb34004835e..e1efa1bf65f 100644 --- a/libs/@local/hash-subgraph/package.json +++ b/libs/@local/hash-subgraph/package.json @@ -39,10 +39,10 @@ "uuid": "9.0.1" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@types/uuid": "10.0.0", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3", "vitest": "2.1.8" diff --git a/libs/@local/hash-subgraph/tsconfig.json b/libs/@local/hash-subgraph/tsconfig.json index b60fa3ed434..35a36985b1e 100644 --- a/libs/@local/hash-subgraph/tsconfig.json +++ b/libs/@local/hash-subgraph/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["src", "tests"], + "include": ["src", "tests", "eslint.config.js", "vitest.config.ts"], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" diff --git a/libs/@local/graph/sdk/typescript/vitest.config.js b/libs/@local/hash-subgraph/vitest.config.ts similarity index 100% rename from libs/@local/graph/sdk/typescript/vitest.config.js rename to libs/@local/hash-subgraph/vitest.config.ts diff --git a/libs/@local/internal-api-client/typescript/package.json b/libs/@local/internal-api-client/typescript/package.json index 0fe25df176c..76e527d5f70 100644 --- a/libs/@local/internal-api-client/typescript/package.json +++ b/libs/@local/internal-api-client/typescript/package.json @@ -15,7 +15,6 @@ "axios": "1.7.9" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", "@openapitools/openapi-generator-cli": "2.15.3", "@types/node": "22.10.1", "prettier": "3.4.2", diff --git a/libs/@local/repo-chores/node/.eslintrc.cjs b/libs/@local/repo-chores/node/.eslintrc.cjs deleted file mode 100644 index ae0bc9befab..00000000000 --- a/libs/@local/repo-chores/node/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - "global-require": "off", - }, -}; diff --git a/libs/@local/repo-chores/node/eslint.config.js b/libs/@local/repo-chores/node/eslint.config.js new file mode 100644 index 00000000000..9d16684fdcd --- /dev/null +++ b/libs/@local/repo-chores/node/eslint.config.js @@ -0,0 +1,13 @@ +import { createBase, defineConfig } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...defineConfig([ + { + rules: { + "global-require": "off", + }, + }, + { ignores: ["**/scripts/**/.eslintrc.cjs"] }, + ]), +]; diff --git a/libs/@local/repo-chores/node/package.json b/libs/@local/repo-chores/node/package.json index c2e27bdaf9d..584a2ad8b56 100644 --- a/libs/@local/repo-chores/node/package.json +++ b/libs/@local/repo-chores/node/package.json @@ -22,11 +22,11 @@ "typescript": "5.6.3" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/fs-extra": "9.0.13", "@types/prettier": "3.0.0", - "eslint": "8.57.0", + "eslint": "9.16.0", "typescript": "5.6.3" } } diff --git a/libs/@local/repo-chores/node/scripts/create-block.ts b/libs/@local/repo-chores/node/scripts/create-block.ts index 725d57ee5c6..c0d1c8f2fa7 100644 --- a/libs/@local/repo-chores/node/scripts/create-block.ts +++ b/libs/@local/repo-chores/node/scripts/create-block.ts @@ -1,4 +1,4 @@ -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import type { JsonObject } from "@blockprotocol/core"; @@ -8,7 +8,7 @@ import fs from "fs-extra"; import { monorepoRootDirPath } from "./shared/monorepo"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const script = async () => { const args = process.argv.slice(2); @@ -59,7 +59,7 @@ const script = async () => { (packageJson.scripts as JsonObject).format = "prettier --write --ignore-unknown src/types/generated/*.ts"; - (packageJson.devDependencies as JsonObject)["@local/eslint-config"] = + (packageJson.devDependencies as JsonObject)["@local/eslint"] = "0.0.0-private"; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); diff --git a/libs/@local/repo-chores/node/scripts/shared/monorepo.ts b/libs/@local/repo-chores/node/scripts/shared/monorepo.ts index f445e14b18e..e02d6bcf2c2 100644 --- a/libs/@local/repo-chores/node/scripts/shared/monorepo.ts +++ b/libs/@local/repo-chores/node/scripts/shared/monorepo.ts @@ -1,10 +1,10 @@ -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import execa from "execa"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); export const monorepoRootDirPath = path.resolve(__dirname, "../../../../../.."); diff --git a/libs/@local/repo-chores/node/tsconfig.json b/libs/@local/repo-chores/node/tsconfig.json index 7d1d7a1d07e..3154c3f4e8e 100644 --- a/libs/@local/repo-chores/node/tsconfig.json +++ b/libs/@local/repo-chores/node/tsconfig.json @@ -1,4 +1,5 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", + "include": ["scripts"], "exclude": ["scripts/create-block/**/*.d.ts"] } diff --git a/libs/@local/status/typescript/.eslintrc.cjs b/libs/@local/status/typescript/.eslintrc.cjs deleted file mode 100644 index fff09db378a..00000000000 --- a/libs/@local/status/typescript/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - "no-console": "off", - }, -}; diff --git a/libs/@local/status/typescript/eslint.config.js b/libs/@local/status/typescript/eslint.config.js new file mode 100644 index 00000000000..a80412afd2e --- /dev/null +++ b/libs/@local/status/typescript/eslint.config.js @@ -0,0 +1,10 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { + rules: { + "no-console": "off", + }, + }, +]; diff --git a/libs/@local/status/typescript/package.json b/libs/@local/status/typescript/package.json index b5813fcb2e9..b20264604c9 100644 --- a/libs/@local/status/typescript/package.json +++ b/libs/@local/status/typescript/package.json @@ -22,12 +22,12 @@ "yargs": "17.7.2" }, "devDependencies": { - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/lodash-es": "4.17.12", "@types/node": "22.10.1", "@types/yargs": "17.0.33", - "eslint": "8.57.0", + "eslint": "9.16.0", "quicktype": "16.0.43", "rimraf": "6.0.1", "typescript": "5.6.3" diff --git a/libs/@local/status/typescript/scripts/codegen.ts b/libs/@local/status/typescript/scripts/codegen.ts index 9412e7868a1..4667d646487 100644 --- a/libs/@local/status/typescript/scripts/codegen.ts +++ b/libs/@local/status/typescript/scripts/codegen.ts @@ -2,7 +2,7 @@ import { existsSync, lstatSync, rmSync } from "node:fs"; import { mkdir, readdir, writeFile } from "node:fs/promises"; -import * as path from "node:path"; +import path from "node:path"; import { argv } from "node:process"; import execa from "execa"; diff --git a/libs/@local/status/typescript/tsconfig.json b/libs/@local/status/typescript/tsconfig.json index 57af11e8ed8..ab95f2df657 100644 --- a/libs/@local/status/typescript/tsconfig.json +++ b/libs/@local/status/typescript/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["./pkg/src/", "./scripts", "./type-defs"], + "include": ["./pkg/src/", "./scripts", "./type-defs", "eslint.config.js"], "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" diff --git a/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json b/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json index 92281e929e0..decdf82abc6 100644 --- a/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json +++ b/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json @@ -34,7 +34,9 @@ "@local/hash-subgraph": ["../hash-subgraph/src/main.ts"], "@local/hash-subgraph/*": ["../hash-subgraph/src/*.ts"], "@local/harpc-client": ["../harpc/client/typescript/src/index.ts"], - "@local/harpc-client/*": ["../harpc/client/typescript/src/*/index.ts"] + "@local/harpc-client/*": ["../harpc/client/typescript/src/*/index.ts"], + "@local/eslint": ["../eslint/src/index.ts"], + "@local/eslint/*": ["../eslint/src/*/index.ts"] }, "outDir": "./dist" }, diff --git a/tests/hash-backend-integration/.eslintrc.cjs b/tests/hash-backend-integration/.eslintrc.cjs deleted file mode 100644 index 04db4b6f9a6..00000000000 --- a/tests/hash-backend-integration/.eslintrc.cjs +++ /dev/null @@ -1,14 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - ...require("@local/eslint-config/temporarily-disable-rules.cjs")([ - /* 2022-11-29: 82 */ "@typescript-eslint/no-unsafe-assignment", - /* 2022-11-29: 28 */ "@typescript-eslint/no-unsafe-call", - /* 2022-11-29: 81 */ "@typescript-eslint/no-unsafe-member-access", - ]), - }, - env: { - node: true, - }, -}; diff --git a/tests/hash-backend-integration/eslint.config.js b/tests/hash-backend-integration/eslint.config.js new file mode 100644 index 00000000000..53e3d898462 --- /dev/null +++ b/tests/hash-backend-integration/eslint.config.js @@ -0,0 +1,10 @@ +import { createBase, disableRules } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + ...disableRules([ + /* 2022-11-29: 82 */ "@typescript-eslint/no-unsafe-assignment", + /* 2022-11-29: 28 */ "@typescript-eslint/no-unsafe-call", + /* 2022-11-29: 81 */ "@typescript-eslint/no-unsafe-member-access", + ]), +]; diff --git a/tests/hash-backend-integration/package.json b/tests/hash-backend-integration/package.json index e8c15471c5b..054b0a8d010 100644 --- a/tests/hash-backend-integration/package.json +++ b/tests/hash-backend-integration/package.json @@ -37,11 +37,11 @@ "@graphql-codegen/typescript": "2.8.8", "@graphql-codegen/typescript-graphql-request": "4.5.9", "@graphql-codegen/typescript-resolvers": "2.7.13", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@types/node-fetch": "2.6.12", "@vitest/coverage-istanbul": "2.1.8", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3", "vitest": "2.1.8" diff --git a/tests/hash-backend-integration/src/tests/graph/knowledge/primitive/entity.test.ts b/tests/hash-backend-integration/src/tests/graph/knowledge/primitive/entity.test.ts index 992571ed64e..87ef891424f 100644 --- a/tests/hash-backend-integration/src/tests/graph/knowledge/primitive/entity.test.ts +++ b/tests/hash-backend-integration/src/tests/graph/knowledge/primitive/entity.test.ts @@ -395,6 +395,7 @@ describe("Entity CRU", () => { }, ], }, + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors ).catch((err) => Promise.reject(err)); expect(updatedEntity.metadata.provenance.edition.createdById).toBe( diff --git a/tests/hash-backend-integration/src/tests/graph/ontology/primitive/data-type.test.ts b/tests/hash-backend-integration/src/tests/graph/ontology/primitive/data-type.test.ts index 8f9749a7ed2..162170ccec9 100644 --- a/tests/hash-backend-integration/src/tests/graph/ontology/primitive/data-type.test.ts +++ b/tests/hash-backend-integration/src/tests/graph/ontology/primitive/data-type.test.ts @@ -138,6 +138,7 @@ describe("Data type CRU", () => { schema: { ...dataTypeSchema, title: updatedTitle }, relationships: [{ relation: "viewer", subject: { kind: "public" } }], conversions: {}, + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors }).catch((err) => Promise.reject(err.data)); expect( diff --git a/tests/hash-backend-integration/src/tests/graph/ontology/primitive/entity-type.test.ts b/tests/hash-backend-integration/src/tests/graph/ontology/primitive/entity-type.test.ts index a5c53397ecb..dff7ab2a72b 100644 --- a/tests/hash-backend-integration/src/tests/graph/ontology/primitive/entity-type.test.ts +++ b/tests/hash-backend-integration/src/tests/graph/ontology/primitive/entity-type.test.ts @@ -497,6 +497,7 @@ describe("Entity type CRU", () => { { relation: "instantiator", subject: { kind: "public" } }, ], }, + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors ).catch((err) => Promise.reject(err.data)); expect( diff --git a/tests/hash-backend-integration/src/tests/graph/ontology/primitive/property-type.test.ts b/tests/hash-backend-integration/src/tests/graph/ontology/primitive/property-type.test.ts index 17be1ff7dda..46b40ee8ff8 100644 --- a/tests/hash-backend-integration/src/tests/graph/ontology/primitive/property-type.test.ts +++ b/tests/hash-backend-integration/src/tests/graph/ontology/primitive/property-type.test.ts @@ -156,6 +156,7 @@ describe("Property type CRU", () => { }, ], }, + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors ).catch((err) => Promise.reject(err.data)); expect( diff --git a/tests/hash-backend-integration/tsconfig.json b/tests/hash-backend-integration/tsconfig.json index 2f82e7ab2e5..8ff51e490d6 100644 --- a/tests/hash-backend-integration/tsconfig.json +++ b/tests/hash-backend-integration/tsconfig.json @@ -1,4 +1,4 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", - "include": ["./src/", "codegen.config.ts"] + "include": ["./src/", "codegen.config.ts", "vitest.config.ts"] } diff --git a/tests/hash-backend-integration/vitest.config.js b/tests/hash-backend-integration/vitest.config.ts similarity index 100% rename from tests/hash-backend-integration/vitest.config.js rename to tests/hash-backend-integration/vitest.config.ts diff --git a/tests/hash-backend-load/.eslintrc.cjs b/tests/hash-backend-load/.eslintrc.cjs deleted file mode 100644 index ae0bc9befab..00000000000 --- a/tests/hash-backend-load/.eslintrc.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - rules: { - "global-require": "off", - }, -}; diff --git a/tests/hash-backend-load/eslint.config.js b/tests/hash-backend-load/eslint.config.js new file mode 100644 index 00000000000..2a4de1a5fc4 --- /dev/null +++ b/tests/hash-backend-load/eslint.config.js @@ -0,0 +1,10 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { + rules: { + "global-require": "off", + }, + }, +]; diff --git a/tests/hash-backend-load/package.json b/tests/hash-backend-load/package.json index 5c8620e4db5..031bfd38414 100644 --- a/tests/hash-backend-load/package.json +++ b/tests/hash-backend-load/package.json @@ -49,14 +49,14 @@ }, "devDependencies": { "@apps/hash-api": "0.0.0-private", - "@local/eslint-config": "0.0.0-private", + "@local/eslint": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@rollup/plugin-commonjs": "28.0.1", "@rollup/plugin-node-resolve": "15.3.0", "@rollup/plugin-typescript": "12.1.1", "@types/dotenv-flow": "3.3.3", "@types/uuid": "10.0.0", - "eslint": "8.57.0", + "eslint": "9.16.0", "rimraf": "6.0.1", "rollup": "4.28.1", "typescript": "5.6.3" diff --git a/tests/hash-playwright/.eslintrc.cjs b/tests/hash-playwright/.eslintrc.cjs deleted file mode 100644 index 1e6d27b0164..00000000000 --- a/tests/hash-playwright/.eslintrc.cjs +++ /dev/null @@ -1,22 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - ...require("@local/eslint-config/generate-workspace-config.cjs")(__dirname), - overrides: [ - { - files: ["**/*.{spec,test}.ts"], - rules: { - "no-restricted-imports": [ - "error", - { - paths: [ - { - name: "@playwright/test", - message: "Please import from ./shared/runtime instead", - }, - ], - }, - ], - }, - }, - ], -}; diff --git a/tests/hash-playwright/eslint.config.js b/tests/hash-playwright/eslint.config.js new file mode 100644 index 00000000000..0143e95540b --- /dev/null +++ b/tests/hash-playwright/eslint.config.js @@ -0,0 +1,21 @@ +import { createBase } from "@local/eslint/deprecated"; + +export default [ + ...createBase(import.meta.dirname), + { + files: ["**/*.{spec,test}.ts"], + rules: { + "no-restricted-imports": [ + "error", + { + paths: [ + { + name: "@playwright/test", + message: "Please import from ./shared/runtime instead", + }, + ], + }, + ], + }, + }, +]; diff --git a/tests/hash-playwright/package.json b/tests/hash-playwright/package.json index ae2212a195d..8e867784c5c 100644 --- a/tests/hash-playwright/package.json +++ b/tests/hash-playwright/package.json @@ -11,18 +11,15 @@ "test:integration": "PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1 PW_EXPERIMENTAL_TS_ESM=1 npx playwright test --project chromium" }, "dependencies": { - "@local/eslint-config": "0.0.0-private", "@local/hash-backend-utils": "0.0.0-private", "@local/hash-graph-sdk": "0.0.0-private", "@local/hash-isomorphic-utils": "0.0.0-private", "@local/hash-subgraph": "0.0.0-private", "@local/tsconfig": "0.0.0-private", "@playwright/test": "1.49.0", - "eslint": "8.57.0", "execa": "5.1.1", "graphql": "16.9.0", - "js-yaml": "4.1.0", - "typescript": "5.6.3" + "js-yaml": "4.1.0" }, "devDependencies": { "@apps/hash-frontend": "0.0.0-private", @@ -31,7 +28,8 @@ "@apps/plugin-browser": "0.0.8", "@blockprotocol/graph": "0.4.0-canary.0", "@graphql-codegen/cli": "^5.0.3", - "eslint": "8.57.0", + "@local/eslint": "0.0.0-private", + "eslint": "9.16.0", "rimraf": "6.0.1", "typescript": "5.6.3" } diff --git a/tests/hash-playwright/tests/browser-plugin/fixtures.ts b/tests/hash-playwright/tests/browser-plugin/fixtures.ts index 60a40a60fa6..e6a3d72cb8c 100644 --- a/tests/hash-playwright/tests/browser-plugin/fixtures.ts +++ b/tests/hash-playwright/tests/browser-plugin/fixtures.ts @@ -1,10 +1,10 @@ -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { type BrowserContext, chromium, test as base } from "@playwright/test"; const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __dirname = path.dirname(__filename); const monorepoRootDir = path.resolve(__dirname, "../../../../"); @@ -27,6 +27,7 @@ export const test = base.extend<{ ], serviceWorkers: "allow", }); + // eslint-disable-next-line react-hooks/rules-of-hooks await use(context); await context.close(); }, @@ -40,6 +41,7 @@ export const test = base.extend<{ if (!extensionId) { throw new Error("Could not find extension ID"); } + // eslint-disable-next-line react-hooks/rules-of-hooks await use(extensionId); }, }); diff --git a/tests/hash-playwright/tests/shared/runtime.ts b/tests/hash-playwright/tests/shared/runtime.ts index d7c43cd53cb..e4f6dc67bb8 100644 --- a/tests/hash-playwright/tests/shared/runtime.ts +++ b/tests/hash-playwright/tests/shared/runtime.ts @@ -21,13 +21,17 @@ export * from "@playwright/test"; export const test = base.extend({ page: async ({ page }, use) => { const messages: string[] = []; + page.on("console", (msg) => { const text = msg.text(); if (tolerableConsoleMessageMatches.some((match) => match.test(text))) { return; } + messages.push(`[${msg.type()}] ${msg.text()}`); }); + // @todo: https://linear.app/hash/issue/H-3769/investigate-new-eslint-errors + // eslint-disable-next-line react-hooks/rules-of-hooks await use(page); expect( messages, diff --git a/tests/hash-playwright/tsconfig.json b/tests/hash-playwright/tsconfig.json index d9ae39e4854..5a93f1d88c1 100644 --- a/tests/hash-playwright/tsconfig.json +++ b/tests/hash-playwright/tsconfig.json @@ -1,5 +1,6 @@ { "extends": "@local/tsconfig/legacy-base-tsconfig-to-refactor.json", + "include": ["tests", "codegen.config.ts", "playwright.config.ts"], "compilerOptions": { "lib": ["dom", "dom.iterable", "ESNext"] } diff --git a/turbo.json b/turbo.json index d9bb744183d..5e461d3c40d 100644 --- a/turbo.json +++ b/turbo.json @@ -87,7 +87,7 @@ "lint:clippy": {}, "lint:eslint": { "env": ["CHECK_TEMPORARILY_DISABLED_RULES"], - "dependsOn": ["codegen"] + "dependsOn": ["codegen", "@local/eslint#build"] }, "lint:tsc": { "dependsOn": ["codegen"] diff --git a/yarn.config.cjs b/yarn.config.cjs index 4791260fb6b..0f921e4553c 100644 --- a/yarn.config.cjs +++ b/yarn.config.cjs @@ -146,6 +146,10 @@ function enforceDevDependenciesAreProperlyDeclared({ Yarn }) { for (const [key, { commands }] of Object.entries( enforcedDevDependencies, )) { + if (workspace.ident === "@local/eslint" && key === "eslint") { + continue; + } + const scriptSplit = script.split(" "); if (commands.some((command) => scriptSplit.includes(command))) { diff --git a/yarn.lock b/yarn.lock index 38ee93a00fb..660d7206cf8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -295,7 +295,7 @@ __metadata: "@google-cloud/storage": "npm:7.14.0" "@google-cloud/vertexai": "npm:1.9.2" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-backend-utils": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" @@ -331,7 +331,7 @@ __metadata: dedent: "npm:0.7.0" dotenv-flow: "npm:3.3.0" e2b: "npm:0.13.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" exponential-backoff: "npm:3.1.1" googleapis: "npm:133.0.0" is-docker: "npm:3.0.0" @@ -382,7 +382,7 @@ __metadata: "@graphql-tools/schema": "npm:8.5.1" "@linear/sdk": "npm:6.0.0" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/harpc-client": "npm:0.0.0-private" "@local/hash-backend-utils": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" @@ -435,7 +435,7 @@ __metadata: cross-env: "npm:7.0.3" dedent: "npm:0.7.0" effect: "npm:3.11.3" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" exponential-backoff: "npm:3.1.1" express: "npm:4.21.2" express-handlebars: "npm:7.1.3" @@ -509,7 +509,7 @@ __metadata: "@hashintel/type-editor": "npm:0.0.25" "@lit-labs/react": "npm:1.2.1" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" "@local/hash-graph-types": "npm:0.0.0-private" @@ -560,7 +560,7 @@ __metadata: dotenv-flow: "npm:3.3.0" elkjs: "npm:0.9.3" emoji-mart: "npm:5.2.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" fractional-indexing: "npm:2.1.0" framer-motion: "npm:6.5.1" graphology: "npm:0.25.4" @@ -652,7 +652,7 @@ __metadata: "@blockprotocol/type-system": "npm:0.1.2-canary.0" "@linear/sdk": "npm:6.0.0" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-backend-utils": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" @@ -668,7 +668,7 @@ __metadata: agentkeepalive: "npm:4.5.0" axios: "npm:1.7.9" dotenv-flow: "npm:3.3.0" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" rimraf: "npm:6.0.1" tsx: "npm:4.19.2" typescript: "npm:5.6.3" @@ -680,12 +680,12 @@ __metadata: version: 0.0.0-use.local resolution: "@apps/hash-realtime@workspace:apps/hash-realtime" dependencies: - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-backend-utils": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/node": "npm:22.10.1" "@types/set-interval-async": "npm:1.0.3" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" set-interval-async: "npm:2.0.3" slonik: "npm:24.2.0" tsx: "npm:4.19.2" @@ -698,12 +698,12 @@ __metadata: resolution: "@apps/hash-search-loader@workspace:apps/hash-search-loader" dependencies: "@apps/hash-api": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-backend-utils": "npm:0.0.0-private" "@local/hash-isomorphic-utils": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/node": "npm:22.10.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" hot-shots: "npm:8.5.2" tsx: "npm:4.19.2" typescript: "npm:5.6.3" @@ -718,7 +718,7 @@ __metadata: "@babel/preset-typescript": "npm:7.26.0" "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@storybook/addon-essentials": "npm:7.6.20" "@storybook/addon-interactions": "npm:7.6.20" @@ -751,7 +751,7 @@ __metadata: "@emotion/server": "npm:11.11.0" "@emotion/styled": "npm:11.13.5" "@fortawesome/free-solid-svg-icons": "npm:6.7.1" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@matejmazur/react-katex": "npm:3.1.3" "@mui/icons-material": "npm:5.16.9" @@ -776,7 +776,7 @@ __metadata: d3: "npm:7.9.0" d3-dag: "npm:1.1.0" date-fns: "npm:4.1.0" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" execa: "npm:7.2.0" feed: "npm:4.2.2" fs-extra: "npm:10.1.0" @@ -814,7 +814,6 @@ __metadata: resolution: "@apps/plugin-browser@workspace:apps/plugin-browser" dependencies: "@babel/core": "npm:7.26.0" - "@babel/eslint-parser": "npm:7.25.9" "@babel/plugin-proposal-class-properties": "npm:7.18.6" "@babel/plugin-proposal-private-property-in-object": "npm:^7.16.7" "@babel/preset-env": "npm:7.26.0" @@ -825,7 +824,7 @@ __metadata: "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" "@local/hash-graph-types": "npm:0.0.0-private" @@ -849,7 +848,7 @@ __metadata: css-loader: "npm:6.11.0" date-fns: "npm:4.1.0" dotenv-flow: "npm:3.3.0" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" file-loader: "npm:6.2.0" fractional-indexing: "npm:2.1.0" fs-extra: "npm:11.1.0" @@ -997,6 +996,13 @@ __metadata: languageName: node linkType: hard +"@astrojs/compiler@npm:^2.0.0": + version: 2.10.3 + resolution: "@astrojs/compiler@npm:2.10.3" + checksum: 10c0/35e7a6e9d197924a3203afd3bd7bff39c8d4271516816c30173cca872302312c3748eefc5a5832523f49b98743115628a1b96922d7d96588a8d96e110a106b88 + languageName: node + linkType: hard + "@aw-web-design/x-default-browser@npm:1.4.126": version: 1.4.126 resolution: "@aw-web-design/x-default-browser@npm:1.4.126" @@ -2373,7 +2379,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0": version: 7.26.2 resolution: "@babel/code-frame@npm:7.26.2" dependencies: @@ -2620,7 +2626,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.25.9": +"@babel/helper-validator-identifier@npm:^7.24.5, @babel/helper-validator-identifier@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-identifier@npm:7.25.9" checksum: 10c0/4fc6f830177b7b7e887ad3277ddb3b91d81e6c4a24151540d9d1023e8dc6b1c0505f0f0628ae653601eb4388a8db45c1c14b2c07a9173837aef7e4116456259d @@ -3904,7 +3910,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.17.9, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.5, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.17.9, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.5, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.26.0 resolution: "@babel/runtime@npm:7.26.0" dependencies: @@ -4110,14 +4116,14 @@ __metadata: dependencies: "@blockprotocol/core": "npm:0.1.3" "@blockprotocol/type-system": "npm:0.1.2-canary.0" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/lodash.isequal": "npm:4.5.8" "@types/node": "npm:22.10.1" "@types/react": "npm:18.2.68" ajv: "npm:8.17.1" ajv-formats: "npm:3.0.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" json-schema-to-typescript: "npm:11.0.5" lit: "npm:2.8.0" lodash.isequal: "npm:4.5.0" @@ -4197,7 +4203,7 @@ __metadata: resolution: "@blockprotocol/type-system@workspace:libs/@blockprotocol/type-system/typescript" dependencies: "@blockprotocol/type-system-rs": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@rollup/plugin-node-resolve": "npm:15.3.0" "@rollup/plugin-typescript": "npm:12.1.1" @@ -4205,7 +4211,7 @@ __metadata: "@types/node": "npm:22.10.1" "@types/react": "npm:18.2.68" "@vitest/coverage-istanbul": "npm:2.1.8" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" react: "npm:18.2.0" rimraf: "npm:6.0.1" rollup: "npm:4.28.1" @@ -4226,13 +4232,13 @@ __metadata: "@fortawesome/free-solid-svg-icons": "npm:6.7.1" "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/lodash.debounce": "npm:4.0.9" "@types/react-dom": "npm:18.2.25" "@types/uuid": "npm:10.0.0" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" lodash.debounce: "npm:4.0.8" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" @@ -4257,13 +4263,13 @@ __metadata: "@blockprotocol/service": "npm:0.1.4" "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/react-dom": "npm:18.2.25" "@types/uuid": "npm:10.0.0" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4287,13 +4293,13 @@ __metadata: "@blockprotocol/service": "npm:0.1.4" "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/react-dom": "npm:18.2.25" "@types/uuid": "npm:10.0.0" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4315,12 +4321,12 @@ __metadata: "@blockprotocol/service": "npm:0.1.4" "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4338,11 +4344,11 @@ __metadata: dependencies: "@blockprotocol/graph": "npm:0.3.4" "@blockprotocol/hook": "npm:0.1.3" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4363,7 +4369,8 @@ __metadata: "@emotion/styled": "npm:11.13.5" "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" + "@local/hash-isomorphic-utils": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/lodash.debounce": "npm:4.0.9" @@ -4371,7 +4378,7 @@ __metadata: "@types/react-is": "npm:18.3.0" block-scripts: "npm:0.3.4" echarts: "npm:5.5.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" lodash.debounce: "npm:4.0.8" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" @@ -4390,12 +4397,12 @@ __metadata: resolution: "@blocks/code@workspace:blocks/code" dependencies: "@blockprotocol/graph": "npm:0.3.4" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/prismjs": "npm:1.26.5" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" prismjs: "npm:1.29.0" @@ -4413,13 +4420,13 @@ __metadata: resolution: "@blocks/countdown@workspace:blocks/countdown" dependencies: "@blockprotocol/graph": "npm:0.3.4" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-datepicker": "npm:4.19.6" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" date-fns: "npm:4.1.0" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4438,11 +4445,11 @@ __metadata: dependencies: "@blockprotocol/core": "npm:0.1.3" "@blockprotocol/graph": "npm:0.3.4" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4458,13 +4465,13 @@ __metadata: version: 0.0.0-use.local resolution: "@blocks/embed@workspace:blocks/embed" dependencies: - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/lodash": "npm:4.17.13" "@types/react-dom": "npm:18.0.9" block-scripts: "npm:0.0.14" blockprotocol: "patch:blockprotocol@npm%3A0.0.12#~/.yarn/patches/blockprotocol-npm-0.0.12-2558a31f0a.patch" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" lodash: "npm:4.17.21" mock-block-dock: "npm:0.0.10" react: "npm:18.2.0" @@ -4485,12 +4492,12 @@ __metadata: "@blockprotocol/graph": "npm:0.3.4" "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/react-dom": "npm:18.2.25" "@types/uuid": "npm:10.0.0" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4509,11 +4516,11 @@ __metadata: dependencies: "@blockprotocol/graph": "npm:0.3.4" "@blockprotocol/hook": "npm:0.1.3" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4532,12 +4539,12 @@ __metadata: "@blockprotocol/graph": "npm:0.3.4" "@hashintel/block-design-system": "npm:0.0.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/react-dom": "npm:18.2.25" "@types/uuid": "npm:10.0.0" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4557,11 +4564,11 @@ __metadata: dependencies: "@blockprotocol/graph": "npm:0.3.4" "@blockprotocol/hook": "npm:0.1.3" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4583,7 +4590,8 @@ __metadata: "@dnd-kit/sortable": "npm:7.0.2" "@dnd-kit/utilities": "npm:3.2.2" "@hashintel/block-design-system": "npm:0.0.2" - "@local/eslint-config": "npm:0.0.0-private" + "@hashintel/design-system": "npm:0.0.8" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/lodash.clonedeep": "npm:4.5.9" @@ -4592,7 +4600,7 @@ __metadata: "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" clsx: "npm:1.2.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" lodash.clonedeep: "npm:4.5.0" lodash.debounce: "npm:4.0.8" lodash.isequal: "npm:4.5.0" @@ -4613,11 +4621,11 @@ __metadata: resolution: "@blocks/minesweeper@workspace:blocks/minesweeper" dependencies: "@blockprotocol/graph": "npm:0.3.4" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" lit: "npm:2.8.0" mine-sweeper-tag: "npm:1.0.6" mock-block-dock: "npm:0.1.9" @@ -4634,11 +4642,11 @@ __metadata: dependencies: "@blockprotocol/graph": "npm:0.3.4" "@blockprotocol/hook": "npm:0.1.3" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4655,13 +4663,13 @@ __metadata: resolution: "@blocks/person@workspace:blocks/person" dependencies: "@blockprotocol/graph": "npm:0.0.18" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/dompurify": "npm:2.4.0" "@types/react-dom": "npm:18.0.9" block-scripts: "npm:0.0.14" dompurify: "npm:2.5.8" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.0.38" react: "npm:18.2.0" react-dom: "npm:18.2.0" @@ -4681,14 +4689,14 @@ __metadata: "@dnd-kit/sortable": "npm:7.0.2" "@dnd-kit/utilities": "npm:3.2.2" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@mui/icons-material": "npm:5.16.9" "@mui/material": "npm:5.16.9" "@types/lodash.isequal": "npm:4.5.8" "@types/uuid": "npm:10.0.0" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" immer: "npm:9.0.21" lodash.isequal: "npm:4.5.0" mock-block-dock: "npm:0.1.9" @@ -4710,7 +4718,9 @@ __metadata: "@blockprotocol/graph": "npm:0.3.4" "@glideapps/glide-data-grid": "patch:@glideapps/glide-data-grid@npm%3A6.0.3#~/.yarn/patches/@glideapps-glide-data-grid-npm-6.0.3-f71d586425.patch" "@hashintel/block-design-system": "npm:0.0.2" - "@local/eslint-config": "npm:0.0.0-private" + "@hashintel/design-system": "npm:0.0.8" + "@local/eslint": "npm:0.0.0-private" + "@local/hash-isomorphic-utils": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@types/lodash.debounce": "npm:4.0.9" @@ -4719,7 +4729,7 @@ __metadata: "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" clsx: "npm:1.2.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" immer: "npm:9.0.21" lodash.debounce: "npm:4.0.8" lodash.isequal: "npm:4.5.0" @@ -4744,13 +4754,13 @@ __metadata: resolution: "@blocks/timer@workspace:blocks/timer" dependencies: "@blockprotocol/graph": "npm:0.3.4" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" date-fns: "npm:4.1.0" duration-fns: "npm:3.0.2" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -4767,11 +4777,11 @@ __metadata: resolution: "@blocks/video@workspace:blocks/video" dependencies: "@blockprotocol/graph": "npm:0.3.4" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/react-dom": "npm:18.2.25" block-scripts: "npm:0.3.4" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" mock-block-dock: "npm:0.1.9" prettier: "npm:3.4.2" react: "npm:18.2.0" @@ -5333,15 +5343,15 @@ __metadata: linkType: hard "@effect/platform-node-shared@npm:^0.20.4": - version: 0.20.4 - resolution: "@effect/platform-node-shared@npm:0.20.4" + version: 0.20.6 + resolution: "@effect/platform-node-shared@npm:0.20.6" dependencies: "@parcel/watcher": "npm:^2.4.1" multipasta: "npm:^0.2.5" peerDependencies: - "@effect/platform": ^0.70.4 - effect: ^3.11.3 - checksum: 10c0/dca46400c108c1e6ee09010973ebd5ee21b83c660e93c6c5ed36eff1fd157c36b415690f58c3befe83dd5675d202336670c75d04a5fbea8b7a46c6edb38343d1 + "@effect/platform": ^0.70.6 + effect: ^3.11.4 + checksum: 10c0/7f2191ada67dcc8c1e68ba1de39e2155dd2b5decaa86363f066e21e0c70f04604a33d9628e1449eccdff5e0cb198d7ada88b995ee577fda812822d369d1096bc languageName: node linkType: hard @@ -5616,6 +5626,17 @@ __metadata: languageName: node linkType: hard +"@es-joy/jsdoccomment@npm:~0.49.0": + version: 0.49.0 + resolution: "@es-joy/jsdoccomment@npm:0.49.0" + dependencies: + comment-parser: "npm:1.4.1" + esquery: "npm:^1.6.0" + jsdoc-type-pratt-parser: "npm:~4.1.0" + checksum: 10c0/16717507d557d37e7b59456fedeefbe0a3bc93aa2d9c043d5db91e24e076509b6fcb10ee6fd1dafcb0c5bbe50ae329b45de5b83541cb5994a98c9e862a45641e + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/aix-ppc64@npm:0.21.5" @@ -6110,34 +6131,209 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0, @eslint-community/regexpp@npm:^4.12.1, @eslint-community/regexpp@npm:^4.8.0": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" +"@eslint-react/ast@npm:1.17.2": + version: 1.17.2 + resolution: "@eslint-react/ast@npm:1.17.2" + dependencies: + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/typescript-estree": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + birecord: "npm:^0.1.1" + string-ts: "npm:^2.2.0" + ts-pattern: "npm:^5.5.0" + checksum: 10c0/7bbf1e21c399248aed6e193108c9a7aa76795cbd4be5828e64d8110c81e25784ec2480079c185dabf69114149daef3a629ad1307646ea30cfc8d8a192f269510 + languageName: node + linkType: hard + +"@eslint-react/core@npm:1.17.2": + version: 1.17.2 + resolution: "@eslint-react/core@npm:1.17.2" + dependencies: + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/jsx": "npm:1.17.2" + "@eslint-react/shared": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@eslint-react/var": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/type-utils": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + birecord: "npm:^0.1.1" + short-unique-id: "npm:^5.2.0" + ts-pattern: "npm:^5.5.0" + checksum: 10c0/fbc40530cf41c79bed4c3d94ad3a2f9fd0cd6eccdb6da3e1530b08aeff233a0a607de80eae9da97abaf18ed2c13d3386c9e29533c0d857be38a994d6127c04e6 + languageName: node + linkType: hard + +"@eslint-react/eslint-plugin@npm:^1.10.1": + version: 1.17.2 + resolution: "@eslint-react/eslint-plugin@npm:1.17.2" + dependencies: + "@eslint-react/shared": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/type-utils": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + eslint-plugin-react-debug: "npm:1.17.2" + eslint-plugin-react-dom: "npm:1.17.2" + eslint-plugin-react-hooks-extra: "npm:1.17.2" + eslint-plugin-react-naming-convention: "npm:1.17.2" + eslint-plugin-react-web-api: "npm:1.17.2" + eslint-plugin-react-x: "npm:1.17.2" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + eslint: + optional: false + typescript: + optional: true + checksum: 10c0/63ee419ff732f00166e52e1da7aefd6ae6fad42baaf099263ff500e178d064eb3eb612c0a4fa06170250028c5d0f1a0625beaabd30c63186f5a8bb888b3f7bb5 + languageName: node + linkType: hard + +"@eslint-react/jsx@npm:1.17.2": + version: 1.17.2 + resolution: "@eslint-react/jsx@npm:1.17.2" + dependencies: + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@eslint-react/var": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + birecord: "npm:^0.1.1" + ts-pattern: "npm:^5.5.0" + checksum: 10c0/c50566ea1b0bb855d4d0488e2baa0ba2a7b72dc7c91b64ec9a6cb28e1f8d2cc608a1f6695a528ce1cedaef0953540d0bac5f8c98a508e753bbfd58672debd2d0 + languageName: node + linkType: hard + +"@eslint-react/shared@npm:1.17.2": + version: 1.17.2 + resolution: "@eslint-react/shared@npm:1.17.2" + dependencies: + "@eslint-react/tools": "npm:1.17.2" + "@typescript-eslint/utils": "npm:^8.16.0" + local-pkg: "npm:^0.5.1" + picomatch: "npm:^4.0.2" + ts-pattern: "npm:^5.5.0" + checksum: 10c0/d0538077c45eacd372eb0b05379f97f05e0ab1ffe6b05a7bdc1a952f3f64fce73652699d37c6f1d5281bfcbc308aaec8805fc3f99d2352c0cf5484c29480a732 + languageName: node + linkType: hard + +"@eslint-react/tools@npm:1.17.2": + version: 1.17.2 + resolution: "@eslint-react/tools@npm:1.17.2" + checksum: 10c0/ad7222bb93f0766ccf94bd96205eb3412ab8c33fb4a4ffb8cce68cfdc712cbbbf0b14dc948274e771e248af95e3897042c369302f970738a0e555035049ccf78 + languageName: node + linkType: hard + +"@eslint-react/types@npm:1.17.2": + version: 1.17.2 + resolution: "@eslint-react/types@npm:1.17.2" + dependencies: + "@eslint-react/tools": "npm:1.17.2" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + checksum: 10c0/6fce23b85d1baefe121888b35bc2311aa4441dde4f9c9b57f9ed3128161221cbecc44e9bfc74b394a3b6d3b899ca67811a73e048616c81e4258f45228bdd1e3e + languageName: node + linkType: hard + +"@eslint-react/var@npm:1.17.2": + version: 1.17.2 + resolution: "@eslint-react/var@npm:1.17.2" + dependencies: + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + ts-pattern: "npm:^5.5.0" + checksum: 10c0/9b629e072d55cd918d9f2ea34134398819bee1d85947937eb697472117f2e53bca6b2de6fa76cabd9946ddc00eff508b9d125692c1ed592c41f6fdbf412063c6 + languageName: node + linkType: hard + +"@eslint/compat@npm:1.2.4, @eslint/compat@npm:^1.1.1": + version: 1.2.4 + resolution: "@eslint/compat@npm:1.2.4" + peerDependencies: + eslint: ^9.10.0 + peerDependenciesMeta: + eslint: + optional: true + checksum: 10c0/afea54435f0ae6b05f1b732132ae4a9d95ff106be0fc9988ac19f31037eb89b2a0e968212be4d2fbf757ff16923031825a27739d94a365559089dfd8269331e3 + languageName: node + linkType: hard + +"@eslint/config-array@npm:^0.19.0": + version: 0.19.0 + resolution: "@eslint/config-array@npm:0.19.0" + dependencies: + "@eslint/object-schema": "npm:^2.1.4" + debug: "npm:^4.3.1" + minimatch: "npm:^3.1.2" + checksum: 10c0/def23c6c67a8f98dc88f1b87e17a5668e5028f5ab9459661aabfe08e08f2acd557474bbaf9ba227be0921ae4db232c62773dbb7739815f8415678eb8f592dbf5 + languageName: node + linkType: hard + +"@eslint/core@npm:^0.9.0": + version: 0.9.0 + resolution: "@eslint/core@npm:0.9.0" + checksum: 10c0/6d8e8e0991cef12314c49425d8d2d9394f5fb1a36753ff82df7c03185a4646cb7c8736cf26638a4a714782cedf4b23cfc17667d282d3e5965b3920a0e7ce20d4 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:3.2.0, @eslint/eslintrc@npm:^3.2.0": + version: 3.2.0 + resolution: "@eslint/eslintrc@npm:3.2.0" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" - espree: "npm:^9.6.0" - globals: "npm:^13.19.0" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" ignore: "npm:^5.2.0" import-fresh: "npm:^3.2.1" js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: 10c0/32f67052b81768ae876c84569ffd562491ec5a5091b0c1e1ca1e0f3c24fb42f804952fdd0a137873bc64303ba368a71ba079a6f691cee25beee9722d94cc8573 + checksum: 10c0/43867a07ff9884d895d9855edba41acf325ef7664a8df41d957135a81a477ff4df4196f5f74dc3382627e5cc8b7ad6b815c2cea1b58f04a75aced7c43414ab8b + languageName: node + linkType: hard + +"@eslint/js@npm:9.16.0, @eslint/js@npm:^9.14.0": + version: 9.16.0 + resolution: "@eslint/js@npm:9.16.0" + checksum: 10c0/a55846a4ddade720662d36682f3eaaf38eac06eeee12c83bb837bba2b7d550dadcb3445b104219f0bc1da2e09b4fe5fb5ba123b8338c8c787bcfbd540878df75 languageName: node linkType: hard -"@eslint/js@npm:8.57.0": - version: 8.57.0 - resolution: "@eslint/js@npm:8.57.0" - checksum: 10c0/9a518bb8625ba3350613903a6d8c622352ab0c6557a59fe6ff6178bf882bf57123f9d92aa826ee8ac3ee74b9c6203fe630e9ee00efb03d753962dcf65ee4bd94 +"@eslint/object-schema@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/object-schema@npm:2.1.4" + checksum: 10c0/e9885532ea70e483fb007bf1275968b05bb15ebaa506d98560c41a41220d33d342e19023d5f2939fed6eb59676c1bda5c847c284b4b55fce521d282004da4dda + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.2.3": + version: 0.2.3 + resolution: "@eslint/plugin-kit@npm:0.2.3" + dependencies: + levn: "npm:^0.4.1" + checksum: 10c0/89a8035976bb1780e3fa8ffe682df013bd25f7d102d991cecd3b7c297f4ce8c1a1b6805e76dd16465b5353455b670b545eff2b4ec3133e0eab81a5f9e99bd90f languageName: node linkType: hard @@ -7250,7 +7446,7 @@ __metadata: "@emotion/react": "npm:11.13.5" "@emotion/styled": "npm:11.13.5" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-isomorphic-utils": "npm:0.0.0-private" "@local/hash-subgraph": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" @@ -7259,8 +7455,8 @@ __metadata: "@types/react": "npm:18.2.68" "@types/react-dom": "npm:18.2.25" "@types/react-syntax-highlighter": "npm:15.5.13" - eslint: "npm:8.57.0" - eslint-plugin-storybook: "npm:0.8.0" + eslint: "npm:9.16.0" + eslint-plugin-storybook: "npm:0.11.1" lowlight: "npm:2.9.0" react: "npm:18.2.0" react-dom: "npm:18.2.0" @@ -7288,7 +7484,7 @@ __metadata: "@emotion/styled": "npm:11.13.5" "@fortawesome/free-regular-svg-icons": "npm:6.7.1" "@fortawesome/free-solid-svg-icons": "npm:6.7.1" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-isomorphic-utils": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" @@ -7298,8 +7494,8 @@ __metadata: "@types/react-dom": "npm:18.2.25" clsx: "npm:1.2.1" echarts: "npm:5.5.1" - eslint: "npm:8.57.0" - eslint-plugin-storybook: "npm:0.8.0" + eslint: "npm:9.16.0" + eslint-plugin-storybook: "npm:0.11.1" react: "npm:18.2.0" react-dom: "npm:18.2.0" react-loading-skeleton: "npm:3.5.0" @@ -7324,11 +7520,12 @@ __metadata: "@fortawesome/free-regular-svg-icons": "npm:6.7.1" "@fortawesome/free-solid-svg-icons": "npm:6.7.1" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@mui/system": "npm:5.16.8" clsx: "npm:1.2.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" + eslint-plugin-storybook: "npm:0.11.1" react: "npm:18.2.0" react-dom: "npm:18.2.0" react-hook-form: "npm:7.54.0" @@ -7351,14 +7548,15 @@ __metadata: "@fortawesome/free-regular-svg-icons": "npm:6.7.1" "@fortawesome/free-solid-svg-icons": "npm:6.7.1" "@hashintel/design-system": "npm:0.0.8" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-subgraph": "npm:0.0.0-private" "@mui/material": "npm:5.16.9" "@mui/system": "npm:5.16.8" "@types/lodash.memoize": "npm:4.1.9" "@types/lodash.uniqueid": "npm:4.0.9" clsx: "npm:1.2.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" + eslint-plugin-storybook: "npm:0.11.1" lodash.memoize: "npm:4.1.2" lodash.uniqueid: "npm:4.0.1" material-ui-popup-state: "npm:4.1.0" @@ -7384,14 +7582,20 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.14": - version: 0.11.14 - resolution: "@humanwhocodes/config-array@npm:0.11.14" +"@humanfs/core@npm:^0.19.1": + version: 0.19.1 + resolution: "@humanfs/core@npm:0.19.1" + checksum: 10c0/aa4e0152171c07879b458d0e8a704b8c3a89a8c0541726c6b65b81e84fd8b7564b5d6c633feadc6598307d34564bd53294b533491424e8e313d7ab6c7bc5dc67 + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.6 + resolution: "@humanfs/node@npm:0.16.6" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.2" - debug: "npm:^4.3.1" - minimatch: "npm:^3.0.5" - checksum: 10c0/66f725b4ee5fdd8322c737cb5013e19fac72d4d69c8bf4b7feb192fcb83442b035b92186f8e9497c220e58b2d51a080f28a73f7899bc1ab288c3be172c467541 + "@humanfs/core": "npm:^0.19.1" + "@humanwhocodes/retry": "npm:^0.3.0" + checksum: 10c0/8356359c9f60108ec204cbd249ecd0356667359b2524886b357617c4a7c3b6aace0fd5a369f63747b926a762a88f8a25bc066fa1778508d110195ce7686243e1 languageName: node linkType: hard @@ -7402,10 +7606,17 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2": - version: 2.0.3 - resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c +"@humanwhocodes/retry@npm:^0.3.0": + version: 0.3.1 + resolution: "@humanwhocodes/retry@npm:0.3.1" + checksum: 10c0/f0da1282dfb45e8120480b9e2e275e2ac9bbe1cf016d046fdad8e27cc1285c45bb9e711681237944445157b430093412b4446c1ab3fc4bb037861b5904101d3b + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.4.1": + version: 0.4.1 + resolution: "@humanwhocodes/retry@npm:0.4.1" + checksum: 10c0/be7bb6841c4c01d0b767d9bb1ec1c9359ee61421ce8ba66c249d035c5acdfd080f32d55a5c9e859cdd7868788b8935774f65b2caf24ec0b7bd7bf333791f063b languageName: node linkType: hard @@ -8040,7 +8251,7 @@ __metadata: languageName: node linkType: hard -"@libp2p/crypto@npm:5.0.7, @libp2p/crypto@npm:^5.0.0, @libp2p/crypto@npm:^5.0.7": +"@libp2p/crypto@npm:5.0.7": version: 5.0.7 resolution: "@libp2p/crypto@npm:5.0.7" dependencies: @@ -8056,6 +8267,22 @@ __metadata: languageName: node linkType: hard +"@libp2p/crypto@npm:^5.0.0, @libp2p/crypto@npm:^5.0.7, @libp2p/crypto@npm:^5.0.8": + version: 5.0.8 + resolution: "@libp2p/crypto@npm:5.0.8" + dependencies: + "@libp2p/interface": "npm:^2.3.0" + "@noble/curves": "npm:^1.7.0" + "@noble/hashes": "npm:^1.6.1" + asn1js: "npm:^3.0.5" + multiformats: "npm:^13.3.1" + protons-runtime: "npm:^5.5.0" + uint8arraylist: "npm:^2.4.8" + uint8arrays: "npm:^5.1.0" + checksum: 10c0/ae26cf47d613be458330f8611b39274b0fc008f46a56834914b5a0753b4bf552ed6da22d33e88ca4ca1a2c5d8ff088d902d7ad5d7c128fdde014d968800612ee + languageName: node + linkType: hard + "@libp2p/identify@npm:3.0.12": version: 3.0.12 resolution: "@libp2p/identify@npm:3.0.12" @@ -8080,19 +8307,19 @@ __metadata: linkType: hard "@libp2p/interface-internal@npm:^2.1.1": - version: 2.1.1 - resolution: "@libp2p/interface-internal@npm:2.1.1" + version: 2.2.0 + resolution: "@libp2p/interface-internal@npm:2.2.0" dependencies: - "@libp2p/interface": "npm:^2.2.1" - "@libp2p/peer-collections": "npm:^6.0.12" - "@multiformats/multiaddr": "npm:^12.2.3" - progress-events: "npm:^1.0.0" + "@libp2p/interface": "npm:^2.3.0" + "@libp2p/peer-collections": "npm:^6.0.13" + "@multiformats/multiaddr": "npm:^12.3.3" + progress-events: "npm:^1.0.1" uint8arraylist: "npm:^2.4.8" - checksum: 10c0/933f735df4da214fc96df8a1a9c7bdaba677e258939604ea3c6d687385ce02f1880273fa902115e9f1f8cee103f54e7158be6695f23eb97d959312360c74e996 + checksum: 10c0/241c5962ab1a11ff3f0b613ad3db82fc4616672e5bf5dcc36023925c815d4382221ad57f4cd5d31d83a825d39d54eb4808acd525d00d8c4a8e916ec950b54aa7 languageName: node linkType: hard -"@libp2p/interface@npm:2.2.1, @libp2p/interface@npm:^2.0.0, @libp2p/interface@npm:^2.2.1": +"@libp2p/interface@npm:2.2.1": version: 2.2.1 resolution: "@libp2p/interface@npm:2.2.1" dependencies: @@ -8106,95 +8333,109 @@ __metadata: languageName: node linkType: hard -"@libp2p/logger@npm:^5.0.1, @libp2p/logger@npm:^5.1.4": - version: 5.1.4 - resolution: "@libp2p/logger@npm:5.1.4" +"@libp2p/interface@npm:^2.0.0, @libp2p/interface@npm:^2.2.1, @libp2p/interface@npm:^2.3.0": + version: 2.3.0 + resolution: "@libp2p/interface@npm:2.3.0" dependencies: - "@libp2p/interface": "npm:^2.2.1" - "@multiformats/multiaddr": "npm:^12.2.3" - interface-datastore: "npm:^8.3.0" - multiformats: "npm:^13.1.0" - weald: "npm:^1.0.2" - checksum: 10c0/784266ce2171b93ea35ee43db8c0c405afcf46195ed2364193d8dff23ef80096b13ccca64c9d3c5838fe010281f01d6afb0b131d224ed94ab3854f5f7b657ea6 + "@multiformats/multiaddr": "npm:^12.3.3" + it-pushable: "npm:^3.2.3" + it-stream-types: "npm:^2.0.2" + multiformats: "npm:^13.3.1" + progress-events: "npm:^1.0.1" + uint8arraylist: "npm:^2.4.8" + checksum: 10c0/773edd70283a2de2aa787eeec6f0d2c1e662b25e14fbe49f443f506f7db443cf44ff578ca22b81c57e830cef3f0d94bce91189eee832bb617212c96eba1a65ca + languageName: node + linkType: hard + +"@libp2p/logger@npm:^5.0.1, @libp2p/logger@npm:^5.1.4, @libp2p/logger@npm:^5.1.5": + version: 5.1.5 + resolution: "@libp2p/logger@npm:5.1.5" + dependencies: + "@libp2p/interface": "npm:^2.3.0" + "@multiformats/multiaddr": "npm:^12.3.3" + interface-datastore: "npm:^8.3.1" + multiformats: "npm:^13.3.1" + weald: "npm:^1.0.4" + checksum: 10c0/9496aed33532a4f178fef5fcde523573ba05ea2dd310e691e22493536e4fd14bb789c633670277c613340a0ae5e6f6de21a1db53fd18c8ebee3649d96b6a99a1 languageName: node linkType: hard "@libp2p/multistream-select@npm:^6.0.9": - version: 6.0.9 - resolution: "@libp2p/multistream-select@npm:6.0.9" + version: 6.0.10 + resolution: "@libp2p/multistream-select@npm:6.0.10" dependencies: - "@libp2p/interface": "npm:^2.2.1" - it-length-prefixed: "npm:^9.0.4" - it-length-prefixed-stream: "npm:^1.1.7" - it-stream-types: "npm:^2.0.1" + "@libp2p/interface": "npm:^2.3.0" + it-length-prefixed: "npm:^9.1.0" + it-length-prefixed-stream: "npm:^1.2.0" + it-stream-types: "npm:^2.0.2" p-defer: "npm:^4.0.1" - race-signal: "npm:^1.0.2" + race-signal: "npm:^1.1.0" uint8-varint: "npm:^2.0.4" uint8arraylist: "npm:^2.4.8" uint8arrays: "npm:^5.1.0" - checksum: 10c0/018294a96932ceacfaf0e0a2a42d7b6e7f9a50879d6e06041fe3b5cec36b0d699898eb8139c4679524d0e76a4c6f438edf6b38d4dddbdf4c91be232ef6d4ba13 + checksum: 10c0/cad7e33ad4d676d16b44f2967b6b36485f650bcca11113460b8511fda40604a6a861ac7872aeafbc15613255f3e1be25e58f8af3efd6ad8f65f02a5a883d4ba8 languageName: node linkType: hard -"@libp2p/peer-collections@npm:^6.0.12": - version: 6.0.12 - resolution: "@libp2p/peer-collections@npm:6.0.12" +"@libp2p/peer-collections@npm:^6.0.12, @libp2p/peer-collections@npm:^6.0.13": + version: 6.0.13 + resolution: "@libp2p/peer-collections@npm:6.0.13" dependencies: - "@libp2p/interface": "npm:^2.2.1" - "@libp2p/peer-id": "npm:^5.0.8" - "@libp2p/utils": "npm:^6.2.1" - multiformats: "npm:^13.2.2" - checksum: 10c0/06aa7ab570ef577ff701a9b582921abb737d28e7ae975419273fb7575ea756f45698befa6f4ec4c583242dee3321c876d3aa5dc03487240d1cdba3902e903c00 + "@libp2p/interface": "npm:^2.3.0" + "@libp2p/peer-id": "npm:^5.0.9" + "@libp2p/utils": "npm:^6.3.0" + multiformats: "npm:^13.3.1" + checksum: 10c0/4faf41d4c8937414b8b33f0a49991f677eb15c7a69d33188032a47367a19078afdb8610875d105d80285674c2607e930b5f375e83349804a78c49f88acab1793 languageName: node linkType: hard -"@libp2p/peer-id@npm:^5.0.0, @libp2p/peer-id@npm:^5.0.8": - version: 5.0.8 - resolution: "@libp2p/peer-id@npm:5.0.8" +"@libp2p/peer-id@npm:^5.0.0, @libp2p/peer-id@npm:^5.0.8, @libp2p/peer-id@npm:^5.0.9": + version: 5.0.9 + resolution: "@libp2p/peer-id@npm:5.0.9" dependencies: - "@libp2p/crypto": "npm:^5.0.7" - "@libp2p/interface": "npm:^2.2.1" - multiformats: "npm:^13.1.0" + "@libp2p/crypto": "npm:^5.0.8" + "@libp2p/interface": "npm:^2.3.0" + multiformats: "npm:^13.3.1" uint8arrays: "npm:^5.1.0" - checksum: 10c0/e4a84545955e31f4fae0f150d8d16216b4a3cfe7230c529fc6a6f9285f9c726f98f9aebc5793da4c3019ce0abbd8071a25dae60f5e34ada6fa4a9b4a1546a400 + checksum: 10c0/bf883a63ad4009fe3349a0e60b3a8f2b7ea1d260cabdfbf5e90d32e31cb269794c18ea184955a9bd7d1a9477ac4ae704adff16283edef89a639f7ab159a1befe languageName: node linkType: hard -"@libp2p/peer-record@npm:^8.0.12": - version: 8.0.12 - resolution: "@libp2p/peer-record@npm:8.0.12" - dependencies: - "@libp2p/crypto": "npm:^5.0.7" - "@libp2p/interface": "npm:^2.2.1" - "@libp2p/peer-id": "npm:^5.0.8" - "@libp2p/utils": "npm:^6.2.1" - "@multiformats/multiaddr": "npm:^12.2.3" - multiformats: "npm:^13.2.2" - protons-runtime: "npm:^5.4.0" +"@libp2p/peer-record@npm:^8.0.12, @libp2p/peer-record@npm:^8.0.13": + version: 8.0.13 + resolution: "@libp2p/peer-record@npm:8.0.13" + dependencies: + "@libp2p/crypto": "npm:^5.0.8" + "@libp2p/interface": "npm:^2.3.0" + "@libp2p/peer-id": "npm:^5.0.9" + "@libp2p/utils": "npm:^6.3.0" + "@multiformats/multiaddr": "npm:^12.3.3" + multiformats: "npm:^13.3.1" + protons-runtime: "npm:^5.5.0" uint8-varint: "npm:^2.0.4" uint8arraylist: "npm:^2.4.8" uint8arrays: "npm:^5.1.0" - checksum: 10c0/0f48c8734f25176864adfafceb57fc1293a1bf7d912ce2c8716a29ec193904f949f157fa418c4810c83b155ad18b3f74c357f61094dd147d5196ea48344c4406 + checksum: 10c0/eea057c572d73e3713d1291f1ee43d33f49cbe9207c93aaec1b281bc28b4c9c6c1723412631560aaa409b4655bfc915765b734abef82806fb82edf9495f17c7b languageName: node linkType: hard "@libp2p/peer-store@npm:^11.0.12": - version: 11.0.12 - resolution: "@libp2p/peer-store@npm:11.0.12" - dependencies: - "@libp2p/crypto": "npm:^5.0.7" - "@libp2p/interface": "npm:^2.2.1" - "@libp2p/peer-id": "npm:^5.0.8" - "@libp2p/peer-record": "npm:^8.0.12" - "@multiformats/multiaddr": "npm:^12.2.3" - interface-datastore: "npm:^8.3.0" + version: 11.0.13 + resolution: "@libp2p/peer-store@npm:11.0.13" + dependencies: + "@libp2p/crypto": "npm:^5.0.8" + "@libp2p/interface": "npm:^2.3.0" + "@libp2p/peer-id": "npm:^5.0.9" + "@libp2p/peer-record": "npm:^8.0.13" + "@multiformats/multiaddr": "npm:^12.3.3" + interface-datastore: "npm:^8.3.1" it-all: "npm:^3.0.6" - mortice: "npm:^3.0.4" - multiformats: "npm:^13.1.0" - protons-runtime: "npm:^5.4.0" + mortice: "npm:^3.0.6" + multiformats: "npm:^13.3.1" + protons-runtime: "npm:^5.5.0" uint8arraylist: "npm:^2.4.8" uint8arrays: "npm:^5.1.0" - checksum: 10c0/f8e4f48f00e7c82926b59f4cd9a812586ef73de287ec191635c9def0c8ac44a9ca229f0cb5d820950a70ffe06c494399a45351f39f24c49918fcdb3aa44fe441 + checksum: 10c0/2ac1900886ac26b96c5ed7a26bbbf87ed7e0502bbe7f667727aa7103150435e39d7853934ae32f02d175a5e8af6cc893e3cbcf2e8c3999acd78b122690417330 languageName: node linkType: hard @@ -8230,15 +8471,16 @@ __metadata: languageName: node linkType: hard -"@libp2p/utils@npm:^6.0.0, @libp2p/utils@npm:^6.2.1": - version: 6.2.1 - resolution: "@libp2p/utils@npm:6.2.1" +"@libp2p/utils@npm:^6.0.0, @libp2p/utils@npm:^6.2.1, @libp2p/utils@npm:^6.3.0": + version: 6.3.0 + resolution: "@libp2p/utils@npm:6.3.0" dependencies: "@chainsafe/is-ip": "npm:^2.0.2" - "@libp2p/crypto": "npm:^5.0.7" - "@libp2p/interface": "npm:^2.2.1" - "@libp2p/logger": "npm:^5.1.4" - "@multiformats/multiaddr": "npm:^12.2.3" + "@chainsafe/netmask": "npm:^2.0.0" + "@libp2p/crypto": "npm:^5.0.8" + "@libp2p/interface": "npm:^2.3.0" + "@libp2p/logger": "npm:^5.1.5" + "@multiformats/multiaddr": "npm:^12.3.3" "@sindresorhus/fnv1a": "npm:^3.1.0" "@types/murmurhash3js-revisited": "npm:^3.0.3" any-signal: "npm:^4.1.1" @@ -8248,15 +8490,15 @@ __metadata: it-foreach: "npm:^2.1.1" it-pipe: "npm:^3.0.1" it-pushable: "npm:^3.2.3" - it-stream-types: "npm:^2.0.1" + it-stream-types: "npm:^2.0.2" murmurhash3js-revisited: "npm:^3.0.0" netmask: "npm:^2.0.2" p-defer: "npm:^4.0.1" race-event: "npm:^1.3.0" - race-signal: "npm:^1.0.2" + race-signal: "npm:^1.1.0" uint8arraylist: "npm:^2.4.8" uint8arrays: "npm:^5.1.0" - checksum: 10c0/6ad55b55d79e89e7d25b90463d59b85c23f41d5392997e10412d2737236f20de6d268e1d8aae9209b7f8f2d34403b3c6bbf058aa15c2068eb20f0736a76e4b28 + checksum: 10c0/16e52bca3aa034c3ced05dc134b61eb9b1a7668d2fb3baa358463aa850efe7139f979d836ca6ec0bf2c823aa11539ac05e6f8e73af4bb345f92f0247ab88ee20 languageName: node linkType: hard @@ -8406,38 +8648,42 @@ __metadata: version: 0.0.0-use.local resolution: "@local/advanced-types@workspace:libs/@local/advanced-types" dependencies: - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" react: "npm:18.2.0" rimraf: "npm:6.0.1" typescript: "npm:5.6.3" languageName: unknown linkType: soft -"@local/eslint-config@npm:0.0.0-private, @local/eslint-config@workspace:libs/@local/eslint-config": +"@local/eslint@npm:0.0.0-private, @local/eslint@workspace:libs/@local/eslint": version: 0.0.0-use.local - resolution: "@local/eslint-config@workspace:libs/@local/eslint-config" + resolution: "@local/eslint@workspace:libs/@local/eslint" dependencies: "@babel/core": "npm:7.26.0" "@babel/eslint-parser": "npm:7.25.9" - "@babel/preset-react": "npm:7.26.3" + "@eslint/compat": "npm:1.2.4" + "@eslint/eslintrc": "npm:3.2.0" "@local/tsconfig": "npm:0.0.0-private" - "@types/eslint": "npm:8.56.12" + "@types/babel__core": "npm:^7" + "@types/eslint__eslintrc": "npm:2.1.2" "@types/node": "npm:22.10.1" - "@typescript-eslint/eslint-plugin": "npm:7.2.0" - "@typescript-eslint/parser": "npm:7.2.0" - eslint: "npm:8.57.0" + effect: "npm:3.11.3" + eslint: "npm:9.16.0" eslint-config-airbnb: "npm:19.0.4" + eslint-config-flat-gitignore: "npm:0.3.0" eslint-config-prettier: "npm:9.1.0" - eslint-plugin-canonical: "npm:4.18.0" - eslint-plugin-import: "npm:2.29.1" - eslint-plugin-jsx-a11y: "npm:6.8.0" - eslint-plugin-react: "npm:7.34.1" - eslint-plugin-react-hooks: "npm:4.6.0" - eslint-plugin-simple-import-sort: "npm:12.0.0" - eslint-plugin-typescript-sort-keys: "npm:3.2.0" - eslint-plugin-unicorn: "npm:51.0.1" + eslint-config-sheriff: "npm:25.3.0" + eslint-import-resolver-node: "npm:0.3.9" + eslint-import-resolver-typescript: "npm:3.7.0" + eslint-plugin-canonical: "npm:5.0.0" + eslint-plugin-import: "npm:2.31.0" + eslint-plugin-react-hooks: "npm:5.1.0" + eslint-plugin-storybook: "npm:0.11.1" + eslint-unicorn: "npm:55.0.0" + globals: "npm:15.13.0" + rimraf: "npm:6.0.1" typescript: "npm:5.6.3" languageName: unknown linkType: soft @@ -8456,14 +8702,14 @@ __metadata: "@libp2p/interface": "npm:2.2.1" "@libp2p/ping": "npm:2.0.12" "@libp2p/tcp": "npm:10.0.13" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@multiformats/multiaddr": "npm:12.3.4" "@rust/harpc-wire-protocol": "npm:0.0.0-private" "@types/node": "npm:22.10.1" "@vitest/coverage-istanbul": "npm:2.1.8" effect: "npm:3.11.3" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" it-stream-types: "npm:2.0.2" libp2p: "npm:2.3.1" multiformats: "npm:13.3.1" @@ -8485,7 +8731,7 @@ __metadata: "@blockprotocol/type-system": "npm:0.1.2-canary.0" "@linear/sdk": "npm:6.0.0" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" "@local/hash-isomorphic-utils": "npm:0.0.0-private" @@ -8508,7 +8754,7 @@ __metadata: apollo-datasource: "npm:3.3.2" axios: "npm:1.7.9" dotenv-flow: "npm:3.3.0" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" exponential-backoff: "npm:3.1.1" googleapis: "npm:133.0.0" logform: "npm:2.7.0" @@ -8526,7 +8772,6 @@ __metadata: version: 0.0.0-use.local resolution: "@local/hash-graph-client@workspace:libs/@local/graph/client/typescript" dependencies: - "@local/eslint-config": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@openapitools/openapi-generator-cli": "npm:2.15.3" "@redocly/cli": "npm:1.26.0" @@ -8545,14 +8790,14 @@ __metadata: dependencies: "@blockprotocol/graph": "npm:0.4.0-canary.0" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/harpc-client": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-types": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@vitest/coverage-istanbul": "npm:2.1.8" effect: "npm:3.11.3" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" rimraf: "npm:6.0.1" typescript: "npm:5.6.3" vitest: "npm:2.1.8" @@ -8566,10 +8811,10 @@ __metadata: "@blockprotocol/graph": "npm:0.4.0-canary.0" "@blockprotocol/type-system": "npm:0.1.2-canary.0" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" rimraf: "npm:6.0.1" typescript: "npm:5.6.3" languageName: unknown @@ -8588,7 +8833,7 @@ __metadata: "@graphql-codegen/typescript": "npm:2.8.8" "@graphql-codegen/typescript-operations": "npm:2.5.13" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" "@local/hash-graph-types": "npm:0.0.0-private" @@ -8602,7 +8847,7 @@ __metadata: "@types/pluralize": "npm:0.0.33" "@vitest/coverage-istanbul": "npm:2.1.8" apollo-server-express: "npm:3.9.0" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" fix-esm-import-path: "npm:1.10.1" fractional-indexing: "npm:2.1.0" graphql: "npm:16.9.0" @@ -8637,13 +8882,13 @@ __metadata: "@blockprotocol/graph": "npm:0.4.0-canary.0" "@blockprotocol/type-system": "npm:0.1.2-canary.0" "@local/advanced-types": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" "@local/hash-graph-types": "npm:0.0.0-private" "@types/uuid": "npm:10.0.0" "@vitest/coverage-istanbul": "npm:2.1.8" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" rimraf: "npm:6.0.1" typescript: "npm:5.6.3" uuid: "npm:9.0.1" @@ -8655,7 +8900,6 @@ __metadata: version: 0.0.0-use.local resolution: "@local/internal-api-client@workspace:libs/@local/internal-api-client/typescript" dependencies: - "@local/eslint-config": "npm:0.0.0-private" "@openapitools/openapi-generator-cli": "npm:2.15.3" "@types/node": "npm:22.10.1" axios: "npm:1.7.9" @@ -8670,13 +8914,13 @@ __metadata: resolution: "@local/repo-chores@workspace:libs/@local/repo-chores/node" dependencies: "@blockprotocol/core": "npm:0.1.3" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/fs-extra": "npm:9.0.13" "@types/prettier": "npm:3.0.0" chalk: "npm:4.1.2" envalid: "npm:7.3.1" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" execa: "npm:5.1.1" fs-extra: "npm:11.1.0" globby: "npm:11.1.0" @@ -8691,12 +8935,12 @@ __metadata: version: 0.0.0-use.local resolution: "@local/status@workspace:libs/@local/status/typescript" dependencies: - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@types/lodash-es": "npm:4.17.12" "@types/node": "npm:22.10.1" "@types/yargs": "npm:17.0.33" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" execa: "npm:5.1.1" lodash-es: "npm:4.17.21" quicktype: "npm:16.0.43" @@ -8835,6 +9079,25 @@ __metadata: languageName: node linkType: hard +"@microsoft/tsdoc-config@npm:0.16.2": + version: 0.16.2 + resolution: "@microsoft/tsdoc-config@npm:0.16.2" + dependencies: + "@microsoft/tsdoc": "npm:0.14.2" + ajv: "npm:~6.12.6" + jju: "npm:~1.4.0" + resolve: "npm:~1.19.0" + checksum: 10c0/9e8c176b68f01c8bb38e6365d5b543e471bba59fced6070d9bd35b32461fbd650c2e1a6f686e8dca0cf22bc5e7d796e4213e66bce4426c8cb9864c1f6ca6836c + languageName: node + linkType: hard + +"@microsoft/tsdoc@npm:0.14.2": + version: 0.14.2 + resolution: "@microsoft/tsdoc@npm:0.14.2" + checksum: 10c0/c018857ad439144559ce34a397a29ace7cf5b24b999b8e3c1b88d878338088b3a453eaac4435beaf2c7eae13c4c0aac81e42f96f0f1d48e8d4eeb438eb3bb82f + languageName: node + linkType: hard + "@mistralai/mistralai@npm:^0.1.3": version: 0.1.3 resolution: "@mistralai/mistralai@npm:0.1.3" @@ -9205,7 +9468,7 @@ __metadata: languageName: node linkType: hard -"@multiformats/multiaddr@npm:12.3.4, @multiformats/multiaddr@npm:^12.0.0, @multiformats/multiaddr@npm:^12.2.3": +"@multiformats/multiaddr@npm:12.3.4, @multiformats/multiaddr@npm:^12.0.0, @multiformats/multiaddr@npm:^12.2.3, @multiformats/multiaddr@npm:^12.3.3": version: 12.3.4 resolution: "@multiformats/multiaddr@npm:12.3.4" dependencies: @@ -9313,6 +9576,15 @@ __metadata: languageName: node linkType: hard +"@next/eslint-plugin-next@npm:^13.2.3": + version: 13.5.7 + resolution: "@next/eslint-plugin-next@npm:13.5.7" + dependencies: + glob: "npm:7.1.7" + checksum: 10c0/5c12ef319dc463c586d0194c3dba16871d2d51ee51820eb0abfe9184b528af99e0c317d169580edde6024faa53ddce0195c23fc259fa6753104e7b8e80003c27 + languageName: node + linkType: hard + "@next/swc-darwin-arm64@npm:13.5.5": version: 13.5.5 resolution: "@next/swc-darwin-arm64@npm:13.5.5" @@ -9465,7 +9737,7 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:^1.1.0, @noble/curves@npm:^1.4.0": +"@noble/curves@npm:^1.1.0, @noble/curves@npm:^1.4.0, @noble/curves@npm:^1.7.0": version: 1.7.0 resolution: "@noble/curves@npm:1.7.0" dependencies: @@ -9481,7 +9753,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.4.0": +"@noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:^1.6.1": version: 1.6.1 resolution: "@noble/hashes@npm:1.6.1" checksum: 10c0/27643cd8b551bc933b57cc29aa8c8763d586552fc4c3e06ecf7897f55be3463c0c9dff7f6ebacd88e5ce6d0cdb5415ca4874d0cf4359b5ea4a85be21ada03aab @@ -9505,7 +9777,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:^1.2.3": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -12006,6 +12278,13 @@ __metadata: languageName: node linkType: hard +"@regru/eslint-plugin-prefer-early-return@npm:^1.0.0": + version: 1.0.0 + resolution: "@regru/eslint-plugin-prefer-early-return@npm:1.0.0" + checksum: 10c0/65eff2b9073925b8fab5f0e38023ad0522d1fa6ee75eb51c61cb3a9d86b66b1c2d0d8bd24305db455f395b264a21d1fd19151440d046690baf2c9b0590a5e395 + languageName: node + linkType: hard + "@repeaterjs/repeater@npm:^3.0.4, @repeaterjs/repeater@npm:^3.0.6": version: 3.0.6 resolution: "@repeaterjs/repeater@npm:3.0.6" @@ -12252,6 +12531,13 @@ __metadata: languageName: node linkType: hard +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 10c0/b5bcfb0d87f7d1c1c7c0f7693f53b07866ed9fec4c34a97a8c948fb9a7c0082e416ce4d3b60beb4f5e167cbe04cdeefbf6771320f3ede059b9ce91188c409a5b + languageName: node + linkType: hard + "@rudderstack/rudder-sdk-node@npm:2.1.1": version: 2.1.1 resolution: "@rudderstack/rudder-sdk-node@npm:2.1.1" @@ -12588,10 +12874,10 @@ __metadata: version: 0.0.0-use.local resolution: "@rust/hash-graph-type-defs@workspace:libs/@local/graph/type-defs" dependencies: - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/status": "npm:0.0.0-private" "@rust/hash-status": "npm:0.0.0-private" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" quicktype: "npm:16.0.43" tsx: "npm:4.19.2" typescript: "npm:5.6.3" @@ -14754,21 +15040,12 @@ __metadata: languageName: node linkType: hard -"@storybook/csf@npm:^0.0.1": - version: 0.0.1 - resolution: "@storybook/csf@npm:0.0.1" - dependencies: - lodash: "npm:^4.17.15" - checksum: 10c0/7b0f75763415f9147692a460b44417ee56ea9639433716a1fd4d1df4c8b0221cbc71b8da0fbed4dcecb3ccd6c7ed64be39f5c255c713539a6088a1d6488aaa24 - languageName: node - linkType: hard - -"@storybook/csf@npm:^0.1.2": - version: 0.1.11 - resolution: "@storybook/csf@npm:0.1.11" +"@storybook/csf@npm:^0.1.11, @storybook/csf@npm:^0.1.2": + version: 0.1.12 + resolution: "@storybook/csf@npm:0.1.12" dependencies: type-fest: "npm:^2.19.0" - checksum: 10c0/c5329fc13e7d762049b5c91df1bc1c0e510a1a898c401b72b68f1ff64139a85ab64a92f8e681d2fcb226c0a4a55d0f23b569b2bdb517e0f067bd05ea46228356 + checksum: 10c0/3d96a976ada67eb683279338d1eb6aa730b228107d4c4f6616ea7b94061899c1fdc11957a756e7bc0708d18cb39af0010c865d124efd84559cd82dcb2d8bc959 languageName: node linkType: hard @@ -15065,6 +15342,21 @@ __metadata: languageName: node linkType: hard +"@stylistic/eslint-plugin@npm:^2.6.4": + version: 2.11.0 + resolution: "@stylistic/eslint-plugin@npm:2.11.0" + dependencies: + "@typescript-eslint/utils": "npm:^8.13.0" + eslint-visitor-keys: "npm:^4.2.0" + espree: "npm:^10.3.0" + estraverse: "npm:^5.3.0" + picomatch: "npm:^4.0.2" + peerDependencies: + eslint: ">=8.40.0" + checksum: 10c0/6ca19b6656be5ed657cf4d1920602fb27144dc5d51ba188e0bdcb2a4e0b740d4fdb27052fc268d164fa1269c972aeab15541c9e15b3ff4b7884ecae47f18ff67 + languageName: node + linkType: hard + "@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0": version: 8.0.0 resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0" @@ -15865,7 +16157,7 @@ __metadata: "@graphql-codegen/typescript": "npm:2.8.8" "@graphql-codegen/typescript-graphql-request": "npm:4.5.9" "@graphql-codegen/typescript-resolvers": "npm:2.7.13" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-backend-utils": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" @@ -15877,7 +16169,7 @@ __metadata: "@rust/hash-graph-type-defs": "npm:0.0.0-private" "@types/node-fetch": "npm:2.6.12" "@vitest/coverage-istanbul": "npm:2.1.8" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" execa: "npm:5.1.1" fractional-indexing: "npm:2.1.0" graphql: "npm:16.9.0" @@ -15894,7 +16186,7 @@ __metadata: resolution: "@tests/hash-backend-load@workspace:tests/hash-backend-load" dependencies: "@apps/hash-api": "npm:0.0.0-private" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-backend-utils": "npm:0.0.0-private" "@local/hash-graph-client": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" @@ -15916,7 +16208,7 @@ __metadata: "@types/uuid": "npm:10.0.0" artillery: "npm:2.0.20" dotenv-flow: "npm:3.3.0" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" rimraf: "npm:6.0.1" rollup: "npm:4.28.1" typescript: "npm:5.6.3" @@ -15934,14 +16226,14 @@ __metadata: "@apps/plugin-browser": "npm:0.0.8" "@blockprotocol/graph": "npm:0.4.0-canary.0" "@graphql-codegen/cli": "npm:^5.0.3" - "@local/eslint-config": "npm:0.0.0-private" + "@local/eslint": "npm:0.0.0-private" "@local/hash-backend-utils": "npm:0.0.0-private" "@local/hash-graph-sdk": "npm:0.0.0-private" "@local/hash-isomorphic-utils": "npm:0.0.0-private" "@local/hash-subgraph": "npm:0.0.0-private" "@local/tsconfig": "npm:0.0.0-private" "@playwright/test": "npm:1.49.0" - eslint: "npm:8.57.0" + eslint: "npm:9.16.0" execa: "npm:5.1.1" graphql: "npm:16.9.0" js-yaml: "npm:4.1.0" @@ -16269,7 +16561,7 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.18.0": +"@types/babel__core@npm:^7, @types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.18.0": version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" dependencies: @@ -16811,13 +17103,12 @@ __metadata: languageName: node linkType: hard -"@types/eslint@npm:8.56.12": - version: 8.56.12 - resolution: "@types/eslint@npm:8.56.12" +"@types/eslint__eslintrc@npm:2.1.2": + version: 2.1.2 + resolution: "@types/eslint__eslintrc@npm:2.1.2" dependencies: - "@types/estree": "npm:*" - "@types/json-schema": "npm:*" - checksum: 10c0/e4ca426abe9d55f82b69a3250bec78b6d340ad1e567f91c97ecc59d3b2d6a1d8494955ac62ad0ea14b97519db580611c02be8277cbea370bdfb0f96aa2910504 + "@types/eslint": "npm:*" + checksum: 10c0/ccbeb74886fbbee1b016ed9c920ad932cb0b970c42eec4cea27e04c2640d5a92c20e44d4610de73551c4c8f658963a769ddc9fd75eac72edf33f035129600637 languageName: node linkType: hard @@ -17393,7 +17684,7 @@ __metadata: languageName: node linkType: hard -"@types/normalize-package-data@npm:^2.4.0": +"@types/normalize-package-data@npm:^2.4.0, @types/normalize-package-data@npm:^2.4.3": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" checksum: 10c0/aef7bb9b015883d6f4119c423dd28c4bdc17b0e8a0ccf112c78b4fe0e91fbc4af7c6204b04bba0e199a57d2f3fbbd5b4a14bf8739bf9d2a39b2a0aad545e0f86 @@ -17682,7 +17973,7 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.12, @types/semver@npm:^7.3.4, @types/semver@npm:^7.5.0": +"@types/semver@npm:^7.3.4, @types/semver@npm:^7.5.0": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" checksum: 10c0/8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa @@ -17910,67 +18201,62 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.2.0" +"@typescript-eslint/eslint-plugin@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.16.0" dependencies: - "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/type-utils": "npm:7.2.0" - "@typescript-eslint/utils": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" - debug: "npm:^4.3.4" + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/type-utils": "npm:8.16.0" + "@typescript-eslint/utils": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.4" + ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" + ts-api-utils: "npm:^1.3.0" peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/8725c2193a16cc103a697d6e408c515a7618df3902dc504cf69999f60634dac79ce14a5bd942f0388ba7547caba44ac40e01097cda1106aa3912e2303dada8ab + checksum: 10c0/b03612b726ee5aff631cd50e05ceeb06a522e64465e4efdc134e3a27a09406b959ef7a05ec4acef1956b3674dc4fedb6d3a62ce69382f9e30c227bd4093003e5 languageName: node linkType: hard -"@typescript-eslint/experimental-utils@npm:^5.0.0": - version: 5.62.0 - resolution: "@typescript-eslint/experimental-utils@npm:5.62.0" +"@typescript-eslint/parser@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/parser@npm:8.16.0" dependencies: - "@typescript-eslint/utils": "npm:5.62.0" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" + debug: "npm:^4.3.4" peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/f7037977e00849cd8c03677a88b0659a4f0e0b1e0151aebb47c49c92b8e57408578142df598eac08b364623d926343c724f42494f87662e437b1c89f0b2e815b + eslint: ^8.57.0 || ^9.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/e49c6640a7a863a16baecfbc5b99392a4731e9c7e9c9aaae4efbc354e305485fe0f39a28bf0acfae85bc01ce37fe0cc140fd315fdaca8b18f9b5e0addff8ceae languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/parser@npm:7.2.0" +"@typescript-eslint/parser@npm:^6.2.0": + version: 6.21.0 + resolution: "@typescript-eslint/parser@npm:6.21.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/typescript-estree": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" + "@typescript-eslint/scope-manager": "npm:6.21.0" + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/typescript-estree": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" debug: "npm:^4.3.4" peerDependencies: - eslint: ^8.56.0 + eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/11ce36c68212fdbf98fc6fd32ba0977d46b645fd669a3f4fdb8be2036225f86ad005b31a66f97097e90517c44c92cf9cc5fb1d6e9647ee2fa125c4af21cdb477 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/scope-manager@npm:5.62.0" - dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - checksum: 10c0/861253235576c1c5c1772d23cdce1418c2da2618a479a7de4f6114a12a7ca853011a1e530525d0931c355a8fd237b9cd828fac560f85f9623e24054fd024726f + checksum: 10c0/a8f99820679decd0d115c0af61903fb1de3b1b5bec412dc72b67670bf636de77ab07f2a68ee65d6da7976039bbf636907f9d5ca546db3f0b98a31ffbc225bc7d languageName: node linkType: hard @@ -17984,30 +18270,50 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/scope-manager@npm:7.2.0" +"@typescript-eslint/scope-manager@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/scope-manager@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" - checksum: 10c0/4d088c127e6ba1a7de8567f70684779083be24b48746c3b4a86a0ec7062bca58693ee08482349ad6572a17ada8aa6f26b74d1c7139c8fcf7101fa09a572e0ea6 + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" + checksum: 10c0/038cd58c2271de146b3a594afe2c99290034033326d57ff1f902976022c8b0138ffd3cb893ae439ae41003b5e4bcc00cabf6b244ce40e8668f9412cc96d97b8e languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/type-utils@npm:7.2.0" +"@typescript-eslint/scope-manager@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/scope-manager@npm:8.16.0" + dependencies: + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" + checksum: 10c0/23b7c738b83f381c6419a36e6ca951944187e3e00abb8e012bce8041880410fe498303e28bdeb0e619023a69b14cf32a5ec1f9427c5382807788cd8e52a46a6e + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:8.17.0, @typescript-eslint/scope-manager@npm:^7.0.0 || ^8.0.0, @typescript-eslint/scope-manager@npm:^8.16.0": + version: 8.17.0 + resolution: "@typescript-eslint/scope-manager@npm:8.17.0" + dependencies: + "@typescript-eslint/types": "npm:8.17.0" + "@typescript-eslint/visitor-keys": "npm:8.17.0" + checksum: 10c0/0c08d14240bad4b3f6874f08ba80b29db1a6657437089a6f109db458c544d835bcdc06ba9140bb4f835233ba4326d9a86e6cf6bdb5209960d2f7025aa3191f4f + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.16.0, @typescript-eslint/type-utils@npm:^8.0.0, @typescript-eslint/type-utils@npm:^8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/type-utils@npm:8.16.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.2.0" - "@typescript-eslint/utils": "npm:7.2.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" + "@typescript-eslint/utils": "npm:8.16.0" debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.0.1" + ts-api-utils: "npm:^1.3.0" peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/069b65ef327e1bfa1e59009504c8307f88f3673ebcc23d17ad370452ece107013c9dc321876092673d2c02ddd35104f67231b31b0e4f7d5ca6fbf95b43f828b2 + checksum: 10c0/24c0e815c8bdf99bf488c7528bd6a7c790e8b3b674cb7fb075663afc2ee26b48e6f4cf7c0d14bb21e2376ca62bd8525cbcb5688f36135b00b62b1d353d7235b9 languageName: node linkType: hard @@ -18025,28 +18331,24 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/types@npm:7.2.0" - checksum: 10c0/135aae061720185855bea61ea6cfd33f4801d2de57f65e50079bbdb505100f844632aa4e4bdeec9e9e79d29aaddad949178d0e918e41867da6ab4b1390820e33 +"@typescript-eslint/types@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/types@npm:7.18.0" + checksum: 10c0/eb7371ac55ca77db8e59ba0310b41a74523f17e06f485a0ef819491bc3dd8909bb930120ff7d30aaf54e888167e0005aa1337011f3663dc90fb19203ce478054 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.62.0, @typescript-eslint/typescript-estree@npm:^5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" - dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - semver: "npm:^7.3.7" - tsutils: "npm:^3.21.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/d7984a3e9d56897b2481940ec803cb8e7ead03df8d9cfd9797350be82ff765dfcf3cfec04e7355e1779e948da8f02bc5e11719d07a596eb1cb995c48a95e38cf +"@typescript-eslint/types@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/types@npm:8.16.0" + checksum: 10c0/141e257ab4060a9c0e2e14334ca14ab6be713659bfa38acd13be70a699fb5f36932a2584376b063063ab3d723b24bc703dbfb1ce57d61d7cfd7ec5bd8a975129 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:8.17.0, @typescript-eslint/types@npm:^7.0.0 || ^8.0.0, @typescript-eslint/types@npm:^7.7.1 || ^8, @typescript-eslint/types@npm:^8.16.0": + version: 8.17.0 + resolution: "@typescript-eslint/types@npm:8.17.0" + checksum: 10c0/26b1bf9dfc3ee783c85c6f354b84c28706d5689d777f3ff2de2cb496e45f9d0189c0d561c03ccbc8b24712438be17cf63dd0871ff3ca2083e7f48749770d1893 languageName: node linkType: hard @@ -18069,61 +18371,99 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.2.0" +"@typescript-eslint/typescript-estree@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/visitor-keys": "npm:7.2.0" + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" - minimatch: "npm:9.0.3" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/0c7f109a2e460ec8a1524339479cf78ff17814d23c83aa5112c77fb345e87b3642616291908dcddea1e671da63686403dfb712e4a4435104f92abdfddf9aba81 + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.16.0" + dependencies: + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" + debug: "npm:^4.3.4" + fast-glob: "npm:^3.3.2" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" peerDependenciesMeta: typescript: optional: true - checksum: 10c0/2730bb17730e6f3ca4061f00688a70386a808f5d174fdeb757c3cfa92c455373f69080df33237c1a8970e818af0cea0ae5a083970ed8ba493f3b04458c6f9271 + checksum: 10c0/f28fea5af4798a718b6735d1758b791a331af17386b83cb2856d89934a5d1693f7cb805e73c3b33f29140884ac8ead9931b1d7c3de10176fa18ca7a346fe10d0 languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.62.0, @typescript-eslint/utils@npm:^5.62.0": +"@typescript-eslint/typescript-estree@npm:8.17.0, @typescript-eslint/typescript-estree@npm:^7.0.0 || ^8.0.0, @typescript-eslint/typescript-estree@npm:^8.16.0": + version: 8.17.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.17.0" + dependencies: + "@typescript-eslint/types": "npm:8.17.0" + "@typescript-eslint/visitor-keys": "npm:8.17.0" + debug: "npm:^4.3.4" + fast-glob: "npm:^3.3.2" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/523013f9b5cf2c58c566868e4c3b0b9ac1b4807223a6d64e2a7c58e01e53b6587ba61f1a8241eade361f3f426d6057657515473176141ef8aebb352bc0d223ce + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:^5.62.0": version: 5.62.0 - resolution: "@typescript-eslint/utils@npm:5.62.0" + resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@types/json-schema": "npm:^7.0.9" - "@types/semver": "npm:^7.3.12" - "@typescript-eslint/scope-manager": "npm:5.62.0" "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/typescript-estree": "npm:5.62.0" - eslint-scope: "npm:^5.1.1" + "@typescript-eslint/visitor-keys": "npm:5.62.0" + debug: "npm:^4.3.4" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" semver: "npm:^7.3.7" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/f09b7d9952e4a205eb1ced31d7684dd55cee40bf8c2d78e923aa8a255318d97279825733902742c09d8690f37a50243f4c4d383ab16bd7aefaf9c4b438f785e1 + tsutils: "npm:^3.21.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/d7984a3e9d56897b2481940ec803cb8e7ead03df8d9cfd9797350be82ff765dfcf3cfec04e7355e1779e948da8f02bc5e11719d07a596eb1cb995c48a95e38cf languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/utils@npm:7.2.0" +"@typescript-eslint/utils@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/utils@npm:8.16.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@types/json-schema": "npm:^7.0.12" - "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:7.2.0" - "@typescript-eslint/types": "npm:7.2.0" - "@typescript-eslint/typescript-estree": "npm:7.2.0" - semver: "npm:^7.5.4" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" peerDependencies: - eslint: ^8.56.0 - checksum: 10c0/37944e1a4038820da82b51ac4756e09cff31851d9d957d3fd67a3b6fd2cf6c0e87767161eaeb8b6e63de418e513bb2570a6ee3fa986ba77f6d451d66a538f753 + eslint: ^8.57.0 || ^9.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/1e61187eef3da1ab1486d2a977d8f3b1cb8ef7fa26338500a17eb875ca42a8942ef3f2241f509eef74cf7b5620c109483afc7d83d5b0ab79b1e15920f5a49818 languageName: node linkType: hard -"@typescript-eslint/utils@npm:^6.1.0": +"@typescript-eslint/utils@npm:^6.0.0": version: 6.21.0 resolution: "@typescript-eslint/utils@npm:6.21.0" dependencies: @@ -18140,6 +18480,37 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:^6.0.0 || ^7.0.0 || ^8.0.0, @typescript-eslint/utils@npm:^8.13.0, @typescript-eslint/utils@npm:^8.16.0, @typescript-eslint/utils@npm:^8.2.0, @typescript-eslint/utils@npm:^8.8.1": + version: 8.17.0 + resolution: "@typescript-eslint/utils@npm:8.17.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" + "@typescript-eslint/scope-manager": "npm:8.17.0" + "@typescript-eslint/types": "npm:8.17.0" + "@typescript-eslint/typescript-estree": "npm:8.17.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/a9785ae5f7e7b51d521dc3f48b15093948e4fcd03352c0b60f39bae366cbc935947d215f91e2ae3182d52fa6affb5ccbb50feff487bd1209011f3e0da02cdf07 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:^7.16.0": + version: 7.18.0 + resolution: "@typescript-eslint/utils@npm:7.18.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" + "@typescript-eslint/scope-manager": "npm:7.18.0" + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/typescript-estree": "npm:7.18.0" + peerDependencies: + eslint: ^8.56.0 + checksum: 10c0/a25a6d50eb45c514469a01ff01f215115a4725fb18401055a847ddf20d1b681409c4027f349033a95c4ff7138d28c3b0a70253dfe8262eb732df4b87c547bd1e + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" @@ -18160,17 +18531,37 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.2.0": - version: 7.2.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.2.0" +"@typescript-eslint/visitor-keys@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" dependencies: - "@typescript-eslint/types": "npm:7.2.0" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10c0/2d7467495b2b76f3edb1b3047e97076c2242e7eca6d50bbbdd88219f9ff754dbcb9334a0568fe0ceb4c562823980938bd278aa2ba53da6343e7d99a167924f24 + "@typescript-eslint/types": "npm:7.18.0" + eslint-visitor-keys: "npm:^3.4.3" + checksum: 10c0/538b645f8ff1d9debf264865c69a317074eaff0255e63d7407046176b0f6a6beba34a6c51d511f12444bae12a98c69891eb6f403c9f54c6c2e2849d1c1cb73c0 + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.16.0" + dependencies: + "@typescript-eslint/types": "npm:8.16.0" + eslint-visitor-keys: "npm:^4.2.0" + checksum: 10c0/537df37801831aa8d91082b2adbffafd40305ed4518f0e7d3cbb17cc466d8b9ac95ac91fa232e7fe585d7c522d1564489ec80052ebb2a6ab9bbf89ef9dd9b7bc + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.17.0": + version: 8.17.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.17.0" + dependencies: + "@typescript-eslint/types": "npm:8.17.0" + eslint-visitor-keys: "npm:^4.2.0" + checksum: 10c0/9144c4e4a63034fb2031a0ee1fc77e80594f30cab3faafa9a1f7f83782695774dd32fac8986f260698b4e150b4dd52444f2611c07e4c101501f08353eb47c82c languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.0.0, @ungap/structured-clone@npm:^1.2.0": +"@ungap/structured-clone@npm:^1.0.0": version: 1.2.0 resolution: "@ungap/structured-clone@npm:1.2.0" checksum: 10c0/8209c937cb39119f44eb63cf90c0b73e7c754209a6411c707be08e50e29ee81356dca1a848a405c8bdeebfe2f5e4f831ad310ae1689eeef65e7445c090c6657d @@ -18215,6 +18606,23 @@ __metadata: languageName: node linkType: hard +"@vitest/eslint-plugin@npm:^1.0.3": + version: 1.1.13 + resolution: "@vitest/eslint-plugin@npm:1.1.13" + peerDependencies: + "@typescript-eslint/utils": ">= 8.0" + eslint: ">= 8.57.0" + typescript: ">= 5.0.0" + vitest: "*" + peerDependenciesMeta: + typescript: + optional: true + vitest: + optional: true + checksum: 10c0/179b095dfa0d19c34dcbd52f4a0048b4d1a6827b473b1328c2a8e69be57592e0ab2bebb1686b93c375c4e21ec54887422fc446f5d3f2d1839ba42925cb33685c + languageName: node + linkType: hard + "@vitest/expect@npm:2.1.8": version: 2.1.8 resolution: "@vitest/expect@npm:2.1.8" @@ -19000,7 +19408,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5": +"ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5, ajv@npm:~6.12.6": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -19394,6 +19802,13 @@ __metadata: languageName: node linkType: hard +"are-docs-informative@npm:^0.0.2": + version: 0.0.2 + resolution: "are-docs-informative@npm:0.0.2" + checksum: 10c0/f0326981bd699c372d268b526b170a28f2e1aec2cf99d7de0686083528427ecdf6ae41fef5d9988e224a5616298af747ad8a76e7306b0a7c97cc085a99636d60 + languageName: node + linkType: hard + "are-we-there-yet@npm:^2.0.0": version: 2.0.0 resolution: "are-we-there-yet@npm:2.0.0" @@ -19452,7 +19867,7 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^5.3.0": +"aria-query@npm:^5.3.2": version: 5.3.2 resolution: "aria-query@npm:5.3.2" checksum: 10c0/003c7e3e2cff5540bf7a7893775fc614de82b0c5dde8ae823d47b7a28a9d4da1f7ed85f340bdb93d5649caa927755f0e31ecc7ab63edfdfc00c8ef07e505e03e @@ -19501,7 +19916,7 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.7": +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8": version: 3.1.8 resolution: "array-includes@npm:3.1.8" dependencies: @@ -19545,7 +19960,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlast@npm:^1.2.4": +"array.prototype.findlast@npm:^1.2.5": version: 1.2.5 resolution: "array.prototype.findlast@npm:1.2.5" dependencies: @@ -19559,7 +19974,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.3": +"array.prototype.findlastindex@npm:^1.2.5": version: 1.2.5 resolution: "array.prototype.findlastindex@npm:1.2.5" dependencies: @@ -19597,19 +20012,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.toreversed@npm:^1.1.2": - version: 1.1.2 - resolution: "array.prototype.toreversed@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10c0/2b7627ea85eae1e80ecce665a500cc0f3355ac83ee4a1a727562c7c2a1d5f1c0b4dd7b65c468ec6867207e452ba01256910a2c0b41486bfdd11acf875a7a3435 - languageName: node - linkType: hard - -"array.prototype.tosorted@npm:^1.1.3": +"array.prototype.tosorted@npm:^1.1.4": version: 1.1.4 resolution: "array.prototype.tosorted@npm:1.1.4" dependencies: @@ -19939,6 +20342,38 @@ __metadata: languageName: node linkType: hard +"astro-eslint-parser@npm:^1.0.2": + version: 1.1.0 + resolution: "astro-eslint-parser@npm:1.1.0" + dependencies: + "@astrojs/compiler": "npm:^2.0.0" + "@typescript-eslint/scope-manager": "npm:^7.0.0 || ^8.0.0" + "@typescript-eslint/types": "npm:^7.0.0 || ^8.0.0" + "@typescript-eslint/typescript-estree": "npm:^7.0.0 || ^8.0.0" + astrojs-compiler-sync: "npm:^1.0.0" + debug: "npm:^4.3.4" + entities: "npm:^4.5.0" + eslint-scope: "npm:^8.0.1" + eslint-visitor-keys: "npm:^4.0.0" + espree: "npm:^10.0.0" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" + semver: "npm:^7.3.8" + checksum: 10c0/61021ded2e10949d16e879b13dee96582e1f8cc20884c6f2b4481ef926109161e6e1a5583be8f85c09772b4452a8b8a42f577da61f20292bcddf88763c65f5e2 + languageName: node + linkType: hard + +"astrojs-compiler-sync@npm:^1.0.0": + version: 1.0.1 + resolution: "astrojs-compiler-sync@npm:1.0.1" + dependencies: + synckit: "npm:^0.9.0" + peerDependencies: + "@astrojs/compiler": ">=0.27.0" + checksum: 10c0/bf2a81216fceac6cd53f367ac2df73902bc223f5a2223ffa1613678863a2b00759cd7cd57b1e2c8d1bf137e99c5e0624a2d667a36215b3ddc4aca61f83d7c107 + languageName: node + linkType: hard + "async-hook-domain@npm:^4.0.1": version: 4.0.1 resolution: "async-hook-domain@npm:4.0.1" @@ -20054,10 +20489,10 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:=4.7.0": - version: 4.7.0 - resolution: "axe-core@npm:4.7.0" - checksum: 10c0/89ac5712b5932ac7d23398b4cb5ba081c394a086e343acc68ba49c83472706e18e0799804e8388c779dcdacc465377deb29f2714241d3fbb389cf3a6b275c9ba +"axe-core@npm:^4.10.0": + version: 4.10.2 + resolution: "axe-core@npm:4.10.2" + checksum: 10c0/0e20169077de96946a547fce0df39d9aeebe0077f9d3eeff4896518b96fde857f80b98f0d4279274a7178791744dd5a54bb4f322de45b4f561ffa2586ff9a09d languageName: node linkType: hard @@ -20122,10 +20557,10 @@ __metadata: languageName: node linkType: hard -"axobject-query@npm:^3.2.1": - version: 3.2.4 - resolution: "axobject-query@npm:3.2.4" - checksum: 10c0/3848c9119273d4c8d8c8283154ee8de1c7ce85fc07990f98bbb3a188628bf58261ca3aa59ec982485dc975ab66ea0ead317db7b5cceea84c019f0943de78257f +"axobject-query@npm:^4.1.0": + version: 4.1.0 + resolution: "axobject-query@npm:4.1.0" + checksum: 10c0/c470e4f95008f232eadd755b018cb55f16c03ccf39c027b941cd8820ac6b68707ce5d7368a46756db4256fbc91bb4ead368f84f7fb034b2b7932f082f6dc0775 languageName: node linkType: hard @@ -20518,6 +20953,13 @@ __metadata: languageName: node linkType: hard +"birecord@npm:^0.1.1": + version: 0.1.1 + resolution: "birecord@npm:0.1.1" + checksum: 10c0/7c7f8c38caebd98bcbfc8a209eaa3044384636ea162757de670c8633b7d1064b3b58e4e3d3a48fe10e279cd39290a76a31a18956a1c76b2b13522b6cf0293238 + languageName: node + linkType: hard + "bl@npm:^1.0.0": version: 1.2.3 resolution: "bl@npm:1.2.3" @@ -22124,6 +22566,13 @@ __metadata: languageName: node linkType: hard +"comment-parser@npm:1.4.1, comment-parser@npm:^1.4.0": + version: 1.4.1 + resolution: "comment-parser@npm:1.4.1" + checksum: 10c0/d6c4be3f5be058f98b24f2d557f745d8fe1cc9eb75bebbdccabd404a0e1ed41563171b16285f593011f8b6a5ec81f564fb1f2121418ac5cbf0f49255bf0840dd + languageName: node + linkType: hard + "commist@npm:^3.2.0": version: 3.2.0 resolution: "commist@npm:3.2.0" @@ -22159,6 +22608,13 @@ __metadata: languageName: node linkType: hard +"compare-versions@npm:^6.1.1": + version: 6.1.1 + resolution: "compare-versions@npm:6.1.1" + checksum: 10c0/415205c7627f9e4f358f571266422980c9fe2d99086be0c9a48008ef7c771f32b0fbe8e97a441ffedc3910872f917a0675fe0fe3c3b6d331cda6d8690be06338 + languageName: node + linkType: hard + "component-emitter@npm:^1.2.0": version: 1.3.1 resolution: "component-emitter@npm:1.3.1" @@ -22292,7 +22748,7 @@ __metadata: languageName: node linkType: hard -"confusing-browser-globals@npm:^1.0.10": +"confusing-browser-globals@npm:^1.0.10, confusing-browser-globals@npm:^1.0.11": version: 1.0.11 resolution: "confusing-browser-globals@npm:1.0.11" checksum: 10c0/475d0a284fa964a5182b519af5738b5b64bf7e413cfd703c1b3496bf6f4df9f827893a9b221c0ea5873c1476835beb1e0df569ba643eff0734010c1eb780589e @@ -22475,7 +22931,7 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.34.0, core-js-compat@npm:^3.38.0, core-js-compat@npm:^3.38.1": +"core-js-compat@npm:^3.37.0, core-js-compat@npm:^3.38.0, core-js-compat@npm:^3.38.1": version: 3.39.0 resolution: "core-js-compat@npm:3.39.0" dependencies: @@ -22675,7 +23131,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.5": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -24710,7 +25166,7 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5": +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5": version: 1.23.5 resolution: "es-abstract@npm:1.23.5" dependencies: @@ -24797,7 +25253,7 @@ __metadata: languageName: node linkType: hard -"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.17": +"es-iterator-helpers@npm:^1.1.0": version: 1.2.0 resolution: "es-iterator-helpers@npm:1.2.0" dependencies: @@ -24827,7 +25283,7 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^1.2.1, es-module-lexer@npm:^1.4.1, es-module-lexer@npm:^1.5.4": +"es-module-lexer@npm:^1.2.1, es-module-lexer@npm:^1.4.1, es-module-lexer@npm:^1.5.3, es-module-lexer@npm:^1.5.4": version: 1.5.4 resolution: "es-module-lexer@npm:1.5.4" checksum: 10c0/300a469488c2f22081df1e4c8398c78db92358496e639b0df7f89ac6455462aaf5d8893939087c1a1cbcbf20eed4610c70e0bcb8f3e4b0d80a5d2611c539408c @@ -25286,6 +25742,17 @@ __metadata: languageName: node linkType: hard +"eslint-compat-utils@npm:^0.6.0": + version: 0.6.4 + resolution: "eslint-compat-utils@npm:0.6.4" + dependencies: + semver: "npm:^7.5.4" + peerDependencies: + eslint: ">=6.0.0" + checksum: 10c0/5b665c4051e978b9f9c48621f63d07e6b2a8ba1b334fc430f1ce0d8b596968677bdb54c23c00ca961ad5b4673d5e83e014a52b4baf9a2f7d4ccd79e3c213acfb + languageName: node + linkType: hard + "eslint-config-airbnb-base@npm:^15.0.0": version: 15.0.0 resolution: "eslint-config-airbnb-base@npm:15.0.0" @@ -25318,6 +25785,18 @@ __metadata: languageName: node linkType: hard +"eslint-config-flat-gitignore@npm:0.3.0, eslint-config-flat-gitignore@npm:^0.3.0": + version: 0.3.0 + resolution: "eslint-config-flat-gitignore@npm:0.3.0" + dependencies: + "@eslint/compat": "npm:^1.1.1" + find-up-simple: "npm:^1.0.0" + peerDependencies: + eslint: ^9.5.0 + checksum: 10c0/0fd0f9c7839dec4adef633ee23c6c3aacd6edbdfc09f0f464e7d2c8e20abd514f7a6bd822fb21535f0532cf4abc49302d7334af21fcbfaedc5fbcdc8c5f1d169 + languageName: node + linkType: hard + "eslint-config-prettier@npm:9.1.0": version: 9.1.0 resolution: "eslint-config-prettier@npm:9.1.0" @@ -25329,7 +25808,49 @@ __metadata: languageName: node linkType: hard -"eslint-import-resolver-node@npm:^0.3.9": +"eslint-config-sheriff@npm:25.3.0": + version: 25.3.0 + resolution: "eslint-config-sheriff@npm:25.3.0" + dependencies: + "@eslint-react/eslint-plugin": "npm:^1.10.1" + "@eslint/compat": "npm:^1.1.1" + "@eslint/js": "npm:^9.14.0" + "@next/eslint-plugin-next": "npm:^13.2.3" + "@regru/eslint-plugin-prefer-early-return": "npm:^1.0.0" + "@stylistic/eslint-plugin": "npm:^2.6.4" + "@vitest/eslint-plugin": "npm:^1.0.3" + confusing-browser-globals: "npm:^1.0.11" + eslint-config-flat-gitignore: "npm:^0.3.0" + eslint-import-resolver-typescript: "npm:^3.6.3" + eslint-plugin-arrow-return-style: "npm:^1.3.0" + eslint-plugin-astro: "npm:^1.2.3" + eslint-plugin-fsecond: "npm:^1.1.1" + eslint-plugin-import: "npm:^2.31.0" + eslint-plugin-jest: "npm:^28.8.0" + eslint-plugin-jsdoc: "npm:^50.4.3" + eslint-plugin-jsx-a11y: "npm:^6.10.0" + eslint-plugin-lodash-f: "npm:^7.5.3" + eslint-plugin-playwright: "npm:^1.6.2" + eslint-plugin-react: "npm:^7.36.1" + eslint-plugin-react-hooks: "npm:^5.0.0" + eslint-plugin-react-refresh: "npm:^0.4.14" + eslint-plugin-regexp: "npm:^2.6.0" + eslint-plugin-remeda: "npm:^1.4.0" + eslint-plugin-simple-import-sort: "npm:^12.1.0" + eslint-plugin-sonarjs: "npm:^1.0.4" + eslint-plugin-storybook: "npm:^0.10.2" + eslint-plugin-tsdoc: "npm:^0.2.17" + eslint-plugin-unicorn: "npm:^55.0.0" + globals: "npm:^15.11.0" + typescript-eslint: "npm:^8.15.0" + peerDependencies: + eslint: ">=9.0.0" + typescript: ">=5.0.0" + checksum: 10c0/4cfbc0b7a1a32c2c450559364dc09ed47900b6d051a55a9a6a4794faa6af144ddfea86ae4d9dc8d373c80b1380fbc90bf1252536d1507a5ca24867059c460a17 + languageName: node + linkType: hard + +"eslint-import-resolver-node@npm:0.3.9, eslint-import-resolver-node@npm:^0.3.9": version: 0.3.9 resolution: "eslint-import-resolver-node@npm:0.3.9" dependencies: @@ -25340,18 +25861,18 @@ __metadata: languageName: node linkType: hard -"eslint-import-resolver-typescript@npm:^3.5.3": - version: 3.6.3 - resolution: "eslint-import-resolver-typescript@npm:3.6.3" +"eslint-import-resolver-typescript@npm:3.7.0, eslint-import-resolver-typescript@npm:^3.6.1, eslint-import-resolver-typescript@npm:^3.6.3": + version: 3.7.0 + resolution: "eslint-import-resolver-typescript@npm:3.7.0" dependencies: "@nolyfill/is-core-module": "npm:1.0.39" - debug: "npm:^4.3.5" + debug: "npm:^4.3.7" enhanced-resolve: "npm:^5.15.0" - eslint-module-utils: "npm:^2.8.1" fast-glob: "npm:^3.3.2" get-tsconfig: "npm:^4.7.5" is-bun-module: "npm:^1.0.2" is-glob: "npm:^4.0.3" + stable-hash: "npm:^0.0.4" peerDependencies: eslint: "*" eslint-plugin-import: "*" @@ -25361,11 +25882,11 @@ __metadata: optional: true eslint-plugin-import-x: optional: true - checksum: 10c0/5933b00791b7b077725b9ba9a85327d2e2dc7c8944c18a868feb317a0bf0e1e77aed2254c9c5e24dcc49360d119331d2c15281837f4269592965ace380a75111 + checksum: 10c0/b1dec542a31486b3b5730f71f08a8ee2ac4915dbc4aa1493fd15bc8fcadcb029772ab39a425824c235045b3a7e629290a339d4a7e7f3dd32b24e715106352d40 languageName: node linkType: hard -"eslint-module-utils@npm:^2.7.4, eslint-module-utils@npm:^2.8.0, eslint-module-utils@npm:^2.8.1": +"eslint-module-utils@npm:^2.12.0, eslint-module-utils@npm:^2.8.1": version: 2.12.0 resolution: "eslint-module-utils@npm:2.12.0" dependencies: @@ -25377,15 +25898,45 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-canonical@npm:4.18.0": - version: 4.18.0 - resolution: "eslint-plugin-canonical@npm:4.18.0" +"eslint-plugin-arrow-return-style@npm:^1.3.0": + version: 1.3.1 + resolution: "eslint-plugin-arrow-return-style@npm:1.3.1" dependencies: - "@typescript-eslint/utils": "npm:^6.1.0" + "@typescript-eslint/utils": "npm:^7.16.0" + scule: "npm:^1.3.0" + peerDependencies: + eslint: ">=8.0.0" + checksum: 10c0/7bbc002ffc384248b734c1f3d89644097f722c3392ec0d4b3e5a84f2559baccfe7ca3a670019e1ab999ba9e417108fc97eb4b36ce4bc943ffa39073ba13a8b74 + languageName: node + linkType: hard + +"eslint-plugin-astro@npm:^1.2.3": + version: 1.3.1 + resolution: "eslint-plugin-astro@npm:1.3.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.2.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + "@typescript-eslint/types": "npm:^7.7.1 || ^8" + astro-eslint-parser: "npm:^1.0.2" + eslint-compat-utils: "npm:^0.6.0" + globals: "npm:^15.0.0" + postcss: "npm:^8.4.14" + postcss-selector-parser: "npm:^7.0.0" + peerDependencies: + eslint: ">=8.57.0" + checksum: 10c0/640c2c0d53e8d5063bdbf4b2c68c5b5356331c8ae6f22b9432c6a2c0d1062b9b12d83c91fdd24a6ee3d54d717cddb11407d75c57d49a446f269baba9713326aa + languageName: node + linkType: hard + +"eslint-plugin-canonical@npm:5.0.0": + version: 5.0.0 + resolution: "eslint-plugin-canonical@npm:5.0.0" + dependencies: + "@typescript-eslint/utils": "npm:^8.2.0" chance: "npm:^1.1.11" debug: "npm:^4.3.4" - eslint-import-resolver-typescript: "npm:^3.5.3" - eslint-module-utils: "npm:^2.7.4" + eslint-import-resolver-typescript: "npm:^3.6.1" + eslint-module-utils: "npm:^2.8.1" is-get-set-prop: "npm:^1.0.0" is-js-type: "npm:^2.0.0" is-obj-prop: "npm:^1.0.0" @@ -25396,149 +25947,453 @@ __metadata: roarr: "npm:^7.14.2" ts-unused-exports: "npm:^9.0.3" xregexp: "npm:^5.1.1" - checksum: 10c0/77296af3c14e063ea43d046923fad162a2a221d2a3a0733f1d6ea95830f878965b1ebd36047fab6b5023a8ff5345479230c233442b24c930c243d52c33857ba1 + checksum: 10c0/c4a071a00179deff87c31fdaa66e3c86757ce9af387617078ad4ca042209b201406fd94a7d1096c41459b6c2f3fcf6d47cb5808b2a58030d0abdcac745e93582 languageName: node linkType: hard -"eslint-plugin-import@npm:2.29.1": - version: 2.29.1 - resolution: "eslint-plugin-import@npm:2.29.1" +"eslint-plugin-fsecond@npm:^1.1.1": + version: 1.3.0 + resolution: "eslint-plugin-fsecond@npm:1.3.0" + dependencies: + "@typescript-eslint/parser": "npm:^6.2.0" + "@typescript-eslint/utils": "npm:^6.0.0" + minimatch: "npm:^9.0.4" + read-package-up: "npm:^11.0.0" + peerDependencies: + eslint: ">=8.23.0" + typescript: ">=4.0.0" + checksum: 10c0/36fef7789ac8292f78053dd12805a4187974fa2b9d868fffee4e41d8535afeeab68add3619748504e94e41bdeb9343ae362155fe892512b9a8bab5998d755b6a + languageName: node + linkType: hard + +"eslint-plugin-import@npm:2.31.0, eslint-plugin-import@npm:^2.31.0": + version: 2.31.0 + resolution: "eslint-plugin-import@npm:2.31.0" dependencies: - array-includes: "npm:^3.1.7" - array.prototype.findlastindex: "npm:^1.2.3" + "@rtsao/scc": "npm:^1.1.0" + array-includes: "npm:^3.1.8" + array.prototype.findlastindex: "npm:^1.2.5" array.prototype.flat: "npm:^1.3.2" array.prototype.flatmap: "npm:^1.3.2" debug: "npm:^3.2.7" doctrine: "npm:^2.1.0" eslint-import-resolver-node: "npm:^0.3.9" - eslint-module-utils: "npm:^2.8.0" - hasown: "npm:^2.0.0" - is-core-module: "npm:^2.13.1" + eslint-module-utils: "npm:^2.12.0" + hasown: "npm:^2.0.2" + is-core-module: "npm:^2.15.1" is-glob: "npm:^4.0.3" minimatch: "npm:^3.1.2" - object.fromentries: "npm:^2.0.7" - object.groupby: "npm:^1.0.1" - object.values: "npm:^1.1.7" + object.fromentries: "npm:^2.0.8" + object.groupby: "npm:^1.0.3" + object.values: "npm:^1.2.0" semver: "npm:^6.3.1" + string.prototype.trimend: "npm:^1.0.8" tsconfig-paths: "npm:^3.15.0" peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: 10c0/5f35dfbf4e8e67f741f396987de9504ad125c49f4144508a93282b4ea0127e052bde65ab6def1f31b6ace6d5d430be698333f75bdd7dca3bc14226c92a083196 + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + checksum: 10c0/e21d116ddd1900e091ad120b3eb68c5dd5437fe2c930f1211781cd38b246f090a6b74d5f3800b8255a0ed29782591521ad44eb21c5534960a8f1fb4040fd913a languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:6.8.0": - version: 6.8.0 - resolution: "eslint-plugin-jsx-a11y@npm:6.8.0" +"eslint-plugin-jest@npm:^28.8.0": + version: 28.9.0 + resolution: "eslint-plugin-jest@npm:28.9.0" dependencies: - "@babel/runtime": "npm:^7.23.2" - aria-query: "npm:^5.3.0" - array-includes: "npm:^3.1.7" + "@typescript-eslint/utils": "npm:^6.0.0 || ^7.0.0 || ^8.0.0" + peerDependencies: + "@typescript-eslint/eslint-plugin": ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + jest: "*" + peerDependenciesMeta: + "@typescript-eslint/eslint-plugin": + optional: true + jest: + optional: true + checksum: 10c0/56b0d2fb18a32bf56b0eb8c7790c355513535a239451d9d00184829cbd0ba35b6c68eec64e850a6299453f9c37338b6797d3184594c0326c8fdcc029024065b8 + languageName: node + linkType: hard + +"eslint-plugin-jsdoc@npm:^50.4.3": + version: 50.6.0 + resolution: "eslint-plugin-jsdoc@npm:50.6.0" + dependencies: + "@es-joy/jsdoccomment": "npm:~0.49.0" + are-docs-informative: "npm:^0.0.2" + comment-parser: "npm:1.4.1" + debug: "npm:^4.3.6" + escape-string-regexp: "npm:^4.0.0" + espree: "npm:^10.1.0" + esquery: "npm:^1.6.0" + parse-imports: "npm:^2.1.1" + semver: "npm:^7.6.3" + spdx-expression-parse: "npm:^4.0.0" + synckit: "npm:^0.9.1" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + checksum: 10c0/f878714212f52602819da77c6727f75ccda66232cd7b383b9437981ec21255be62b6099b20be43710d8e37ceb16e05343d4dc701eebfc488b4e4d54e0bf2e150 + languageName: node + linkType: hard + +"eslint-plugin-jsx-a11y@npm:^6.10.0": + version: 6.10.2 + resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" + dependencies: + aria-query: "npm:^5.3.2" + array-includes: "npm:^3.1.8" array.prototype.flatmap: "npm:^1.3.2" ast-types-flow: "npm:^0.0.8" - axe-core: "npm:=4.7.0" - axobject-query: "npm:^3.2.1" + axe-core: "npm:^4.10.0" + axobject-query: "npm:^4.1.0" damerau-levenshtein: "npm:^1.0.8" emoji-regex: "npm:^9.2.2" - es-iterator-helpers: "npm:^1.0.15" - hasown: "npm:^2.0.0" + hasown: "npm:^2.0.2" jsx-ast-utils: "npm:^3.3.5" language-tags: "npm:^1.0.9" minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.7" - object.fromentries: "npm:^2.0.7" + object.fromentries: "npm:^2.0.8" + safe-regex-test: "npm:^1.0.3" + string.prototype.includes: "npm:^2.0.1" peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10c0/199b883e526e6f9d7c54cb3f094abc54f11a1ec816db5fb6cae3b938eb0e503acc10ccba91ca7451633a9d0b9abc0ea03601844a8aba5fe88c5e8897c9ac8f49 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + checksum: 10c0/d93354e03b0cf66f018d5c50964e074dffe4ddf1f9b535fa020d19c4ae45f89c1a16e9391ca61ac3b19f7042c751ac0d361a056a65cbd1de24718a53ff8daa6e languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:4.6.0": - version: 4.6.0 - resolution: "eslint-plugin-react-hooks@npm:4.6.0" +"eslint-plugin-lodash-f@npm:^7.5.3": + version: 7.5.3 + resolution: "eslint-plugin-lodash-f@npm:7.5.3" + dependencies: + lodash: "npm:^4.17.21" + peerDependencies: + eslint: ">=2" + checksum: 10c0/7011be275d8f4e3dfe97f2d41d09110ad77dc27895814f47fb636ef7c05d1ee15360ab0751380b57f8d3229354e9b3e99664fdc9eb923c58ba3a554b1c62add0 + languageName: node + linkType: hard + +"eslint-plugin-playwright@npm:^1.6.2": + version: 1.8.3 + resolution: "eslint-plugin-playwright@npm:1.8.3" + dependencies: + globals: "npm:^13.23.0" + peerDependencies: + eslint: ">=8.40.0" + eslint-plugin-jest: ">=25" + peerDependenciesMeta: + eslint-plugin-jest: + optional: true + checksum: 10c0/41c90ad82d7bfd336b11d88a7dd4aee3832878f3abc5df0c7e988124ac3d4e0ffc7de760f4e986a275bf088da2a360d177e8a48d6b3193dcb5f60b17138cf0fe + languageName: node + linkType: hard + +"eslint-plugin-react-debug@npm:1.17.2": + version: 1.17.2 + resolution: "eslint-plugin-react-debug@npm:1.17.2" + dependencies: + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/core": "npm:1.17.2" + "@eslint-react/jsx": "npm:1.17.2" + "@eslint-react/shared": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@eslint-react/var": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/type-utils": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + string-ts: "npm:^2.2.0" + ts-pattern: "npm:^5.5.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + eslint: + optional: false + typescript: + optional: true + checksum: 10c0/449c47a76d0208140c83a37ee22e8602ced50e3090fec7ee85dac4d56dfe9797b44e433f8a769f98d0e8da8f62be6dc158ef36421c3191f4022bb3881375037e + languageName: node + linkType: hard + +"eslint-plugin-react-dom@npm:1.17.2": + version: 1.17.2 + resolution: "eslint-plugin-react-dom@npm:1.17.2" + dependencies: + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/core": "npm:1.17.2" + "@eslint-react/jsx": "npm:1.17.2" + "@eslint-react/shared": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@eslint-react/var": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + compare-versions: "npm:^6.1.1" + ts-pattern: "npm:^5.5.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + eslint: + optional: false + typescript: + optional: true + checksum: 10c0/911262c6e483128b4c8b03b419f0e726c880d725f7b97e719474b338b7b106a0e247a36a90893a6140ada9c82fdfdd08eaf0150a137f8d46445571e1ca4d9a22 + languageName: node + linkType: hard + +"eslint-plugin-react-hooks-extra@npm:1.17.2": + version: 1.17.2 + resolution: "eslint-plugin-react-hooks-extra@npm:1.17.2" + dependencies: + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/core": "npm:1.17.2" + "@eslint-react/jsx": "npm:1.17.2" + "@eslint-react/shared": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@eslint-react/var": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/type-utils": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + ts-pattern: "npm:^5.5.0" peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 10c0/58c7e10ea5792c33346fcf5cb4024e14837035ce412ff99c2dcb7c4f903dc9b17939078f80bfef826301ce326582c396c00e8e0ac9d10ac2cde2b42d33763c65 + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + eslint: + optional: false + typescript: + optional: true + checksum: 10c0/bfdc9b180e02e60dbd25395e534c342fbfeaafa93927f4a7defba5ca9d7896f5b6c13eead58431205ba30d734187b382657a2a64221de6daf96459ec2b87bc95 languageName: node linkType: hard -"eslint-plugin-react@npm:7.34.1": - version: 7.34.1 - resolution: "eslint-plugin-react@npm:7.34.1" +"eslint-plugin-react-hooks@npm:5.1.0, eslint-plugin-react-hooks@npm:^5.0.0": + version: 5.1.0 + resolution: "eslint-plugin-react-hooks@npm:5.1.0" + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + checksum: 10c0/37ef76e1d916d46ab8e93a596078efcf2162e2c653614437e0c54e31d02a5dadabec22802fab717effe257aeb4bdc20c2a710666a89ab1cf07e01e614dde75d8 + languageName: node + linkType: hard + +"eslint-plugin-react-naming-convention@npm:1.17.2": + version: 1.17.2 + resolution: "eslint-plugin-react-naming-convention@npm:1.17.2" dependencies: - array-includes: "npm:^3.1.7" - array.prototype.findlast: "npm:^1.2.4" + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/core": "npm:1.17.2" + "@eslint-react/jsx": "npm:1.17.2" + "@eslint-react/shared": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/type-utils": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + ts-pattern: "npm:^5.5.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + eslint: + optional: false + typescript: + optional: true + checksum: 10c0/08313381ae16dadfb92e2a01c96433c49b2443021401b51ff37e8cdd384be84852be2679742ba694e9b237d7bc66bceb760cabb7363bc3d71dfd04840c7a32fc + languageName: node + linkType: hard + +"eslint-plugin-react-refresh@npm:^0.4.14": + version: 0.4.16 + resolution: "eslint-plugin-react-refresh@npm:0.4.16" + peerDependencies: + eslint: ">=8.40" + checksum: 10c0/0628d54b6cc6773a89252e2a7c82c7905a00dc8dc99a6ae2885a64f3b45bd3012a40cf9791ee24aa5dcf75665d8c8be4699845bbbf205cd0ef652702701a7865 + languageName: node + linkType: hard + +"eslint-plugin-react-web-api@npm:1.17.2": + version: 1.17.2 + resolution: "eslint-plugin-react-web-api@npm:1.17.2" + dependencies: + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/core": "npm:1.17.2" + "@eslint-react/jsx": "npm:1.17.2" + "@eslint-react/shared": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@eslint-react/var": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + birecord: "npm:^0.1.1" + ts-pattern: "npm:^5.5.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + eslint: + optional: false + typescript: + optional: true + checksum: 10c0/f9efa836f98cbc928dd295f46cfe175d23fe4e0cd5df295937e08dcd68cf1a39083ac07c3b44728ac6735e75770c2ca685df86874f082e9dd33b753a0bdef985 + languageName: node + linkType: hard + +"eslint-plugin-react-x@npm:1.17.2": + version: 1.17.2 + resolution: "eslint-plugin-react-x@npm:1.17.2" + dependencies: + "@eslint-react/ast": "npm:1.17.2" + "@eslint-react/core": "npm:1.17.2" + "@eslint-react/jsx": "npm:1.17.2" + "@eslint-react/shared": "npm:1.17.2" + "@eslint-react/tools": "npm:1.17.2" + "@eslint-react/types": "npm:1.17.2" + "@eslint-react/var": "npm:1.17.2" + "@typescript-eslint/scope-manager": "npm:^8.16.0" + "@typescript-eslint/type-utils": "npm:^8.16.0" + "@typescript-eslint/types": "npm:^8.16.0" + "@typescript-eslint/utils": "npm:^8.16.0" + compare-versions: "npm:^6.1.1" + is-immutable-type: "npm:^5.0.0" + ts-pattern: "npm:^5.5.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + eslint: + optional: false + typescript: + optional: true + checksum: 10c0/94eed0a966e17afccae5f56e5769e7fc1f8c2f160998aa43b82fd412fdf8fe4a347fda35279ed131a77b58d85fecb1d1ebbddbc4c4f52c870a4df8ad75c5d21f + languageName: node + linkType: hard + +"eslint-plugin-react@npm:^7.36.1": + version: 7.37.2 + resolution: "eslint-plugin-react@npm:7.37.2" + dependencies: + array-includes: "npm:^3.1.8" + array.prototype.findlast: "npm:^1.2.5" array.prototype.flatmap: "npm:^1.3.2" - array.prototype.toreversed: "npm:^1.1.2" - array.prototype.tosorted: "npm:^1.1.3" + array.prototype.tosorted: "npm:^1.1.4" doctrine: "npm:^2.1.0" - es-iterator-helpers: "npm:^1.0.17" + es-iterator-helpers: "npm:^1.1.0" estraverse: "npm:^5.3.0" + hasown: "npm:^2.0.2" jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.7" - object.fromentries: "npm:^2.0.7" - object.hasown: "npm:^1.1.3" - object.values: "npm:^1.1.7" + object.entries: "npm:^1.1.8" + object.fromentries: "npm:^2.0.8" + object.values: "npm:^1.2.0" prop-types: "npm:^15.8.1" resolve: "npm:^2.0.0-next.5" semver: "npm:^6.3.1" - string.prototype.matchall: "npm:^4.0.10" + string.prototype.matchall: "npm:^4.0.11" + string.prototype.repeat: "npm:^1.0.0" peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10c0/7c61b1314d37a4ac2f2474f9571f801f1a1a5d81dcd4abbb5d07145406518722fb792367267757ee116bde254be9753242d6b93c9619110398b3fe1746e4848c + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + checksum: 10c0/01c498f263c201698bf653973760f86a07fa0cdec56c044f3eaa5ddaae71c64326015dfa5fde76ca8c5386ffe789fc79932624b614e13b6a1ad789fee3f7c491 languageName: node linkType: hard -"eslint-plugin-simple-import-sort@npm:12.0.0": - version: 12.0.0 - resolution: "eslint-plugin-simple-import-sort@npm:12.0.0" +"eslint-plugin-regexp@npm:^2.6.0": + version: 2.7.0 + resolution: "eslint-plugin-regexp@npm:2.7.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.2.0" + "@eslint-community/regexpp": "npm:^4.11.0" + comment-parser: "npm:^1.4.0" + jsdoc-type-pratt-parser: "npm:^4.0.0" + refa: "npm:^0.12.1" + regexp-ast-analysis: "npm:^0.7.1" + scslre: "npm:^0.3.0" + peerDependencies: + eslint: ">=8.44.0" + checksum: 10c0/c4882b441bab92e89c82cb27d6650540ad318750df5e99b42989f0fdf9ea381a9156de8470f1221483f98b5dc9cd6c493da73ccc18d94dee8d4a0f0ce78bd122 + languageName: node + linkType: hard + +"eslint-plugin-remeda@npm:^1.4.0": + version: 1.4.0 + resolution: "eslint-plugin-remeda@npm:1.4.0" + dependencies: + lodash-es: "npm:^4.17.21" + peerDependencies: + eslint: ">=9.0.0" + checksum: 10c0/aa234c6f95702a00f8635dea79c571d8349c63120e08c78c621cb43eb00eb919acca730f62f9011af6ab2f11ba6b008f3df9fb069e754e398e23db59978d26f6 + languageName: node + linkType: hard + +"eslint-plugin-simple-import-sort@npm:^12.1.0": + version: 12.1.1 + resolution: "eslint-plugin-simple-import-sort@npm:12.1.1" peerDependencies: eslint: ">=5.0.0" - checksum: 10c0/5405f01e4ca5b3c9a2a1b019e39fa858bb081872eb9602fb85d2e4913356fec0a9b3f997e957b1df0c370908ec124114148491e442d57e911b8249728d474398 + checksum: 10c0/0ad1907ad9ddbadd1db655db0a9d0b77076e274b793a77b982c8525d808d868e6ecfce24f3a411e8a1fa551077387f9ebb38c00956073970ebd7ee6a029ce2b3 languageName: node linkType: hard -"eslint-plugin-storybook@npm:0.8.0": - version: 0.8.0 - resolution: "eslint-plugin-storybook@npm:0.8.0" +"eslint-plugin-sonarjs@npm:^1.0.4": + version: 1.0.4 + resolution: "eslint-plugin-sonarjs@npm:1.0.4" + peerDependencies: + eslint: ^8.0.0 || ^9.0.0 + checksum: 10c0/37d0229ea16158dfaa6ea8cd11e467b085fa26c35478fa37c33103810e753ba2d8f8eb8612fde8c8c375b9a2ec21b2a530ba612c669d71fb1605c768e5119b14 + languageName: node + linkType: hard + +"eslint-plugin-storybook@npm:0.11.1": + version: 0.11.1 + resolution: "eslint-plugin-storybook@npm:0.11.1" dependencies: - "@storybook/csf": "npm:^0.0.1" - "@typescript-eslint/utils": "npm:^5.62.0" - requireindex: "npm:^1.2.0" + "@storybook/csf": "npm:^0.1.11" + "@typescript-eslint/utils": "npm:^8.8.1" ts-dedent: "npm:^2.2.0" peerDependencies: eslint: ">=6" - checksum: 10c0/c76f6decdd4c826cd6a8bb613085e0cde804f4648093a0464a39867cc0ba4e1d34be15ff91eed827730da5efbbf55ae5e71af648bb0b461946d5e41384669ab8 + checksum: 10c0/0520018311c6da25fe2d0db24a59e99ecefe74c4cadd4eba42ce3b1b0ce2c3cc6f88d48680389374f99e10151a7ef3da52386853d9d5a4058c41ae72e2184549 languageName: node linkType: hard -"eslint-plugin-typescript-sort-keys@npm:3.2.0": - version: 3.2.0 - resolution: "eslint-plugin-typescript-sort-keys@npm:3.2.0" +"eslint-plugin-storybook@npm:^0.10.2": + version: 0.10.2 + resolution: "eslint-plugin-storybook@npm:0.10.2" dependencies: - "@typescript-eslint/experimental-utils": "npm:^5.0.0" - json-schema: "npm:^0.4.0" - natural-compare-lite: "npm:^1.4.0" + "@storybook/csf": "npm:^0.1.11" + "@typescript-eslint/utils": "npm:^8.8.1" + ts-dedent: "npm:^2.2.0" peerDependencies: - "@typescript-eslint/parser": ^6 || ^7 - eslint: ^7 || ^8 - typescript: ^3 || ^4 || ^5 - checksum: 10c0/c832d5a93cac4f955f05b126ad79d1df49f9f11402ab225b1835d42972291a3855e477d28b07696d2a65a511ccdcdf64001eeda216248da82a5187af6d03e70f + eslint: ">=6" + checksum: 10c0/a5dc86602509b655ef2a4dc7f13786a1bc9e52deebfc12e722ccd796be5b20e5b6dfd65635b2da72f359372c5978c3277b46b2f8aeed2d96bb5d0285f7afcd3b + languageName: node + linkType: hard + +"eslint-plugin-tsdoc@npm:^0.2.17": + version: 0.2.17 + resolution: "eslint-plugin-tsdoc@npm:0.2.17" + dependencies: + "@microsoft/tsdoc": "npm:0.14.2" + "@microsoft/tsdoc-config": "npm:0.16.2" + checksum: 10c0/26cad40b22f3dc0adfb06b1ea12f7d3c9cb257ac8bb56ad6a023e3b3bdfc6144d95a8b01323563e75283cca90baaf4d68816f5cea6994c6cd660a642e820847a languageName: node linkType: hard -"eslint-plugin-unicorn@npm:51.0.1": - version: 51.0.1 - resolution: "eslint-plugin-unicorn@npm:51.0.1" +"eslint-plugin-unicorn@npm:^55.0.0": + version: 55.0.0 + resolution: "eslint-plugin-unicorn@npm:55.0.0" dependencies: - "@babel/helper-validator-identifier": "npm:^7.22.20" + "@babel/helper-validator-identifier": "npm:^7.24.5" "@eslint-community/eslint-utils": "npm:^4.4.0" - "@eslint/eslintrc": "npm:^2.1.4" ci-info: "npm:^4.0.0" clean-regexp: "npm:^1.0.0" - core-js-compat: "npm:^3.34.0" + core-js-compat: "npm:^3.37.0" esquery: "npm:^1.5.0" + globals: "npm:^15.7.0" indent-string: "npm:^4.0.0" is-builtin-module: "npm:^3.2.1" jsesc: "npm:^3.0.2" @@ -25546,15 +26401,15 @@ __metadata: read-pkg-up: "npm:^7.0.1" regexp-tree: "npm:^0.1.27" regjsparser: "npm:^0.10.0" - semver: "npm:^7.5.4" + semver: "npm:^7.6.1" strip-indent: "npm:^3.0.0" peerDependencies: eslint: ">=8.56.0" - checksum: 10c0/e3b019e55d60511c18aec081ff512366f917d0162db3ee122e1f881657b9a1c89e0d505bb7aec968d612ff3c757c055d5b734aaf0b3078a283315bb7db56ca04 + checksum: 10c0/31620da5c823abc791a3f4c9a0ab19baf21820bd38f018eafbc862ea0bbc3e4baedbdaaaf48f2dc1b2a59dfc7b341e654f2126c394f5d62fb5216e632d8a2c03 languageName: node linkType: hard -"eslint-scope@npm:5.1.1, eslint-scope@npm:^5.1.1": +"eslint-scope@npm:5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" dependencies: @@ -25564,13 +26419,39 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-scope@npm:^8.0.1, eslint-scope@npm:^8.2.0": + version: 8.2.0 + resolution: "eslint-scope@npm:8.2.0" dependencies: esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10c0/613c267aea34b5a6d6c00514e8545ef1f1433108097e857225fed40d397dd6b1809dffd11c2fde23b37ca53d7bf935fe04d2a18e6fc932b31837b6ad67e1c116 + checksum: 10c0/8d2d58e2136d548ac7e0099b1a90d9fab56f990d86eb518de1247a7066d38c908be2f3df477a79cf60d70b30ba18735d6c6e70e9914dca2ee515a729975d70d6 + languageName: node + linkType: hard + +"eslint-unicorn@npm:55.0.0": + version: 55.0.0 + resolution: "eslint-unicorn@npm:55.0.0" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.24.5" + "@eslint-community/eslint-utils": "npm:^4.4.0" + ci-info: "npm:^4.0.0" + clean-regexp: "npm:^1.0.0" + core-js-compat: "npm:^3.37.0" + esquery: "npm:^1.5.0" + globals: "npm:^15.7.0" + indent-string: "npm:^4.0.0" + is-builtin-module: "npm:^3.2.1" + jsesc: "npm:^3.0.2" + pluralize: "npm:^8.0.0" + read-pkg-up: "npm:^7.0.1" + regexp-tree: "npm:^0.1.27" + regjsparser: "npm:^0.10.0" + semver: "npm:^7.6.1" + strip-indent: "npm:^3.0.0" + peerDependencies: + eslint: ">=8.56.0" + checksum: 10c0/c771e3d1b2831330400a4be50d459a38573d304b8bef754e619601628f3495aa2bede1f220256b2c6a9daf0b4f1ee3faf6c4f60474646ba484e91182ef1185ac languageName: node linkType: hard @@ -25588,51 +26469,59 @@ __metadata: languageName: node linkType: hard -"eslint@npm:8.57.0": - version: 8.57.0 - resolution: "eslint@npm:8.57.0" +"eslint-visitor-keys@npm:^4.0.0, eslint-visitor-keys@npm:^4.2.0": + version: 4.2.0 + resolution: "eslint-visitor-keys@npm:4.2.0" + checksum: 10c0/2ed81c663b147ca6f578312919483eb040295bbab759e5a371953456c636c5b49a559883e2677112453728d66293c0a4c90ab11cab3428cf02a0236d2e738269 + languageName: node + linkType: hard + +"eslint@npm:9.16.0": + version: 9.16.0 + resolution: "eslint@npm:9.16.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" - "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.57.0" - "@humanwhocodes/config-array": "npm:^0.11.14" + "@eslint-community/regexpp": "npm:^4.12.1" + "@eslint/config-array": "npm:^0.19.0" + "@eslint/core": "npm:^0.9.0" + "@eslint/eslintrc": "npm:^3.2.0" + "@eslint/js": "npm:9.16.0" + "@eslint/plugin-kit": "npm:^0.2.3" + "@humanfs/node": "npm:^0.16.6" "@humanwhocodes/module-importer": "npm:^1.0.1" - "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" + "@humanwhocodes/retry": "npm:^0.4.1" + "@types/estree": "npm:^1.0.6" + "@types/json-schema": "npm:^7.0.15" ajv: "npm:^6.12.4" chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.2" + cross-spawn: "npm:^7.0.5" debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" - esquery: "npm:^1.4.2" + eslint-scope: "npm:^8.2.0" + eslint-visitor-keys: "npm:^4.2.0" + espree: "npm:^10.3.0" + esquery: "npm:^1.5.0" esutils: "npm:^2.0.2" fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" + file-entry-cache: "npm:^8.0.0" find-up: "npm:^5.0.0" glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" - graphemer: "npm:^1.4.0" ignore: "npm:^5.2.0" imurmurhash: "npm:^0.1.4" is-glob: "npm:^4.0.0" - is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" - levn: "npm:^0.4.1" lodash.merge: "npm:^4.6.2" minimatch: "npm:^3.1.2" natural-compare: "npm:^1.4.0" optionator: "npm:^0.9.3" - strip-ansi: "npm:^6.0.1" - text-table: "npm:^0.2.0" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true bin: eslint: bin/eslint.js - checksum: 10c0/00bb96fd2471039a312435a6776fe1fd557c056755eaa2b96093ef3a8508c92c8775d5f754768be6b1dddd09fdd3379ddb231eeb9b6c579ee17ea7d68000a529 + checksum: 10c0/f36d12652c6f20bab8a77375b8ad29a6af030c3840deb0a5f9dd4cee49d68a2d68d7dc73b0c25918df59d83cd686dd5712e11387e696e1f3842e8dde15cd3255 languageName: node linkType: hard @@ -25648,7 +26537,18 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.4.1, espree@npm:^9.6.0, espree@npm:^9.6.1": +"espree@npm:^10.0.0, espree@npm:^10.0.1, espree@npm:^10.1.0, espree@npm:^10.3.0": + version: 10.3.0 + resolution: "espree@npm:10.3.0" + dependencies: + acorn: "npm:^8.14.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^4.2.0" + checksum: 10c0/272beeaca70d0a1a047d61baff64db04664a33d7cfb5d144f84bc8a5c6194c6c8ebe9cc594093ca53add88baa23e59b01e69e8a0160ab32eac570482e165c462 + languageName: node + linkType: hard + +"espree@npm:^9.4.1": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -25679,7 +26579,7 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2, esquery@npm:^1.5.0": +"esquery@npm:^1.5.0, esquery@npm:^1.6.0": version: 1.6.0 resolution: "esquery@npm:1.6.0" dependencies: @@ -26443,12 +27343,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" dependencies: - flat-cache: "npm:^3.0.4" - checksum: 10c0/58473e8a82794d01b38e5e435f6feaf648e3f36fdb3a56e98f417f4efae71ad1c0d4ebd8a9a7c50c3ad085820a93fc7494ad721e0e4ebc1da3573f4e1c3c7cdd + flat-cache: "npm:^4.0.0" + checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638 languageName: node linkType: hard @@ -26654,6 +27554,13 @@ __metadata: languageName: node linkType: hard +"find-up-simple@npm:^1.0.0": + version: 1.0.0 + resolution: "find-up-simple@npm:1.0.0" + checksum: 10c0/de1ad5e55c8c162f5600fe3297bb55a3da5cd9cb8c6755e463ec1d52c4c15a84e312a68397fb5962d13263b3dbd4ea294668c465ccacc41291d7cc97588769f9 + languageName: node + linkType: hard + "find-up@npm:^3.0.0": version: 3.0.0 resolution: "find-up@npm:3.0.0" @@ -26725,6 +27632,16 @@ __metadata: languageName: node linkType: hard +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" + dependencies: + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.4" + checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc + languageName: node + linkType: hard + "flat@npm:^5.0.2": version: 5.0.2 resolution: "flat@npm:5.0.2" @@ -27582,6 +28499,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:7.1.7, glob@npm:~7.1.3": + version: 7.1.7 + resolution: "glob@npm:7.1.7" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.0.4" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10c0/173245e6f9ccf904309eb7ef4a44a11f3bf68e9e341dff5a28b5db0dd7123b7506daf41497f3437a0710f57198187b758c2351eeaabce4d16935e956920da6a4 + languageName: node + linkType: hard + "glob@npm:9.3.5, glob@npm:^9.3.2": version: 9.3.5 resolution: "glob@npm:9.3.5" @@ -27653,17 +28584,10 @@ __metadata: languageName: node linkType: hard -"glob@npm:~7.1.3": - version: 7.1.7 - resolution: "glob@npm:7.1.7" - dependencies: - fs.realpath: "npm:^1.0.0" - inflight: "npm:^1.0.4" - inherits: "npm:2" - minimatch: "npm:^3.0.4" - once: "npm:^1.3.0" - path-is-absolute: "npm:^1.0.0" - checksum: 10c0/173245e6f9ccf904309eb7ef4a44a11f3bf68e9e341dff5a28b5db0dd7123b7506daf41497f3437a0710f57198187b758c2351eeaabce4d16935e956920da6a4 +"globals@npm:15.13.0, globals@npm:^15.0.0, globals@npm:^15.11.0, globals@npm:^15.7.0": + version: 15.13.0 + resolution: "globals@npm:15.13.0" + checksum: 10c0/640365115ca5f81d91e6a7667f4935021705e61a1a5a76a6ec5c3a5cdf6e53f165af7f9db59b7deb65cf2e1f83d03ac8d6660d0b14c569c831a9b6483eeef585 languageName: node linkType: hard @@ -27674,7 +28598,7 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0": +"globals@npm:^13.23.0": version: 13.24.0 resolution: "globals@npm:13.24.0" dependencies: @@ -27683,6 +28607,13 @@ __metadata: languageName: node linkType: hard +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 10c0/b96ff42620c9231ad468d4c58ff42afee7777ee1c963013ff8aabe095a451d0ceeb8dcd8ef4cbd64d2538cef45f787a78ba3a9574f4a634438963e334471302d + languageName: node + linkType: hard + "globalthis@npm:^1.0.4": version: 1.0.4 resolution: "globalthis@npm:1.0.4" @@ -29133,7 +30064,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.9, ignore@npm:^5.2.0, ignore@npm:^5.2.4": +"ignore@npm:^5.1.9, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 @@ -29259,6 +30190,13 @@ __metadata: languageName: node linkType: hard +"index-to-position@npm:^0.1.2": + version: 0.1.2 + resolution: "index-to-position@npm:0.1.2" + checksum: 10c0/7c91bde8bafc22684b74a7a24915bee4691cba48352ddb4ebe3b20a3a87bc0fa7a05f586137245ca8f92222a11f341f7631ff7f38cd78a523505d2d02dbfa257 + languageName: node + linkType: hard + "inflight@npm:^1.0.4": version: 1.0.6 resolution: "inflight@npm:1.0.6" @@ -29416,7 +30354,7 @@ __metadata: languageName: node linkType: hard -"interface-datastore@npm:^8.0.0, interface-datastore@npm:^8.3.0": +"interface-datastore@npm:^8.0.0, interface-datastore@npm:^8.3.0, interface-datastore@npm:^8.3.1": version: 8.3.1 resolution: "interface-datastore@npm:8.3.1" dependencies: @@ -29701,7 +30639,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1": +"is-core-module@npm:^2.1.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1": version: 2.15.1 resolution: "is-core-module@npm:2.15.1" dependencies: @@ -29892,6 +30830,20 @@ __metadata: languageName: node linkType: hard +"is-immutable-type@npm:^5.0.0": + version: 5.0.0 + resolution: "is-immutable-type@npm:5.0.0" + dependencies: + "@typescript-eslint/type-utils": "npm:^8.0.0" + ts-api-utils: "npm:^1.3.0" + ts-declaration-location: "npm:^1.0.4" + peerDependencies: + eslint: "*" + typescript: ">=4.7.4" + checksum: 10c0/dd6e7964f47cb349e7382158d3942121a7cc2a7b656e7d1656883c625f48c8f0e66a82ec22196cfff8eca49eeededba05c049a65abc9a6b89410b4b41401d8c5 + languageName: node + linkType: hard + "is-inside-container@npm:^1.0.0": version: 1.0.0 resolution: "is-inside-container@npm:1.0.0" @@ -30052,7 +31004,7 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": +"is-path-inside@npm:^3.0.2": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05 @@ -30583,7 +31535,7 @@ __metadata: languageName: node linkType: hard -"it-length-prefixed-stream@npm:^1.0.0, it-length-prefixed-stream@npm:^1.1.7": +"it-length-prefixed-stream@npm:^1.0.0, it-length-prefixed-stream@npm:^1.2.0": version: 1.2.0 resolution: "it-length-prefixed-stream@npm:1.2.0" dependencies: @@ -30595,7 +31547,7 @@ __metadata: languageName: node linkType: hard -"it-length-prefixed@npm:^9.0.1, it-length-prefixed@npm:^9.0.4": +"it-length-prefixed@npm:^9.0.1, it-length-prefixed@npm:^9.1.0": version: 9.1.0 resolution: "it-length-prefixed@npm:9.1.0" dependencies: @@ -30712,7 +31664,7 @@ __metadata: languageName: node linkType: hard -"it-stream-types@npm:2.0.2, it-stream-types@npm:^2.0.1": +"it-stream-types@npm:2.0.2, it-stream-types@npm:^2.0.1, it-stream-types@npm:^2.0.2": version: 2.0.2 resolution: "it-stream-types@npm:2.0.2" checksum: 10c0/da2a035234b3a914c12cfbfc38cbae201c8464b917db1e6dadd88aaa87d4ca6c52c35827b9c3405fe0c55862bdc63d5cefca33a219394d0b4c2f22987e838807 @@ -30883,11 +31835,18 @@ __metadata: linkType: hard "jiti@npm:^2.0.0": - version: 2.4.0 - resolution: "jiti@npm:2.4.0" + version: 2.4.1 + resolution: "jiti@npm:2.4.1" bin: jiti: lib/jiti-cli.mjs - checksum: 10c0/f97365a83169e0544b0a6e7f415f1ee69ca9c0bdd55e336035490b4b7a6ff99b63b9df89c70babfc49e924247dfbdc730f9eb0c5ed4771d3db989ac70e49bf18 + checksum: 10c0/3cf67d1b952a9e8cffbb4f96527880da6cdb58a1eae2a6d2deb4645621dfc8b766d21549f71c6153a2094a40bb635ffafed4cd0dd42f3b3263b187d1ee846225 + languageName: node + linkType: hard + +"jju@npm:~1.4.0": + version: 1.4.0 + resolution: "jju@npm:1.4.0" + checksum: 10c0/f3f444557e4364cfc06b1abf8331bf3778b26c0c8552ca54429bc0092652172fdea26cbffe33e1017b303d5aa506f7ede8571857400efe459cb7439180e2acad languageName: node linkType: hard @@ -31055,6 +32014,13 @@ __metadata: languageName: node linkType: hard +"jsdoc-type-pratt-parser@npm:^4.0.0, jsdoc-type-pratt-parser@npm:~4.1.0": + version: 4.1.0 + resolution: "jsdoc-type-pratt-parser@npm:4.1.0" + checksum: 10c0/7700372d2e733a32f7ea0a1df9cec6752321a5345c11a91b2ab478a031a426e934f16d5c1f15c8566c7b2c10af9f27892a29c2c789039f595470e929a4aa60ea + languageName: node + linkType: hard + "jsdom@npm:24.1.3": version: 24.1.3 resolution: "jsdom@npm:24.1.3" @@ -31191,7 +32157,7 @@ __metadata: languageName: node linkType: hard -"json-schema@npm:0.4.0, json-schema@npm:^0.4.0": +"json-schema@npm:0.4.0": version: 0.4.0 resolution: "json-schema@npm:0.4.0" checksum: 10c0/d4a637ec1d83544857c1c163232f3da46912e971d5bf054ba44fdb88f07d8d359a462b4aec46f2745efbc57053365608d88bc1d7b1729f7b4fc3369765639ed3 @@ -31479,7 +32445,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.0.0, keyv@npm:^4.5.3": +"keyv@npm:^4.0.0, keyv@npm:^4.5.3, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -31966,6 +32932,16 @@ __metadata: languageName: node linkType: hard +"local-pkg@npm:^0.5.1": + version: 0.5.1 + resolution: "local-pkg@npm:0.5.1" + dependencies: + mlly: "npm:^1.7.3" + pkg-types: "npm:^1.2.1" + checksum: 10c0/ade8346f1dc04875921461adee3c40774b00d4b74095261222ebd4d5fd0a444676e36e325f76760f21af6a60bc82480e154909b54d2d9f7173671e36dacf1808 + languageName: node + linkType: hard + "localforage@npm:^1.8.1": version: 1.10.0 resolution: "localforage@npm:1.10.0" @@ -32287,7 +33263,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.17.21, lodash@npm:^4, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:~4.17.0": +"lodash@npm:4.17.21, lodash@npm:^4, lodash@npm:^4.17.14, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:~4.17.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -34423,7 +35399,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:3.1.2, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:3.1.2, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -34441,7 +35417,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.0.0, minimatch@npm:~10.0.1": +"minimatch@npm:^10.0.0, minimatch@npm:^10.0.1, minimatch@npm:~10.0.1": version: 10.0.1 resolution: "minimatch@npm:10.0.1" dependencies: @@ -34665,7 +35641,7 @@ __metadata: languageName: node linkType: hard -"mlly@npm:^1.7.2": +"mlly@npm:^1.7.2, mlly@npm:^1.7.3": version: 1.7.3 resolution: "mlly@npm:1.7.3" dependencies: @@ -34907,7 +35883,7 @@ __metadata: languageName: node linkType: hard -"mortice@npm:^3.0.4": +"mortice@npm:^3.0.6": version: 3.0.6 resolution: "mortice@npm:3.0.6" dependencies: @@ -35061,7 +36037,7 @@ __metadata: languageName: node linkType: hard -"multiformats@npm:13.3.1, multiformats@npm:^13.0.0, multiformats@npm:^13.1.0, multiformats@npm:^13.2.2": +"multiformats@npm:13.3.1, multiformats@npm:^13.0.0, multiformats@npm:^13.1.0, multiformats@npm:^13.3.1": version: 13.3.1 resolution: "multiformats@npm:13.3.1" checksum: 10c0/12a68569a2b74b0b3ed554af866149300ed587aa46ce65ef6539c522fc8d7deb5d38d38e41e004b50bc1109566e2c04bf848f1909c9e687e86f504c6cf586eac @@ -35170,13 +36146,6 @@ __metadata: languageName: node linkType: hard -"natural-compare-lite@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare-lite@npm:1.4.0" - checksum: 10c0/f6cef26f5044515754802c0fc475d81426f3b90fe88c20fabe08771ce1f736ce46e0397c10acb569a4dd0acb84c7f1ee70676122f95d5bfdd747af3a6c6bbaa8 - languageName: node - linkType: hard - "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -36066,7 +37035,7 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.5, object.entries@npm:^1.1.7": +"object.entries@npm:^1.1.5, object.entries@npm:^1.1.8": version: 1.1.8 resolution: "object.entries@npm:1.1.8" dependencies: @@ -36077,7 +37046,7 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.7": +"object.fromentries@npm:^2.0.8": version: 2.0.8 resolution: "object.fromentries@npm:2.0.8" dependencies: @@ -36089,7 +37058,7 @@ __metadata: languageName: node linkType: hard -"object.groupby@npm:^1.0.1": +"object.groupby@npm:^1.0.3": version: 1.0.3 resolution: "object.groupby@npm:1.0.3" dependencies: @@ -36100,17 +37069,6 @@ __metadata: languageName: node linkType: hard -"object.hasown@npm:^1.1.3": - version: 1.1.4 - resolution: "object.hasown@npm:1.1.4" - dependencies: - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/f23187b08d874ef1aea060118c8259eb7f99f93c15a50771d710569534119062b90e087b92952b2d0fb1bb8914d61fb0b43c57fb06f622aaad538fe6868ab987 - languageName: node - linkType: hard - "object.omit@npm:^3.0.0": version: 3.0.0 resolution: "object.omit@npm:3.0.0" @@ -36120,7 +37078,7 @@ __metadata: languageName: node linkType: hard -"object.values@npm:^1.1.6, object.values@npm:^1.1.7": +"object.values@npm:^1.1.6, object.values@npm:^1.2.0": version: 1.2.0 resolution: "object.values@npm:1.2.0" dependencies: @@ -36842,6 +37800,16 @@ __metadata: languageName: node linkType: hard +"parse-imports@npm:^2.1.1": + version: 2.2.1 + resolution: "parse-imports@npm:2.2.1" + dependencies: + es-module-lexer: "npm:^1.5.3" + slashes: "npm:^3.0.12" + checksum: 10c0/bc541ce4ef2ff77d53247de39a956e0ee7a1a4b9b175c3e0f898222fe7994595f011491154db4ed408cbaf5049ede9d0b6624125565be208e973a54420cbe069 + languageName: node + linkType: hard + "parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" @@ -36854,6 +37822,17 @@ __metadata: languageName: node linkType: hard +"parse-json@npm:^8.0.0": + version: 8.1.0 + resolution: "parse-json@npm:8.1.0" + dependencies: + "@babel/code-frame": "npm:^7.22.13" + index-to-position: "npm:^0.1.2" + type-fest: "npm:^4.7.1" + checksum: 10c0/39a49acafc1c41a763df2599a826eb77873a44b098a5f2ba548843229b334a16ff9d613d0381328e58031b0afaabc18ed2a01337a6522911ac7a81828df58bcb + languageName: node + linkType: hard + "parse-srcset@npm:^1.0.2": version: 1.0.2 resolution: "parse-srcset@npm:1.0.2" @@ -37030,7 +38009,7 @@ __metadata: languageName: node linkType: hard -"path-parse@npm:^1.0.7": +"path-parse@npm:^1.0.6, path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1 @@ -37706,7 +38685,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.3.11, postcss@npm:^8.4.23, postcss@npm:^8.4.33, postcss@npm:^8.4.43, postcss@npm:^8.4.48": +"postcss@npm:^8.3.11, postcss@npm:^8.4.14, postcss@npm:^8.4.23, postcss@npm:^8.4.33, postcss@npm:^8.4.43, postcss@npm:^8.4.48": version: 8.4.49 resolution: "postcss@npm:8.4.49" dependencies: @@ -38005,7 +38984,7 @@ __metadata: languageName: node linkType: hard -"progress-events@npm:^1.0.0": +"progress-events@npm:^1.0.0, progress-events@npm:^1.0.1": version: 1.0.1 resolution: "progress-events@npm:1.0.1" checksum: 10c0/27d998de678ca91ea8fdfba4c39c1e393144e658663fcdab344aacc4a3c7d420d2007eaba9e981c1b0894d4b1df05facfc90f5844e1c6518dcf95330fd09473d @@ -38761,7 +39740,7 @@ __metadata: languageName: node linkType: hard -"race-signal@npm:^1.0.2": +"race-signal@npm:^1.0.2, race-signal@npm:^1.1.0": version: 1.1.0 resolution: "race-signal@npm:1.1.0" checksum: 10c0/b640d5ee8769044b5a5155fad993b03a19b68f26c627d1af77c21caf71f12563187f8e8ac36523ee88627d8efeefede011657c40f4bc4ac7f563a7339187ee4c @@ -39621,6 +40600,17 @@ __metadata: languageName: node linkType: hard +"read-package-up@npm:^11.0.0": + version: 11.0.0 + resolution: "read-package-up@npm:11.0.0" + dependencies: + find-up-simple: "npm:^1.0.0" + read-pkg: "npm:^9.0.0" + type-fest: "npm:^4.6.0" + checksum: 10c0/ffee09613c2b3c3ff7e7b5e838aa01f33cba5c6dfa14f87bf6f64ed27e32678e5550e712fd7e3f3105a05c43aa774d084af04ee86d3044978edb69f30ee4505a + languageName: node + linkType: hard + "read-pkg-up@npm:^7.0.1": version: 7.0.1 resolution: "read-pkg-up@npm:7.0.1" @@ -39644,6 +40634,19 @@ __metadata: languageName: node linkType: hard +"read-pkg@npm:^9.0.0": + version: 9.0.1 + resolution: "read-pkg@npm:9.0.1" + dependencies: + "@types/normalize-package-data": "npm:^2.4.3" + normalize-package-data: "npm:^6.0.0" + parse-json: "npm:^8.0.0" + type-fest: "npm:^4.6.0" + unicorn-magic: "npm:^0.1.0" + checksum: 10c0/f3e27549dcdb18335597f4125a3d093a40ab0a18c16a6929a1575360ed5d8679b709b4a672730d9abf6aa8537a7f02bae0b4b38626f99409255acbd8f72f9964 + languageName: node + linkType: hard + "read-yaml-file@npm:^1.1.0": version: 1.1.0 resolution: "read-yaml-file@npm:1.1.0" @@ -39879,6 +40882,15 @@ __metadata: languageName: node linkType: hard +"refa@npm:^0.12.0, refa@npm:^0.12.1": + version: 0.12.1 + resolution: "refa@npm:0.12.1" + dependencies: + "@eslint-community/regexpp": "npm:^4.8.0" + checksum: 10c0/5c2f3dc5421f73aba44ec3d67bad58f36ff921dc13b0a921e1784c0510cf26be6d4e14010955a71607e67ff23a815f3ac30b337d06b5a2e8914417b67626c900 + languageName: node + linkType: hard + "reflect-metadata@npm:0.1.13": version: 0.1.13 resolution: "reflect-metadata@npm:0.1.13" @@ -39972,6 +40984,16 @@ __metadata: languageName: node linkType: hard +"regexp-ast-analysis@npm:^0.7.0, regexp-ast-analysis@npm:^0.7.1": + version: 0.7.1 + resolution: "regexp-ast-analysis@npm:0.7.1" + dependencies: + "@eslint-community/regexpp": "npm:^4.8.0" + refa: "npm:^0.12.1" + checksum: 10c0/1b0e6d66e1e619b42a0e7f62b4c9983d0ce69d94fc759802c02272cbab8abd2e0d5b94186472de4e7c4baaf5826ca674d3c7c083615e39c4be55d1ff9d12c823 + languageName: node + linkType: hard + "regexp-tree@npm:^0.1.27": version: 0.1.27 resolution: "regexp-tree@npm:0.1.27" @@ -40314,13 +41336,6 @@ __metadata: languageName: node linkType: hard -"requireindex@npm:^1.2.0": - version: 1.2.0 - resolution: "requireindex@npm:1.2.0" - checksum: 10c0/7fb42aed73bf8de9acc4d6716cf07acc7fbe180e58729433bafcf702e76e7bb10e54f8266c06bfec62d752e0ac14d50e8758833de539e6f4e2cd642077866153 - languageName: node - linkType: hard - "requirejs-config-file@npm:^4.0.0": version: 4.0.0 resolution: "requirejs-config-file@npm:4.0.0" @@ -40428,6 +41443,16 @@ __metadata: languageName: node linkType: hard +"resolve@npm:~1.19.0": + version: 1.19.0 + resolution: "resolve@npm:1.19.0" + dependencies: + is-core-module: "npm:^2.1.0" + path-parse: "npm:^1.0.6" + checksum: 10c0/1c8afdfb88c9adab0a19b6f16756d47f5917f64047bf5a38c17aa543aae5ccca2a0631671b19ce8460a7a3e65ead98ee70e046d3056ec173d3377a27487848a8 + languageName: node + linkType: hard + "resolve@patch:resolve@npm%3A1.22.8#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.3#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin, resolve@patch:resolve@npm%3A^1.9.0#optional!builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" @@ -40454,6 +41479,16 @@ __metadata: languageName: node linkType: hard +"resolve@patch:resolve@npm%3A~1.19.0#optional!builtin": + version: 1.19.0 + resolution: "resolve@patch:resolve@npm%3A1.19.0#optional!builtin::version=1.19.0&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.1.0" + path-parse: "npm:^1.0.6" + checksum: 10c0/254980f60dd9fdb28b34a511e70df6e3027d9627efce86a40757eea9b87252d172829c84517554560c4541ebfe207868270c19a0f086997b41209367aa8ef74f + languageName: node + linkType: hard + "response-iterator@npm:^0.2.6": version: 0.2.6 resolution: "response-iterator@npm:0.2.6" @@ -41006,6 +42041,17 @@ __metadata: languageName: node linkType: hard +"scslre@npm:^0.3.0": + version: 0.3.0 + resolution: "scslre@npm:0.3.0" + dependencies: + "@eslint-community/regexpp": "npm:^4.8.0" + refa: "npm:^0.12.0" + regexp-ast-analysis: "npm:^0.7.0" + checksum: 10c0/47eb72cf913693b453b7622dfee26871b4c408169874b31b8a1f3de8f41698e6dbacd7565fccc8d24cd2fd30f53c21f16995a7f9072e8b25cd938a6c3a750c3c + languageName: node + linkType: hard + "scuid@npm:^1.1.0": version: 1.1.0 resolution: "scuid@npm:1.1.0" @@ -41013,6 +42059,13 @@ __metadata: languageName: node linkType: hard +"scule@npm:^1.3.0": + version: 1.3.0 + resolution: "scule@npm:1.3.0" + checksum: 10c0/5d1736daa10622c420f2aa74e60d3c722e756bfb139fa784ae5c66669fdfe92932d30ed5072e4ce3107f9c3053e35ad73b2461cb18de45b867e1d4dea63f8823 + languageName: node + linkType: hard + "section-matter@npm:^1.0.0": version: 1.0.0 resolution: "section-matter@npm:1.0.0" @@ -41109,7 +42162,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3": +"semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.1, semver@npm:^7.6.3": version: 7.6.3 resolution: "semver@npm:7.6.3" bin: @@ -41470,6 +42523,16 @@ __metadata: languageName: node linkType: hard +"short-unique-id@npm:^5.2.0": + version: 5.2.0 + resolution: "short-unique-id@npm:5.2.0" + bin: + short-unique-id: bin/short-unique-id + suid: bin/short-unique-id + checksum: 10c0/fb5f2d11bf38c3a2de629caaa55de858b4e1c0b02399b9c42afa1ef05e5203ae6e3ab5b11449b56c68d04d74f76515a778780afd7d16742b340d77d2967498f1 + languageName: node + linkType: hard + "should-equal@npm:^2.0.0": version: 2.0.0 resolution: "should-equal@npm:2.0.0" @@ -41716,6 +42779,13 @@ __metadata: languageName: node linkType: hard +"slashes@npm:^3.0.12": + version: 3.0.12 + resolution: "slashes@npm:3.0.12" + checksum: 10c0/71ca2a1fcd1ab6814b0fdb8cf9c33a3d54321deec2aa8d173510f0086880201446021a9b9e6a18561f7c472b69a2145977c6a8fb9c53a8ff7be31778f203d175 + languageName: node + linkType: hard + "slate-react@npm:^0.83.1": version: 0.83.2 resolution: "slate-react@npm:0.83.2" @@ -42112,6 +43182,16 @@ __metadata: languageName: node linkType: hard +"spdx-expression-parse@npm:^4.0.0": + version: 4.0.0 + resolution: "spdx-expression-parse@npm:4.0.0" + dependencies: + spdx-exceptions: "npm:^2.1.0" + spdx-license-ids: "npm:^3.0.0" + checksum: 10c0/965c487e77f4fb173f1c471f3eef4eb44b9f0321adc7f93d95e7620da31faa67d29356eb02523cd7df8a7fc1ec8238773cdbf9e45bd050329d2b26492771b736 + languageName: node + linkType: hard + "spdx-license-ids@npm:^3.0.0": version: 3.0.20 resolution: "spdx-license-ids@npm:3.0.20" @@ -42218,6 +43298,13 @@ __metadata: languageName: node linkType: hard +"stable-hash@npm:^0.0.4": + version: 0.0.4 + resolution: "stable-hash@npm:0.0.4" + checksum: 10c0/53d010d2a1b014fb60d398c095f43912c353b7b44774e55222bb26fd428bc75b73d7bdfcae509ce927c23ca9c5aff2dc1bc82f191d30e57a879550bc2952bdb0 + languageName: node + linkType: hard + "stack-trace@npm:0.0.x": version: 0.0.10 resolution: "stack-trace@npm:0.0.10" @@ -42473,6 +43560,13 @@ __metadata: languageName: node linkType: hard +"string-ts@npm:^2.2.0": + version: 2.2.0 + resolution: "string-ts@npm:2.2.0" + checksum: 10c0/5a854fefa3ec44b35fc75d4a03bfe50391eb64e40c350ed68a7ec067e235ea5bc81c1e75a45767b3659575e3f517f3fe5ccb77ca8d45b541f62f7b7cbc2046c0 + languageName: node + linkType: hard + "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -42516,7 +43610,18 @@ __metadata: languageName: node linkType: hard -"string.prototype.matchall@npm:^4.0.10": +"string.prototype.includes@npm:^2.0.1": + version: 2.0.1 + resolution: "string.prototype.includes@npm:2.0.1" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.3" + checksum: 10c0/25ce9c9b49128352a2618fbe8758b46f945817a58a4420f4799419e40a8d28f116e176c7590d767d5327a61e75c8f32c86171063f48e389b9fdd325f1bd04ee5 + languageName: node + linkType: hard + +"string.prototype.matchall@npm:^4.0.11": version: 4.0.11 resolution: "string.prototype.matchall@npm:4.0.11" dependencies: @@ -42536,6 +43641,16 @@ __metadata: languageName: node linkType: hard +"string.prototype.repeat@npm:^1.0.0": + version: 1.0.0 + resolution: "string.prototype.repeat@npm:1.0.0" + dependencies: + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.17.5" + checksum: 10c0/94c7978566cffa1327d470fd924366438af9b04b497c43a9805e476e2e908aa37a1fd34cc0911156c17556dab62159d12c7b92b3cc304c3e1281fe4c8e668f40 + languageName: node + linkType: hard + "string.prototype.trim@npm:^1.2.9": version: 1.2.9 resolution: "string.prototype.trim@npm:1.2.9" @@ -43090,7 +44205,7 @@ __metadata: languageName: node linkType: hard -"synckit@npm:0.9.2": +"synckit@npm:0.9.2, synckit@npm:^0.9.0, synckit@npm:^0.9.1": version: 0.9.2 resolution: "synckit@npm:0.9.2" dependencies: @@ -43430,13 +44545,6 @@ __metadata: languageName: node linkType: hard -"text-table@npm:^0.2.0": - version: 0.2.0 - resolution: "text-table@npm:0.2.0" - checksum: 10c0/02805740c12851ea5982686810702e2f14369a5f4c5c40a836821e3eefc65ffeec3131ba324692a37608294b0fd8c1e55a2dd571ffed4909822787668ddbee5c - languageName: node - linkType: hard - "textextensions@npm:^5.14.0": version: 5.16.0 resolution: "textextensions@npm:5.16.0" @@ -43883,12 +44991,23 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.0.1": - version: 1.4.2 - resolution: "ts-api-utils@npm:1.4.2" +"ts-api-utils@npm:^1.0.1, ts-api-utils@npm:^1.3.0": + version: 1.4.3 + resolution: "ts-api-utils@npm:1.4.3" peerDependencies: typescript: ">=4.2.0" - checksum: 10c0/b9d82922af42cefa14650397f5ff42a1ff8c8a1b4fac3590fa3e2daeeb3666fbe260a324f55dc748d9653dce30c2a21a148fba928511b2022bedda66423695bf + checksum: 10c0/e65dc6e7e8141140c23e1dc94984bf995d4f6801919c71d6dc27cf0cd51b100a91ffcfe5217626193e5bea9d46831e8586febdc7e172df3f1091a7384299e23a + languageName: node + linkType: hard + +"ts-declaration-location@npm:^1.0.4": + version: 1.0.5 + resolution: "ts-declaration-location@npm:1.0.5" + dependencies: + minimatch: "npm:^10.0.1" + peerDependencies: + typescript: ">=4.0.0" + checksum: 10c0/b733288856a360cc811fb030c384c9ac33c3e987f67bb90e584de472bc0a72d9aa078fdf901f20b62b94e758937cf3bcd99dff6cd7d9d278f51d515d85a6c67f languageName: node linkType: hard @@ -43986,6 +45105,13 @@ __metadata: languageName: node linkType: hard +"ts-pattern@npm:^5.5.0": + version: 5.5.0 + resolution: "ts-pattern@npm:5.5.0" + checksum: 10c0/4ae1fbeadcf193e72b27419d5fe71f559c100e45710eabf29e2ff3a8fa9ba29adfcd6d5d7d8169b95e2b264683a2eb8d94dbd3c893357b045b52b0c34c2b7c72 + languageName: node + linkType: hard + "ts-unused-exports@npm:^9.0.3": version: 9.0.5 resolution: "ts-unused-exports@npm:9.0.5" @@ -44375,6 +45501,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^4.6.0, type-fest@npm:^4.7.1": + version: 4.29.1 + resolution: "type-fest@npm:4.29.1" + checksum: 10c0/93019c35cedec6dc12a324edcf6bd71719881c944f70e6bf029fd2deb4132589439510f4043f82d7afa6238c0850becfe64fa299a0bca351bed9d839b65463e2 + languageName: node + linkType: hard + "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -44464,6 +45597,22 @@ __metadata: languageName: node linkType: hard +"typescript-eslint@npm:^8.15.0": + version: 8.16.0 + resolution: "typescript-eslint@npm:8.16.0" + dependencies: + "@typescript-eslint/eslint-plugin": "npm:8.16.0" + "@typescript-eslint/parser": "npm:8.16.0" + "@typescript-eslint/utils": "npm:8.16.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/3da9401d6c2416b9d95c96a41a9423a5379d233a120cd3304e2c03f191d350ce91cf0c7e60017f7b10c93b4cc1190592702735735b771c1ce1bf68f71a9f1647 + languageName: node + linkType: hard + "typescript-json-schema@npm:^0.53.0": version: 0.53.1 resolution: "typescript-json-schema@npm:0.53.1" @@ -45939,7 +47088,7 @@ __metadata: languageName: node linkType: hard -"weald@npm:^1.0.2": +"weald@npm:^1.0.4": version: 1.0.4 resolution: "weald@npm:1.0.4" dependencies: From e41519d9422f7a003b75e00af99a36245bd3798d Mon Sep 17 00:00:00 2001 From: Tim Diekmann <21277928+TimDiekmann@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:36:43 +0100 Subject: [PATCH 4/4] H-3776: Enable HaRPC in AWS (#5857) --- infra/terraform/hash/hash_application/graph.tf | 1 - infra/terraform/hash/main.tf | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/infra/terraform/hash/hash_application/graph.tf b/infra/terraform/hash/hash_application/graph.tf index 77e28b89e6b..298f1f9b151 100644 --- a/infra/terraform/hash/hash_application/graph.tf +++ b/infra/terraform/hash/hash_application/graph.tf @@ -206,7 +206,6 @@ locals { }, { name = local.graph_rpc_container_port_name - appProtocol = "http2" containerPort = local.graph_rpc_container_port protocol = "tcp" } diff --git a/infra/terraform/hash/main.tf b/infra/terraform/hash/main.tf index 18b5d2a6f58..ea73e16e56c 100644 --- a/infra/terraform/hash/main.tf +++ b/infra/terraform/hash/main.tf @@ -257,7 +257,7 @@ module "application" { { name = "HASH_GRAPH_PG_HOST", secret = false, value = module.postgres.pg_host }, { name = "HASH_GRAPH_PG_PORT", secret = false, value = module.postgres.pg_port }, { name = "HASH_GRAPH_PG_DATABASE", secret = false, value = "graph" }, - # { name = "HASH_GRAPH_RPC_ENABLED", secret = false, value = "true" }, + { name = "HASH_GRAPH_RPC_ENABLED", secret = false, value = "true" }, { name = "HASH_SPICEDB_GRPC_PRESHARED_KEY", secret = true, value = sensitive(data.vault_kv_secret_v2.secrets.data["spicedb_grpc_preshared_key"]) @@ -358,7 +358,7 @@ module "application" { { name = "HASH_REDIS_PORT", secret = false, value = module.redis.node.port }, { name = "HASH_REDIS_ENCRYPTED_TRANSIT", secret = false, value = "true" }, { name = "HASH_INTEGRATION_QUEUE_NAME", secret = false, value = "integration" }, - # { name = "HASH_RPC_ENABLED", secret = false, value = "true" }, + { name = "HASH_RPC_ENABLED", secret = false, value = "true" }, { name = "HASH_VAULT_HOST", secret = true, value = sensitive(data.vault_kv_secret_v2.secrets.data["hash_vault_host"])