diff --git a/cjs/lib.js b/cjs/lib.js
index f873b79..c33ef38 100644
--- a/cjs/lib.js
+++ b/cjs/lib.js
@@ -22,7 +22,7 @@ const cp = require("child_process");
const { execFile, execFileSync } = cp;
/**
* @template T, A, B
- * @typedef {unknown extends T ? A : T extends (void | false | undefined) ? A : B} Conditional
+ * @typedef {void extends T ? A : T extends (void | false | undefined) ? A : B} Conditional
*/
/**
* @template R
@@ -37,37 +37,40 @@ const { execFile, execFileSync } = cp;
*/
const defaultLocale = "en_US";
/**
+ * @typedef {cp.ExecFileException} ExecFileException
* @typedef {"defaults" | "locale" | "wmic"} TLocalCmdToken
+ * @typedef TExecuteCmdOpt
+ * @prop {true} [async]
+ * @prop {TLocalCmdToken} command
+ * @prop {readonly string[]} [args]
*/
/**
- * execute command by execFile
- *
- * more details see {@link https://nodejs.org/api/child_process.html#child_process_child_process_execfile_file_args_options_callback child_process.execFile}
- *
- * @param {TLocalCmdToken} command
- * @param {readonly string[]} [args]
- */
-const getStdOut = (command, args) => new Promise((resolve) => {
- execFile(command, args /*, execOpt*/, (err, stdout /*, stderr*/) => {
- resolve(err || stdout);
- });
-});
-/**
- * execute command by execFileSync
- *
- * more details see {@link https://nodejs.org/api/child_process.html#child_process_child_process_execfilesync_file_args_options child_process.execFileSync}
- *
- * @param {TLocalCmdToken} command
- * @param {readonly string[]} [args]
+ * @template {TExecuteCmdOpt} P
+ * @template {Conditional
>} R
+ * @param {P} options
+ * @returns {R}
+ * @date 2024-01-03
*/
-const getStdOutSync = (command, args) => {
- try {
- return execFileSync(command, args /*, execOpt*/);
+function execCommand(options) {
+ const { async, command, args } = options;
+ if (async) {
+ /** @type {Promise} */
+ const p = new Promise((resolve) => {
+ execFile(command, args, (err, stdout) => {
+ resolve(err || stdout);
+ });
+ });
+ return /** @type {R} */ (p);
}
- catch (e) {
- return e;
+ else {
+ try {
+ return /** @type {R} */ (execFileSync(command, args /*, execOpt*/));
+ }
+ catch (e) {
+ return e;
+ }
}
-};
+}
/**
* If an exception occurs while executing command such as
* `locale`, `wmic os get locale` the result cannot be applied,
@@ -77,7 +80,7 @@ const getStdOutSync = (command, args) => {
*
* @todo latest error cache
* @param {string | any} result `string` or `Error` object
- * @param {(result: string) => TBD} [processor] If `result` is a `string`, delegate processing
+ * @param {(result: string) => string} [processor] If `result` is a `string`, delegate processing
*/
function validate(result, processor) {
if (typeof result === "string" && result.length) {
@@ -123,7 +126,10 @@ exports.purgeExtraToken = pet;
* @param {string} locales result of command `locale -a`
*/
const getSupportedLocale = (locale, locales) => locales.includes(locale) ? locale : /* istanbul ignore next */ defaultLocale;
-const [getAppleLocale, getAppleLocaleSync] = /** @type {(a: TLocalCmdToken, b: string[], c: TLocalCmdToken, d: string[]) => TAsyncSyncPair} */ ((cmd0, args0, cmd1, args1) => {
+/**
+ * @typedef {(a: TLocalCmdToken, b: string[], c: TLocalCmdToken, d: string[]) => TAsyncSyncPair} TAppleLocaleFunctions
+ */
+const [getAppleLocale, getAppleLocaleSync] = /** @type {TAppleLocaleFunctions} */ ((cmd0, args0, cmd1, args1) => {
return [
/**
* Locale detection for MAC OS
@@ -131,15 +137,29 @@ const [getAppleLocale, getAppleLocaleSync] = /** @type {(a: TLocalCmdToken, b: s
*/
async () => {
const results = await Promise.all([
- getStdOut(cmd0, args0).then(ret => validate(ret)),
- getStdOut(cmd1, args1).then(ret => validate(ret))
+ execCommand({
+ async: true,
+ command: cmd0,
+ args: args0
+ }).then(ret => validate(ret)),
+ execCommand({
+ async: true,
+ command: cmd1,
+ args: args1
+ }).then(ret => validate(ret)),
]);
return getSupportedLocale(results[0], results[1]);
},
/**
* Locale detection for MAC OS
*/
- () => getSupportedLocale(validate(getStdOutSync(cmd0, args0)), validate(getStdOutSync(cmd1, args1)))
+ () => getSupportedLocale(validate(execCommand({
+ command: cmd0,
+ args: args0
+ })), validate(execCommand({
+ command: cmd1,
+ args: args1
+ })))
];
})("defaults", ["read", "-globalDomain", "AppleLocale"], "locale", ["-a"]);
const [getUnixLocale, getUnixLocaleSync] = /** @type {(cmd: TLocalCmdToken) => TAsyncSyncPair} */ ((cmd) => {
@@ -148,11 +168,14 @@ const [getUnixLocale, getUnixLocaleSync] = /** @type {(cmd: TLocalCmdToken) => T
* Locale detection for UNIX OS related
* @async
*/
- async () => pet(parseLocale(await getStdOut(cmd).then(ret => validate(ret)))),
+ async () => pet(parseLocale(await execCommand({
+ async: true,
+ command: cmd
+ }).then(ret => validate(ret)))),
/**
* Locale detection for UNIX OS related
*/
- () => pet(parseLocale(validate(getStdOutSync(cmd))))
+ () => pet(parseLocale(validate(execCommand({ command: cmd }))))
];
})("locale");
/**
@@ -164,6 +187,7 @@ const parseLCID = (result) => {
return lcid.from(lcidCode) || defaultLocale;
};
const [getWinLocale, getWinLocaleSync] = /** @type {(a: TLocalCmdToken, b: string[]) => TAsyncSyncPair} */ ((cmd0, args0) => {
+ const opt = { command: cmd0, args: args0 };
return [
/**
* Locale detection for windows OS
@@ -172,11 +196,11 @@ const [getWinLocale, getWinLocaleSync] = /** @type {(a: TLocalCmdToken, b: strin
*
* @async
*/
- async () => validate(await getStdOut(cmd0, args0), parseLCID),
+ async () => validate(await execCommand(opt), parseLCID),
/**
* Locale detection for windows OS
*/
- () => validate(getStdOutSync(cmd0, args0), parseLCID)
+ () => validate(execCommand(opt), parseLCID)
];
})("wmic", ["os", "get", "locale"]);
/** @type {[ TGetLocaleFunctions, TGetLocaleFunctions> ]} */
diff --git a/esm/lib.js b/esm/lib.js
index 46b7477..5cf9ec1 100644
--- a/esm/lib.js
+++ b/esm/lib.js
@@ -19,7 +19,7 @@ import * as cp from "child_process";
const { execFile, execFileSync } = cp;
/**
* @template T, A, B
- * @typedef {unknown extends T ? A : T extends (void | false | undefined) ? A : B} Conditional
+ * @typedef {void extends T ? A : T extends (void | false | undefined) ? A : B} Conditional
*/
/**
* @template R
@@ -34,37 +34,40 @@ const { execFile, execFileSync } = cp;
*/
const defaultLocale = "en_US";
/**
+ * @typedef {cp.ExecFileException} ExecFileException
* @typedef {"defaults" | "locale" | "wmic"} TLocalCmdToken
+ * @typedef TExecuteCmdOpt
+ * @prop {true} [async]
+ * @prop {TLocalCmdToken} command
+ * @prop {readonly string[]} [args]
*/
/**
- * execute command by execFile
- *
- * more details see {@link https://nodejs.org/api/child_process.html#child_process_child_process_execfile_file_args_options_callback child_process.execFile}
- *
- * @param {TLocalCmdToken} command
- * @param {readonly string[]} [args]
- */
-const getStdOut = (command, args) => new Promise((resolve) => {
- execFile(command, args /*, execOpt*/, (err, stdout /*, stderr*/) => {
- resolve(err || stdout);
- });
-});
-/**
- * execute command by execFileSync
- *
- * more details see {@link https://nodejs.org/api/child_process.html#child_process_child_process_execfilesync_file_args_options child_process.execFileSync}
- *
- * @param {TLocalCmdToken} command
- * @param {readonly string[]} [args]
+ * @template {TExecuteCmdOpt} P
+ * @template {Conditional>} R
+ * @param {P} options
+ * @returns {R}
+ * @date 2024-01-03
*/
-const getStdOutSync = (command, args) => {
- try {
- return execFileSync(command, args /*, execOpt*/);
+function execCommand(options) {
+ const { async, command, args } = options;
+ if (async) {
+ /** @type {Promise} */
+ const p = new Promise((resolve) => {
+ execFile(command, args, (err, stdout) => {
+ resolve(err || stdout);
+ });
+ });
+ return /** @type {R} */ (p);
}
- catch (e) {
- return e;
+ else {
+ try {
+ return /** @type {R} */ (execFileSync(command, args /*, execOpt*/));
+ }
+ catch (e) {
+ return e;
+ }
}
-};
+}
/**
* If an exception occurs while executing command such as
* `locale`, `wmic os get locale` the result cannot be applied,
@@ -74,7 +77,7 @@ const getStdOutSync = (command, args) => {
*
* @todo latest error cache
* @param {string | any} result `string` or `Error` object
- * @param {(result: string) => TBD} [processor] If `result` is a `string`, delegate processing
+ * @param {(result: string) => string} [processor] If `result` is a `string`, delegate processing
*/
function validate(result, processor) {
if (typeof result === "string" && result.length) {
@@ -120,7 +123,10 @@ export const purgeExtraToken = pet;
* @param {string} locales result of command `locale -a`
*/
const getSupportedLocale = (locale, locales) => locales.includes(locale) ? locale : /* istanbul ignore next */ defaultLocale;
-const [getAppleLocale, getAppleLocaleSync] = /** @type {(a: TLocalCmdToken, b: string[], c: TLocalCmdToken, d: string[]) => TAsyncSyncPair} */ ((cmd0, args0, cmd1, args1) => {
+/**
+ * @typedef {(a: TLocalCmdToken, b: string[], c: TLocalCmdToken, d: string[]) => TAsyncSyncPair} TAppleLocaleFunctions
+ */
+const [getAppleLocale, getAppleLocaleSync] = /** @type {TAppleLocaleFunctions} */ ((cmd0, args0, cmd1, args1) => {
return [
/**
* Locale detection for MAC OS
@@ -128,15 +134,29 @@ const [getAppleLocale, getAppleLocaleSync] = /** @type {(a: TLocalCmdToken, b: s
*/
async () => {
const results = await Promise.all([
- getStdOut(cmd0, args0).then(ret => validate(ret)),
- getStdOut(cmd1, args1).then(ret => validate(ret))
+ execCommand({
+ async: true,
+ command: cmd0,
+ args: args0
+ }).then(ret => validate(ret)),
+ execCommand({
+ async: true,
+ command: cmd1,
+ args: args1
+ }).then(ret => validate(ret)),
]);
return getSupportedLocale(results[0], results[1]);
},
/**
* Locale detection for MAC OS
*/
- () => getSupportedLocale(validate(getStdOutSync(cmd0, args0)), validate(getStdOutSync(cmd1, args1)))
+ () => getSupportedLocale(validate(execCommand({
+ command: cmd0,
+ args: args0
+ })), validate(execCommand({
+ command: cmd1,
+ args: args1
+ })))
];
})("defaults", ["read", "-globalDomain", "AppleLocale"], "locale", ["-a"]);
const [getUnixLocale, getUnixLocaleSync] = /** @type {(cmd: TLocalCmdToken) => TAsyncSyncPair} */ ((cmd) => {
@@ -145,11 +165,14 @@ const [getUnixLocale, getUnixLocaleSync] = /** @type {(cmd: TLocalCmdToken) => T
* Locale detection for UNIX OS related
* @async
*/
- async () => pet(parseLocale(await getStdOut(cmd).then(ret => validate(ret)))),
+ async () => pet(parseLocale(await execCommand({
+ async: true,
+ command: cmd
+ }).then(ret => validate(ret)))),
/**
* Locale detection for UNIX OS related
*/
- () => pet(parseLocale(validate(getStdOutSync(cmd))))
+ () => pet(parseLocale(validate(execCommand({ command: cmd }))))
];
})("locale");
/**
@@ -161,6 +184,7 @@ const parseLCID = (result) => {
return lcid.from(lcidCode) || defaultLocale;
};
const [getWinLocale, getWinLocaleSync] = /** @type {(a: TLocalCmdToken, b: string[]) => TAsyncSyncPair} */ ((cmd0, args0) => {
+ const opt = { command: cmd0, args: args0 };
return [
/**
* Locale detection for windows OS
@@ -169,11 +193,11 @@ const [getWinLocale, getWinLocaleSync] = /** @type {(a: TLocalCmdToken, b: strin
*
* @async
*/
- async () => validate(await getStdOut(cmd0, args0), parseLCID),
+ async () => validate(await execCommand(opt), parseLCID),
/**
* Locale detection for windows OS
*/
- () => validate(getStdOutSync(cmd0, args0), parseLCID)
+ () => validate(execCommand(opt), parseLCID)
];
})("wmic", ["os", "get", "locale"]);
/** @type {[ TGetLocaleFunctions, TGetLocaleFunctions> ]} */