[7.x] [ts] enable "resolveJsonModule" and disable existing failures (#78855) (#79043)

Co-authored-by: spalger <spalger@users.noreply.github.com>
# Conflicts:
#	x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.test.tsx
#	x-pack/typings/index.d.ts
This commit is contained in:
Spencer 2020-09-30 17:19:54 -07:00 committed by GitHub
parent 087aaede54
commit ee8cf2cea0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 69 additions and 36 deletions

View file

@ -39,6 +39,8 @@
// Resolve modules in the same way as Node.js. Aka make `require` works the // Resolve modules in the same way as Node.js. Aka make `require` works the
// same in TypeScript as it does in Node.js. // same in TypeScript as it does in Node.js.
"moduleResolution": "node", "moduleResolution": "node",
// "resolveJsonModule" allows for importing, extracting types from and generating .json files.
"resolveJsonModule": true,
// Disallow inconsistently-cased references to the same file. // Disallow inconsistently-cased references to the same file.
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
// Forbid unused local variables as the rule was deprecated by ts-lint // Forbid unused local variables as the rule was deprecated by ts-lint

9
typings/index.d.ts vendored
View file

@ -35,15 +35,6 @@ declare module '*.svg' {
export default content; export default content;
} }
// allow JSON files to be imported directly without lint errors
// see: https://github.com/palantir/tslint/issues/1264#issuecomment-228433367
// and: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#arbitrary-expressions-are-forbidden-in-export-assignments-in-ambient-contexts
declare module '*.json' {
const json: any;
// eslint-disable-next-line import/no-default-export
export default json;
}
type MethodKeysOf<T> = { type MethodKeysOf<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never; [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
}[keyof T]; }[keyof T];

View file

