Add more TS lints and fix types (#6037)

* Add as const lint

* Add lint for no implied eval

* Fix incorrect type and add lints

* Add more type lints

* Remove redundant type assertions and add lint

* Fix to turn off incorrect base rules

* Fix yarn lint workflow to wait for build:wasm

* Change so that we don't build:wasm more than once in the workflow
This commit is contained in:
Jonathan Tran
2025-03-28 00:24:24 -04:00
committed by GitHub
parent d1f811f91d
commit cc2efd316c
20 changed files with 163 additions and 65 deletions

View File

@ -20,9 +20,20 @@
"plugin:react-hooks/recommended"
],
"rules": {
"no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-array-constructor": "error",
"@typescript-eslint/no-array-delete": "error",
"@typescript-eslint/no-duplicate-enum-values": "error",
"@typescript-eslint/no-duplicate-type-constituents": "error",
"@typescript-eslint/no-empty-object-type": "error",
"@typescript-eslint/no-floating-promises": "error",
"no-implied-eval": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-implied-eval": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-unnecessary-type-constraint": "error",
"no-unused-vars": "off", // This is wrong; use the @typescript-eslint one instead.
"@typescript-eslint/no-unused-vars": ["error", {
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_",
@ -30,6 +41,7 @@
"vars": "all",
"args": "none"
}],
"@typescript-eslint/prefer-as-const": "warn",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",

View File

@ -28,43 +28,57 @@ jobs:
- run: yarn fmt-check
yarn-build-wasm:
runs-on: ubuntu-22.04
# Build the wasm blob once on the fastest runner.
runs-on: runs-on=${{ github.run_id }}/family=i7ie.2xlarge/image=ubuntu22-full-x64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- name: Install dependencies
run: yarn install
- name: Use correct Rust toolchain
shell: bash
run: |
[ -e rust-toolchain.toml ] || cp rust/rust-toolchain.toml ./
- name: Install rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: false # Configured below.
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
yarn-tsc:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- run: yarn --cwd ./rust/kcl-language-server --modules-folder node_modules install
- uses: Swatinem/rust-cache@v2
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: './rust'
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
- run: yarn tsc
- name: Build Wasm
shell: bash
run: yarn build:wasm
yarn-lint:
runs-on: ubuntu-22.04
- uses: actions/upload-artifact@v4
with:
name: prepared-wasm
path: |
rust/kcl-wasm-lib/pkg/kcl_wasm_lib*
- uses: actions/upload-artifact@v4
with:
name: prepared-ts-rs-bindings
path: |
rust/kcl-lib/bindings/*
yarn-tsc:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
@ -73,7 +87,53 @@ jobs:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- run: yarn --cwd ./rust/kcl-language-server --modules-folder node_modules install
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn tsc
yarn-lint:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn lint
python-codespell:
@ -91,6 +151,7 @@ jobs:
yarn-unit-test-kcl-samples:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
@ -103,7 +164,22 @@ jobs:
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}
@ -120,6 +196,7 @@ jobs:
yarn-unit-test:
runs-on: ubuntu-latest
needs: yarn-build-wasm
steps:
- uses: actions/checkout@v4
@ -132,7 +209,22 @@ jobs:
- uses: taiki-e/install-action@37bdc826eaedac215f638a96472df572feab0f9b
with:
tool: wasm-pack
- run: yarn build:wasm
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Copy prepared wasm
run: |
ls -R prepared-wasm
cp prepared-wasm/kcl_wasm_lib_bg.wasm public
mkdir rust/kcl-wasm-lib/pkg
cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg
- name: Copy prepared ts-rs bindings
run: |
ls -R prepared-ts-rs-bindings
mkdir rust/kcl-lib/bindings
cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/
- run: yarn simpleserver:bg
if: ${{ github.event_name != 'release' && github.event_name != 'schedule' }}

View File

@ -90,7 +90,7 @@ export default class StreamDemuxer extends Queue<Uint8Array> {
}
add(bytes: Uint8Array): void {
const message = Codec.decode(bytes) as vsrpc.Message
const message = Codec.decode<vsrpc.Message>(bytes)
if (this.trace) {
Tracer.server(message)
}

View File

@ -669,7 +669,7 @@ const ConstraintSymbol = ({
return Promise.reject(pResult)
const _node1 = getNodeFromPath<CallExpression | CallExpressionKw>(
pResult.program!,
pResult.program,
pathToNode,
['CallExpression', 'CallExpressionKw'],
true

View File

@ -43,8 +43,8 @@ export const INTERSECTION_PLANE_LAYER = 1
export const SKETCH_LAYER = 2
// redundant types so that it can be changed temporarily but CI will catch the wrong type
export const DEBUG_SHOW_INTERSECTION_PLANE: false = false
export const DEBUG_SHOW_BOTH_SCENES: false = false
export const DEBUG_SHOW_INTERSECTION_PLANE = false
export const DEBUG_SHOW_BOTH_SCENES = false
export const RAYCASTABLE_PLANE = 'raycastable-plane'

View File

@ -1037,7 +1037,7 @@ class ArcSegment implements SegmentUtils {
endAngle,
scale,
color: grey, // Red color for the angle indicator
}) as Line
})
angleIndicator.name = 'angleIndicator'
// Create a new angle indicator for the end angle
@ -1048,7 +1048,7 @@ class ArcSegment implements SegmentUtils {
endAngle: (endAngle * Math.PI) / 180,
scale,
color: grey, // Green color for the end angle indicator
}) as Line
})
endAngleIndicator.name = 'endAngleIndicator'
// Create a length indicator for the end angle

View File

@ -1,8 +1,7 @@
import {
IconDefinition as SolidIconDefinition,
IconDefinition,
faCircleExclamation,
} from '@fortawesome/free-solid-svg-icons'
import { IconDefinition as BrandIconDefinition } from '@fortawesome/free-brands-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { CustomIcon, CustomIconName } from './CustomIcon'
@ -14,7 +13,7 @@ const iconSizes = {
}
export interface ActionIconProps extends React.PropsWithChildren {
icon?: SolidIconDefinition | BrandIconDefinition | CustomIconName
icon?: IconDefinition | CustomIconName
iconColor?: string
className?: string
bgClassName?: string

View File

@ -98,9 +98,7 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
.map(([argName, arg], i) => {
const argValue =
(typeof argumentsToSubmit[argName] === 'function'
? (argumentsToSubmit[argName] as Function)(
commandBarState.context
)
? argumentsToSubmit[argName](commandBarState.context)
: argumentsToSubmit[argName]) || ''
return (

View File

@ -517,10 +517,7 @@ interface FileTreeProps {
className?: string
file?: IndexLoaderData['file']
onNavigateToFile: (
focusableElement?:
| HTMLElement
| React.MutableRefObject<HTMLElement | null>
| undefined
focusableElement?: HTMLElement | React.MutableRefObject<HTMLElement | null>
) => void
}

View File

@ -1431,7 +1431,6 @@ export const ModelingMachineProvider = ({
parsed = pResult.program
if (trap(parsed)) return Promise.reject(parsed)
parsed = parsed as Node<Program>
if (!result.pathToReplaced)
return Promise.reject(new Error('No path to replaced node'))
const {

View File

@ -8,9 +8,9 @@ export const NODE_ENV = env.NODE_ENV as string | undefined
export const VITE_KC_API_WS_MODELING_URL = env.VITE_KC_API_WS_MODELING_URL as
| string
| undefined
export const VITE_KC_API_BASE_URL = env.VITE_KC_API_BASE_URL as string
export const VITE_KC_SITE_BASE_URL = env.VITE_KC_SITE_BASE_URL as string
export const VITE_KC_SITE_APP_URL = env.VITE_KC_SITE_APP_URL as string
export const VITE_KC_API_BASE_URL = env.VITE_KC_API_BASE_URL
export const VITE_KC_SITE_BASE_URL = env.VITE_KC_SITE_BASE_URL
export const VITE_KC_SITE_APP_URL = env.VITE_KC_SITE_APP_URL
export const VITE_KC_SKIP_AUTH = env.VITE_KC_SKIP_AUTH as string | undefined
export const VITE_KC_CONNECTION_TIMEOUT_MS =
env.VITE_KC_CONNECTION_TIMEOUT_MS as string | undefined

View File

@ -340,7 +340,7 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
defaultValue: (commandBarContext) => {
return Object.values(
commandBarContext.machineManager.machines || []
)[0] as components['schemas']['MachineInfoResponse']
)[0]
},
},
},

View File

@ -74,8 +74,8 @@ export const projectsCommandBarConfig: StateMachineCommandSetConfig<
required: true,
options: (_, context) =>
context?.projects.map((p) => ({
name: p.name!,
value: p.name!,
name: p.name,
value: p.name,
})) || [],
},
},
@ -91,8 +91,8 @@ export const projectsCommandBarConfig: StateMachineCommandSetConfig<
required: true,
options: (_, context) =>
context?.projects.map((p) => ({
name: p.name!,
value: p.name!,
name: p.name,
value: p.name,
})) || [],
},
newName: {
@ -136,8 +136,8 @@ export const projectsCommandBarConfig: StateMachineCommandSetConfig<
skip: true,
options: (_, context) =>
context?.projects.map((p) => ({
name: p.name!,
value: p.name!,
name: p.name,
value: p.name,
})) || [],
},
name: {

View File

@ -28,7 +28,7 @@ export const FILE_EXT = '.kcl'
/** Default file to open when a project is opened */
export const PROJECT_ENTRYPOINT = `main${FILE_EXT}` as const
/** Thumbnail file name */
export const PROJECT_IMAGE_NAME = `thumbnail.png` as const
export const PROJECT_IMAGE_NAME = `thumbnail.png`
/** The localStorage key for last-opened projects */
export const FILE_PERSIST_KEY = `${PROJECT_FOLDER}-last-opened` as const
/** The default name given to new kcl files in a project */
@ -169,11 +169,11 @@ export const ZOO_STUDIO_PROTOCOL = 'zoo-studio'
export const ASK_TO_OPEN_QUERY_PARAM = 'ask-open-desktop'
/** Real execution. */
export const EXECUTION_TYPE_REAL = 'real' as const
export const EXECUTION_TYPE_REAL = 'real'
/** Mock execution. */
export const EXECUTION_TYPE_MOCK = 'mock' as const
export const EXECUTION_TYPE_MOCK = 'mock'
/** No execution. */
export const EXECUTION_TYPE_NONE = 'none' as const
export const EXECUTION_TYPE_NONE = 'none'
/**
* Enum of engine execution kinds.
*/

View File

@ -23,7 +23,7 @@ type OnboardingPaths = {
[K in keyof typeof onboardingPaths]: `/onboarding${(typeof onboardingPaths)[K]}`
}
const SETTINGS = '/settings' as const
const SETTINGS = '/settings'
export type ProjectRoute = {
projectName: string | null

View File

@ -12,6 +12,7 @@ import {
defaultSourceRange,
topLevelRange,
ArtifactGraph,
CallExpressionKw,
} from 'lang/wasm'
import { ModelingMachineEvent } from 'machines/modelingMachine'
import { isNonNullable, uuidv4 } from 'lib/utils'
@ -337,7 +338,7 @@ function updateSceneObjectColors(codeBasedSelections: Selection[]) {
Object.values(sceneEntitiesManager.activeSegments).forEach((segmentGroup) => {
if (!SEGMENT_BODIES_PLUS_PROFILE_START.includes(segmentGroup?.name)) return
const nodeMeta = getNodeFromPath<Node<CallExpression | CallExpression>>(
const nodeMeta = getNodeFromPath<Node<CallExpression | CallExpressionKw>>(
updated,
segmentGroup.userData.pathToNode,
['CallExpression', 'CallExpressionKw']
@ -716,7 +717,7 @@ export function updateSelections(
},
}
})
.filter((x?: Selection) => x !== undefined) as Selection[]
.filter((x?: Selection) => x !== undefined)
// for when there is no artifact (sketch mode since mock execute does not update artifactGraph)
const pathToNodeBasedSelections: Selections['graphSelections'] = []

View File

@ -302,7 +302,7 @@ export function createSettings() {
defaultUnit: new Setting<BaseUnit>({
defaultValue: 'mm',
description: 'The default unit to use in modeling dimensions',
validate: (v) => baseUnitsUnion.includes(v as BaseUnit),
validate: (v) => baseUnitsUnion.includes(v),
commandConfig: {
inputType: 'options',
defaultValueFromContext: (context) =>
@ -332,7 +332,7 @@ export function createSettings() {
mouseControls: new Setting<CameraSystem>({
defaultValue: 'Zoo',
description: 'The controls for how to navigate the 3D view',
validate: (v) => cameraSystems.includes(v as CameraSystem),
validate: (v) => cameraSystems.includes(v),
hideOnLevel: 'project',
commandConfig: {
inputType: 'options',

View File

@ -17,7 +17,7 @@ export function usePreviousVarMentions(context: CompletionContext) {
return null
}
return {
from: word?.from!,
from: word?.from,
options: [...data],
}
}

View File

@ -17,7 +17,7 @@ export function varMentions(data: Completion[] = []): Extension {
return null
}
return {
from: word?.from!,
from: word?.from,
options: [...data],
}
},

View File

@ -146,7 +146,7 @@ export const settingsMachine = setup({
actor: input.actor,
})
)
.filter((c) => c !== null) as Command[]
.filter((c) => c !== null)
const addCommands = () =>
commandBarActor.send({
type: 'Add commands',