1import { argsert } from './argsert.js';
2import { isPromise } from './utils/is-promise.js';
3export class GlobalMiddleware {
4    constructor(yargs) {
5        this.globalMiddleware = [];
6        this.frozens = [];
7        this.yargs = yargs;
8    }
9    addMiddleware(callback, applyBeforeValidation, global = true, mutates = false) {
10        argsert('<array|function> [boolean] [boolean] [boolean]', [callback, applyBeforeValidation, global], arguments.length);
11        if (Array.isArray(callback)) {
12            for (let i = 0; i < callback.length; i++) {
13                if (typeof callback[i] !== 'function') {
14                    throw Error('middleware must be a function');
15                }
16                const m = callback[i];
17                m.applyBeforeValidation = applyBeforeValidation;
18                m.global = global;
19            }
20            Array.prototype.push.apply(this.globalMiddleware, callback);
21        }
22        else if (typeof callback === 'function') {
23            const m = callback;
24            m.applyBeforeValidation = applyBeforeValidation;
25            m.global = global;
26            m.mutates = mutates;
27            this.globalMiddleware.push(callback);
28        }
29        return this.yargs;
30    }
31    addCoerceMiddleware(callback, option) {
32        const aliases = this.yargs.getAliases();
33        this.globalMiddleware = this.globalMiddleware.filter(m => {
34            const toCheck = [...(aliases[option] || []), option];
35            if (!m.option)
36                return true;
37            else
38                return !toCheck.includes(m.option);
39        });
40        callback.option = option;
41        return this.addMiddleware(callback, true, true, true);
42    }
43    getMiddleware() {
44        return this.globalMiddleware;
45    }
46    freeze() {
47        this.frozens.push([...this.globalMiddleware]);
48    }
49    unfreeze() {
50        const frozen = this.frozens.pop();
51        if (frozen !== undefined)
52            this.globalMiddleware = frozen;
53    }
54    reset() {
55        this.globalMiddleware = this.globalMiddleware.filter(m => m.global);
56    }
57}
58export function commandMiddlewareFactory(commandMiddleware) {
59    if (!commandMiddleware)
60        return [];
61    return commandMiddleware.map(middleware => {
62        middleware.applyBeforeValidation = false;
63        return middleware;
64    });
65}
66export function applyMiddleware(argv, yargs, middlewares, beforeValidation) {
67    return middlewares.reduce((acc, middleware) => {
68        if (middleware.applyBeforeValidation !== beforeValidation) {
69            return acc;
70        }
71        if (middleware.mutates) {
72            if (middleware.applied)
73                return acc;
74            middleware.applied = true;
75        }
76        if (isPromise(acc)) {
77            return acc
78                .then(initialObj => Promise.all([initialObj, middleware(initialObj, yargs)]))
79                .then(([initialObj, middlewareObj]) => Object.assign(initialObj, middlewareObj));
80        }
81        else {
82            const result = middleware(acc, yargs);
83            return isPromise(result)
84                ? result.then(middlewareObj => Object.assign(acc, middlewareObj))
85                : Object.assign(acc, result);
86        }
87    }, argv);
88}
89