Skip to content

Commit 0f61f18

Browse files
committed
fix: used async API from fs
1 parent ed9fcdd commit 0f61f18

File tree

9 files changed

+65
-46
lines changed

9 files changed

+65
-46
lines changed

src/cli/configuration.ts

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* eslint-disable @typescript-eslint/no-non-null-assertion */
2-
import { existsSync, mkdirSync, statSync } from 'fs';
2+
import { promises as fs } from 'fs';
33
import { isAbsolute, resolve } from 'path';
44
import { EndpointConfiguration, Logger } from './shared.js';
5+
import { exists as exists } from './file-system-helper.js';
56

67
export class Configuration {
78

@@ -33,11 +34,11 @@ export class Configuration {
3334
throw new Error('When providing a configuration file, the --config needs to be the first CLI argument.');
3435
}
3536
const configPath = resolve(process.cwd(), args[i + 1]);
36-
if (!existsSync(configPath) || !statSync(configPath).isFile()) {
37+
if (!await exists(configPath) || !(await fs.stat(configPath)).isFile()) {
3738
throw new Error(`The config file "${configPath}" does not exist.`);
3839
}
3940
// eslint-disable-next-line @typescript-eslint/no-var-requires
40-
instance.applyConfiguration(await require(configPath) as ConfigSchema);
41+
await instance.applyConfiguration(await require(configPath) as ConfigSchema);
4142
break;
4243
}
4344
case 'endpoint':
@@ -47,7 +48,7 @@ export class Configuration {
4748
instance.setEndpoints(JSON.parse(args[i + 1]) as string | EndpointConfiguration[]);
4849
break;
4950
case 'outputDir': {
50-
instance.setOutputDir(args[i + 1], true);
51+
await instance.setOutputDir(args[i + 1], true);
5152
break;
5253
}
5354
case 'quoteStyle':
@@ -78,8 +79,8 @@ export class Configuration {
7879

7980
private constructor() { /* noop */ }
8081

81-
private applyConfiguration(config: ConfigSchema) {
82-
this.setOutputDir(config.outputDir, false);
82+
private async applyConfiguration(config: ConfigSchema) {
83+
await this.setOutputDir(config.outputDir, false);
8384
this.setEndpointsFromConfig(config);
8485
this.setQuote(config.quoteStyle);
8586
this.setIndentation(config.indentSize);
@@ -110,12 +111,12 @@ export class Configuration {
110111
this.adjustOutputPaths();
111112
}
112113

113-
private setOutputDir(outputDir: string | undefined, throwError: boolean) {
114+
private async setOutputDir(outputDir: string | undefined, throwError: boolean) {
114115
if (!outputDir) { return; }
115116
const absolutePath: string = resolve(process.cwd(), outputDir);
116-
if (!existsSync(absolutePath)) {
117-
mkdirSync(absolutePath, { recursive: true });
118-
} else if (throwError && !statSync(absolutePath).isDirectory()) {
117+
if (!await exists(absolutePath)) {
118+
await fs.mkdir(absolutePath, { recursive: true });
119+
} else if (throwError && !(await fs.stat(absolutePath)).isDirectory()) {
119120
throw new Error(`The output path "${absolutePath}" is not a directory.`);
120121
}
121122
this.outputDir = absolutePath;

src/cli/file-system-helper.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { promises } from 'fs';
2+
3+
/**
4+
* Checks if a file or directory exists.
5+
* @param path
6+
* @returns `true` if the file or directory exists, `false` otherwise.
7+
*/
8+
export async function exists(path: string): Promise<boolean> {
9+
try {
10+
await promises.access(path);
11+
return true;
12+
} catch {
13+
return false;
14+
}
15+
}

src/cli/generator.ts

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable @typescript-eslint/no-non-null-assertion */
2-
import { existsSync, writeFileSync, mkdirSync } from 'fs';
2+
import { promises as fs } from 'fs';
33
import { EOL } from 'os';
44
import { dirname } from 'path';
55
// eslint-disable-next-line @typescript-eslint/no-shadow
@@ -18,6 +18,7 @@ import {
1818
ComplexTypeInfoSet,
1919
} from './shared.js';
2020
import { EdmTemplate, EndpointTemplate } from './templates.js';
21+
import { exists } from './file-system-helper.js';
2122

2223
// interface ImportInfo { ns: string; type: string; }
2324

@@ -94,7 +95,7 @@ export class $Generator {
9495
private readonly endpointTemplate = new EndpointTemplate();
9596
private readonly edmTemplate = new EdmTemplate();
9697

97-
public generateEdm(metadata: string, endpoints: Endpoint[], configuration: EndpointConfiguration): void {
98+
public async generateEdm(metadata: string, endpoints: Endpoint[], configuration: EndpointConfiguration): Promise<void> {
9899
const parsed = new DOMParser()
99100
.parseFromString(metadata, 'application/xml')
100101
.documentElement;
@@ -104,17 +105,17 @@ export class $Generator {
104105
}
105106
const edmInfo = this.generateCodeContent(parsed, endpoints, configuration);
106107
if (edmInfo !== null) {
107-
this.generateEdmFile(edmInfo);
108+
await this.generateEdmFile(edmInfo);
108109
}
109110
}
110111

111-
public generateEndpointsFile(endpoints: Endpoint[], configuration: EndpointConfiguration): void {
112+
public async generateEndpointsFile(endpoints: Endpoint[], configuration: EndpointConfiguration): Promise<void> {
112113
const path = getEndpointsPath(configuration);
113114
const dirName = dirname(path);
114-
if (!existsSync(dirName)) {
115-
mkdirSync(dirName, { recursive: true });
115+
if (!await exists(dirName)) {
116+
await fs.mkdir(dirName, { recursive: true });
116117
}
117-
writeFileSync(path, this.endpointTemplate.render(endpoints));
118+
await fs.writeFile(path, this.endpointTemplate.render(endpoints));
118119
}
119120

120121
private generateStringEnum(acc: EnumInfo[], enumType: Element, ignored: string[]): EnumInfo[] {
@@ -177,17 +178,17 @@ export class $Generator {
177178
return new EdmInfo(schema.getAttribute('Namespace')!, /* imports, */ entities, $complexTypes, enums, configuration);
178179
}
179180

180-
private generateEdmFile(edmInfo: EdmInfo) {
181+
private async generateEdmFile(edmInfo: EdmInfo) {
181182
const filePath = edmInfo.filePath;
182183

183184
const dirName = dirname(filePath);
184-
if (!existsSync(dirName)) {
185-
mkdirSync(dirName, { recursive: true });
185+
if (!await exists(dirName)) {
186+
await fs.mkdir(dirName, { recursive: true });
186187
}
187188

188189
const template = this.edmTemplate;
189190
const content = template.render(edmInfo);
190-
writeFileSync(filePath, content);
191+
await fs.writeFile(filePath, content);
191192
}
192193

193194
private generateEntityInfo(

src/cli/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ Options:
5151
const baseEndpoint = ep.url;
5252
const { value: endpoints } = JSON.parse(await getData(baseEndpoint)) as { value: Endpoint[] };
5353

54-
generator.generateEndpointsFile(endpoints, ep);
54+
await generator.generateEndpointsFile(endpoints, ep);
5555
Logger.info(`generated endpoints for ${baseEndpoint}.`);
5656

57-
generator.generateEdm(await getData(`${baseEndpoint}/$metadata`), endpoints, ep);
57+
await generator.generateEdm(await getData(`${baseEndpoint}/$metadata`), endpoints, ep);
5858
Logger.info(`generated EDM for ${baseEndpoint}.`);
5959
}
6060
} finally {

tests/generator.spec.ts

+25-23
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,32 @@
44
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
55
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
66
import { assert } from 'chai';
7-
import { red, green, gray } from 'colorette';
7+
import { gray, green, red } from 'colorette';
88
import { diffLines } from 'diff';
9-
import { existsSync, readdirSync, readFileSync } from 'fs';
9+
import { Dirent, promises as fs } from 'fs';
1010
import mockFs from 'mock-fs';
1111
import type { DirectoryItems } from 'mock-fs/lib/filesystem';
1212
import { join } from 'path';
13-
// eslint-disable-next-line @typescript-eslint/no-shadow
14-
import { URL } from 'url';
13+
import { URL } from 'node:url';
1514
import { v4 as uuid } from 'uuid';
1615
import { Configuration } from '../src/cli/configuration.js';
1716
import { $Generator } from '../src/cli/generator.js';
1817
import { Endpoint, EndpointConfiguration } from '../src/cli/shared.js';
18+
import { exists } from '../src/cli/file-system-helper.js';
1919

2020
const __dirname = process.cwd();
2121

2222
describe('generator', function () {
2323

24-
function readAllContent(path: string): Map<string, string> {
24+
async function readAllContent(path: string): Promise<Map<string, string>> {
2525
const result = new Map<string, string>();
26-
for (const dirent of readdirSync(path, { encoding: 'utf8', withFileTypes: true })) {
26+
for (const dirent of await fs.readdir(path, { encoding: 'utf8', withFileTypes: true })) {
2727
const entryName = dirent.name;
2828
const completePath = join(path, entryName);
2929
if (dirent.isFile()) {
30-
result.set(entryName, readFileSync(completePath, 'utf8'));
30+
result.set(entryName, await fs.readFile(completePath, 'utf8'));
3131
} else {
32-
const content = readAllContent(completePath);
32+
const content = await readAllContent(completePath);
3333
for (const [key, value] of content) {
3434
result.set(join(entryName, key), value);
3535
}
@@ -65,12 +65,14 @@ describe('generator', function () {
6565
}
6666

6767
const dataPath = join(__dirname, 'tests', 'data');
68-
for (const dirent of
69-
readdirSync(dataPath, { encoding: 'utf8', withFileTypes: true })
70-
.filter((x) => x.isDirectory())
71-
) {
68+
let directoryEntries: Dirent[] = [];
69+
before(async function () {
70+
directoryEntries = (await fs.readdir(dataPath, { encoding: 'utf8', withFileTypes: true }))
71+
.filter((x) => x.isDirectory());
72+
});
73+
for (const dirent of directoryEntries) {
7274
const dirName = dirent.name;
73-
it(`works for ${dirName}`, async function () {
75+
it.only(`works for ${dirName}`, async function () {
7476
let generator: $Generator | null = null;
7577
try {
7678
// arrange
@@ -84,36 +86,36 @@ describe('generator', function () {
8486
let configuredEndpoints: EndpointConfiguration[] | undefined = undefined;
8587
let hasConfiguredEndpoints = false;
8688
const args = ['--outputDir', baseOutputPath];
87-
if (existsSync(configFilePath)) {
89+
if (await exists(configFilePath)) {
8890
args.unshift('--config', configFilePath);
8991
mockFsConfig[configFilePath] = mockFs.load(configFilePath);
90-
// eslint-disable-next-line @typescript-eslint/no-var-requires
91-
configuredEndpoints = (await import(configFilePath)).endpoints;
92+
configuredEndpoints = (await import(`file:///${configFilePath}`)).endpoints;
9293
hasConfiguredEndpoints = Array.isArray(configuredEndpoints) && configuredEndpoints.length > 0;
9394
}
9495
if (!hasConfiguredEndpoints) {
9596
args.push('--endpoint', 'https://api.example.com');
9697
}
97-
const expected = readAllContent(join(caseDir, 'expected'));
98+
const expected = await readAllContent(join(caseDir, 'expected'));
9899
mockFs(mockFsConfig, { createCwd: true });
99100
const configuration = await Configuration.createFromCLIArgs(args);
100101
generator = new $Generator();
101102

102103
for (const ep of configuration.endpoints) {
103104
let epInput = join(inputDir, new URL(ep.url).hostname);
104-
epInput = mockFs.bypass(() => existsSync(epInput)) ? epInput : inputDir;
105+
epInput = await exists(epInput) ? epInput : inputDir;
105106

106-
const edmxXml = mockFs.bypass(() => readFileSync(join(epInput, 'metadata.xml'), 'utf8'));
107+
const edmxXml = await fs.readFile(join(epInput, 'metadata.xml'), 'utf8');
108+
console.log('[test] edmxXml', edmxXml);
107109
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
108-
const endpoints: Endpoint[] = mockFs.bypass(() => JSON.parse(readFileSync(join(epInput, 'endpoints.json'), 'utf8')).value);
110+
const endpoints: Endpoint[] = JSON.parse(await fs.readFile(join(epInput, 'endpoints.json'), 'utf8')).value;
109111

110112
// act
111-
generator.generateEndpointsFile(endpoints, ep);
112-
generator.generateEdm(edmxXml, endpoints, ep);
113+
await generator.generateEndpointsFile(endpoints, ep);
114+
await generator.generateEdm(edmxXml, endpoints, ep);
113115
}
114116

115117
// assert
116-
const actual = readAllContent(baseOutputPath);
118+
const actual = await readAllContent(baseOutputPath);
117119
assertContent(actual, expected);
118120
} catch (e) {
119121
assert.fail((e as Error).message);

0 commit comments

Comments
 (0)