Skip to content

Commit 8255a9a

Browse files
authored
chore: tighten types across mobile surface areas (#1209)
* chore(app): tighten types across app workspace * fixes * save wip * save wip linting * fix any types * fix types * fix: import forwardRef directly from react - Changed from React.forwardRef to forwardRef import - Resolves linting warning about named exports * save typing and linting updates * cr feedback. final pass * more cr feedback * pipeline fixes
1 parent 04562d1 commit 8255a9a

File tree

92 files changed

+797
-389
lines changed

Some content is hidden

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

92 files changed

+797
-389
lines changed

.github/workflows/circuits-build.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@ on:
1111
workflow_dispatch:
1212
inputs:
1313
circuit-type:
14-
description: 'Circuits to build (comma-separated: register, register_id, register_aadhaar, disclose, dsc). Leave empty to build all.'
14+
description: "Circuits to build (comma-separated: register, register_id, register_aadhaar, disclose, dsc). Leave empty to build all."
1515
required: false
1616
type: string
17-
default: ''
17+
default: ""
1818
circuit-name:
19-
description: 'Circuit names to build (comma-separated: register_sha256_sha224_sha224_ecdsa_secp224r1, dsc_sha256_rsa_65537_4096). Cannot be used with circuit-type.'
19+
description: "Circuit names to build (comma-separated: register_sha256_sha224_sha224_ecdsa_secp224r1, dsc_sha256_rsa_65537_4096). Cannot be used with circuit-type."
2020
required: false
2121
type: string
22-
default: ''
22+
default: ""
2323
run-id:
24-
description: 'Run ID to download artifacts .'
24+
description: "Run ID to download artifacts ."
2525
required: false
2626
type: string
27-
default: ''
27+
default: ""
2828

2929
concurrency:
3030
group: circuits-build-${{ github.workflow }}-${{ github.ref }}

app/.eslintrc.cjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,16 @@ module.exports = {
173173
'@typescript-eslint/ban-ts-comment': 'off',
174174
'no-empty': 'off',
175175

176+
// TypeScript Import Rules
177+
178+
'@typescript-eslint/consistent-type-imports': [
179+
'error',
180+
{
181+
prefer: 'type-imports',
182+
disallowTypeAnnotations: false,
183+
},
184+
],
185+
176186
// Override rules conflicting with TypeScript union formatting
177187

178188
'@typescript-eslint/indent': 'off',

app/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@
170170
"@testing-library/react-native": "^13.3.3",
171171
"@tsconfig/react-native": "^3.0.6",
172172
"@types/add": "^2",
173+
"@types/bn.js": "^5.2.0",
173174
"@types/dompurify": "^3.2.0",
174-
"@types/elliptic": "^6",
175+
"@types/elliptic": "^6.4.18",
175176
"@types/jest": "^29.5.14",
176177
"@types/node": "^22.18.3",
177178
"@types/node-forge": "^1.3.14",

app/scripts/alias-imports.cjs

Lines changed: 102 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -20,70 +20,124 @@ function transformProjectToAliasImports(project, appRootPath) {
2020

2121
// Handle import declarations
2222
for (const declaration of sourceFile.getImportDeclarations()) {
23-
const spec = declaration.getModuleSpecifierValue();
23+
try {
24+
// Skip if no module specifier or not a string literal
25+
const moduleSpecifier = declaration.getModuleSpecifier();
26+
if (
27+
!moduleSpecifier ||
28+
moduleSpecifier.getKind() !== SyntaxKind.StringLiteral
29+
) {
30+
continue;
31+
}
2432

25-
// Skip existing alias imports
26-
if (spec.startsWith('@/') || spec.startsWith('@tests/')) {
27-
continue;
28-
}
33+
const spec = declaration.getModuleSpecifierValue();
2934

30-
// Handle relative imports
31-
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
32-
const abs = path.resolve(dir, spec);
33-
let baseDir = null;
34-
let baseAlias = null;
35+
// Skip existing alias imports
36+
if (spec.startsWith('@/') || spec.startsWith('@tests/')) {
37+
continue;
38+
}
3539

36-
// Determine containment safely using path.relative to avoid startsWith false positives
37-
const relFromSrc = path.relative(srcDir, abs);
38-
if (!relFromSrc.startsWith('..') && !path.isAbsolute(relFromSrc)) {
39-
baseDir = srcDir;
40-
baseAlias = '@';
41-
} else {
42-
const relFromTests = path.relative(testsDir, abs);
43-
if (!relFromTests.startsWith('..') && !path.isAbsolute(relFromTests)) {
44-
baseDir = testsDir;
45-
baseAlias = '@tests';
40+
// Handle relative imports
41+
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
42+
const abs = path.resolve(dir, spec);
43+
let baseDir = null;
44+
let baseAlias = null;
45+
46+
// Determine containment safely using path.relative to avoid startsWith false positives
47+
const relFromSrc = path.relative(srcDir, abs);
48+
if (!relFromSrc.startsWith('..') && !path.isAbsolute(relFromSrc)) {
49+
baseDir = srcDir;
50+
baseAlias = '@';
4651
} else {
47-
continue;
52+
const relFromTests = path.relative(testsDir, abs);
53+
if (
54+
!relFromTests.startsWith('..') &&
55+
!path.isAbsolute(relFromTests)
56+
) {
57+
baseDir = testsDir;
58+
baseAlias = '@tests';
59+
} else {
60+
continue;
61+
}
4862
}
49-
}
5063

51-
const newSpec = determineAliasStrategy(dir, abs, baseDir, baseAlias);
52-
declaration.setModuleSpecifier(newSpec);
64+
const newSpec = determineAliasStrategy(dir, abs, baseDir, baseAlias);
65+
declaration.setModuleSpecifier(newSpec);
66+
} catch (error) {
67+
// Skip declarations that can't be processed (e.g., type-only imports with issues)
68+
const msg = error instanceof Error ? error.message : String(error);
69+
console.warn(
70+
`Skipping import declaration in ${sourceFile.getFilePath()}: ${msg}`,
71+
);
72+
try {
73+
console.debug('Import declaration text:', declaration.getText());
74+
} catch {}
75+
if (error && typeof error === 'object' && 'stack' in error) {
76+
console.debug('Error stack:', error.stack);
77+
}
78+
continue;
79+
}
5380
}
5481

5582
// Handle export declarations like: export * from '../x' or export {A} from '../x'
5683
for (const declaration of sourceFile.getExportDeclarations()) {
57-
const spec = declaration.getModuleSpecifierValue();
58-
if (!spec) continue;
84+
try {
85+
// Skip if no module specifier or not a string literal
86+
const moduleSpecifier = declaration.getModuleSpecifier();
87+
if (
88+
!moduleSpecifier ||
89+
moduleSpecifier.getKind() !== SyntaxKind.StringLiteral
90+
) {
91+
continue;
92+
}
5993

60-
// Skip existing alias exports
61-
if (spec.startsWith('@/') || spec.startsWith('@tests/')) {
62-
continue;
63-
}
94+
const spec = declaration.getModuleSpecifierValue();
95+
if (!spec) continue;
6496

65-
// Handle relative exports
66-
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
67-
const abs = path.resolve(dir, spec);
68-
let baseDir = null;
69-
let baseAlias = null;
97+
// Skip existing alias exports
98+
if (spec.startsWith('@/') || spec.startsWith('@tests/')) {
99+
continue;
100+
}
70101

71-
const relFromSrc = path.relative(srcDir, abs);
72-
if (!relFromSrc.startsWith('..') && !path.isAbsolute(relFromSrc)) {
73-
baseDir = srcDir;
74-
baseAlias = '@';
75-
} else {
76-
const relFromTests = path.relative(testsDir, abs);
77-
if (!relFromTests.startsWith('..') && !path.isAbsolute(relFromTests)) {
78-
baseDir = testsDir;
79-
baseAlias = '@tests';
102+
// Handle relative exports
103+
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
104+
const abs = path.resolve(dir, spec);
105+
let baseDir = null;
106+
let baseAlias = null;
107+
108+
const relFromSrc = path.relative(srcDir, abs);
109+
if (!relFromSrc.startsWith('..') && !path.isAbsolute(relFromSrc)) {
110+
baseDir = srcDir;
111+
baseAlias = '@';
80112
} else {
81-
continue;
113+
const relFromTests = path.relative(testsDir, abs);
114+
if (
115+
!relFromTests.startsWith('..') &&
116+
!path.isAbsolute(relFromTests)
117+
) {
118+
baseDir = testsDir;
119+
baseAlias = '@tests';
120+
} else {
121+
continue;
122+
}
82123
}
83-
}
84124

85-
const newSpec = determineAliasStrategy(dir, abs, baseDir, baseAlias);
86-
declaration.setModuleSpecifier(newSpec);
125+
const newSpec = determineAliasStrategy(dir, abs, baseDir, baseAlias);
126+
declaration.setModuleSpecifier(newSpec);
127+
} catch (error) {
128+
// Skip declarations that can't be processed
129+
const msg = error instanceof Error ? error.message : String(error);
130+
console.warn(
131+
`Skipping export declaration in ${sourceFile.getFilePath()}: ${msg}`,
132+
);
133+
try {
134+
console.debug('Export declaration text:', declaration.getText());
135+
} catch {}
136+
if (error && typeof error === 'object' && 'stack' in error) {
137+
console.debug('Error stack:', error.stack);
138+
}
139+
continue;
140+
}
87141
}
88142

89143
// Handle require() calls

app/src/components/DelayedLottieView.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import type { LottieViewProps } from 'lottie-react-native';
66
import LottieView from 'lottie-react-native';
7-
import React, { useEffect, useRef } from 'react';
7+
import React, { forwardRef, useEffect, useRef } from 'react';
88

99
/**
1010
* Wrapper around LottieView that fixes iOS native module initialization timing.
@@ -20,7 +20,7 @@ import React, { useEffect, useRef } from 'react';
2020
* @example
2121
* <DelayedLottieView autoPlay loop source={animation} style={styles.animation} />
2222
*/
23-
export const DelayedLottieView = React.forwardRef<LottieView, LottieViewProps>(
23+
export const DelayedLottieView = forwardRef<LottieView, LottieViewProps>(
2424
(props, forwardedRef) => {
2525
const internalRef = useRef<LottieView>(null);
2626
const ref = (forwardedRef as React.RefObject<LottieView>) || internalRef;

app/src/components/buttons/AbstractButton.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
44

55
import React from 'react';
6-
import type { GestureResponderEvent, ViewStyle } from 'react-native';
6+
import type {
7+
GestureResponderEvent,
8+
LayoutChangeEvent,
9+
ViewStyle,
10+
} from 'react-native';
711
import { Platform, StyleSheet } from 'react-native';
812
import type { ViewProps } from 'tamagui';
913
import { Button, Text } from 'tamagui';
@@ -16,6 +20,7 @@ export interface ButtonProps extends ViewProps {
1620
children: React.ReactNode;
1721
animatedComponent?: React.ReactNode;
1822
trackEvent?: string;
23+
onLayout?: (event: LayoutChangeEvent) => void;
1924
}
2025

2126
interface AbstractButtonProps extends ButtonProps {

app/src/components/buttons/PrimaryButtonLongHold.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ export function HeldPrimaryButton({
9393
{...props}
9494
onPressIn={onPressIn}
9595
onPressOut={onPressOut}
96-
// @ts-expect-error actually it is there
9796
onLayout={getButtonSize}
9897
animatedComponent={renderAnimatedComponent()}
9998
>

app/src/components/buttons/PrimaryButtonLongHold.web.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ export function HeldPrimaryButton({
8383
{...props}
8484
onPressIn={onPressIn}
8585
onPressOut={onPressOut}
86-
// @ts-expect-error actually it is there
8786
onLayout={getButtonSize}
8887
animatedComponent={renderAnimatedComponent()}
8988
>

app/src/components/homeScreen/SvgXmlWrapper.native.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,12 @@
22
// SPDX-License-Identifier: BUSL-1.1
33
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
44

5-
import React, { forwardRef } from 'react';
6-
import type { StyleProp, ViewStyle } from 'react-native';
5+
import type { ComponentProps } from 'react';
6+
import React from 'react';
77
import { SvgXml as RNSvgXml } from 'react-native-svg';
88

9-
type Props = {
10-
xml: string;
11-
width?: number;
12-
height?: number;
13-
style?: StyleProp<ViewStyle>;
14-
};
9+
type Props = ComponentProps<typeof RNSvgXml>;
1510

16-
export const SvgXml = forwardRef<any, Props>((p, _ref) => <RNSvgXml {...p} />);
11+
export const SvgXml: React.FC<Props> = props => <RNSvgXml {...props} />;
1712
SvgXml.displayName = 'SvgXml';
1813
export default SvgXml;

app/src/components/homeScreen/SvgXmlWrapper.web.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: BUSL-1.1
33
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
44

5-
import DOMPurify from 'dompurify';
5+
import createDOMPurify from 'dompurify';
66
import {
77
createElement,
88
type CSSProperties,
@@ -20,7 +20,7 @@ type Props = {
2020
export const SvgXml = forwardRef<HTMLDivElement, Props>(
2121
({ xml, width, height, style, ...props }, ref) => {
2222
// Initialize DOMPurify for web browser environment
23-
const purify = DOMPurify(window);
23+
const purify = createDOMPurify(window);
2424
const safe = purify.sanitize(xml, {
2525
USE_PROFILES: { svg: true, svgFilters: true },
2626
});

0 commit comments

Comments
 (0)