@ -43,6 +43,7 @@ describe('ErrorGroupOverview -> List', () => {
<MemoryRouter> <MemoryRouter>
<MockApmPluginContextWrapper> <MockApmPluginContextWrapper>
<MockUrlParamsContextProvider> <MockUrlParamsContextProvider>
{/* @ts-expect-error invalid json props */}
<ErrorGroupList items={props.items} serviceName="opbeans-python" /> <ErrorGroupList items={props.items} serviceName="opbeans-python" />
</MockUrlParamsContextProvider> </MockUrlParamsContextProvider>
</MockApmPluginContextWrapper> </MockApmPluginContextWrapper>

View file

@ -15,6 +15,7 @@ import mockTransaction from './mockTransaction.json';
describe('DiscoverTransactionLink component', () => { describe('DiscoverTransactionLink component', () => {
it('should render with data', () => { it('should render with data', () => {
// @ts-expect-error invalid json mock
const transaction: Transaction = mockTransaction; const transaction: Transaction = mockTransaction;
expect( expect(
@ -25,6 +26,7 @@ describe('DiscoverTransactionLink component', () => {
describe('getDiscoverQuery', () => { describe('getDiscoverQuery', () => {
it('should return the correct query params object', () => { it('should return the correct query params object', () => {
// @ts-expect-error invalid json mock
const transaction: Transaction = mockTransaction; const transaction: Transaction = mockTransaction;
const result = getDiscoverQuery(transaction); const result = getDiscoverQuery(transaction);
expect(result).toMatchSnapshot(); expect(result).toMatchSnapshot();

View file

@ -10,6 +10,7 @@ import expectedGroupedData from './mock_responses/group_resource_nodes_grouped.j
describe('groupResourceNodes', () => { describe('groupResourceNodes', () => {
it('should group external nodes', () => { it('should group external nodes', () => {
// @ts-expect-error invalid json mock
const responseWithGroups = groupResourceNodes(preGroupedData); const responseWithGroups = groupResourceNodes(preGroupedData);
expect(responseWithGroups.elements).toHaveLength( expect(responseWithGroups.elements).toHaveLength(
expectedGroupedData.elements.length expectedGroupedData.elements.length
@ -17,7 +18,7 @@ describe('groupResourceNodes', () => {
for (const element of responseWithGroups.elements) { for (const element of responseWithGroups.elements) {
const expectedElement = expectedGroupedData.elements.find( const expectedElement = expectedGroupedData.elements.find(
({ data: { id } }: { data: { id: string } }) => id === element.data.id ({ data: { id } }: { data: { id: string } }) => id === element.data.id
); )!;
expect(element).toMatchObject(expectedElement); expect(element).toMatchObject(expectedElement);
} }
}); });

View file

@ -31,6 +31,7 @@ describe('getServiceAnnotations', () => {
searchAggregatedTransactions: false, searchAggregatedTransactions: false,
}), }),
{ {
// @ts-expect-error invalid json mock
mockResponse: () => noVersions, mockResponse: () => noVersions,
} }
); );
@ -50,6 +51,7 @@ describe('getServiceAnnotations', () => {
searchAggregatedTransactions: false, searchAggregatedTransactions: false,
}), }),
{ {
// @ts-expect-error invalid json mock
mockResponse: () => oneVersion, mockResponse: () => oneVersion,
} }
); );
@ -74,6 +76,7 @@ describe('getServiceAnnotations', () => {
searchAggregatedTransactions: false, searchAggregatedTransactions: false,
}), }),
{ {
// @ts-expect-error invalid json mock
mockResponse: () => responses.shift(), mockResponse: () => responses.shift(),
} }
); );

View file

@ -61,6 +61,7 @@ export function demodata(): ExpressionFunctionDefinition<
{ id: 'project', name: 'project', meta: { type: 'string' } }, { id: 'project', name: 'project', meta: { type: 'string' } },
{ id: 'percent_uptime', name: 'percent_uptime', meta: { type: 'number' } }, { id: 'percent_uptime', name: 'percent_uptime', meta: { type: 'number' } },
], ],
// @ts-expect-error invalid json mock
rows: sortBy(demoRows, 'time'), rows: sortBy(demoRows, 'time'),
}; };
} else if (args.type === DemoRows.SHIRTS) { } else if (args.type === DemoRows.SHIRTS) {

View file

@ -4,10 +4,10 @@
* you may not use this file except in compliance with the Elastic License. * you may not use this file except in compliance with the Elastic License.
*/ */
/* /*
One test relies on react-dom at a version of 16.9... it can be enabled One test relies on react-dom at a version of 16.9... it can be enabled
once renovate completes the upgrade. Relevant code has been commented out once renovate completes the upgrade. Relevant code has been commented out
in the meantime. in the meantime.
*/ */
import { mount, ReactWrapper } from 'enzyme'; import { mount, ReactWrapper } from 'enzyme';

View file

@ -11,4 +11,11 @@ import test from './workpads/test.json';
export * from './utils'; export * from './utils';
export type WorkpadNames = keyof typeof sharedWorkpads; export type WorkpadNames = keyof typeof sharedWorkpads;
export const sharedWorkpads = { hello, austin, test }; export const sharedWorkpads = {
// TODO: the automatic types for these JSON files are insufficient, and "austin" is so massive
// that Typescript refuses to type it. These should be converted to TypeScript and typed to fit
// the requirements. "austin" should also be reduced to the necessary data
hello: hello as any,
austin: austin as any,
test: test as any,
};

View file

@ -16,6 +16,7 @@ export const createApolloClient = (fetch: HttpHandler) => {
const cache = new InMemoryCache({ const cache = new InMemoryCache({
addTypename: false, addTypename: false,
fragmentMatcher: new IntrospectionFragmentMatcher({ fragmentMatcher: new IntrospectionFragmentMatcher({
// @ts-expect-error apollo-cache-inmemory types don't match actual introspection data
introspectionQueryResultData, introspectionQueryResultData,
}), }),
}); });

View file

@ -21,6 +21,7 @@ describe('AnnotationDescriptionList', () => {
}); });
test('Initialization with annotation.', () => { test('Initialization with annotation.', () => {
// @ts-expect-error mock data is too loosely typed
const wrapper = shallowWithIntl(<AnnotationDescriptionList annotation={mockAnnotations[0]} />); const wrapper = shallowWithIntl(<AnnotationDescriptionList annotation={mockAnnotations[0]} />);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });

View file

@ -51,6 +51,7 @@ describe('DeleteAction', () => {
it('should display a tooltip when isDisabled prop is true.', () => { it('should display a tooltip when isDisabled prop is true.', () => {
const { container } = render( const { container } = render(
// @ts-expect-error mock data is incorrectly typed
<DeleteActionName isDisabled={true} item={mockAnalyticsListItem} /> <DeleteActionName isDisabled={true} item={mockAnalyticsListItem} />
); );
@ -59,6 +60,7 @@ describe('DeleteAction', () => {
it('should not display a tooltip when isDisabled prop is false.', () => { it('should not display a tooltip when isDisabled prop is false.', () => {
const { container } = render( const { container } = render(
// @ts-expect-error mock data is incorrectly typed
<DeleteActionName isDisabled={false} item={mockAnalyticsListItem} /> <DeleteActionName isDisabled={false} item={mockAnalyticsListItem} />
); );
@ -78,8 +80,12 @@ describe('DeleteAction', () => {
{deleteAction.isModalVisible && <DeleteActionModal {...deleteAction} />} {deleteAction.isModalVisible && <DeleteActionModal {...deleteAction} />}
<button <button
data-test-subj="mlAnalyticsJobDeleteButton" data-test-subj="mlAnalyticsJobDeleteButton"
onClick={() => deleteAction.openModal(mockAnalyticsListItem)} onClick={() => {
// @ts-expect-error mock data is incorrectly typed
deleteAction.openModal(mockAnalyticsListItem);
}}
> >
{/* @ts-expect-error mock data is incorrectly typed */}
<DeleteActionName isDisabled={false} item={mockAnalyticsListItem} /> <DeleteActionName isDisabled={false} item={mockAnalyticsListItem} />
</button> </button>
</> </>

View file

@ -10,6 +10,7 @@ import { getAnnotationLevels } from './timeseries_chart_annotations';
describe('Timeseries Chart Annotations: getAnnotationLevels()', () => { describe('Timeseries Chart Annotations: getAnnotationLevels()', () => {
test('getAnnotationLevels()', () => { test('getAnnotationLevels()', () => {
// @ts-expect-error mock data is too loosely typed
const levels = getAnnotationLevels(mockAnnotationsOverlap); const levels = getAnnotationLevels(mockAnnotationsOverlap);
expect(levels).toEqual({ A: 0, B: 1, C: 2, D: 2 }); expect(levels).toEqual({ A: 0, B: 1, C: 2, D: 2 });
}); });

View file

@ -144,6 +144,7 @@ describe('ML - validateTimeRange', () => {
it('invalid time field', () => { it('invalid time field', () => {
const mockSearchResponseInvalid = cloneDeep(mockSearchResponse); const mockSearchResponseInvalid = cloneDeep(mockSearchResponse);
// @ts-expect-error creating intentionally invalid data
mockSearchResponseInvalid.fieldCaps = undefined; mockSearchResponseInvalid.fieldCaps = undefined;
const duration = { start: 0, end: 1 }; const duration = { start: 0, end: 1 };
return validateTimeRange( return validateTimeRange(

View file

@ -26,6 +26,7 @@ describe('getLinks helper', () => {
const mockCache = new InMemoryCache({ const mockCache = new InMemoryCache({
dataIdFromObject: () => null, dataIdFromObject: () => null,
fragmentMatcher: new IntrospectionFragmentMatcher({ fragmentMatcher: new IntrospectionFragmentMatcher({
// @ts-expect-error apollo-cache-inmemory types don't match actual introspection data
introspectionQueryResultData, introspectionQueryResultData,
}), }),
}); });

View file

@ -17,6 +17,7 @@ export function composeLibs(core: CoreStart): AppFrontendLibs {
const cache = new InMemoryCache({ const cache = new InMemoryCache({
dataIdFromObject: () => null, dataIdFromObject: () => null,
fragmentMatcher: new IntrospectionFragmentMatcher({ fragmentMatcher: new IntrospectionFragmentMatcher({
// @ts-expect-error apollo-cache-inmemory types don't match actual introspection data
introspectionQueryResultData, introspectionQueryResultData,
}), }),
}); });

View file

@ -7,8 +7,11 @@
import { uniq } from 'lodash/fp'; import { uniq } from 'lodash/fp';
import { db } from 'suricata-sid-db'; import { db } from 'suricata-sid-db';
const has = <T>(obj: T, key: string | number | symbol): key is keyof T =>
Object.prototype.hasOwnProperty.call(obj, key);
export const getLinksFromSignature = (id: number): string[] => { export const getLinksFromSignature = (id: number): string[] => {
const refs = db[id]; const refs = has(db, id) ? db[id] : null;
if (refs != null) { if (refs != null) {
return uniq(refs); return uniq(refs);
} else { } else {

View file

@ -8,7 +8,6 @@ import signalsMapping from './signals_mapping.json';
import ecsMapping from './ecs_mapping.json'; import ecsMapping from './ecs_mapping.json';
export const getSignalsTemplate = (index: string) => { export const getSignalsTemplate = (index: string) => {
ecsMapping.mappings.properties.signal = signalsMapping.mappings.properties.signal;
const template = { const template = {
settings: { settings: {
index: { index: {
@ -24,7 +23,13 @@ export const getSignalsTemplate = (index: string) => {
}, },
}, },
index_patterns: [`${index}-*`], index_patterns: [`${index}-*`],
mappings: ecsMapping.mappings, mappings: {
...ecsMapping.mappings,
properties: {
...ecsMapping.mappings.properties,
signal: signalsMapping.mappings.properties.signal,
},
},
version: 1, version: 1,
}; };
return template; return template;

View file

@ -33,12 +33,14 @@ describe('get_existing_prepackaged_rules', () => {
}); });
test('should throw an exception if a pre-packaged rule is not valid', () => { test('should throw an exception if a pre-packaged rule is not valid', () => {
// @ts-expect-error intentionally invalid argument
expect(() => getPrepackagedRules([{ not_valid_made_up_key: true }])).toThrow( expect(() => getPrepackagedRules([{ not_valid_made_up_key: true }])).toThrow(
'name: "(rule name unknown)", rule_id: "(rule rule_id unknown)" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "name",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "rule_id",Invalid value "undefined" supplied to "version", Full rule contents are:\n{\n "not_valid_made_up_key": true\n}' 'name: "(rule name unknown)", rule_id: "(rule rule_id unknown)" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "name",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "rule_id",Invalid value "undefined" supplied to "version", Full rule contents are:\n{\n "not_valid_made_up_key": true\n}'
); );
}); });
test('should throw an exception with a message having rule_id and name in it', () => { test('should throw an exception with a message having rule_id and name in it', () => {
// @ts-expect-error intentionally invalid argument
expect(() => getPrepackagedRules([{ name: 'rule name', rule_id: 'id-123' }])).toThrow( expect(() => getPrepackagedRules([{ name: 'rule name', rule_id: 'id-123' }])).toThrow(
'name: "rule name", rule_id: "id-123" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "version", Full rule contents are:\n{\n "name": "rule name",\n "rule_id": "id-123"\n}' 'name: "rule name", rule_id: "id-123" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "version", Full rule contents are:\n{\n "name": "rule name",\n "rule_id": "id-123"\n}'
); );

View file

@ -15,6 +15,8 @@ import {
AddPrepackagedRulesSchemaDecoded, AddPrepackagedRulesSchemaDecoded,
} from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema';
import { BadRequestError } from '../errors/bad_request_error'; import { BadRequestError } from '../errors/bad_request_error';
// TODO: convert rules files to TS and add explicit type definitions
import { rawRules } from './prepackaged_rules'; import { rawRules } from './prepackaged_rules';
/** /**
@ -49,5 +51,7 @@ export const validateAllPrepackagedRules = (
}); });
}; };
export const getPrepackagedRules = (rules = rawRules): AddPrepackagedRulesSchemaDecoded[] => export const getPrepackagedRules = (
validateAllPrepackagedRules(rules); // @ts-expect-error mock data is too loosely typed
rules: AddPrepackagedRulesSchema[] = rawRules
): AddPrepackagedRulesSchemaDecoded[] => validateAllPrepackagedRules(rules);

View file

@ -12,11 +12,12 @@ import { getTransformProgress, isCompletedBatchTransform } from './transform_sta
const getRow = (statsId: string) => { const getRow = (statsId: string) => {
return { return {
// @ts-expect-error mock data does not actually match TransformListRow type
...(mockTransformListRow as TransformListRow), ...(mockTransformListRow as TransformListRow),
stats: { stats: {
...mockTransformStats.transforms.find( ...(mockTransformStats.transforms as Array<TransformListRow['stats']>).find(
(stats: TransformListRow['stats']) => stats.id === statsId (stats) => stats.id === statsId
), )!,
}, },
}; };
}; };

View file

@ -17,6 +17,7 @@ jest.mock('../../../../../app/app_dependencies');
describe('Transform: Transform List Actions <StartAction />', () => { describe('Transform: Transform List Actions <StartAction />', () => {
test('Minimal initialization', () => { test('Minimal initialization', () => {
// @ts-expect-error mock data is too loosely typed
const item: TransformListRow = transformListRow; const item: TransformListRow = transformListRow;
const props: StartActionNameProps = { const props: StartActionNameProps = {
forceDisable: false, forceDisable: false,

View file

@ -17,6 +17,7 @@ jest.mock('../../../../../app/app_dependencies');
describe('Transform: Transform List Actions <StopAction />', () => { describe('Transform: Transform List Actions <StopAction />', () => {
test('Minimal initialization', () => { test('Minimal initialization', () => {
// @ts-expect-error mock data is too loosely typed
const item: TransformListRow = transformListRow; const item: TransformListRow = transformListRow;
const props: StopActionNameProps = { const props: StopActionNameProps = {
forceDisable: false, forceDisable: false,

View file

@ -15,14 +15,15 @@ describe('Transform: isCompletedBatchTransform()', () => {
// check the transform config/state against the conditions // check the transform config/state against the conditions
// that will be used by isCompletedBatchTransform() // that will be used by isCompletedBatchTransform()
// followed by a call to isCompletedBatchTransform() itself // followed by a call to isCompletedBatchTransform() itself
// @ts-expect-error mock data is too loosely typed
const row = mockTransformListRow as TransformListRow; const row = mockTransformListRow as TransformListRow;
expect(row.stats.checkpointing.last.checkpoint === 1).toBe(true); expect(row.stats.checkpointing.last.checkpoint === 1).toBe(true);
expect(row.config.sync === undefined).toBe(true); expect(row.config.sync === undefined).toBe(true);
expect(row.stats.state === TRANSFORM_STATE.STOPPED).toBe(true); expect(row.stats.state === TRANSFORM_STATE.STOPPED).toBe(true);
expect(isCompletedBatchTransform(mockTransformListRow)).toBe(true); expect(isCompletedBatchTransform(row)).toBe(true);
// adapt the mock config to resemble a non-completed transform. // adapt the mock config to resemble a non-completed transform.
row.stats.checkpointing.last.checkpoint = 0; row.stats.checkpointing.last.checkpoint = 0;
expect(isCompletedBatchTransform(mockTransformListRow)).toBe(false); expect(isCompletedBatchTransform(row)).toBe(false);
}); });
}); });

View file

@ -27,6 +27,7 @@ describe('Transform: Transform List <ExpandedRow />', () => {
}); });
test('Minimal initialization', async () => { test('Minimal initialization', async () => {
// @ts-expect-error mock data is too loosely typed
const item: TransformListRow = transformListRow; const item: TransformListRow = transformListRow;
const { getByText, getByTestId } = render(<ExpandedRow item={item} />); const { getByText, getByTestId } = render(<ExpandedRow item={item} />);

View file

@ -25,6 +25,7 @@ const defaultProps = {
*/ */
describe('CheckupTab', () => { describe('CheckupTab', () => {
test('render with deprecations', () => { test('render with deprecations', () => {
// @ts-expect-error mock data is too loosely typed
expect(shallow(<CheckupTab {...defaultProps} />)).toMatchSnapshot(); expect(shallow(<CheckupTab {...defaultProps} />)).toMatchSnapshot();
}); });

View file

@ -34,6 +34,7 @@ describe('getUpgradeAssistantStatus', () => {
}); });
beforeEach(() => { beforeEach(() => {
// @ts-expect-error mock data is too loosely typed
deprecationsResponse = _.cloneDeep(fakeDeprecations); deprecationsResponse = _.cloneDeep(fakeDeprecations);
}); });

View file

@ -47,6 +47,7 @@ export function InfraOpsGraphQLClientFactoryProvider({ getService }: FtrProvider
return new ApolloClient({ return new ApolloClient({
cache: new InMemoryCache({ cache: new InMemoryCache({
fragmentMatcher: new IntrospectionFragmentMatcher({ fragmentMatcher: new IntrospectionFragmentMatcher({
// @ts-expect-error apollo-cache-inmemory types don't match actual introspection data
introspectionQueryResultData, introspectionQueryResultData,
}), }),
}), }),

View file

@ -46,6 +46,7 @@ export function SecuritySolutionGraphQLClientFactoryProvider({ getService }: Ftr
return new ApolloClient({ return new ApolloClient({
cache: new InMemoryCache({ cache: new InMemoryCache({
fragmentMatcher: new IntrospectionFragmentMatcher({ fragmentMatcher: new IntrospectionFragmentMatcher({
// @ts-expect-error apollo-cache-inmemory types don't match actual introspection data
introspectionQueryResultData, introspectionQueryResultData,
}), }),
}), }),

View file

@ -15,7 +15,6 @@
"plugins/licensing/**/*" "plugins/licensing/**/*"
], ],
"compilerOptions": { "compilerOptions": {
"outDir": ".",
"paths": { "paths": {
"kibana/public": ["src/core/public"], "kibana/public": ["src/core/public"],
"kibana/server": ["src/core/server"], "kibana/server": ["src/core/server"],

View file

@ -33,12 +33,3 @@ declare module 'axios/lib/adapters/xhr';
type Writable<T> = { type Writable<T> = {
-readonly [K in keyof T]: T[K]; -readonly [K in keyof T]: T[K];
}; };
// allow JSON files to be imported directly without lint errors
// see: https://github.com/palantir/tslint/issues/1264#issuecomment-228433367
// and: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#arbitrary-expressions-are-forbidden-in-export-assignments-in-ambient-contexts
declare module '*.json' {
const json: any;
// eslint-disable-next-line import/no-default-export
export default json;
}