Skip to content

Commit f67f24c

Browse files
committed
AINATIVEM-41 use native fs lib
1 parent 77eed6a commit f67f24c

12 files changed

Lines changed: 44 additions & 101 deletions

package-lock.json

Lines changed: 1 addition & 65 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@
1616
"dependencies": {
1717
"@clack/prompts": "^0.9.0",
1818
"dedent": "^1.7.2",
19-
"fs-extra": "^11.2.0",
2019
"prettier": "^3.3.0"
2120
},
2221
"devDependencies": {
2322
"@eslint/js": "^9.0.0",
2423
"@types/dedent": "^0.7.2",
25-
"@types/fs-extra": "^11.0.4",
26-
"@types/node": "^20.0.0",
24+
"@types/node": "^20.19.39",
2725
"eslint": "^9.0.0",
2826
"tsx": "^4.7.0",
2927
"typescript": "^5.4.0",

src/generators/node/app.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { afterEach, describe, expect, it } from 'vitest';
2-
import { readFile, remove } from 'fs-extra';
2+
import { readFile, rm } from 'node:fs/promises';
33
import { join } from 'path';
44
import { tmpdir } from 'os';
55
import type { GeneratorOptions } from '../interface.js';
66

77
const tmpDir = join(tmpdir(), 'cpa-app-test');
88

99
afterEach(async () => {
10-
await remove(tmpDir);
10+
await rm(tmpDir, { recursive: true, force: true });
1111
});
1212

1313
async function getAppContent(options: GeneratorOptions): Promise<string> {

src/generators/node/appExtensions.test.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { afterEach, describe, expect, it } from 'vitest';
2-
import { pathExists, remove } from 'fs-extra';
2+
import { access, rm } from 'node:fs/promises';
33
import { join } from 'path';
44
import { tmpdir } from 'os';
55
import type { GeneratorOptions } from '../interface.js';
66

77
const tmpDir = join(tmpdir(), 'cpa-appext-test');
8+
const exists = (p: string) => access(p).then(() => true, () => false);
89

910
afterEach(async () => {
10-
await remove(tmpDir);
11+
await rm(tmpDir, { recursive: true, force: true });
1112
});
1213

1314
describe('generateAppExtensions', () => {
@@ -20,8 +21,8 @@ describe('generateAppExtensions', () => {
2021
appExtensions: ['custom-panel'],
2122
};
2223
await generateAppExtensions(tmpDir, options);
23-
expect(await pathExists(join(tmpDir, 'src/app-extensions/panel/index.ts'))).toBe(true);
24-
expect(await pathExists(join(tmpDir, 'src/app-extensions/modal/index.ts'))).toBe(false);
24+
expect(await exists(join(tmpDir, 'src/app-extensions/panel/index.ts'))).toBe(true);
25+
expect(await exists(join(tmpDir, 'src/app-extensions/modal/index.ts'))).toBe(false);
2526
});
2627

2728
it('creates modal stub when custom-modal is selected', async () => {
@@ -33,8 +34,8 @@ describe('generateAppExtensions', () => {
3334
appExtensions: ['custom-modal'],
3435
};
3536
await generateAppExtensions(tmpDir, options);
36-
expect(await pathExists(join(tmpDir, 'src/app-extensions/modal/index.ts'))).toBe(true);
37-
expect(await pathExists(join(tmpDir, 'src/app-extensions/panel/index.ts'))).toBe(false);
37+
expect(await exists(join(tmpDir, 'src/app-extensions/modal/index.ts'))).toBe(true);
38+
expect(await exists(join(tmpDir, 'src/app-extensions/panel/index.ts'))).toBe(false);
3839
});
3940

4041
it('creates both stubs when both types are selected', async () => {
@@ -46,7 +47,7 @@ describe('generateAppExtensions', () => {
4647
appExtensions: ['custom-panel', 'custom-modal'],
4748
};
4849
await generateAppExtensions(tmpDir, options);
49-
expect(await pathExists(join(tmpDir, 'src/app-extensions/panel/index.ts'))).toBe(true);
50-
expect(await pathExists(join(tmpDir, 'src/app-extensions/modal/index.ts'))).toBe(true);
50+
expect(await exists(join(tmpDir, 'src/app-extensions/panel/index.ts'))).toBe(true);
51+
expect(await exists(join(tmpDir, 'src/app-extensions/modal/index.ts'))).toBe(true);
5152
});
5253
});

src/generators/node/database.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { afterEach, describe, expect, it } from 'vitest';
2-
import { pathExists, readFile, remove } from 'fs-extra';
2+
import { access, readFile, rm } from 'node:fs/promises';
33
import { join } from 'path';
44
import { tmpdir } from 'os';
55
import type { GeneratorOptions } from '../interface.js';
66

77
const tmpDir = join(tmpdir(), 'cpa-database-test');
8+
const exists = (p: string) => access(p).then(() => true, () => false);
89
const options: GeneratorOptions = {
910
projectName: 'test-app',
1011
database: 'postgres',
@@ -13,14 +14,14 @@ const options: GeneratorOptions = {
1314
};
1415

1516
afterEach(async () => {
16-
await remove(tmpDir);
17+
await rm(tmpDir, { recursive: true, force: true });
1718
});
1819

1920
describe('generateDatabase', () => {
2021
it('creates src/database/index.ts', async () => {
2122
const { generateDatabase } = await import('./database.js');
2223
await generateDatabase(tmpDir, options);
23-
expect(await pathExists(join(tmpDir, 'src/database/index.ts'))).toBe(true);
24+
expect(await exists(join(tmpDir, 'src/database/index.ts'))).toBe(true);
2425
});
2526

2627
it('file is valid TypeScript (exports something)', async () => {

src/generators/node/index.test.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { afterEach, describe, expect, it } from 'vitest';
2-
import { pathExists, remove } from 'fs-extra';
2+
import { access, rm } from 'node:fs/promises';
33
import { join } from 'path';
44
import { tmpdir } from 'os';
55
import { execSync } from 'child_process';
66
import { nodeGenerator } from './index.js';
77
import type { GeneratorOptions } from '../interface.js';
88

99
const tmpDir = join(tmpdir(), 'cpa-e2e-test');
10+
const exists = (p: string) => access(p).then(() => true, () => false);
1011

1112
afterEach(async () => {
12-
await remove(tmpDir);
13+
await rm(tmpDir, { recursive: true, force: true });
1314
});
1415

1516
const fullOptions: GeneratorOptions = {
@@ -45,16 +46,16 @@ describe('nodeGenerator', () => {
4546
];
4647

4748
for (const file of expectedFiles) {
48-
expect(await pathExists(join(tmpDir, file)), `Missing: ${file}`).toBe(true);
49+
expect(await exists(join(tmpDir, file)), `Missing: ${file}`).toBe(true);
4950
}
5051
});
5152

5253
it('omits conditional files for minimal options', async () => {
5354
await nodeGenerator.generate(tmpDir, minimalOptions);
5455

55-
expect(await pathExists(join(tmpDir, 'src/webhooks/index.ts'))).toBe(false);
56-
expect(await pathExists(join(tmpDir, 'src/app-extensions'))).toBe(false);
57-
expect(await pathExists(join(tmpDir, 'docker-compose.yml'))).toBe(false);
56+
expect(await exists(join(tmpDir, 'src/webhooks/index.ts'))).toBe(false);
57+
expect(await exists(join(tmpDir, 'src/app-extensions'))).toBe(false);
58+
expect(await exists(join(tmpDir, 'docker-compose.yml'))).toBe(false);
5859
});
5960

6061
it('generated project passes tsc --noEmit', async () => {

src/generators/node/oauth.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { afterEach, describe, expect, it } from 'vitest';
2-
import { pathExists, readFile, remove } from 'fs-extra';
2+
import { access, readFile, rm } from 'node:fs/promises';
33
import { join } from 'path';
44
import { tmpdir } from 'os';
55
import type { GeneratorOptions } from '../interface.js';
@@ -13,14 +13,14 @@ const options: GeneratorOptions = {
1313
};
1414

1515
afterEach(async () => {
16-
await remove(tmpDir);
16+
await rm(tmpDir, { recursive: true, force: true });
1717
});
1818

1919
describe('generateOauth', () => {
2020
it('creates src/oauth/index.ts', async () => {
2121
const { generateOauth } = await import('./oauth.js');
2222
await generateOauth(tmpDir, options);
23-
expect(await pathExists(join(tmpDir, 'src/oauth/index.ts'))).toBe(true);
23+
expect(await access(join(tmpDir, 'src/oauth/index.ts')).then(() => true, () => false)).toBe(true);
2424
});
2525

2626
it('exports a default Express Router', async () => {

src/generators/node/webhooks.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { afterEach, describe, expect, it } from 'vitest';
2-
import { pathExists, readFile, remove } from 'fs-extra';
2+
import { access, readFile, rm } from 'node:fs/promises';
33
import { join } from 'path';
44
import { tmpdir } from 'os';
55
import type { GeneratorOptions } from '../interface.js';
66

77
const tmpDir = join(tmpdir(), 'cpa-webhooks-test');
8+
const exists = (p: string) => access(p).then(() => true, () => false);
89

910
afterEach(async () => {
10-
await remove(tmpDir);
11+
await rm(tmpDir, { recursive: true, force: true });
1112
});
1213

1314
describe('generateWebhooks', () => {
@@ -20,7 +21,7 @@ describe('generateWebhooks', () => {
2021
appExtensions: [],
2122
};
2223
await generateWebhooks(tmpDir, options);
23-
expect(await pathExists(join(tmpDir, 'src/webhooks/index.ts'))).toBe(true);
24+
expect(await exists(join(tmpDir, 'src/webhooks/index.ts'))).toBe(true);
2425
});
2526

2627
it('exports a default Express Router', async () => {

src/prompts/projectName.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ describe('promptProjectName', () => {
2828
vi.mocked(clack.text).mockResolvedValue(Symbol('cancel') as never);
2929
vi.mocked(clack.isCancel).mockReturnValue(true);
3030
vi.mocked(clack.cancel).mockImplementation(() => {});
31-
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => undefined as never);
31+
const exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {
32+
throw new Error('process.exit');
33+
});
3234
const { promptProjectName } = await import('./projectName.js');
33-
await promptProjectName();
35+
await expect(promptProjectName()).rejects.toThrow('process.exit');
3436
expect(exitSpy).toHaveBeenCalledWith(0);
3537
});
3638
});

src/utils/writeFile.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import { afterEach, describe, expect, it } from 'vitest';
2-
import { pathExists, readFile, remove } from 'fs-extra';
2+
import { access, readFile, rm } from 'node:fs/promises';
33
import { join } from 'path';
44
import { tmpdir } from 'os';
55

66
const tmpDir = join(tmpdir(), 'cpa-writefile-test');
77

88
afterEach(async () => {
9-
await remove(tmpDir);
9+
await rm(tmpDir, { recursive: true, force: true });
1010
});
1111

1212
describe('writeFile', () => {
1313
it('creates file and all parent directories', async () => {
1414
const { writeFile } = await import('./writeFile.js');
1515
const filePath = join(tmpDir, 'nested/dir/file.ts');
1616
await writeFile(filePath, 'export const x = 1;');
17-
expect(await pathExists(filePath)).toBe(true);
17+
expect(await access(filePath).then(() => true, () => false)).toBe(true);
1818
});
1919

2020
it('formats TypeScript content with prettier', async () => {

0 commit comments

Comments
 (0)