From d1a9011a9b6ef661d5e2d75a94d4967f2c13611c Mon Sep 17 00:00:00 2001 From: Kyle McDonald Date: Fri, 24 Jul 2026 09:27:30 -0500 Subject: [PATCH 1/4] chore(KNO-14398): adopt oxlint, oxfmt, and TypeScript 7 for packages Replace ESLint with oxlint and Prettier with oxfmt across the published packages, and type-check them with TypeScript 7 (installed as the `typescript-7` alias). This removes the @typescript-eslint dependency on the old TypeScript JS API from the packages' lint path. - Add root .oxlintrc.json (mirrors the prior eslint-config coverage) and .oxfmtrc.json (reproduces the prettier-config settings). - Point each package's lint/format/type:check at oxlint/oxfmt/TS7; remove per-package .eslintrc.js and the eslint/prettier devDependencies. - Keep TypeScript 5.x for builds (vite-plugin-dts). - Example apps are unchanged and still run ESLint/Prettier (follow-up). --- .oxfmtrc.json | 17 + .oxlintrc.json | 29 + AGENTS.md | 2 + package.json | 3 + packages/client/.eslintrc.js | 8 - packages/client/package.json | 13 +- packages/expo/.eslintrc.js | 11 - packages/expo/package.json | 13 +- packages/expo/src/modules/push/types.ts | 3 +- packages/react-core/.eslintrc.js | 11 - packages/react-core/package.json | 13 +- .../hooks/useConnectedMsTeamsChannels.ts | 2 +- .../modules/ms-teams/hooks/useMsTeamsAuth.ts | 2 +- .../slack/context/KnockSlackProvider.tsx | 2 +- .../slack/hooks/useConnectedSlackChannels.ts | 2 +- .../src/modules/slack/hooks/useSlackAuth.ts | 2 +- .../modules/slack/hooks/useSlackChannels.ts | 2 +- packages/react-native/.eslintrc.js | 11 - packages/react-native/package.json | 13 +- packages/react/.eslintrc.js | 17 - packages/react/package.json | 15 +- packages/react/src/App.tsx | 3 +- packages/types/.eslintrc.js | 5 - packages/types/package.json | 9 +- yarn.lock | 801 +++++++++++++++--- 25 files changed, 745 insertions(+), 264 deletions(-) create mode 100644 .oxfmtrc.json create mode 100644 .oxlintrc.json delete mode 100644 packages/client/.eslintrc.js delete mode 100644 packages/expo/.eslintrc.js delete mode 100644 packages/react-core/.eslintrc.js delete mode 100644 packages/react-native/.eslintrc.js delete mode 100644 packages/react/.eslintrc.js delete mode 100644 packages/types/.eslintrc.js diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 000000000..20925225c --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,17 @@ +{ + "printWidth": 80, + "trailingComma": "all", + "singleQuote": false, + "tabWidth": 2, + "sortImports": { + "internalPattern": ["@/"], + "ignoreCase": false, + "newlinesBetween": true, + "groups": [ + ["value-builtin", "value-external", "type-import"], + ["value-internal", "type-internal"], + ["value-parent", "type-parent"], + ["value-sibling", "value-index", "type-sibling", "type-index"] + ] + } +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 000000000..e27f56285 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,29 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "react", "react-hooks", "jsx-a11y"], + "categories": { + "correctness": "error" + }, + "rules": { + "no-unused-vars": [ + "error", + { + "args": "all", + "argsIgnorePattern": "^_", + "caughtErrors": "all", + "caughtErrorsIgnorePattern": "^_", + "destructuredArrayIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "ignoreRestSiblings": true + } + ], + "jsx-a11y/prefer-tag-over-role": "off" + }, + "ignorePatterns": [ + "**/dist/**", + "**/build/**", + "**/coverage/**", + "examples/**", + "integration/**" + ] +} diff --git a/AGENTS.md b/AGENTS.md index f13027507..01d3c169e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,6 +49,8 @@ yarn format - **Package manager**: Yarn 4.1.0 - **Testing**: Vitest - **Releases**: Changesets for versioning +- **Linting & formatting**: `packages/*` use the oxc toolchain — oxlint (`.oxlintrc.json`) and oxfmt (`.oxfmtrc.json`), configured at the repo root and auto-discovered per package. Example apps still run ESLint/Prettier. +- **Type-checking**: `packages/*` type-check with TypeScript 7, installed as the `typescript-7` alias (`npm:typescript@7.0.2`); TypeScript 5.x is retained for builds (`vite-plugin-dts`). ## Adding Dependencies diff --git a/package.json b/package.json index e1955f526..a9a706c45 100644 --- a/package.json +++ b/package.json @@ -61,8 +61,11 @@ "@knocklabs/typescript-config": "workspace:^", "@manypkg/cli": "^0.25.0", "@vitest/coverage-v8": "^3.2.4", + "oxfmt": "0.60.0", + "oxlint": "1.75.0", "prettier": "^3.5.3", "turbo": "^2.9.16", + "typescript-7": "npm:typescript@7.0.2", "vitest": "^3.2.4" }, "engines": { diff --git a/packages/client/.eslintrc.js b/packages/client/.eslintrc.js deleted file mode 100644 index d24bab583..000000000 --- a/packages/client/.eslintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - extends: ["@knocklabs/eslint-config/library.js"], - parserOptions: { - projects: ["tsconfig.json", "tsconfig.node.json"], - }, -}; diff --git a/packages/client/package.json b/packages/client/package.json index 4fb046195..bba7e2bf0 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -34,10 +34,10 @@ }, "scripts": { "dev": "tsc && vite build --watch --emptyOutDir false", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "format": "prettier \"src/**/*.{js,ts,tsx}\" --write", - "format:check": "prettier \"src/**/*.{js,ts,tsx}\" --check", - "type:check": "tsc --noEmit", + "lint": "oxlint --max-warnings=0", + "format": "oxfmt \"src/**/*.{ts,tsx,js}\"", + "format:check": "oxfmt --check \"src/**/*.{ts,tsx,js}\"", + "type:check": "node ../../node_modules/typescript-7/bin/tsc --noEmit", "coverage": "vitest run --coverage", "clean": "rimraf dist", "build": "yarn clean && yarn build:cjs && yarn build:esm", @@ -55,13 +55,10 @@ "@babel/preset-typescript": "^7.28.5", "@codecov/vite-plugin": "^2.0.1", "@types/jsonwebtoken": "^9.0.10", - "@typescript-eslint/eslint-plugin": "^8.59.4", - "@typescript-eslint/parser": "^8.59.4", + "@types/node": "^24.3.0", "cross-env": "^7.0.3", "crypto": "^1.0.1", - "eslint": "^8.56.0", "jsonwebtoken": "^9.0.3", - "prettier": "^3.5.3", "rimraf": "^6.0.1", "rollup": "^4.46.2", "typescript": "^5.8.3", diff --git a/packages/expo/.eslintrc.js b/packages/expo/.eslintrc.js deleted file mode 100644 index d4f519594..000000000 --- a/packages/expo/.eslintrc.js +++ /dev/null @@ -1,11 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - extends: [ - "@knocklabs/eslint-config/library.js", - "plugin:react-hooks/recommended", - ], - parserOptions: { - projects: ["tsconfig.json", "tsconfig.node.json"], - }, -}; diff --git a/packages/expo/package.json b/packages/expo/package.json index 838277d99..d101a4bc6 100644 --- a/packages/expo/package.json +++ b/packages/expo/package.json @@ -28,10 +28,10 @@ "build": "yarn clean && yarn build:esm && yarn build:cjs", "build:esm": "BUILD_TARGET=esm; tsc && vite build", "build:cjs": "BUILD_TARGET=cjs; tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "format": "prettier \"src/**/*.{js,ts,tsx}\" --write", - "format:check": "prettier \"src/**/*.{js,ts,tsx}\" --check", - "type:check": "tsc --noEmit", + "lint": "oxlint --max-warnings=0", + "format": "oxfmt \"src/**/*.{ts,tsx,js}\"", + "format:check": "oxfmt --check \"src/**/*.{ts,tsx,js}\"", + "type:check": "node ../../node_modules/typescript-7/bin/tsc --noEmit", "preview": "vite preview", "test": "vitest run", "test:watch": "vitest" @@ -65,12 +65,7 @@ "@testing-library/react": "^16.3.2", "@types/react": "^19.2.17", "@types/react-native-htmlview": "^0.16.6", - "@typescript-eslint/eslint-plugin": "^8.59.4", - "@typescript-eslint/parser": "^8.59.4", "@vitejs/plugin-react": "^4.5.1", - "eslint": "^8.56.0", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.5.2", "expo": "~56.0.5", "expo-constants": "~56.0.16", "expo-device": "~56.0.4", diff --git a/packages/expo/src/modules/push/types.ts b/packages/expo/src/modules/push/types.ts index 1a896bf7e..ac2267fb4 100644 --- a/packages/expo/src/modules/push/types.ts +++ b/packages/expo/src/modules/push/types.ts @@ -11,8 +11,7 @@ import type { * Context type for the Expo push notification provider. * Extends the base push notification context with Expo-specific functionality. */ -export interface KnockExpoPushNotificationContextType - extends KnockPushNotificationContextType { +export interface KnockExpoPushNotificationContextType extends KnockPushNotificationContextType { /** The Expo push token, or null if not yet registered */ expoPushToken: string | null; diff --git a/packages/react-core/.eslintrc.js b/packages/react-core/.eslintrc.js deleted file mode 100644 index d4f519594..000000000 --- a/packages/react-core/.eslintrc.js +++ /dev/null @@ -1,11 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - extends: [ - "@knocklabs/eslint-config/library.js", - "plugin:react-hooks/recommended", - ], - parserOptions: { - projects: ["tsconfig.json", "tsconfig.node.json"], - }, -}; diff --git a/packages/react-core/package.json b/packages/react-core/package.json index 5ec0ed841..762a2fba3 100644 --- a/packages/react-core/package.json +++ b/packages/react-core/package.json @@ -30,10 +30,10 @@ "build": "yarn clean && yarn build:esm && yarn build:cjs", "build:esm": "BUILD_TARGET=esm; vite build", "build:cjs": "BUILD_TARGET=cjs; vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "format": "prettier \"src/**/*.{js,ts,tsx}\" --write", - "format:check": "prettier \"src/**/*.{js,ts,tsx}\" --check", - "type:check": "tsc --noEmit", + "lint": "oxlint --max-warnings=0", + "format": "oxfmt \"src/**/*.{ts,tsx,js}\"", + "format:check": "oxfmt --check \"src/**/*.{ts,tsx,js}\"", + "type:check": "node ../../node_modules/typescript-7/bin/tsc --noEmit", "coverage": "vitest run --coverage", "preview": "vite preview" }, @@ -59,13 +59,8 @@ "@testing-library/react": "^16.3.2", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "@typescript-eslint/eslint-plugin": "^8.59.4", - "@typescript-eslint/parser": "^8.59.4", "@vitejs/plugin-react": "^4.5.1", "babel-plugin-react-require": "^4.0.3", - "eslint": "^8.56.0", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.5.2", "jsdom": "^29.1.0", "react": "^19.2.7", "react-dom": "^19.2.7", diff --git a/packages/react-core/src/modules/ms-teams/hooks/useConnectedMsTeamsChannels.ts b/packages/react-core/src/modules/ms-teams/hooks/useConnectedMsTeamsChannels.ts index aade9f56d..03cfce211 100644 --- a/packages/react-core/src/modules/ms-teams/hooks/useConnectedMsTeamsChannels.ts +++ b/packages/react-core/src/modules/ms-teams/hooks/useConnectedMsTeamsChannels.ts @@ -1,9 +1,9 @@ -import { useKnockMsTeamsClient } from ".."; import { MsTeamsChannelConnection } from "@knocklabs/client"; import { GenericData } from "@knocklabs/types"; import { useState } from "react"; import useSWR from "swr"; +import { useKnockMsTeamsClient } from ".."; import { RecipientObject } from "../../.."; import { useKnockClient } from "../../core"; import { useTranslations } from "../../i18n"; diff --git a/packages/react-core/src/modules/ms-teams/hooks/useMsTeamsAuth.ts b/packages/react-core/src/modules/ms-teams/hooks/useMsTeamsAuth.ts index d065f3a49..146f11e62 100644 --- a/packages/react-core/src/modules/ms-teams/hooks/useMsTeamsAuth.ts +++ b/packages/react-core/src/modules/ms-teams/hooks/useMsTeamsAuth.ts @@ -1,7 +1,7 @@ -import { useKnockMsTeamsClient } from ".."; import { TENANT_OBJECT_COLLECTION } from "@knocklabs/client"; import { useCallback, useMemo } from "react"; +import { useKnockMsTeamsClient } from ".."; import { useKnockClient } from "../../core"; const MS_TEAMS_ADMINCONSENT_URL = diff --git a/packages/react-core/src/modules/slack/context/KnockSlackProvider.tsx b/packages/react-core/src/modules/slack/context/KnockSlackProvider.tsx index d14e6f59c..47f8828bd 100644 --- a/packages/react-core/src/modules/slack/context/KnockSlackProvider.tsx +++ b/packages/react-core/src/modules/slack/context/KnockSlackProvider.tsx @@ -1,7 +1,7 @@ -import { useSlackConnectionStatus } from ".."; import * as React from "react"; import { PropsWithChildren, useRef } from "react"; +import { useSlackConnectionStatus } from ".."; import { type ConnectionStatus, slackProviderKey } from "../../core"; import { useKnockClient } from "../../core"; diff --git a/packages/react-core/src/modules/slack/hooks/useConnectedSlackChannels.ts b/packages/react-core/src/modules/slack/hooks/useConnectedSlackChannels.ts index 86c43b4eb..68c21ad01 100644 --- a/packages/react-core/src/modules/slack/hooks/useConnectedSlackChannels.ts +++ b/packages/react-core/src/modules/slack/hooks/useConnectedSlackChannels.ts @@ -1,9 +1,9 @@ -import { useKnockSlackClient } from ".."; import { SlackChannelConnection } from "@knocklabs/client"; import { GenericData } from "@knocklabs/types"; import { useState } from "react"; import useSWR from "swr"; +import { useKnockSlackClient } from ".."; import { RecipientObject } from "../../.."; import { useKnockClient } from "../../core"; import { useTranslations } from "../../i18n"; diff --git a/packages/react-core/src/modules/slack/hooks/useSlackAuth.ts b/packages/react-core/src/modules/slack/hooks/useSlackAuth.ts index 393f77a2c..30a888742 100644 --- a/packages/react-core/src/modules/slack/hooks/useSlackAuth.ts +++ b/packages/react-core/src/modules/slack/hooks/useSlackAuth.ts @@ -1,7 +1,7 @@ -import { useKnockSlackClient } from ".."; import { TENANT_OBJECT_COLLECTION } from "@knocklabs/client"; import { useCallback } from "react"; +import { useKnockSlackClient } from ".."; import { useKnockClient } from "../../core"; const SLACK_AUTHORIZE_URL = "https://slack.com/oauth/v2/authorize"; diff --git a/packages/react-core/src/modules/slack/hooks/useSlackChannels.ts b/packages/react-core/src/modules/slack/hooks/useSlackChannels.ts index 658442a36..f9185dce6 100644 --- a/packages/react-core/src/modules/slack/hooks/useSlackChannels.ts +++ b/packages/react-core/src/modules/slack/hooks/useSlackChannels.ts @@ -1,8 +1,8 @@ -import { SlackChannelQueryOptions, useKnockSlackClient } from ".."; import { GetSlackChannelsResponse, SlackChannel } from "@knocklabs/client"; import { useCallback, useEffect, useMemo, useRef } from "react"; import useSWRInfinite from "swr/infinite"; +import { SlackChannelQueryOptions, useKnockSlackClient } from ".."; import { useKnockClient } from "../../core"; const MAX_COUNT = 1000; diff --git a/packages/react-native/.eslintrc.js b/packages/react-native/.eslintrc.js deleted file mode 100644 index d4f519594..000000000 --- a/packages/react-native/.eslintrc.js +++ /dev/null @@ -1,11 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - extends: [ - "@knocklabs/eslint-config/library.js", - "plugin:react-hooks/recommended", - ], - parserOptions: { - projects: ["tsconfig.json", "tsconfig.node.json"], - }, -}; diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 620096c62..735084a05 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -28,10 +28,10 @@ "build": "yarn clean && yarn build:esm && yarn build:cjs", "build:esm": "BUILD_TARGET=esm; tsc && vite build", "build:cjs": "BUILD_TARGET=cjs; tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "format": "prettier \"src/**/*.{js,ts,tsx}\" --write", - "format:check": "prettier \"src/**/*.{js,ts,tsx}\" --check", - "type:check": "tsc --noEmit", + "lint": "oxlint --max-warnings=0", + "format": "oxfmt \"src/**/*.{ts,tsx,js}\"", + "format:check": "oxfmt --check \"src/**/*.{ts,tsx,js}\"", + "type:check": "node ../../node_modules/typescript-7/bin/tsc --noEmit", "preview": "vite preview" }, "repository": { @@ -58,12 +58,7 @@ "@types/react": "^19.2.17", "@types/react-native-get-random-values": "^1", "@types/react-native-htmlview": "^0.16.6", - "@typescript-eslint/eslint-plugin": "^8.59.4", - "@typescript-eslint/parser": "^8.59.4", "@vitejs/plugin-react": "^4.5.1", - "eslint": "^8.56.0", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.5.2", "react": "^19.2.7", "react-dom": "^19.2.7", "react-native": "^0.85.3", diff --git a/packages/react/.eslintrc.js b/packages/react/.eslintrc.js deleted file mode 100644 index 4c1e8a3fa..000000000 --- a/packages/react/.eslintrc.js +++ /dev/null @@ -1,17 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - extends: [ - "@knocklabs/eslint-config/library.js", - "plugin:react-hooks/recommended", - "plugin:jsx-a11y/strict", - ], - parserOptions: { - projects: ["tsconfig.json", "tsconfig.node.json"], - }, - settings: { - "jsx-a11y": { - polymorphicPropName: "as", - }, - }, -}; diff --git a/packages/react/package.json b/packages/react/package.json index c0a96ca60..60a6b2e46 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -43,11 +43,11 @@ "build": "yarn clean && yarn build:esm && yarn build:cjs", "build:esm": "BUILD_TARGET=esm; vite build", "build:cjs": "BUILD_TARGET=cjs; vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "format": "prettier \"src/**/*.{js,ts,tsx}\" --write", - "format:check": "prettier \"src/**/*.{js,ts,tsx}\" --check", + "lint": "oxlint --max-warnings=0", + "format": "oxfmt \"src/**/*.{ts,tsx,js}\"", + "format:check": "oxfmt --check \"src/**/*.{ts,tsx,js}\"", "gen:tokens": "node ./scripts/generateCssTokens.js", - "type:check": "tsc --noEmit", + "type:check": "node ../../node_modules/typescript-7/bin/tsc --noEmit", "coverage": "vitest run --coverage", "preview": "vite preview" }, @@ -97,17 +97,10 @@ "@telegraph/style-engine": "^0.3.7", "@testing-library/dom": "^10.4.1", "@testing-library/react": "^16.3.2", - "@types/eslint-plugin-jsx-a11y": "^6", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "@typescript-eslint/eslint-plugin": "^8.59.4", - "@typescript-eslint/parser": "^8.59.4", "@vitejs/plugin-react": "^4.5.1", "babel-plugin-react-require": "^4.0.3", - "eslint": "^8.56.0", - "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.5.2", "jsdom": "^29.1.0", "next": "15.3.6", "react": "^19.2.7", diff --git a/packages/react/src/App.tsx b/packages/react/src/App.tsx index 796042abd..17cb4e289 100644 --- a/packages/react/src/App.tsx +++ b/packages/react/src/App.tsx @@ -1,6 +1,7 @@ -import { Button, ButtonGroup, KnockFeedProvider, KnockProvider } from "."; import { FunctionComponent } from "react"; +import { Button, ButtonGroup, KnockFeedProvider, KnockProvider } from "."; + // Test out components here by running yarn dev:local in the package const App: FunctionComponent = () => { return ( diff --git a/packages/types/.eslintrc.js b/packages/types/.eslintrc.js deleted file mode 100644 index 8d7f82c25..000000000 --- a/packages/types/.eslintrc.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - extends: ["@knocklabs/eslint-config/library.js"], -}; diff --git a/packages/types/package.json b/packages/types/package.json index ece68147c..598eb4039 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -6,13 +6,12 @@ "license": "MIT", "types": "./src/index.d.ts", "scripts": { - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "type:check": "tsc --noEmit", - "format": "prettier \"src/**/*.{js,ts,tsx}\" --write", - "format:check": "prettier \"src/**/*.{js,ts,tsx}\" --check" + "lint": "oxlint --max-warnings=0", + "type:check": "node ../../node_modules/typescript-7/bin/tsc --noEmit", + "format": "oxfmt \"src/**/*.{ts,tsx,js}\"", + "format:check": "oxfmt --check \"src/**/*.{ts,tsx,js}\"" }, "devDependencies": { - "eslint": "^8.56.0", "typescript": "^5.8.3" }, "publishConfig": { diff --git a/yarn.lock b/yarn.lock index fc56c23e5..d5f01e91f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3606,7 +3606,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1": +"@eslint-community/eslint-utils@npm:^4.9.1": version: 4.9.1 resolution: "@eslint-community/eslint-utils@npm:4.9.1" dependencies: @@ -3642,17 +3642,6 @@ __metadata: languageName: node linkType: hard -"@eslint/config-array@npm:^0.21.2": - version: 0.21.2 - resolution: "@eslint/config-array@npm:0.21.2" - dependencies: - "@eslint/object-schema": "npm:^2.1.7" - debug: "npm:^4.3.1" - minimatch: "npm:^3.1.5" - checksum: 10c0/89dfe815d18456177c0a1f238daf4593107fd20298b3598e0103054360d3b8d09d967defd8318f031185d68df1f95cfa68becf1390a9c5c6887665f1475142e3 - languageName: node - linkType: hard - "@eslint/config-helpers@npm:^0.3.0": version: 0.3.0 resolution: "@eslint/config-helpers@npm:0.3.0" @@ -3660,15 +3649,6 @@ __metadata: languageName: node linkType: hard -"@eslint/config-helpers@npm:^0.4.2": - version: 0.4.2 - resolution: "@eslint/config-helpers@npm:0.4.2" - dependencies: - "@eslint/core": "npm:^0.17.0" - checksum: 10c0/92efd7a527b2d17eb1a148409d71d80f9ac160b565ac73ee092252e8bf08ecd08670699f46b306b94f13d22e88ac88a612120e7847570dd7cdc72f234d50dcb4 - languageName: node - linkType: hard - "@eslint/core@npm:^0.14.0": version: 0.14.0 resolution: "@eslint/core@npm:0.14.0" @@ -3687,15 +3667,6 @@ __metadata: languageName: node linkType: hard -"@eslint/core@npm:^0.17.0": - version: 0.17.0 - resolution: "@eslint/core@npm:0.17.0" - dependencies: - "@types/json-schema": "npm:^7.0.15" - checksum: 10c0/9a580f2246633bc752298e7440dd942ec421860d1946d0801f0423830e67887e4aeba10ab9a23d281727a978eb93d053d1922a587d502942a713607f40ed704e - languageName: node - linkType: hard - "@eslint/eslintrc@npm:^2.1.4": version: 2.1.4 resolution: "@eslint/eslintrc@npm:2.1.4" @@ -3713,7 +3684,7 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^3, @eslint/eslintrc@npm:^3.3.1, @eslint/eslintrc@npm:^3.3.5": +"@eslint/eslintrc@npm:^3, @eslint/eslintrc@npm:^3.3.1": version: 3.3.5 resolution: "@eslint/eslintrc@npm:3.3.5" dependencies: @@ -3744,13 +3715,6 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.39.4": - version: 9.39.4 - resolution: "@eslint/js@npm:9.39.4" - checksum: 10c0/5aa7dea2cbc5decf7f5e3b0c6f86a084ccee0f792d288ca8e839f8bc1b64e03e227068968e49b26096e6f71fd857ab6e42691d1b993826b9a3883f1bdd7a0e46 - languageName: node - linkType: hard - "@eslint/js@npm:^9.9.0": version: 9.27.0 resolution: "@eslint/js@npm:9.27.0" @@ -3765,13 +3729,6 @@ __metadata: languageName: node linkType: hard -"@eslint/object-schema@npm:^2.1.7": - version: 2.1.7 - resolution: "@eslint/object-schema@npm:2.1.7" - checksum: 10c0/936b6e499853d1335803f556d526c86f5fe2259ed241bc665000e1d6353828edd913feed43120d150adb75570cae162cf000b5b0dfc9596726761c36b82f4e87 - languageName: node - linkType: hard - "@eslint/plugin-kit@npm:^0.3.1": version: 0.3.3 resolution: "@eslint/plugin-kit@npm:0.3.3" @@ -3782,16 +3739,6 @@ __metadata: languageName: node linkType: hard -"@eslint/plugin-kit@npm:^0.4.1": - version: 0.4.1 - resolution: "@eslint/plugin-kit@npm:0.4.1" - dependencies: - "@eslint/core": "npm:^0.17.0" - levn: "npm:^0.4.1" - checksum: 10c0/51600f78b798f172a9915dffb295e2ffb44840d583427bc732baf12ecb963eb841b253300e657da91d890f4b323d10a1bd12934bf293e3018d8bb66fdce5217b - languageName: node - linkType: hard - "@exodus/bytes@npm:^1.11.0, @exodus/bytes@npm:^1.15.0, @exodus/bytes@npm:^1.6.0": version: 1.15.0 resolution: "@exodus/bytes@npm:1.15.0" @@ -4950,17 +4897,14 @@ __metadata: "@knocklabs/types": "workspace:^" "@tanstack/store": "npm:^0.7.2" "@types/jsonwebtoken": "npm:^9.0.10" + "@types/node": "npm:^24.3.0" "@types/phoenix": "npm:^1.6.7" - "@typescript-eslint/eslint-plugin": "npm:^8.59.4" - "@typescript-eslint/parser": "npm:^8.59.4" cross-env: "npm:^7.0.3" crypto: "npm:^1.0.1" - eslint: "npm:^8.56.0" eventemitter2: "npm:^6.4.5" jsonwebtoken: "npm:^9.0.3" nanoid: "npm:^3.3.12" phoenix: "npm:1.8.5" - prettier: "npm:^3.5.3" rimraf: "npm:^6.0.1" rollup: "npm:^4.46.2" typescript: "npm:^5.8.3" @@ -5040,12 +4984,7 @@ __metadata: "@testing-library/react": "npm:^16.3.2" "@types/react": "npm:^19.2.17" "@types/react-native-htmlview": "npm:^0.16.6" - "@typescript-eslint/eslint-plugin": "npm:^8.59.4" - "@typescript-eslint/parser": "npm:^8.59.4" "@vitejs/plugin-react": "npm:^4.5.1" - eslint: "npm:^8.56.0" - eslint-plugin-react-hooks: "npm:^5.2.0" - eslint-plugin-react-refresh: "npm:^0.5.2" expo: "npm:~56.0.5" expo-constants: "npm:~56.0.16" expo-device: "npm:~56.0.4" @@ -5089,8 +5028,11 @@ __metadata: "@knocklabs/typescript-config": "workspace:^" "@manypkg/cli": "npm:^0.25.0" "@vitest/coverage-v8": "npm:^3.2.4" + oxfmt: "npm:0.60.0" + oxlint: "npm:1.75.0" prettier: "npm:^3.5.3" turbo: "npm:^2.9.16" + typescript-7: "npm:typescript@7.0.2" vitest: "npm:^3.2.4" dependenciesMeta: "@swc/core": @@ -5133,14 +5075,9 @@ __metadata: "@testing-library/react": "npm:^16.3.2" "@types/react": "npm:^19.2.17" "@types/react-dom": "npm:^19.2.3" - "@typescript-eslint/eslint-plugin": "npm:^8.59.4" - "@typescript-eslint/parser": "npm:^8.59.4" "@vitejs/plugin-react": "npm:^4.5.1" babel-plugin-react-require: "npm:^4.0.3" date-fns: "npm:^4.0.0" - eslint: "npm:^8.56.0" - eslint-plugin-react-hooks: "npm:^5.2.0" - eslint-plugin-react-refresh: "npm:^0.5.2" jsdom: "npm:^29.1.0" react: "npm:^19.2.7" react-dom: "npm:^19.2.7" @@ -5167,12 +5104,7 @@ __metadata: "@types/react": "npm:^19.2.17" "@types/react-native-get-random-values": "npm:^1" "@types/react-native-htmlview": "npm:^0.16.6" - "@typescript-eslint/eslint-plugin": "npm:^8.59.4" - "@typescript-eslint/parser": "npm:^8.59.4" "@vitejs/plugin-react": "npm:^4.5.1" - eslint: "npm:^8.56.0" - eslint-plugin-react-hooks: "npm:^5.2.0" - eslint-plugin-react-refresh: "npm:^0.5.2" react: "npm:^19.2.7" react-dom: "npm:^19.2.7" react-native: "npm:^0.85.3" @@ -5217,17 +5149,10 @@ __metadata: "@telegraph/typography": "npm:>=0.4.2" "@testing-library/dom": "npm:^10.4.1" "@testing-library/react": "npm:^16.3.2" - "@types/eslint-plugin-jsx-a11y": "npm:^6" "@types/react": "npm:^19.2.17" "@types/react-dom": "npm:^19.2.3" - "@typescript-eslint/eslint-plugin": "npm:^8.59.4" - "@typescript-eslint/parser": "npm:^8.59.4" "@vitejs/plugin-react": "npm:^4.5.1" babel-plugin-react-require: "npm:^4.0.3" - eslint: "npm:^8.56.0" - eslint-plugin-jsx-a11y: "npm:^6.10.2" - eslint-plugin-react-hooks: "npm:^5.2.0" - eslint-plugin-react-refresh: "npm:^0.5.2" jsdom: "npm:^29.1.0" lucide-react: "npm:^0.544.0" next: "npm:15.3.6" @@ -5259,7 +5184,6 @@ __metadata: version: 0.0.0-use.local resolution: "@knocklabs/types@workspace:packages/types" dependencies: - eslint: "npm:^8.56.0" typescript: "npm:^5.8.3" languageName: unknown linkType: soft @@ -5784,6 +5708,272 @@ __metadata: languageName: node linkType: hard +"@oxfmt/binding-android-arm-eabi@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-android-arm-eabi@npm:0.60.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@oxfmt/binding-android-arm64@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-android-arm64@npm:0.60.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@oxfmt/binding-darwin-arm64@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-darwin-arm64@npm:0.60.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@oxfmt/binding-darwin-x64@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-darwin-x64@npm:0.60.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@oxfmt/binding-freebsd-x64@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-freebsd-x64@npm:0.60.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@oxfmt/binding-linux-arm-gnueabihf@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-arm-gnueabihf@npm:0.60.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@oxfmt/binding-linux-arm-musleabihf@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-arm-musleabihf@npm:0.60.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@oxfmt/binding-linux-arm64-gnu@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-arm64-gnu@npm:0.60.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@oxfmt/binding-linux-arm64-musl@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-arm64-musl@npm:0.60.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@oxfmt/binding-linux-ppc64-gnu@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-ppc64-gnu@npm:0.60.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@oxfmt/binding-linux-riscv64-gnu@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-riscv64-gnu@npm:0.60.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@oxfmt/binding-linux-riscv64-musl@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-riscv64-musl@npm:0.60.0" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@oxfmt/binding-linux-s390x-gnu@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-s390x-gnu@npm:0.60.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@oxfmt/binding-linux-x64-gnu@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-x64-gnu@npm:0.60.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@oxfmt/binding-linux-x64-musl@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-linux-x64-musl@npm:0.60.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@oxfmt/binding-openharmony-arm64@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-openharmony-arm64@npm:0.60.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@oxfmt/binding-win32-arm64-msvc@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-win32-arm64-msvc@npm:0.60.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@oxfmt/binding-win32-ia32-msvc@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-win32-ia32-msvc@npm:0.60.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@oxfmt/binding-win32-x64-msvc@npm:0.60.0": + version: 0.60.0 + resolution: "@oxfmt/binding-win32-x64-msvc@npm:0.60.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@oxlint/binding-android-arm-eabi@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-android-arm-eabi@npm:1.75.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@oxlint/binding-android-arm64@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-android-arm64@npm:1.75.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@oxlint/binding-darwin-arm64@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-darwin-arm64@npm:1.75.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@oxlint/binding-darwin-x64@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-darwin-x64@npm:1.75.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@oxlint/binding-freebsd-x64@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-freebsd-x64@npm:1.75.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@oxlint/binding-linux-arm-gnueabihf@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-arm-gnueabihf@npm:1.75.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@oxlint/binding-linux-arm-musleabihf@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-arm-musleabihf@npm:1.75.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@oxlint/binding-linux-arm64-gnu@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-arm64-gnu@npm:1.75.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@oxlint/binding-linux-arm64-musl@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-arm64-musl@npm:1.75.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@oxlint/binding-linux-ppc64-gnu@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-ppc64-gnu@npm:1.75.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@oxlint/binding-linux-riscv64-gnu@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-riscv64-gnu@npm:1.75.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@oxlint/binding-linux-riscv64-musl@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-riscv64-musl@npm:1.75.0" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@oxlint/binding-linux-s390x-gnu@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-s390x-gnu@npm:1.75.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@oxlint/binding-linux-x64-gnu@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-x64-gnu@npm:1.75.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@oxlint/binding-linux-x64-musl@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-linux-x64-musl@npm:1.75.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@oxlint/binding-openharmony-arm64@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-openharmony-arm64@npm:1.75.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@oxlint/binding-win32-arm64-msvc@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-win32-arm64-msvc@npm:1.75.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@oxlint/binding-win32-ia32-msvc@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-win32-ia32-msvc@npm:1.75.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@oxlint/binding-win32-x64-msvc@npm:1.75.0": + version: 1.75.0 + resolution: "@oxlint/binding-win32-x64-msvc@npm:1.75.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -8114,15 +8304,6 @@ __metadata: languageName: node linkType: hard -"@types/eslint-plugin-jsx-a11y@npm:^6": - version: 6.10.1 - resolution: "@types/eslint-plugin-jsx-a11y@npm:6.10.1" - dependencies: - eslint: "npm:^9" - checksum: 10c0/fe2ce003279f046225fc8ce5ea9b621254f0b6cf6577ea03da4cdd436c6780a7e1565308c2b3406851f5bb6abda0e9e2694f75dc462d8915f031854b10824012 - languageName: node - linkType: hard - "@types/eslint@npm:^8.44.7": version: 8.56.12 resolution: "@types/eslint@npm:8.56.12" @@ -8244,6 +8425,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^24.3.0": + version: 24.13.3 + resolution: "@types/node@npm:24.13.3" + dependencies: + undici-types: "npm:~7.18.0" + checksum: 10c0/a5bc08f49b9581dcdca90e02cd77197a3c799840807664942e5cd5161a553d4d2ae8064f7e3294410d748d7d098b5c1848be7fa50c06f29c4193ab16be4e59eb + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.0": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" @@ -9025,6 +9215,146 @@ __metadata: languageName: node linkType: hard +"@typescript/typescript-aix-ppc64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-aix-ppc64@npm:7.0.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@typescript/typescript-darwin-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-darwin-arm64@npm:7.0.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-darwin-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-darwin-x64@npm:7.0.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-freebsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-freebsd-arm64@npm:7.0.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-freebsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-freebsd-x64@npm:7.0.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-arm64@npm:7.0.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-arm@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-arm@npm:7.0.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@typescript/typescript-linux-loong64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-loong64@npm:7.0.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-mips64el@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-mips64el@npm:7.0.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@typescript/typescript-linux-ppc64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-ppc64@npm:7.0.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-riscv64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-riscv64@npm:7.0.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-s390x@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-s390x@npm:7.0.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@typescript/typescript-linux-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-x64@npm:7.0.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-netbsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-netbsd-arm64@npm:7.0.2" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-netbsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-netbsd-x64@npm:7.0.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-openbsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-openbsd-arm64@npm:7.0.2" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-openbsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-openbsd-x64@npm:7.0.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-sunos-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-sunos-x64@npm:7.0.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-win32-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-win32-arm64@npm:7.0.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-win32-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-win32-x64@npm:7.0.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@ungap/structured-clone@npm:^1.2.0, @ungap/structured-clone@npm:^1.3.0": version: 1.3.0 resolution: "@ungap/structured-clone@npm:1.3.0" @@ -12602,7 +12932,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:^6.10.0, eslint-plugin-jsx-a11y@npm:^6.10.2, eslint-plugin-jsx-a11y@npm:^6.8.0": +"eslint-plugin-jsx-a11y@npm:^6.10.0, eslint-plugin-jsx-a11y@npm:^6.8.0": version: 6.10.2 resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" dependencies: @@ -12928,55 +13258,6 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^9": - version: 9.39.4 - resolution: "eslint@npm:9.39.4" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.8.0" - "@eslint-community/regexpp": "npm:^4.12.1" - "@eslint/config-array": "npm:^0.21.2" - "@eslint/config-helpers": "npm:^0.4.2" - "@eslint/core": "npm:^0.17.0" - "@eslint/eslintrc": "npm:^3.3.5" - "@eslint/js": "npm:9.39.4" - "@eslint/plugin-kit": "npm:^0.4.1" - "@humanfs/node": "npm:^0.16.6" - "@humanwhocodes/module-importer": "npm:^1.0.1" - "@humanwhocodes/retry": "npm:^0.4.2" - "@types/estree": "npm:^1.0.6" - ajv: "npm:^6.14.0" - chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.6" - debug: "npm:^4.3.2" - escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^8.4.0" - eslint-visitor-keys: "npm:^4.2.1" - espree: "npm:^10.4.0" - esquery: "npm:^1.5.0" - esutils: "npm:^2.0.2" - fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^8.0.0" - find-up: "npm:^5.0.0" - glob-parent: "npm:^6.0.2" - ignore: "npm:^5.2.0" - imurmurhash: "npm:^0.1.4" - is-glob: "npm:^4.0.0" - json-stable-stringify-without-jsonify: "npm:^1.0.1" - lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.1.5" - natural-compare: "npm:^1.4.0" - optionator: "npm:^0.9.3" - peerDependencies: - jiti: "*" - peerDependenciesMeta: - jiti: - optional: true - bin: - eslint: bin/eslint.js - checksum: 10c0/1955067c2d991f0c84f4c4abfafe31bb47fa3b717a7fd3e43fe1e511c6f859d7700cbca969f85661dc4c130f7aeced5e5444884314198a54428f5e5141db9337 - languageName: node - linkType: hard - "eslint@npm:^9.24.0": version: 9.30.1 resolution: "eslint@npm:9.30.1" @@ -17521,6 +17802,159 @@ __metadata: languageName: node linkType: hard +"oxfmt@npm:0.60.0": + version: 0.60.0 + resolution: "oxfmt@npm:0.60.0" + dependencies: + "@oxfmt/binding-android-arm-eabi": "npm:0.60.0" + "@oxfmt/binding-android-arm64": "npm:0.60.0" + "@oxfmt/binding-darwin-arm64": "npm:0.60.0" + "@oxfmt/binding-darwin-x64": "npm:0.60.0" + "@oxfmt/binding-freebsd-x64": "npm:0.60.0" + "@oxfmt/binding-linux-arm-gnueabihf": "npm:0.60.0" + "@oxfmt/binding-linux-arm-musleabihf": "npm:0.60.0" + "@oxfmt/binding-linux-arm64-gnu": "npm:0.60.0" + "@oxfmt/binding-linux-arm64-musl": "npm:0.60.0" + "@oxfmt/binding-linux-ppc64-gnu": "npm:0.60.0" + "@oxfmt/binding-linux-riscv64-gnu": "npm:0.60.0" + "@oxfmt/binding-linux-riscv64-musl": "npm:0.60.0" + "@oxfmt/binding-linux-s390x-gnu": "npm:0.60.0" + "@oxfmt/binding-linux-x64-gnu": "npm:0.60.0" + "@oxfmt/binding-linux-x64-musl": "npm:0.60.0" + "@oxfmt/binding-openharmony-arm64": "npm:0.60.0" + "@oxfmt/binding-win32-arm64-msvc": "npm:0.60.0" + "@oxfmt/binding-win32-ia32-msvc": "npm:0.60.0" + "@oxfmt/binding-win32-x64-msvc": "npm:0.60.0" + tinypool: "npm:2.1.0" + peerDependencies: + svelte: ^5.0.0 + vite-plus: "*" + dependenciesMeta: + "@oxfmt/binding-android-arm-eabi": + optional: true + "@oxfmt/binding-android-arm64": + optional: true + "@oxfmt/binding-darwin-arm64": + optional: true + "@oxfmt/binding-darwin-x64": + optional: true + "@oxfmt/binding-freebsd-x64": + optional: true + "@oxfmt/binding-linux-arm-gnueabihf": + optional: true + "@oxfmt/binding-linux-arm-musleabihf": + optional: true + "@oxfmt/binding-linux-arm64-gnu": + optional: true + "@oxfmt/binding-linux-arm64-musl": + optional: true + "@oxfmt/binding-linux-ppc64-gnu": + optional: true + "@oxfmt/binding-linux-riscv64-gnu": + optional: true + "@oxfmt/binding-linux-riscv64-musl": + optional: true + "@oxfmt/binding-linux-s390x-gnu": + optional: true + "@oxfmt/binding-linux-x64-gnu": + optional: true + "@oxfmt/binding-linux-x64-musl": + optional: true + "@oxfmt/binding-openharmony-arm64": + optional: true + "@oxfmt/binding-win32-arm64-msvc": + optional: true + "@oxfmt/binding-win32-ia32-msvc": + optional: true + "@oxfmt/binding-win32-x64-msvc": + optional: true + peerDependenciesMeta: + svelte: + optional: true + vite-plus: + optional: true + bin: + oxfmt: bin/oxfmt + checksum: 10c0/44541bc1381964f75d2abf9cc6bbed868c1b4ddef7b4f6cd40a883c46e8b86de5208a4d3192875fc8decbce2a3c930970013455319ebeee9c126eb2afbf56229 + languageName: node + linkType: hard + +"oxlint@npm:1.75.0": + version: 1.75.0 + resolution: "oxlint@npm:1.75.0" + dependencies: + "@oxlint/binding-android-arm-eabi": "npm:1.75.0" + "@oxlint/binding-android-arm64": "npm:1.75.0" + "@oxlint/binding-darwin-arm64": "npm:1.75.0" + "@oxlint/binding-darwin-x64": "npm:1.75.0" + "@oxlint/binding-freebsd-x64": "npm:1.75.0" + "@oxlint/binding-linux-arm-gnueabihf": "npm:1.75.0" + "@oxlint/binding-linux-arm-musleabihf": "npm:1.75.0" + "@oxlint/binding-linux-arm64-gnu": "npm:1.75.0" + "@oxlint/binding-linux-arm64-musl": "npm:1.75.0" + "@oxlint/binding-linux-ppc64-gnu": "npm:1.75.0" + "@oxlint/binding-linux-riscv64-gnu": "npm:1.75.0" + "@oxlint/binding-linux-riscv64-musl": "npm:1.75.0" + "@oxlint/binding-linux-s390x-gnu": "npm:1.75.0" + "@oxlint/binding-linux-x64-gnu": "npm:1.75.0" + "@oxlint/binding-linux-x64-musl": "npm:1.75.0" + "@oxlint/binding-openharmony-arm64": "npm:1.75.0" + "@oxlint/binding-win32-arm64-msvc": "npm:1.75.0" + "@oxlint/binding-win32-ia32-msvc": "npm:1.75.0" + "@oxlint/binding-win32-x64-msvc": "npm:1.75.0" + peerDependencies: + oxlint-tsgolint: ">=7.0.2001" + vite-plus: "*" + dependenciesMeta: + "@oxlint/binding-android-arm-eabi": + optional: true + "@oxlint/binding-android-arm64": + optional: true + "@oxlint/binding-darwin-arm64": + optional: true + "@oxlint/binding-darwin-x64": + optional: true + "@oxlint/binding-freebsd-x64": + optional: true + "@oxlint/binding-linux-arm-gnueabihf": + optional: true + "@oxlint/binding-linux-arm-musleabihf": + optional: true + "@oxlint/binding-linux-arm64-gnu": + optional: true + "@oxlint/binding-linux-arm64-musl": + optional: true + "@oxlint/binding-linux-ppc64-gnu": + optional: true + "@oxlint/binding-linux-riscv64-gnu": + optional: true + "@oxlint/binding-linux-riscv64-musl": + optional: true + "@oxlint/binding-linux-s390x-gnu": + optional: true + "@oxlint/binding-linux-x64-gnu": + optional: true + "@oxlint/binding-linux-x64-musl": + optional: true + "@oxlint/binding-openharmony-arm64": + optional: true + "@oxlint/binding-win32-arm64-msvc": + optional: true + "@oxlint/binding-win32-ia32-msvc": + optional: true + "@oxlint/binding-win32-x64-msvc": + optional: true + peerDependenciesMeta: + oxlint-tsgolint: + optional: true + vite-plus: + optional: true + bin: + oxlint: bin/oxlint + checksum: 10c0/3cdd0d30ddd284d3c4caab9f9a9b0c71d18aab7fc00b115c37da95d5c648d8c62686c6aad3aab4633f25beb88e75f1f9bcc42dd66cedf7bdfacbfbe048e5dcf1 + languageName: node + linkType: hard + "p-filter@npm:^2.1.0": version: 2.1.0 resolution: "p-filter@npm:2.1.0" @@ -20565,6 +20999,13 @@ __metadata: languageName: node linkType: hard +"tinypool@npm:2.1.0": + version: 2.1.0 + resolution: "tinypool@npm:2.1.0" + checksum: 10c0/9fb1c760558c6264e0f4cfde96a63b12450b43f1730fbe6274aa24ddbdf488745c08924d0dea7a1303b47d555416a6415f2113898c69b6ecf731e75ac95238a5 + languageName: node + linkType: hard + "tinypool@npm:^1.1.1": version: 1.1.1 resolution: "tinypool@npm:1.1.1" @@ -20879,6 +21320,77 @@ __metadata: languageName: node linkType: hard +"typescript-7@npm:typescript@7.0.2": + version: 7.0.2 + resolution: "typescript@npm:7.0.2" + dependencies: + "@typescript/typescript-aix-ppc64": "npm:7.0.2" + "@typescript/typescript-darwin-arm64": "npm:7.0.2" + "@typescript/typescript-darwin-x64": "npm:7.0.2" + "@typescript/typescript-freebsd-arm64": "npm:7.0.2" + "@typescript/typescript-freebsd-x64": "npm:7.0.2" + "@typescript/typescript-linux-arm": "npm:7.0.2" + "@typescript/typescript-linux-arm64": "npm:7.0.2" + "@typescript/typescript-linux-loong64": "npm:7.0.2" + "@typescript/typescript-linux-mips64el": "npm:7.0.2" + "@typescript/typescript-linux-ppc64": "npm:7.0.2" + "@typescript/typescript-linux-riscv64": "npm:7.0.2" + "@typescript/typescript-linux-s390x": "npm:7.0.2" + "@typescript/typescript-linux-x64": "npm:7.0.2" + "@typescript/typescript-netbsd-arm64": "npm:7.0.2" + "@typescript/typescript-netbsd-x64": "npm:7.0.2" + "@typescript/typescript-openbsd-arm64": "npm:7.0.2" + "@typescript/typescript-openbsd-x64": "npm:7.0.2" + "@typescript/typescript-sunos-x64": "npm:7.0.2" + "@typescript/typescript-win32-arm64": "npm:7.0.2" + "@typescript/typescript-win32-x64": "npm:7.0.2" + dependenciesMeta: + "@typescript/typescript-aix-ppc64": + optional: true + "@typescript/typescript-darwin-arm64": + optional: true + "@typescript/typescript-darwin-x64": + optional: true + "@typescript/typescript-freebsd-arm64": + optional: true + "@typescript/typescript-freebsd-x64": + optional: true + "@typescript/typescript-linux-arm": + optional: true + "@typescript/typescript-linux-arm64": + optional: true + "@typescript/typescript-linux-loong64": + optional: true + "@typescript/typescript-linux-mips64el": + optional: true + "@typescript/typescript-linux-ppc64": + optional: true + "@typescript/typescript-linux-riscv64": + optional: true + "@typescript/typescript-linux-s390x": + optional: true + "@typescript/typescript-linux-x64": + optional: true + "@typescript/typescript-netbsd-arm64": + optional: true + "@typescript/typescript-netbsd-x64": + optional: true + "@typescript/typescript-openbsd-arm64": + optional: true + "@typescript/typescript-openbsd-x64": + optional: true + "@typescript/typescript-sunos-x64": + optional: true + "@typescript/typescript-win32-arm64": + optional: true + "@typescript/typescript-win32-x64": + optional: true + bin: + tsc: bin/tsc + checksum: 10c0/3dcee51ec8c332492325bcdbf7df48b66668751f127e622ae7d41b6c716eb19184424a45e14f7750f50f340232388b69e6287859155f06a5ce2df76f12cb31cf + languageName: node + linkType: hard + "typescript-eslint@npm:^8.61.0": version: 8.61.0 resolution: "typescript-eslint@npm:8.61.0" @@ -20985,6 +21497,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~7.18.0": + version: 7.18.2 + resolution: "undici-types@npm:7.18.2" + checksum: 10c0/85a79189113a238959d7a647368e4f7c5559c3a404ebdb8fc4488145ce9426fcd82252a844a302798dfc0e37e6fb178ff481ed03bc4caf634c5757d9ef43521d + languageName: node + linkType: hard + "undici@npm:^6.23.0": version: 6.25.0 resolution: "undici@npm:6.25.0" From 0f3c45ae6232f211b8e5ab1d5b1e2f98b625cf0d Mon Sep 17 00:00:00 2001 From: Kyle McDonald Date: Fri, 24 Jul 2026 09:27:40 -0500 Subject: [PATCH 2/4] fix(KNO-14398): resolve correctness issues surfaced by oxlint - react: stop passing children to the void in the guide Modal/Card image components (invalid and ignored at runtime). - client: type KnockGuideActivationUrlPattern.pattern against the urlpattern-polyfill URLPattern it is constructed from, and add an explicit @types/node reference for the build-time process.env version string (TS7 no longer auto-includes ambient @types). - client: drop a redundant parameter-property assignment in Feed. --- .changeset/oxc-migration-correctness-fixes.md | 9 +++++++++ packages/client/src/api.ts | 1 + packages/client/src/clients/feed/feed.ts | 1 - packages/client/src/clients/guide/types.ts | 9 +++++---- .../react/src/modules/guide/components/Card/Card.tsx | 12 ++++++------ .../src/modules/guide/components/Modal/Modal.tsx | 12 ++++++------ 6 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 .changeset/oxc-migration-correctness-fixes.md diff --git a/.changeset/oxc-migration-correctness-fixes.md b/.changeset/oxc-migration-correctness-fixes.md new file mode 100644 index 000000000..ab95cd9ee --- /dev/null +++ b/.changeset/oxc-migration-correctness-fixes.md @@ -0,0 +1,9 @@ +--- +"@knocklabs/client": patch +"@knocklabs/react": patch +--- + +Fix correctness issues surfaced while migrating packages to oxlint: + +- `@knocklabs/react`: the guide `Modal`/`Card` image components no longer pass `children` to the void `` element (previously invalid and ignored at runtime). +- `@knocklabs/client`: `KnockGuideActivationUrlPattern.pattern` is now typed against the `urlpattern-polyfill` `URLPattern` it is constructed from, rather than the DOM lib's global `URLPattern`. diff --git a/packages/client/src/api.ts b/packages/client/src/api.ts index 1e2c74e21..7ce316e4b 100644 --- a/packages/client/src/api.ts +++ b/packages/client/src/api.ts @@ -1,3 +1,4 @@ +/// import { Socket } from "phoenix"; import { exponentialBackoffFullJitter } from "./helpers"; diff --git a/packages/client/src/clients/feed/feed.ts b/packages/client/src/clients/feed/feed.ts index 139e15931..03dbf0066 100644 --- a/packages/client/src/clients/feed/feed.ts +++ b/packages/client/src/clients/feed/feed.ts @@ -69,7 +69,6 @@ class Feed { ); } - this.feedId = feedId; this.userFeedId = this.buildUserFeedId(); this.referenceId = CLIENT_REF_ID_PREFIX + nanoid(); this.socketManager = socketManager; diff --git a/packages/client/src/clients/guide/types.ts b/packages/client/src/clients/guide/types.ts index d56dfcc20..11d707029 100644 --- a/packages/client/src/clients/guide/types.ts +++ b/packages/client/src/clients/guide/types.ts @@ -1,4 +1,5 @@ import { GenericData } from "@knocklabs/types"; +import type { URLPattern } from "urlpattern-polyfill"; // i.e. useGuide vs useGuides export type SelectQueryLimit = "one" | "all"; @@ -205,8 +206,9 @@ export type GuideSocketEvent = // Guide client // -export interface KnockGuideStep - extends GuideStepData { +export interface KnockGuideStep< + TContent = Any, +> extends GuideStepData { markAsSeen: () => Promise | undefined>; markAsInteracted: (params?: { metadata?: GenericData; @@ -214,8 +216,7 @@ export interface KnockGuideStep markAsArchived: () => Promise | undefined>; } -export interface KnockGuideActivationUrlPattern - extends GuideActivationUrlPatternData { +export interface KnockGuideActivationUrlPattern extends GuideActivationUrlPatternData { pattern: URLPattern; } diff --git a/packages/react/src/modules/guide/components/Card/Card.tsx b/packages/react/src/modules/guide/components/Card/Card.tsx index fdcfc74b2..0e206d7a7 100644 --- a/packages/react/src/modules/guide/components/Card/Card.tsx +++ b/packages/react/src/modules/guide/components/Card/Card.tsx @@ -86,17 +86,17 @@ const Body: React.FC<{ body: string } & React.ComponentPropsWithRef<"div">> = ({ }; Body.displayName = "CardView.Body"; -const Img: React.FC< - React.PropsWithChildren> -> = ({ children, className, alt, ...props }) => { +const Img: React.FC> = ({ + className, + alt, + ...props +}) => { return ( {alt - {children} - + /> ); }; Img.displayName = "CardView.Img"; diff --git a/packages/react/src/modules/guide/components/Modal/Modal.tsx b/packages/react/src/modules/guide/components/Modal/Modal.tsx index a2c218b7d..4f80c35d8 100644 --- a/packages/react/src/modules/guide/components/Modal/Modal.tsx +++ b/packages/react/src/modules/guide/components/Modal/Modal.tsx @@ -111,17 +111,17 @@ const Body: React.FC<{ body: string } & React.ComponentPropsWithRef<"div">> = ({ }; Body.displayName = "ModalView.Body"; -const Img: React.FC< - React.PropsWithChildren> -> = ({ children, className, alt, ...props }) => { +const Img: React.FC> = ({ + className, + alt, + ...props +}) => { return ( {alt - {children} - + /> ); }; Img.displayName = "ModalView.Img"; From 85911f5078a79e7f9dfa699faa9f88ca4bdeea4e Mon Sep 17 00:00:00 2001 From: Kyle McDonald Date: Fri, 24 Jul 2026 09:32:02 -0500 Subject: [PATCH 3/4] chore(KNO-14398): pin client @types/node to ^24 for manypkg consistency --- packages/client/package.json | 2 +- yarn.lock | 18 +----------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/packages/client/package.json b/packages/client/package.json index bba7e2bf0..ae181b667 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -55,7 +55,7 @@ "@babel/preset-typescript": "^7.28.5", "@codecov/vite-plugin": "^2.0.1", "@types/jsonwebtoken": "^9.0.10", - "@types/node": "^24.3.0", + "@types/node": "^24", "cross-env": "^7.0.3", "crypto": "^1.0.1", "jsonwebtoken": "^9.0.3", diff --git a/yarn.lock b/yarn.lock index d5f01e91f..24fceb0e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4897,7 +4897,7 @@ __metadata: "@knocklabs/types": "workspace:^" "@tanstack/store": "npm:^0.7.2" "@types/jsonwebtoken": "npm:^9.0.10" - "@types/node": "npm:^24.3.0" + "@types/node": "npm:^24" "@types/phoenix": "npm:^1.6.7" cross-env: "npm:^7.0.3" crypto: "npm:^1.0.1" @@ -8425,15 +8425,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^24.3.0": - version: 24.13.3 - resolution: "@types/node@npm:24.13.3" - dependencies: - undici-types: "npm:~7.18.0" - checksum: 10c0/a5bc08f49b9581dcdca90e02cd77197a3c799840807664942e5cd5161a553d4d2ae8064f7e3294410d748d7d098b5c1848be7fa50c06f29c4193ab16be4e59eb - languageName: node - linkType: hard - "@types/normalize-package-data@npm:^2.4.0": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" @@ -21497,13 +21488,6 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~7.18.0": - version: 7.18.2 - resolution: "undici-types@npm:7.18.2" - checksum: 10c0/85a79189113a238959d7a647368e4f7c5559c3a404ebdb8fc4488145ce9426fcd82252a844a302798dfc0e37e6fb178ff481ed03bc4caf634c5757d9ef43521d - languageName: node - linkType: hard - "undici@npm:^6.23.0": version: 6.25.0 resolution: "undici@npm:6.25.0" From 9e5fdd6fc90f3acfb69dde22cf4f24c48d1bc0de Mon Sep 17 00:00:00 2001 From: Kyle McDonald Date: Fri, 24 Jul 2026 10:17:33 -0500 Subject: [PATCH 4/4] test(KNO-14398): cover guide image components, exclude dev playground The guide Modal/Card `Img` components rewritten in this PR had no test, so the changed lines showed up as uncovered (codecov patch/project). Add direct render tests for `CardView.Img` / `ModalView.Img` that assert a void `` with the right alt/class and no children (regression guard for the fix), and exclude the dev-only `App.tsx` playground (`yarn dev:local`, not exported/shipped) from coverage. --- packages/react/test/guide/Card.test.tsx | 12 +++++++++++- packages/react/test/guide/Modal.test.tsx | 16 ++++++++++++++++ vitest/config.ts | 2 ++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 packages/react/test/guide/Modal.test.tsx diff --git a/packages/react/test/guide/Card.test.tsx b/packages/react/test/guide/Card.test.tsx index 2980c021e..fd6f9c678 100644 --- a/packages/react/test/guide/Card.test.tsx +++ b/packages/react/test/guide/Card.test.tsx @@ -1,7 +1,7 @@ import { render } from "@testing-library/react"; import { describe, expect, test, vi } from "vitest"; -import { Card } from "../../src/modules/guide/components/Card/Card"; +import { Card, CardView } from "../../src/modules/guide/components/Card/Card"; vi.mock("@knocklabs/react-core", async () => { const actual = await vi.importActual("@knocklabs/react-core"); @@ -30,4 +30,14 @@ describe("Card", () => { expect(getByText("Heads up!")).toBeInTheDocument(); expect(getByText("Quick Tip")).toBeInTheDocument(); }); + + test("CardView.Img renders a void img with no children", () => { + const { getByAltText } = render( + , + ); + const img = getByAltText("Example image"); + expect(img.tagName).toBe("IMG"); + expect(img).toHaveClass("knock-guide-card__img"); + expect(img).toBeEmptyDOMElement(); + }); }); diff --git a/packages/react/test/guide/Modal.test.tsx b/packages/react/test/guide/Modal.test.tsx new file mode 100644 index 000000000..92d054e9d --- /dev/null +++ b/packages/react/test/guide/Modal.test.tsx @@ -0,0 +1,16 @@ +import { render } from "@testing-library/react"; +import { describe, expect, test } from "vitest"; + +import { ModalView } from "../../src/modules/guide/components/Modal/Modal"; + +describe("ModalView.Img", () => { + test("renders a void img with no children", () => { + const { getByAltText } = render( + , + ); + const img = getByAltText("Example image"); + expect(img.tagName).toBe("IMG"); + expect(img).toHaveClass("knock-guide-modal__img"); + expect(img).toBeEmptyDOMElement(); + }); +}); diff --git a/vitest/config.ts b/vitest/config.ts index d3098f588..0c93152ed 100644 --- a/vitest/config.ts +++ b/vitest/config.ts @@ -13,6 +13,8 @@ const sharedConfig = defineConfig({ "*.d.ts", "**/dist/**", "**/node_modules/**", + // Dev-only playground (yarn dev:local), not part of the shipped package + "**/src/App.tsx", // Ignore config packages "packages/eslint-config", "packages/prettier-config",