Skip to content

Commit fb642a3

Browse files
author
lukasz.klejszta
committed
feat: example generator v2
1 parent 2564054 commit fb642a3

File tree

3 files changed

+90
-32
lines changed

3 files changed

+90
-32
lines changed

packages/falso/src/lib/abbreviation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { data } from './abbreviation.json';
1313
* @example
1414
*
1515
* randAbbreviation({ length: 10 })
16-
*
16+
*
1717
* @automaticallyGeneratedExamples
1818
* @example
1919
* SCSI

packages/falso/src/lib/account.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ export interface AccountOptions extends FakeOptions {
2121
*
2222
* randAccount({ length: 10 })
2323
*
24+
* @automaticallyGeneratedExamples
25+
* @example
26+
* 752923821
27+
* 334864247
28+
* 556647372
2429
*/
30+
2531
export function randAccount<Options extends AccountOptions = never>(
2632
options?: Options
2733
) {

scripts/example-generator.js

Lines changed: 83 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,91 @@
11
const fs = require('fs');
22

3-
const [libDirectoryPath] = process.argv.slice(2);
3+
const [directoryPath] = process.argv.slice(2);
44
const GENERATE_INDICATOR = "@automaticallyGeneratedExamples"
5-
// https://regex101.com/r/rlqGTA/1
6-
const regexp = new RegExp(`(${GENERATE_INDICATOR}).*\\/`,"gs");
7-
const errors = [];
5+
// https://regex101.com/r/qxpfyX/1
6+
const regexp = new RegExp(`(${GENERATE_INDICATOR}).*[*]\\/`,"gs");
87

98
console.log('Generating examples...')
10-
const filenames = fs
11-
.readdirSync(libDirectoryPath)
12-
.filter((jsonFilename, index, array) => jsonFilename.includes(".json") && array.find(tsFilename => tsFilename.replace('ts','json') === jsonFilename))
13-
14-
filenames.forEach(filename => {
15-
try {
16-
const tsFilepath = `${libDirectoryPath}${filename.replace('json','ts')}`
17-
const tsFileContent = fs.readFileSync(tsFilepath).toString();
18-
if(!tsFileContent.includes(GENERATE_INDICATOR)) {
19-
console.log(`file is missing '${GENERATE_INDICATOR}' and will be ignored ${filename.replace('json','ts')}`);
20-
return;
21-
}
22-
const jsonFilepath = `${libDirectoryPath}${filename}`
23-
const jsonFileContent = JSON.parse(fs.readFileSync(jsonFilepath));
24-
if(jsonFileContent.data === undefined) {
25-
throw Error(`missing data field in file: ${filename}`);
26-
}
27-
if(!(jsonFileContent.data instanceof Array)) {
28-
throw Error(`invalid data field, must be an array: ${filename}`);
29-
}
30-
fs.writeFileSync(tsFilepath, tsFileContent.replace(regexp, `${GENERATE_INDICATOR}\n * @example\n${jsonFileContent.data.slice(0,3).map(example => ` * ${example}\n`).join('')} */`));
31-
} catch(error) {
32-
errors.push({filename, error});
9+
10+
const ERRORS = {
11+
missingIndicatorProperty: `'${GENERATE_INDICATOR}' is missing in jsdoc`,
12+
tsFileDoesNotExists: `corresponding ts file does not exists`,
13+
missingJsonDataField: `'json.data' field is missing`,
14+
jsonDataFieldValueMustBeArray: "'json.data' field value is not array",
15+
jsonDataMustNotBeEmptyArray: "'json.data' field value is empty array",
16+
tsFileDoesNotContainRandFunction: "ts file must contain function which name starts with 'rand'"
17+
};
18+
19+
const getFileContent = (filepath) => {
20+
try {
21+
return fs.readFileSync(filepath).toString()
22+
} catch(error) {
23+
if(error.message.startsWith("ENOENT")) {
24+
return null;
3325
}
34-
});
26+
throw error;
27+
}
28+
};
3529

36-
if(errors.length > 0) {
37-
console.log(errors);
30+
const getExamplesFromJson = (json) => {
31+
if(json.data === undefined) {
32+
return [null, ERRORS.missingJsonDataField];
33+
}
34+
if(!(json.data instanceof Array)) {
35+
return [null, ERRORS.jsonDataFieldValueMustBeArray]
36+
}
37+
const examples = json.data.slice(0,3);
38+
if(examples.length === 0) {
39+
return [null, ERRORS.jsonDataMustNotBeEmptyArray]
3840
}
39-
console.log(`Generating examples finished ${filenames.length - errors.length}/${filenames.length}`);
41+
return [examples, null];
42+
};
43+
44+
45+
const getExamplesFromTs = (tsContent) => {
46+
const [,randFunction] = Object.entries(tsContent).find(([key]) => key.startsWith('rand'));
47+
if(randFunction === undefined || typeof randFunction !== 'function') {
48+
return [null, ERRORS.tsFileDoesNotContainRandFunction]
49+
}
50+
return [Array.from({ length: 3 }, randFunction), null]
51+
};
52+
53+
const directoryFilenames = fs.readdirSync(directoryPath)
54+
.map(filename => filename.split('.')[0])
55+
.filter((filename, index, filenames) => filenames.indexOf(filename) === index);
56+
57+
58+
const errors = directoryFilenames.reduce((acc, filename) => {
59+
const basePath = `${directoryPath}${filename}`
60+
const filePath = {
61+
ts: `${basePath}.ts`,
62+
json: `${basePath}.json`,
63+
};
64+
const tsFileContent = getFileContent(filePath.ts);
65+
if(tsFileContent === null) {
66+
acc[ERRORS.tsFileDoesNotExists].push(filename);
67+
return acc;
68+
}
69+
if(!tsFileContent.includes(GENERATE_INDICATOR)) {
70+
acc[ERRORS.missingIndicatorProperty].push(filename);
71+
return acc;
72+
}
73+
const jsonFileContent = getFileContent(filePath.json);
74+
const [examples, error] = jsonFileContent === null
75+
? getExamplesFromTs(require(`../${basePath}`))
76+
: getExamplesFromJson(JSON.parse(jsonFileContent));
77+
if(error !== null) {
78+
acc[error].push(filename);
79+
return acc;
80+
}
81+
82+
const replacement = `${GENERATE_INDICATOR}\n * @example\n${examples.map(example => ` * ${example}\n`).join('')} */`
83+
fs.writeFileSync(`${basePath}.ts`, tsFileContent.replace(regexp, replacement));
84+
return acc;
85+
}, Object.values(ERRORS).reduce((acc, errorText) => ({...acc, [errorText]: []}), {}));
86+
87+
console.log(Object.entries(errors).reduce((acc, [key, value]) => `${acc}--> ${value.length} - ${key}:\n [${value.join(', ')}]\n` ,'<<-- Generator Errors -->>\n'));
88+
console.log(`<<-- Generator Result -->>
89+
--> generated: ${directoryFilenames.length - Object.values(errors).flat().length}
90+
--> files: ${directoryFilenames.length}`);
91+

0 commit comments

Comments
 (0)