Skip to content

Commit 2734de5

Browse files
chore!: enable noUncheckedIndexedAccess (#2006)
enables stricter types for array access. --------- Co-authored-by: Marco Vettorello <[email protected]>
1 parent b613189 commit 2734de5

File tree

245 files changed

+1316
-1294
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

245 files changed

+1316
-1294
lines changed

.buildkite/utils/github.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ export const updateCheckStatus = async (
229229
// revert the completed check run is to create a new check run. This will not show as a duplicate run.
230230
const newCheckNeeded = options.status !== 'completed' && checkRun?.status === 'completed';
231231

232-
console.trace('updateCheckStatus', checkId, title);
233-
console.log(JSON.stringify(options, null, 2));
232+
// console.trace('updateCheckStatus', checkId, title);
233+
// console.log(JSON.stringify(options, null, 2));
234234

235235
try {
236236
const output =

e2e/page_objects/common.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ export class CommonPage {
167167

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

e2e/tests/legend_stories.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ test.describe('Legend stories', () => {
208208
const getPositionalUrl = (p1: string, p2: string, others: string = '') =>
209209
`http://localhost:9001/?path=/story/legend--inside-chart&knob-vAlign_Legend=${p1}&knob-hAlign_Legend=${p2}${others}`;
210210

211-
pwEach.test([
211+
pwEach.test<[Position, Position]>([
212212
[Position.Top, Position.Left],
213213
[Position.Top, Position.Right],
214214
[Position.Bottom, Position.Left],
@@ -220,7 +220,7 @@ test.describe('Legend stories', () => {
220220
},
221221
);
222222

223-
pwEach.test([
223+
pwEach.test<[Position, Position]>([
224224
[Position.Top, Position.Left],
225225
[Position.Top, Position.Right],
226226
[Position.Bottom, Position.Left],
@@ -235,7 +235,7 @@ test.describe('Legend stories', () => {
235235
const longLabel =
236236
'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.';
237237

238-
pwEach.test([
238+
pwEach.test<[Position, Position]>([
239239
[Position.Top, Position.Left],
240240
[Position.Top, Position.Right],
241241
[Position.Bottom, Position.Left],

github_bot/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM node:16-alpine as builder
22
WORKDIR /app
33
COPY package.json yarn.lock ./
44
RUN yarn install --frozen-lockfile
5-
COPY tsconfig.json ./
5+
COPY tsconfig.main.json ./tsconfig.json
66
COPY src src
77
RUN yarn build
88

github_bot/src/github/events/push/trigger_build.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@ import { checkCommitFn, isBaseRepo, testPatternString, updateAllChecks } from '.
1616
* build trigger for pushes to select base branches not pull requests
1717
*/
1818
export function setupBuildTrigger(app: Probot) {
19+
// @ts-ignore - probot issue https://github.com/probot/probot/issues/1680
1920
app.on('push', async (ctx) => {
2021
const [branch] = ctx.payload.ref.split('/').reverse();
2122

22-
if (!isBaseRepo(ctx.payload.repository) || !getConfig().github.env.branch.base.some(testPatternString(branch))) {
23+
if (
24+
!branch ||
25+
!isBaseRepo(ctx.payload.repository) ||
26+
!getConfig().github.env.branch.base.some(testPatternString(branch))
27+
) {
2328
return;
2429
}
2530

github_bot/src/github/utils.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ export async function syncChecks(ctx: ProbotEventContext<'pull_request'>) {
259259

260260
const [previousCommitSha] = await getLatestCommits(ctx);
261261

262+
if (!previousCommitSha) throw new Error('Unable to load previous commit');
263+
262264
const {
263265
data: { check_runs: checks },
264266
} = await ctx.octokit.checks.listForRef({
@@ -348,14 +350,15 @@ export async function updatePreviousDeployments(
348350
await Promise.all(
349351
deployments.map(async ({ id }) => {
350352
const {
351-
data: [{ environment, state: currentState, ...status }],
353+
data: [data],
352354
} = await ctx.octokit.repos.listDeploymentStatuses({
353355
...ctx.repo(),
354356
deployment_id: id,
355357
per_page: 1,
356358
});
357359

358-
if (['in_progress', 'queued', 'pending'].includes(currentState)) {
360+
if (data && ['in_progress', 'queued', 'pending'].includes(data.state)) {
361+
const { environment, ...status } = data;
359362
await ctx.octokit.repos.createDeploymentStatus({
360363
...ctx.repo(),
361364
...status,
File renamed without changes.

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@
5252
"test:e2e:generate:page": "./e2e_server/scripts/compile_vrt_page.sh",
5353
"test:e2e:server": "sh ./e2e_server/scripts/start.sh",
5454
"test:e2e:server:build": "cd e2e_server/server && webpack build",
55+
"typecheck:base": "tsc -p ./tsconfig.base.json --noEmit",
5556
"typecheck:src": "lerna run --loglevel=silent --scope @elastic/charts typecheck --stream --no-prefix",
56-
"typecheck:all": "tsc -p ./tsconfig.json --noEmit",
57+
"typecheck:storybook": "lerna run --loglevel=silent --scope charts-storybook typecheck --stream --no-prefix",
58+
"typecheck:all": "yarn typecheck:base && yarn typecheck:src && yarn typecheck:storybook",
5759
"ts:prune": "ts-prune"
5860
},
5961
"devDependencies": {

packages/charts/api-extractor.jsonc

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
7979
* DEFAULT VALUE: "<projectFolder>/tsconfig.json"
8080
*/
81-
"tsconfigFilePath": "<projectFolder>/tsconfig.json",
81+
"tsconfigFilePath": "<projectFolder>/tsconfig.src.json",
8282
/**
8383
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
8484
* The object must conform to the TypeScript tsconfig schema:

packages/charts/api/charts.api.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2247,7 +2247,7 @@ export type Ratio = number;
22472247
export type RawTextGetter = (node: ShapeTreeNode) => string;
22482248

22492249
// @public (undocumented)
2250-
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">>;
2250+
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">>;
22512251

22522252
// @public
22532253
export interface RectAnnotationDatum {

packages/charts/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
"build:ts": "yarn build:clean && yarn build:compile && yarn build:check",
2424
"build:css": "yarn build:sass && yarn autoprefix:css && yarn concat:sass",
2525
"build:clean": "echo 'Cleaning dist...' && rm -rf ./dist",
26-
"build:compile": "echo 'Compiling...' && tsc -p ./tsconfig.json && tsc -p ./tsconfig.nocomments.json",
26+
"build:compile": "echo 'Compiling...' && tsc -p ./tsconfig.src.json && tsc -p ./tsconfig.nocomments.json",
2727
"build:sass": "echo 'Building sass...' && sass src:dist --style compressed --quiet --color",
2828
"build:check": "echo 'Type checking dist...' && tsc -p ./tsconfig.check.json",
29-
"build:watch": "echo 'Watching build...' && yarn build:clean && yarn build:css && tsc -p ./tsconfig.json -w",
29+
"build:watch": "echo 'Watching build...' && yarn build:clean && yarn build:css && tsc -p ./tsconfig.src.json -w",
3030
"concat:sass": "echo 'Concat SASS...' && node scripts/concat_sass.js",
3131
"semantic-release": "semantic-release",
32-
"typecheck": "tsc -p ./tsconfig.json --noEmit && tsc -p ./tsconfig.nocomments.json --noEmit"
32+
"typecheck": "tsc -p ./tsconfig.src.json --noEmit && tsc -p ./tsconfig.nocomments.json --noEmit"
3333
},
3434
"dependencies": {
3535
"@popperjs/core": "^2.4.0",

packages/charts/src/chart_types/flame_chart/flame_chart.tsx

+35-34
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { getChartThemeSelector } from '../../state/selectors/get_chart_theme';
3333
import { getSettingsSpecSelector } from '../../state/selectors/get_settings_spec';
3434
import { getTooltipSpecSelector } from '../../state/selectors/get_tooltip_spec';
3535
import { getSpecsFromStore } from '../../state/utils';
36-
import { clamp, isFiniteNumber } from '../../utils/common';
36+
import { clamp, isFiniteNumber, isNil } from '../../utils/common';
3737
import { Size } from '../../utils/dimensions';
3838
import { FlamegraphStyle } from '../../utils/themes/theme';
3939

@@ -60,7 +60,7 @@ const WOBBLE_REPEAT_COUNT = 2;
6060
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
6161
const NODE_TWEEN_DURATION_MS = 500;
6262

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

7272
const columnToRowPositions = ({ position1, size1 }: FlameSpec['columnarData'], i: number) => ({
73-
x0: position1[i * 2],
74-
x1: position1[i * 2] + size1[i],
75-
y0: position1[i * 2 + 1],
76-
y1: position1[i * 2 + 1] + unitRowPitch(position1),
73+
x0: position1[i * 2] ?? 0,
74+
x1: (position1[i * 2] ?? 0) + (size1[i] ?? 0),
75+
y0: position1[i * 2 + 1] ?? 0,
76+
y1: (position1[i * 2 + 1] ?? 0) + unitRowPitch(position1),
7777
});
7878

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

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

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

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

474475
if (prevHoverIndex !== this.hoverIndex) {
475476
const columns = this.props.columnarViewModel;
476-
this.tooltipValues =
477-
this.hoverIndex >= 0
478-
? [
479-
{
480-
label: columns.label[this.hoverIndex],
481-
color: getColor(columns.color, this.hoverIndex),
482-
isHighlighted: false,
483-
isVisible: true,
484-
seriesIdentifier: { specId: '', key: '' },
485-
value: columns.value[this.hoverIndex],
486-
formattedValue: `${specValueFormatter(columns.value[this.hoverIndex])}`,
487-
valueAccessor: this.hoverIndex,
488-
},
489-
]
490-
: [];
477+
const hoverValue = this.hoverIndex >= 0 ? columns.value[this.hoverIndex] : null;
478+
this.tooltipValues = !isNil(hoverValue)
479+
? [
480+
{
481+
label: columns.label[this.hoverIndex] ?? '',
482+
color: getColor(columns.color, this.hoverIndex),
483+
isHighlighted: false,
484+
isVisible: true,
485+
seriesIdentifier: { specId: '', key: '' },
486+
value: hoverValue,
487+
formattedValue: `${specValueFormatter(hoverValue)}`,
488+
valueAccessor: this.hoverIndex,
489+
},
490+
]
491+
: [];
491492
}
492493
this.setState({}); // exact tooltip location needs an update
493494
}
@@ -707,13 +708,13 @@ class FlameComponent extends React.Component<FlameProps> {
707708
let y1 = -Infinity;
708709
// todo unify with matcher loop and setup in focusOnHit
709710
for (let i = 0; i < datumCount; i++) {
710-
const label = this.caseSensitive ? labels[i] : labels[i].toLowerCase();
711-
if (regex ? label.match(regex) : label.includes(customizedSearchString)) {
711+
const label = this.caseSensitive ? labels[i] : labels[i]?.toLowerCase();
712+
if (regex ? label?.match(regex) : label?.includes(customizedSearchString)) {
712713
this.currentSearchHitCount++;
713-
x0 = Math.min(x0, position[2 * i]);
714-
x1 = Math.max(x1, position[2 * i] + size[i]);
715-
y0 = Math.min(y0, position[2 * i + 1]);
716-
y1 = Math.max(y1, position[2 * i + 1] + rowHeight);
714+
x0 = Math.min(x0, position[2 * i] ?? 0);
715+
x1 = Math.max(x1, (position[2 * i] ?? 0) + (size[i] ?? 0));
716+
y0 = Math.min(y0, position[2 * i + 1] ?? 0);
717+
y1 = Math.max(y1, (position[2 * i + 1] ?? 0) + rowHeight);
717718
} else {
718719
this.currentColor[4 * i + 3] *= 0.25; // multiply alpha
719720
}
@@ -794,8 +795,8 @@ class FlameComponent extends React.Component<FlameProps> {
794795
const labels = this.props.columnarViewModel.label;
795796
// todo unify with matcher loop and setup in focusOnAllMatches
796797
for (let i = 0; i < labels.length; i++) {
797-
const label = this.caseSensitive ? labels[i] : labels[i].toLowerCase();
798-
if (regex ? label.match(regex) : label.includes(customizedSearchString)) {
798+
const label = this.caseSensitive ? labels[i] : labels[i]?.toLowerCase();
799+
if (regex ? label?.match(regex) : label?.includes(customizedSearchString)) {
799800
datumIndex = i;
800801
hitEnumerator++;
801802
if (hitEnumerator === this.focusedMatchIndex) break;

packages/charts/src/chart_types/flame_chart/render/draw_canvas.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const ROW_OFFSET_Y = 0.45; // approx. middle line (text is middle anchored so ta
2222
const MAX_FONT_HEIGHT_RATIO = 1; // relative to the row height
2323
const MAX_FONT_SIZE = 12;
2424

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

2727
/** @internal */
2828
export const drawCanvas2d = (
@@ -90,7 +90,7 @@ export const drawCanvas2d = (
9090
ctx.fillStyle = textColor;
9191
lastTextColor = textColor;
9292
}
93-
const textAlpha = color[i * 4 + 3];
93+
const textAlpha = color[i * 4 + 3] ?? 1;
9494
if (textAlpha !== lastTextAlpha) {
9595
// as we're sorting the iteration, the number of color changes (API calls) is minimized
9696
ctx.globalAlpha = textAlpha;

packages/charts/src/chart_types/goal_chart/layout/viewmodel/geoms.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Side Public License, v 1.
77
*/
88

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

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

packages/charts/src/chart_types/goal_chart/layout/viewmodel/utils.ts

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

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

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

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

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

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

6363
/**

packages/charts/src/chart_types/goal_chart/state/chart_state.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import React, { RefObject } from 'react';
1010

1111
import { getChartTypeDescriptionSelector } from './selectors/get_chart_type_description';
12-
import { getSpecOrNull } from './selectors/goal_spec';
12+
import { getGoalSpecSelector } from './selectors/get_goal_spec';
1313
import { isTooltipVisibleSelector } from './selectors/is_tooltip_visible';
1414
import { createOnElementClickCaller } from './selectors/on_element_click_caller';
1515
import { createOnElementOutCaller } from './selectors/on_element_out_caller';
@@ -48,7 +48,7 @@ export class GoalState implements InternalChartState {
4848
}
4949

5050
isInitialized(globalState: GlobalChartState) {
51-
return getSpecOrNull(globalState) !== null ? InitStatus.Initialized : InitStatus.ChartNotInitialized;
51+
return getGoalSpecSelector(globalState) !== null ? InitStatus.Initialized : InitStatus.ChartNotInitialized;
5252
}
5353

5454
isBrushAvailable() {

0 commit comments

Comments
 (0)