Skip to content

Commit fc386e4

Browse files
committed
chore: improve eslint rules and fix issues
1 parent 506c11e commit fc386e4

28 files changed

+221
-152
lines changed

eslint.config.mjs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
1-
// eslint-disable-next-line import-x/extensions,import-x/no-unresolved
21
import { defineConfig, globalIgnores } from 'eslint/config';
3-
import { recommended, vitest } from 'eslint-config-satya164';
2+
import { recommended, vitest, typechecked } from 'eslint-config-satya164';
43

54
export default defineConfig(
65
recommended,
76
vitest,
7+
typechecked,
8+
9+
{
10+
languageOptions: {
11+
parserOptions: {
12+
project: true,
13+
tsconfigRootDir: import.meta.dirname,
14+
},
15+
},
16+
17+
rules: {
18+
'@typescript-eslint/no-unsafe-argument': 'off',
19+
'@typescript-eslint/no-unsafe-assignment': 'off',
20+
'@typescript-eslint/no-unsafe-call': 'off',
21+
'@typescript-eslint/no-unsafe-member-access': 'off',
22+
'@typescript-eslint/no-unnecessary-condition': 'off',
23+
'@typescript-eslint/strict-boolean-expressions': 'off',
24+
},
25+
},
826

927
globalIgnores([
1028
'**/.next/',

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
"commitlint": "^17.0.2",
3131
"concurrently": "^7.2.2",
3232
"eslint": "^9.26.0",
33-
"eslint-config-satya164": "^5.0.3",
33+
"eslint-config-satya164": "^5.1.1",
3434
"globals": "^16.0.0",
3535
"prettier": "^3.5.3",
36-
"typescript": "^5.2.2"
36+
"typescript": "^5.8.3"
3737
},
3838
"commitlint": {
3939
"extends": [
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
#!/usr/bin/env node
22

3-
// eslint-disable-next-line import/no-commonjs
43
require('../lib/index');

packages/create-react-native-library/src/exampleApp/generateExampleApp.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ export default async function generateExampleApp({
117117
'blank',
118118
];
119119
break;
120+
case 'none': {
121+
// Do nothing
122+
}
120123
}
121124

122125
await spawn('npx', args, {
@@ -193,15 +196,18 @@ export default async function generateExampleApp({
193196

194197
if (config.project.moduleConfig === 'nitro-modules') {
195198
const packagesToAddNitro = {
196-
'react-native-nitro-modules': `^${config.versions.nitroModules}`,
199+
'react-native-nitro-modules': `^${config.versions.nitro || 'latest'}`,
197200
};
201+
198202
Object.assign(dependencies, packagesToAddNitro);
199203
}
200204

201205
Object.assign(devDependencies, PACKAGES_TO_ADD_DEV);
202206

203207
if (config.example === 'expo') {
204-
const sdkVersion = dependencies.expo.split('.')[0].replace(/[^\d]/, '');
208+
const sdkVersion: string = dependencies.expo
209+
.split('.')[0]
210+
.replace(/[^\d]/, '');
205211

206212
let bundledNativeModules: Record<string, string>;
207213

@@ -213,11 +219,12 @@ export default async function generateExampleApp({
213219
(res) => {
214220
let data = '';
215221

216-
res.on('data', (chunk) => (data += chunk));
222+
res.on('data', (chunk: string) => (data += chunk));
217223
res.on('end', () => {
218224
try {
219225
resolve(JSON.parse(data));
220226
} catch (e) {
227+
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
221228
reject(e);
222229
}
223230
});

packages/create-react-native-library/src/index.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ type Args = Partial<Answers> & {
3838
[key: string]: unknown;
3939
};
4040

41-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
42-
yargs
41+
void yargs
4342
.command('$0 [name]', 'create a react native library', acceptedArgs, create)
4443
.demandCommand()
4544
.recommendCommands()
@@ -82,9 +81,7 @@ async function create(_argv: Args) {
8281
const config = generateTemplateConfiguration({
8382
versions: {
8483
bob: bobVersion,
85-
nitroModules: nitroModulesVersion,
86-
// Nitro codegen's version is always the same as nitro modules version.
87-
nitroCodegen: nitroModulesVersion,
84+
nitro: nitroModulesVersion,
8885
},
8986
basename: path.basename(answers.name ?? answers.directory),
9087
answers,

packages/create-react-native-library/src/input.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ export async function createQuestions({
276276
try {
277277
const username = await githubUsername(answers.authorEmail);
278278

279-
return `https://github.com/${username}`;
279+
if (username) {
280+
return `https://github.com/${username}`;
281+
}
280282
} catch (e) {
281283
// Ignore error
282284
}
@@ -378,6 +380,7 @@ export function createMetadata(answers: Partial<PromptAnswers>) {
378380
][];
379381

380382
const libraryMetadata = Object.fromEntries(
383+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
381384
(Object.entries(answers) as AnswerEntries).filter(
382385
([answer]) => !ignoredAnswers.includes(answer)
383386
)

packages/create-react-native-library/src/template.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import type { Answers, ExampleApp, ProjectType } from './input';
55

66
export type TemplateVersions = {
77
bob: string;
8-
nitroModules?: string;
9-
nitroCodegen?: string;
8+
nitro: string | undefined;
109
};
1110

1211
export type ModuleConfig =
@@ -126,7 +125,7 @@ export function generateTemplateConfiguration({
126125
basename
127126
: // Otherwise, convert it to PascalCase and remove any non-alphanumeric characters
128127
`${project.charAt(0).toUpperCase()}${project
129-
.replace(/[^a-z0-9](\w)/g, (_, $1) => $1.toUpperCase())
128+
.replace(/[^a-z0-9](\w)/g, (_, $1: string) => $1.toUpperCase())
130129
.slice(1)}`,
131130
package: pack,
132131
package_dir: pack.replace(/\./g, '/'),
@@ -154,7 +153,8 @@ function getModuleConfig(projectType: ProjectType): ModuleConfig {
154153
return 'nitro-modules';
155154
case 'turbo-module':
156155
return 'turbo-modules';
157-
default:
156+
case 'fabric-view':
157+
case 'library':
158158
return null;
159159
}
160160
}
@@ -163,7 +163,9 @@ function getViewConfig(projectType: ProjectType): ViewConfig {
163163
switch (projectType) {
164164
case 'fabric-view':
165165
return 'fabric-view';
166-
default:
166+
case 'nitro-module':
167+
case 'turbo-module':
168+
case 'library':
167169
return null;
168170
}
169171
}

packages/create-react-native-library/src/utils/local.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ type PackageJson = {
1010
export async function addNitroDependencyToLocalLibrary(
1111
config: TemplateConfiguration
1212
): Promise<boolean> {
13-
if (config.versions.nitroModules === undefined) {
13+
if (config.versions.nitro === undefined) {
1414
return false;
1515
}
1616

@@ -22,7 +22,7 @@ export async function addNitroDependencyToLocalLibrary(
2222
const appPackageJson: PackageJson = await fs.readJson(appPackageJsonPath);
2323
const dependencies = appPackageJson['dependencies'] ?? {};
2424

25-
dependencies['react-native-nitro-modules'] = config.versions.nitroModules;
25+
dependencies['react-native-nitro-modules'] = config.versions.nitro;
2626

2727
appPackageJson['dependencies'] = dependencies;
2828
await fs.writeJson(appPackageJsonPath, appPackageJson, {

packages/create-react-native-library/src/utils/prompt.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ export async function prompt<
5858
): Promise<PromptAnswers & Argv> {
5959
const interactive =
6060
options?.interactive ??
61-
Boolean(
62-
process.stdout.isTTY && process.env.TERM !== 'dumb' && !process.env.CI
63-
);
61+
(process.stdout.isTTY && process.env.TERM !== 'dumb' && !process.env.CI);
6462

6563
const onCancel = () => {
6664
// Exit the CLI on Ctrl+C
@@ -182,7 +180,7 @@ export async function prompt<
182180
if (missingQuestions.length) {
183181
onError(
184182
`Missing values for options: ${missingQuestions
185-
.map(kleur.blue)
183+
.map((q) => kleur.blue(q))
186184
.join(', ')}`
187185
);
188186
}
@@ -196,6 +194,7 @@ export async function prompt<
196194

197195
validate(result, questions, onError);
198196

197+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
199198
return result as PromptAnswers & Argv;
200199
}
201200

packages/create-react-native-library/src/utils/resolveNpmPackageVersion.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ export async function resolveNpmPackageVersion(
1212

1313
result = await Promise.race([
1414
new Promise<string>((resolve) => {
15-
setTimeout(() => resolve(fallback), timeout);
15+
setTimeout(() => {
16+
resolve(fallback);
17+
}, timeout);
1618
}),
1719
promise,
1820
]);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
export default function sortObjectKeys<T extends Record<string, unknown>>(
22
obj: T
33
): T {
4+
// eslint-disable-next-line @typescript-eslint/require-array-sort-compare
45
return (Object.keys(obj) as (keyof T)[]).sort().reduce((acc, key) => {
56
acc[key] = obj[key];
67
return acc;
8+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
79
}, {} as T);
810
}

packages/create-react-native-library/src/utils/spawn.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ export const spawn = async (...args: Parameters<typeof crossSpawn>) => {
88
let stderr = '';
99

1010
child.stdout?.setEncoding('utf8');
11-
child.stdout?.on('data', (data) => {
11+
child.stdout?.on('data', (data: string) => {
1212
stdout += data;
1313
});
1414

1515
child.stderr?.setEncoding('utf8');
16-
child.stderr?.on('data', (data) => {
16+
child.stderr?.on('data', (data: string) => {
1717
stderr += data;
1818
});
1919

packages/create-react-native-library/templates/common/$package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
<% if (example !== 'expo') { -%>
105105
"turbo": "^1.10.7",
106106
<% } -%>
107-
"typescript": "^5.2.2"
107+
"typescript": "^5.8.3"
108108
},
109109
"peerDependencies": {
110110
"react": "*",

packages/react-native-builder-bob/babel-preset.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ const browserslist = require('browserslist');
1111
*/
1212
module.exports = function (api, options, cwd) {
1313
const opt = (name) =>
14+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
1415
options[name] !== undefined
1516
? options[name]
16-
: api.caller((caller) => (caller != null ? caller[name] : undefined));
17+
: // eslint-disable-next-line @typescript-eslint/no-unsafe-return
18+
api.caller((caller) => (caller != null ? caller[name] : undefined));
1719

1820
const supportsStaticESM = opt('supportsStaticESM');
1921
const rewriteImportExtensions = opt('rewriteImportExtensions');
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
#!/usr/bin/env node
22

3-
// eslint-disable-next-line import/no-commonjs
43
require('../lib/index');

packages/react-native-builder-bob/metro-config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ const { withMetroConfig } = require('react-native-monorepo-config');
1414
* @returns {import('metro-config').MetroConfig} Metro configuration
1515
*/
1616
exports.getConfig = (baseConfig, { root, project }) =>
17+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
1718
withMetroConfig(baseConfig, { root, dirname: project });

packages/react-native-builder-bob/src/__tests__/init.test.ts

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { afterEach, beforeEach, expect, test, vi, type Mock } from 'vitest';
1+
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
22
import { readFile } from 'fs-extra';
33
import mockFs from 'mock-fs';
44
import { stdin } from 'mock-stdin';
@@ -32,6 +32,7 @@ const waitFor = async (callback: () => void) => {
3232
} catch (error) {
3333
if (timeout <= 0) {
3434
clearInterval(intervalId);
35+
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
3536
reject(error);
3637
}
3738

@@ -64,13 +65,15 @@ afterEach(() => {
6465
});
6566

6667
test('initializes the configuration', async () => {
67-
vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
68+
const writeMock = vi
69+
.spyOn(process.stdout, 'write')
70+
.mockImplementation(() => true);
6871

6972
process.chdir(root);
7073

7174
const run = async () => {
7275
await waitFor(() => {
73-
const lastCall = (process.stdout.write as Mock).mock.lastCall;
76+
const lastCall = writeMock.mock.lastCall;
7477

7578
if (lastCall == null) {
7679
throw new Error('No output');
@@ -81,44 +84,44 @@ test('initializes the configuration', async () => {
8184
}
8285
});
8386

84-
await waitFor(() =>
85-
expect(process.stdout.write).toHaveBeenLastCalledWith(
87+
await waitFor(() => {
88+
expect(writeMock).toHaveBeenLastCalledWith(
8689
expect.stringMatching('Where are your source files?')
87-
)
88-
);
90+
);
91+
});
8992

9093
io?.send(enter);
9194

92-
await waitFor(() =>
93-
expect(process.stdout.write).toHaveBeenLastCalledWith(
95+
await waitFor(() => {
96+
expect(writeMock).toHaveBeenLastCalledWith(
9497
expect.stringMatching('Where do you want to generate the output files?')
95-
)
96-
);
98+
);
99+
});
97100

98101
io?.send(enter);
99102

100-
await waitFor(() =>
101-
expect(process.stdout.write).toHaveBeenLastCalledWith(
103+
await waitFor(() => {
104+
expect(writeMock).toHaveBeenLastCalledWith(
102105
expect.stringMatching('Which targets do you want to build?')
103-
)
104-
);
106+
);
107+
});
105108

106109
io?.send(enter);
107110

108-
await waitFor(() =>
109-
expect(process.stdout.write).toHaveBeenLastCalledWith(
111+
await waitFor(() => {
112+
expect(writeMock).toHaveBeenLastCalledWith(
110113
expect.stringMatching(
111114
"You have enabled 'typescript' compilation, but we couldn't find a 'tsconfig.json' in project root"
112115
)
113-
)
114-
);
116+
);
117+
});
115118

116119
io?.send(enter);
117120
};
118121

119122
await Promise.all([run(), init()]);
120123

121-
expect(process.stdout.write).toHaveBeenLastCalledWith(
124+
expect(writeMock).toHaveBeenLastCalledWith(
122125
expect.stringMatching('configured successfully!')
123126
);
124127

0 commit comments

Comments
 (0)