Skip to content

Commit

Permalink
refactor: enable noUncheckedIndexedAccess (#2006)
Browse files Browse the repository at this point in the history
enables stricter types for array access.

BREAKING CHANGE: Enables stricter type option in src and could have
unexpected changes. This release is meant to serve as a clean break
in case any issues arise.
  • Loading branch information
nickofthyme committed Apr 19, 2023
1 parent b613189 commit f446cca
Show file tree
Hide file tree
Showing 245 changed files with 1,316 additions and 1,294 deletions.
4 changes: 2 additions & 2 deletions .buildkite/utils/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ export const updateCheckStatus = async (
// revert the completed check run is to create a new check run. This will not show as a duplicate run.
const newCheckNeeded = options.status !== 'completed' && checkRun?.status === 'completed';

console.trace('updateCheckStatus', checkId, title);
console.log(JSON.stringify(options, null, 2));
// console.trace('updateCheckStatus', checkId, title);
// console.log(JSON.stringify(options, null, 2));

try {
const output =
Expand Down
2 changes: 1 addition & 1 deletion e2e/page_objects/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export class CommonPage {

static validatePath(path: string | string[]): string | string[] {
const fileName = Array.isArray(path) ? path[path.length - 1] : path;
if (/\.png$/.test(fileName)) return path;
if (fileName && /\.png$/.test(fileName)) return path;
throw new Error(`Screenshot path or last path segment must contain the .png file extension.`);
}

Expand Down
6 changes: 3 additions & 3 deletions e2e/tests/legend_stories.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ test.describe('Legend stories', () => {
const getPositionalUrl = (p1: string, p2: string, others: string = '') =>
`http://localhost:9001/?path=/story/legend--inside-chart&knob-vAlign_Legend=${p1}&knob-hAlign_Legend=${p2}${others}`;

pwEach.test([
pwEach.test<[Position, Position]>([
[Position.Top, Position.Left],
[Position.Top, Position.Right],
[Position.Bottom, Position.Left],
Expand All @@ -220,7 +220,7 @@ test.describe('Legend stories', () => {
},
);

pwEach.test([
pwEach.test<[Position, Position]>([
[Position.Top, Position.Left],
[Position.Top, Position.Right],
[Position.Bottom, Position.Left],
Expand All @@ -235,7 +235,7 @@ test.describe('Legend stories', () => {
const longLabel =
'Non do aliqua veniam dolore ipsum eu aliquip. Culpa in duis amet non velit qui non ullamco sit adipisicing. Ut sunt Lorem mollit exercitation deserunt officia sunt ipsum eu amet.';

pwEach.test([
pwEach.test<[Position, Position]>([
[Position.Top, Position.Left],
[Position.Top, Position.Right],
[Position.Bottom, Position.Left],
Expand Down
2 changes: 1 addition & 1 deletion github_bot/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM node:16-alpine as builder
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY tsconfig.json ./
COPY tsconfig.main.json ./tsconfig.json
COPY src src
RUN yarn build

Expand Down
7 changes: 6 additions & 1 deletion github_bot/src/github/events/push/trigger_build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ import { checkCommitFn, isBaseRepo, testPatternString, updateAllChecks } from '.
* build trigger for pushes to select base branches not pull requests
*/
export function setupBuildTrigger(app: Probot) {
// @ts-ignore - probot issue https://github.com/probot/probot/issues/1680
app.on('push', async (ctx) => {
const [branch] = ctx.payload.ref.split('/').reverse();

if (!isBaseRepo(ctx.payload.repository) || !getConfig().github.env.branch.base.some(testPatternString(branch))) {
if (
!branch ||
!isBaseRepo(ctx.payload.repository) ||
!getConfig().github.env.branch.base.some(testPatternString(branch))
) {
return;
}

Expand Down
7 changes: 5 additions & 2 deletions github_bot/src/github/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ export async function syncChecks(ctx: ProbotEventContext<'pull_request'>) {

const [previousCommitSha] = await getLatestCommits(ctx);

if (!previousCommitSha) throw new Error('Unable to load previous commit');

const {
data: { check_runs: checks },
} = await ctx.octokit.checks.listForRef({
Expand Down Expand Up @@ -348,14 +350,15 @@ export async function updatePreviousDeployments(
await Promise.all(
deployments.map(async ({ id }) => {
const {
data: [{ environment, state: currentState, ...status }],
data: [data],
} = await ctx.octokit.repos.listDeploymentStatuses({
...ctx.repo(),
deployment_id: id,
per_page: 1,
});

if (['in_progress', 'queued', 'pending'].includes(currentState)) {
if (data && ['in_progress', 'queued', 'pending'].includes(data.state)) {
const { environment, ...status } = data;
await ctx.octokit.repos.createDeploymentStatus({
...ctx.repo(),
...status,
Expand Down
File renamed without changes.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@
"test:e2e:generate:page": "./e2e_server/scripts/compile_vrt_page.sh",
"test:e2e:server": "sh ./e2e_server/scripts/start.sh",
"test:e2e:server:build": "cd e2e_server/server && webpack build",
"typecheck:base": "tsc -p ./tsconfig.base.json --noEmit",
"typecheck:src": "lerna run --loglevel=silent --scope @elastic/charts typecheck --stream --no-prefix",
"typecheck:all": "tsc -p ./tsconfig.json --noEmit",
"typecheck:storybook": "lerna run --loglevel=silent --scope charts-storybook typecheck --stream --no-prefix",
"typecheck:all": "yarn typecheck:base && yarn typecheck:src && yarn typecheck:storybook",
"ts:prune": "ts-prune"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/charts/api-extractor.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/tsconfig.json"
*/
"tsconfigFilePath": "<projectFolder>/tsconfig.json",
"tsconfigFilePath": "<projectFolder>/tsconfig.src.json",
/**
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
* The object must conform to the TypeScript tsconfig schema:
Expand Down
2 changes: 1 addition & 1 deletion packages/charts/api/charts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2247,7 +2247,7 @@ export type Ratio = number;
export type RawTextGetter = (node: ShapeTreeNode) => string;

// @public (undocumented)
export const RectAnnotation: FC<SFProps<RectAnnotationSpec, "chartType" | "specType", "style" | "zIndex" | "groupId" | "outside" | "annotationType", "fallbackPlacements" | "placement" | "offset" | "boundary" | "boundaryPadding" | "customTooltip" | "customTooltipDetails" | "hideTooltips" | "animations" | "renderTooltip" | "outsideDimension", "id" | "dataValues">>;
export const RectAnnotation: FC<SFProps<RectAnnotationSpec, "chartType" | "specType", "style" | "zIndex" | "groupId" | "outside" | "annotationType", "fallbackPlacements" | "placement" | "offset" | "boundary" | "boundaryPadding" | "customTooltip" | "hideTooltips" | "customTooltipDetails" | "animations" | "renderTooltip" | "outsideDimension", "id" | "dataValues">>;

// @public
export interface RectAnnotationDatum {
Expand Down
6 changes: 3 additions & 3 deletions packages/charts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
"build:ts": "yarn build:clean && yarn build:compile && yarn build:check",
"build:css": "yarn build:sass && yarn autoprefix:css && yarn concat:sass",
"build:clean": "echo 'Cleaning dist...' && rm -rf ./dist",
"build:compile": "echo 'Compiling...' && tsc -p ./tsconfig.json && tsc -p ./tsconfig.nocomments.json",
"build:compile": "echo 'Compiling...' && tsc -p ./tsconfig.src.json && tsc -p ./tsconfig.nocomments.json",
"build:sass": "echo 'Building sass...' && sass src:dist --style compressed --quiet --color",
"build:check": "echo 'Type checking dist...' && tsc -p ./tsconfig.check.json",
"build:watch": "echo 'Watching build...' && yarn build:clean && yarn build:css && tsc -p ./tsconfig.json -w",
"build:watch": "echo 'Watching build...' && yarn build:clean && yarn build:css && tsc -p ./tsconfig.src.json -w",
"concat:sass": "echo 'Concat SASS...' && node scripts/concat_sass.js",
"semantic-release": "semantic-release",
"typecheck": "tsc -p ./tsconfig.json --noEmit && tsc -p ./tsconfig.nocomments.json --noEmit"
"typecheck": "tsc -p ./tsconfig.src.json --noEmit && tsc -p ./tsconfig.nocomments.json --noEmit"
},
"dependencies": {
"@popperjs/core": "^2.4.0",
Expand Down
69 changes: 35 additions & 34 deletions packages/charts/src/chart_types/flame_chart/flame_chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { getChartThemeSelector } from '../../state/selectors/get_chart_theme';
import { getSettingsSpecSelector } from '../../state/selectors/get_settings_spec';
import { getTooltipSpecSelector } from '../../state/selectors/get_tooltip_spec';
import { getSpecsFromStore } from '../../state/utils';
import { clamp, isFiniteNumber } from '../../utils/common';
import { clamp, isFiniteNumber, isNil } from '../../utils/common';
import { Size } from '../../utils/dimensions';
import { FlamegraphStyle } from '../../utils/themes/theme';

Expand All @@ -60,7 +60,7 @@ const WOBBLE_REPEAT_COUNT = 2;
const WOBBLE_FREQUENCY = SHOULD_DISABLE_WOBBLE ? 0 : 2 * Math.PI * (WOBBLE_REPEAT_COUNT / WOBBLE_DURATION); // e.g. 1/30 means a cycle of every 30ms
const NODE_TWEEN_DURATION_MS = 500;

const unitRowPitch = (position: Float32Array) => (position.length >= 4 ? position[1] - position[3] : 1);
const unitRowPitch = (position: Float32Array) => (position.length >= 4 ? (position[1] ?? 0) - (position[3] ?? 0) : 1);
const initialPixelRowPitch = () => 16;
const specValueFormatter = (d: number) => d; // fixme use the formatter from the spec
const browserRootWindow = () => {
Expand All @@ -70,10 +70,10 @@ const browserRootWindow = () => {
};

const columnToRowPositions = ({ position1, size1 }: FlameSpec['columnarData'], i: number) => ({
x0: position1[i * 2],
x1: position1[i * 2] + size1[i],
y0: position1[i * 2 + 1],
y1: position1[i * 2 + 1] + unitRowPitch(position1),
x0: position1[i * 2] ?? 0,
x1: (position1[i * 2] ?? 0) + (size1[i] ?? 0),
y0: position1[i * 2 + 1] ?? 0,
y1: (position1[i * 2 + 1] ?? 0) + unitRowPitch(position1),
});

/** @internal */
Expand Down Expand Up @@ -111,17 +111,18 @@ const focusRect = (
): FocusRect => focusForArea(chartHeight, columnToRowPositions(columnarViewModel, drilldownDatumIndex || 0));

const getColor = (c: Float32Array, i: number) => {
const r = Math.round(255 * c[4 * i]);
const g = Math.round(255 * c[4 * i + 1]);
const b = Math.round(255 * c[4 * i + 2]);
const r = Math.round(255 * (c[4 * i] ?? 0));
const g = Math.round(255 * (c[4 * i + 1] ?? 0));
const b = Math.round(255 * (c[4 * i + 2] ?? 0));
const a = c[4 * i + 3];
return `rgba(${r}, ${g}, ${b}, ${a})`;
};

const colorToDatumIndex = (pixel: Uint8Array) => {
// this is the inverse of what's done via BIT_SHIFTERS in shader code (bijective color/index mapping)
const isEmptyArea = pixel[0] + pixel[1] + pixel[2] + pixel[3] < GEOM_INDEX_OFFSET; // ie. zero
return isEmptyArea ? NaN : pixel[3] + 256 * (pixel[2] + 256 * (pixel[1] + 256 * pixel[0])) - GEOM_INDEX_OFFSET;
const [p0 = 0, p1 = 0, p2 = 0, p3 = 0] = pixel;
const isEmptyArea = p0 + p1 + p2 + p3 < GEOM_INDEX_OFFSET; // ie. zero
return isEmptyArea ? NaN : p3 + 256 * (p2 + 256 * (p1 + 256 * p0)) - GEOM_INDEX_OFFSET;
};

const getRegExp = (searchString: string): RegExp => {
Expand Down Expand Up @@ -473,21 +474,21 @@ class FlameComponent extends React.Component<FlameProps> {

if (prevHoverIndex !== this.hoverIndex) {
const columns = this.props.columnarViewModel;
this.tooltipValues =
this.hoverIndex >= 0
? [
{
label: columns.label[this.hoverIndex],
color: getColor(columns.color, this.hoverIndex),
isHighlighted: false,
isVisible: true,
seriesIdentifier: { specId: '', key: '' },
value: columns.value[this.hoverIndex],
formattedValue: `${specValueFormatter(columns.value[this.hoverIndex])}`,
valueAccessor: this.hoverIndex,
},
]
: [];
const hoverValue = this.hoverIndex >= 0 ? columns.value[this.hoverIndex] : null;
this.tooltipValues = !isNil(hoverValue)
? [
{
label: columns.label[this.hoverIndex] ?? '',
color: getColor(columns.color, this.hoverIndex),
isHighlighted: false,
isVisible: true,
seriesIdentifier: { specId: '', key: '' },
value: hoverValue,
formattedValue: `${specValueFormatter(hoverValue)}`,
valueAccessor: this.hoverIndex,
},
]
: [];
}
this.setState({}); // exact tooltip location needs an update
}
Expand Down Expand Up @@ -707,13 +708,13 @@ class FlameComponent extends React.Component<FlameProps> {
let y1 = -Infinity;
// todo unify with matcher loop and setup in focusOnHit
for (let i = 0; i < datumCount; i++) {
const label = this.caseSensitive ? labels[i] : labels[i].toLowerCase();
if (regex ? label.match(regex) : label.includes(customizedSearchString)) {
const label = this.caseSensitive ? labels[i] : labels[i]?.toLowerCase();
if (regex ? label?.match(regex) : label?.includes(customizedSearchString)) {
this.currentSearchHitCount++;
x0 = Math.min(x0, position[2 * i]);
x1 = Math.max(x1, position[2 * i] + size[i]);
y0 = Math.min(y0, position[2 * i + 1]);
y1 = Math.max(y1, position[2 * i + 1] + rowHeight);
x0 = Math.min(x0, position[2 * i] ?? 0);
x1 = Math.max(x1, (position[2 * i] ?? 0) + (size[i] ?? 0));
y0 = Math.min(y0, position[2 * i + 1] ?? 0);
y1 = Math.max(y1, (position[2 * i + 1] ?? 0) + rowHeight);
} else {
this.currentColor[4 * i + 3] *= 0.25; // multiply alpha
}
Expand Down Expand Up @@ -794,8 +795,8 @@ class FlameComponent extends React.Component<FlameProps> {
const labels = this.props.columnarViewModel.label;
// todo unify with matcher loop and setup in focusOnAllMatches
for (let i = 0; i < labels.length; i++) {
const label = this.caseSensitive ? labels[i] : labels[i].toLowerCase();
if (regex ? label.match(regex) : label.includes(customizedSearchString)) {
const label = this.caseSensitive ? labels[i] : labels[i]?.toLowerCase();
if (regex ? label?.match(regex) : label?.includes(customizedSearchString)) {
datumIndex = i;
hitEnumerator++;
if (hitEnumerator === this.focusedMatchIndex) break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const ROW_OFFSET_Y = 0.45; // approx. middle line (text is middle anchored so ta
const MAX_FONT_HEIGHT_RATIO = 1; // relative to the row height
const MAX_FONT_SIZE = 12;

const mix = (a: number, b: number, x: number) => (1 - x) * a + x * b; // like the GLSL `mix`
const mix = (a: number = 1, b: number = 1, x: number = 1) => (1 - x) * a + x * b; // like the GLSL `mix`

/** @internal */
export const drawCanvas2d = (
Expand Down Expand Up @@ -90,7 +90,7 @@ export const drawCanvas2d = (
ctx.fillStyle = textColor;
lastTextColor = textColor;
}
const textAlpha = color[i * 4 + 3];
const textAlpha = color[i * 4 + 3] ?? 1;
if (textAlpha !== lastTextAlpha) {
// as we're sorting the iteration, the number of color changes (API calls) is minimized
ctx.globalAlpha = textAlpha;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { getSagitta, getMinSagitta, getTranformDirection } from './utils';
import { getSagitta, getMinSagitta, getTransformDirection } from './utils';
import { GOLDEN_RATIO, TAU } from '../../../../common/constants';
import { PointObject, Radian, Rectangle } from '../../../../common/geometry';
import { cssFontShorthand, Font } from '../../../../common/text_utils';
Expand Down Expand Up @@ -261,7 +261,7 @@ export function geoms(
const circular = subtype === GoalSubtype.Goal;
const vertical = subtype === GoalSubtype.VerticalBullet;

const domain = [lowestValue, highestValue];
const domain: [number, number] = [lowestValue, highestValue];
const data = {
base: { value: base },
...Object.fromEntries(bands.map(({ value }, index) => [`qualitative_${index}`, { value }])),
Expand Down Expand Up @@ -402,7 +402,7 @@ export function geoms(
if (circular) {
const sagitta = getMinSagitta(angleStart, angleEnd, r);
const maxSagitta = getSagitta((3 / 2) * Math.PI, r);
const direction = getTranformDirection(angleStart, angleEnd);
const direction = getTransformDirection(angleStart, angleEnd);
data.yOffset.value = Math.abs(sagitta) >= maxSagitta ? 0 : (direction * (maxSagitta - sagitta)) / 2;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,44 @@ const LIMITING_ANGLE = Math.PI / 2;
* Angles are relative to mathematical angles of a unit circle from -2π > θ > 2π
*/
const hasTopGap = (angleStart: Radian, angleEnd: Radian): boolean => {
const [a, b] = [angleStart, angleEnd].sort();
const [a, b] = ([angleStart, angleEnd] as [number, number]).sort();
return a <= -Math.PI / 2 && a >= (-Math.PI * 3) / 2 && b >= -Math.PI / 2 && b <= Math.PI / 2;
};

/**
* Angles are relative to mathematical angles of a unit circle from -2π > θ > 2π
*/
const hasBottomGap = (angleStart: Radian, angleEnd: Radian): boolean => {
const [a, b] = [angleStart, angleEnd].sort();
const [a, b] = ([angleStart, angleEnd] as [number, number]).sort();
return a >= -Math.PI / 2 && a <= Math.PI / 2 && b < (Math.PI * 3) / 2 && b >= Math.PI / 2;
};

/**
* Angles are relative to mathematical angles of a unit circle from -2π > θ > 2π
*/
const isOnlyTopHalf = (angleStart: Radian, angleEnd: Radian): boolean => {
const [a, b] = [angleStart, angleEnd].sort();
const [a, b] = ([angleStart, angleEnd] as [number, number]).sort();
return a >= 0 && b <= Math.PI;
};

/**
* Angles are relative to mathematical angles of a unit circle from -2π > θ > 2π
*/
const isOnlyBottomHalf = (angleStart: Radian, angleEnd: Radian): boolean => {
const [a, b] = [angleStart, angleEnd].sort();
const [a, b] = ([angleStart, angleEnd] as [number, number]).sort();
return (a >= Math.PI && b <= 2 * Math.PI) || (a >= -Math.PI && b <= 0);
};

/**
* Angles are relative to mathematical angles of a unit circle from -2π > θ > 2π
*/
const isWithinLimitedDomain = (angleStart: Radian, angleEnd: Radian): boolean => {
const [a, b] = [angleStart, angleEnd].sort();
const [a, b] = ([angleStart, angleEnd] as [number, number]).sort();
return a > -2 * Math.PI && b < 2 * Math.PI;
};

/** @internal */
export const getTranformDirection = (angleStart: Radian, angleEnd: Radian): 1 | -1 =>
export const getTransformDirection = (angleStart: Radian, angleEnd: Radian): 1 | -1 =>
hasTopGap(angleStart, angleEnd) || isOnlyBottomHalf(angleStart, angleEnd) ? -1 : 1;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import React, { RefObject } from 'react';

import { getChartTypeDescriptionSelector } from './selectors/get_chart_type_description';
import { getSpecOrNull } from './selectors/goal_spec';
import { getGoalSpecSelector } from './selectors/get_goal_spec';
import { isTooltipVisibleSelector } from './selectors/is_tooltip_visible';
import { createOnElementClickCaller } from './selectors/on_element_click_caller';
import { createOnElementOutCaller } from './selectors/on_element_out_caller';
Expand Down Expand Up @@ -48,7 +48,7 @@ export class GoalState implements InternalChartState {
}

isInitialized(globalState: GlobalChartState) {
return getSpecOrNull(globalState) !== null ? InitStatus.Initialized : InitStatus.ChartNotInitialized;
return getGoalSpecSelector(globalState) !== null ? InitStatus.Initialized : InitStatus.ChartNotInitialized;
}

isBrushAvailable() {
Expand Down
Loading

0 comments on commit f446cca

Please sign in to comment.