Skip to content

Commit

Permalink
Merge pull request #11 from jy95/refactoring
Browse files Browse the repository at this point in the history
Allow config file for command to be a CJS file
  • Loading branch information
jy95 authored Sep 18, 2021
2 parents c3fcfec + d28967b commit 8d8d8ef
Show file tree
Hide file tree
Showing 42 changed files with 4,287 additions and 4,378 deletions.
4,779 changes: 1,947 additions & 2,832 deletions package-lock.json

Large diffs are not rendered by default.

42 changes: 24 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@
"node": ">=12"
},
"scripts": {
"start": "tsdx watch",
"build": "tsdx build",
"test": "tsdx test",
"test:coverage": "tsdx test --coverage",
"lint": "tsdx lint",
"lint-fix": "tsdx lint --fix",
"prepare": "tsdx build",
"start": "dts watch",
"build": "dts build",
"test": "dts test",
"test:coverage": "dts test --coverage",
"lint": "dts lint",
"lint-fix": "dts lint --fix",
"prepare": "dts build",
"size": "size-limit",
"analyze": "size-limit --why",
"semantic-release": "semantic-release"
},
"peerDependencies": {},
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
"pre-commit": "dts lint"
}
},
"prettier": {
Expand All @@ -64,15 +64,15 @@
],
"devDependencies": {
"@size-limit/preset-small-lib": "^5.0.3",
"@types/jest": "^26.0.24",
"@types/lodash": "^4.14.172",
"@types/node": "^16.6.1",
"@types/jest": "^27.0.1",
"@types/lodash": "^4.14.173",
"@types/node": "^16.9.2",
"@types/yargs": "^17.0.2",
"dts-cli": "^0.17.1",
"fsify": "^4.0.2",
"husky": "^7.0.2",
"semantic-release": "^17.4.7",
"size-limit": "^5.0.3",
"tsdx": "^0.14.1",
"tslib": "^2.3.1",
"typescript": "^4.4.3"
},
Expand All @@ -82,12 +82,18 @@
"lodash-es": "^4.17.21",
"yargs": "^17.1.1"
},
"resolutions": {
"**/@typescript-eslint/eslint-plugin": "^4.29.1",
"**/@typescript-eslint/parser": "^4.29.1",
"**/jest": "^27.0.6",
"**/ts-jest": "^27.0.4",
"**/typescript": "^4.3.5"
"eslintConfig": {
"overrides": [
{
"files": [
"*.ts",
"*.js"
],
"rules": {
"import/no-anonymous-default-export": "off"
}
}
]
},
"homepage": "https://jy95.github.io/i18n-tools/",
"repository": {
Expand Down
3 changes: 2 additions & 1 deletion src/checks/diff_checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { FILENAME_CHECK } from './export/index';
// For that, we will use "backupKey" from backupPaths : "paths"
const pathsProp = 'paths';
export const AT_LEAST_2_PATHS_CHECK = async (argv: any) => {
return Object.values(argv[pathsProp]).filter(v => v !== undefined).length >= 2
return Object.values(argv[pathsProp]).filter((v) => v !== undefined).length >=
2
? true
: new Error('At least two paths must be provided');
};
Expand Down
111 changes: 56 additions & 55 deletions src/checks/export/export_common_checks.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,67 @@
import fs from "fs";
import path from "path";
import fs from 'fs';
import path from 'path';

// lodash methodes
import isPlainObject from "lodash/isPlainObject";
import isEmpty from "lodash/isEmpty";
import uniq from "lodash/uniq";
import isPlainObject from 'lodash/isPlainObject';
import isEmpty from 'lodash/isEmpty';
import uniq from 'lodash/uniq';

// validation for filename option
export const FILENAME_CHECK = async (argv : any) => {
let filename : unknown = argv["filename"];
if (path.extname(filename as string).length !== 0) {
return new Error(`${filename} has an extension : Remove it please`);
} else {
return true;
}
}
export const FILENAME_CHECK = async (argv: any) => {
let filename: unknown = argv['filename'];
if (path.extname(filename as string).length !== 0) {
return new Error(`${filename} has an extension : Remove it please`);
} else {
return true;
}
};

// validations for files option
export const FILES_CHECK = async (argv : any) => {
let files = argv.files as any;
if (!isPlainObject(files)) {
return new Error("Option files is not a JSON Object");
}
if (isEmpty(files)) {
return new Error("Option files should have at least one entry");
}
let entries : [string, any][] = Object.entries(files);
if (uniq(Object.values(files)).length !== entries.length) {
return new Error(`At least a duplicated value in files JSON object was detected`);
}
return Promise.all(
entries.map(
entry => verify_files_entry(entry)
)
).then(_ => {
// validated
return true;
})
.catch(/* istanbul ignore next */ err => {
// failed
return err;
});
}
export const FILES_CHECK = async (argv: any) => {
let files = argv.files as any;
if (!isPlainObject(files)) {
return new Error('Option files is not a JSON Object');
}
if (isEmpty(files)) {
return new Error('Option files should have at least one entry');
}
let entries: [string, any][] = Object.entries(files);
if (uniq(Object.values(files)).length !== entries.length) {
return new Error(
`At least a duplicated value in files JSON object was detected`
);
}

try {
await Promise.all(entries.map((entry) => verify_files_entry(entry)));
return true;
} catch (error) {
return error as Error;
}
};

// verify if an entry from files option meet requirements
async function verify_files_entry([_, i18nPath] : [string, any]) : Promise<boolean | Error> {
let potentialJSON;
// check if file is readable
try {
await fs.promises.access(i18nPath);
potentialJSON = await fs.promises.readFile(i18nPath);
} catch (error) {
return Promise.reject(`${i18nPath} cannot be read : check permissions`);
}
// check if the file is a JSON
try {
JSON.parse(potentialJSON.toString());
return Promise.resolve(true);
} catch (error) {
return Promise.reject(`${i18nPath} isn't a valid JSON`);
}
async function verify_files_entry([_, i18nPath]: [string, any]): Promise<
boolean | Error
> {
let potentialJSON;
// check if file is readable
try {
await fs.promises.access(i18nPath);
potentialJSON = await fs.promises.readFile(i18nPath);
} catch (error) {
return Promise.reject(
new Error(`${i18nPath} cannot be read : check permissions`)
);
}
// check if the file is a JSON
try {
JSON.parse(potentialJSON.toString());
return Promise.resolve(true);
} catch (error) {
return Promise.reject(new Error(`${i18nPath} isn't a valid JSON`));
}
}

// export checks in expected order into a single array
export const CHECKS = [FILENAME_CHECK, FILES_CHECK];
export const CHECKS = [FILENAME_CHECK, FILES_CHECK];
4 changes: 4 additions & 0 deletions src/checks/export/export_csv_checks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { COLUMNS_CHECK, COLUMNS_AND_FILES_CHECK } from './export_xlsx_checks';

// export checks in expected order into a single array
export const CHECKS = [COLUMNS_CHECK, COLUMNS_AND_FILES_CHECK];
30 changes: 26 additions & 4 deletions src/checks/export/export_xlsx_checks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// lodash methodes
import isString from 'lodash/isString';
import isFunction from 'lodash/isFunction';
import isArray from 'lodash/isArray';
import isEmpty from 'lodash/isEmpty';
import some from 'lodash/some';
Expand All @@ -26,13 +27,14 @@ export const COLUMNS_CHECK = async (argv: any) => {
{
message: (prop: string) =>
`At least one item in columns array doesn't have "${prop}" property`,
errorDetected: (prop: string) => some(columns, item => !has(item, prop)),
errorDetected: (prop: string) =>
some(columns, (item) => !has(item, prop)),
},
{
message: (prop: string) =>
`At least one item in columns array doesn't have "${prop}" property with a String value`,
errorDetected: (prop: string) =>
some(columns, item => !isString(get(item, prop))),
some(columns, (item) => !isString(get(item, prop))),
},
{
message: (prop: string) =>
Expand All @@ -48,7 +50,7 @@ export const COLUMNS_CHECK = async (argv: any) => {
if (acc instanceof Error) {
return acc;
} else {
let error = find(errors_detectors, rule => rule.errorDetected(prop));
let error = find(errors_detectors, (rule) => rule.errorDetected(prop));
if (error) {
return new Error(error.message(prop));
} else {
Expand Down Expand Up @@ -76,5 +78,25 @@ export const COLUMNS_AND_FILES_CHECK = async (argv: any) => {
}
};

// validations for worksheetCustomizer option
export const WORKSHEETCUSTOMIZER_CHECK = async (argv: any) => {
if ('worksheetCustomizer' in argv) {
let fct = argv.worksheetCustomizer as any;
if (isFunction(fct) && fct.length === 1) {
return true;
} else {
return new Error(
"worksheetCustomizer is not an function or doesn't take an single argument"
);
}
} else {
return true;
}
};

// export checks in expected order into a single array
export const CHECKS = [COLUMNS_CHECK, COLUMNS_AND_FILES_CHECK];
export const CHECKS = [
COLUMNS_CHECK,
COLUMNS_AND_FILES_CHECK,
WORKSHEETCUSTOMIZER_CHECK,
];
6 changes: 3 additions & 3 deletions src/checks/export/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// common check for this command
export * from "./export_common_checks";
export * from './export_common_checks';

// check for xlsx sub command
export * as XLSX from "./export_xlsx_checks";
export * as XLSX from './export_xlsx_checks';

// check for csv sub command
// as it is identical (at that time) to xlsx, simply re-export same module
export * as CSV from "./export_xlsx_checks";
export * as CSV from './export_csv_checks';
4 changes: 2 additions & 2 deletions src/checks/import/import_xlsx_checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const COLUMNS_CHECK = async (argv: any) => {
}

// check presence of required properties
let missingProp = find(REQUIRED_PROPERTIES, prop => !has(columns, prop));
let missingProp = find(REQUIRED_PROPERTIES, (prop) => !has(columns, prop));
if (missingProp) {
return new Error(`${missingProp} couldn't be found in columns object`);
}
Expand All @@ -31,7 +31,7 @@ export const COLUMNS_CHECK = async (argv: any) => {
}

// check if locales values all are string
if (!Object.values(columns.locales).every(v => isString(v))) {
if (!Object.values(columns.locales).every((v) => isString(v))) {
return new Error(
"At least one value for locales key in columns object isn't a string"
);
Expand Down
6 changes: 3 additions & 3 deletions src/checks/import/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// common check for this command
export * from "./import_common_checks";
export * from './import_common_checks';

// check for xlsx sub command
export * as XLSX from "./import_xlsx_checks";
export * as XLSX from './import_xlsx_checks';

// check for csv sub command
// as it is identical (at that time) to xlsx, simply re-export same module
export * as CSV from "./import_xlsx_checks";
export * as CSV from './import_xlsx_checks';
38 changes: 19 additions & 19 deletions src/checks/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
// re export stuff for easier import
export * as EXPORT_CHECKS from "./export/index";
export * as IMPORT_CHECKS from "./import/index";
export * as DIFF_CHECKS from "./diff_checks";
export * as EXPORT_CHECKS from './export/index';
export * as IMPORT_CHECKS from './import/index';
export * as DIFF_CHECKS from './diff_checks';

// Yargs parser doesn't stop when issue(s) occurs and only returns last error.
// So I need something that resolves promises sequentially and return first error
// See https://github.com/yargs/yargs/issues/1399
// See https://github.com/yargs/yargs/issues/1975

type PromiseCheck = (argv : any) => Promise<boolean | Error>;
type PromiseCheck = (argv: any) => Promise<boolean | Error>;

export const resolveChecksInOrder = (checks : PromiseCheck[]) => {
return async (argv : any) => {
for(let check of checks) {
try {
//console.log(`Check ${check.name}`); // to make easier debugging in the future
let result = await check(argv);
if (result !== true) {
return result;
}
} catch (error) {
/* istanbul ignore next */
return error;
}
export const resolveChecksInOrder = (checks: PromiseCheck[]) => {
return async (argv: any) => {
for (let check of checks) {
try {
//console.log(`Check ${check.name}`); // to make easier debugging in the future
let result = await check(argv);
if (result !== true) {
return result;
}
return true;
} catch (error) {
/* istanbul ignore next */
return error;
}
}
}
return true;
};
};
Loading

0 comments on commit 8d8d8ef

Please sign in to comment.