Skip to content

Commit 8779984

Browse files
committed
✨ feat(core)!: remove the ability to return a callback in inspector
1 parent 7278d88 commit 8779984

File tree

1 file changed

+132
-143
lines changed

1 file changed

+132
-143
lines changed

packages/core/src/utils.ts

Lines changed: 132 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,132 @@
1-
import { arrayStartsWith, toArray } from "@clerc/utils";
2-
import { IS_DENO, IS_ELECTRON, IS_NODE } from "is-platform";
3-
import { typeFlag } from "type-flag";
4-
5-
import type { RootType } from "./cli";
6-
import { Root } from "./cli";
7-
import type {
8-
Command,
9-
CommandAlias,
10-
CommandType,
11-
Commands,
12-
Inspector,
13-
InspectorContext,
14-
InspectorFn,
15-
InspectorObject,
16-
TranslateFn,
17-
} from "./types";
18-
import { CommandNameConflictError } from "./errors";
19-
20-
function setCommand(
21-
commandsMap: Map<string[] | RootType, CommandAlias>,
22-
commands: Commands,
23-
command: Command,
24-
t: TranslateFn,
25-
) {
26-
if (command.alias) {
27-
const aliases = toArray(command.alias);
28-
for (const alias of aliases) {
29-
if (alias in commands) {
30-
throw new CommandNameConflictError(commands[alias]!.name, command.name, t);
31-
}
32-
commandsMap.set(typeof alias === "symbol" ? alias : alias.split(" "), { ...command, __isAlias: true });
33-
}
34-
}
35-
}
36-
37-
export function resolveFlattenCommands(commands: Commands, t: TranslateFn) {
38-
const commandsMap = new Map<string[] | RootType, CommandAlias>();
39-
if (commands[Root]) {
40-
commandsMap.set(Root, commands[Root]);
41-
setCommand(commandsMap, commands, commands[Root], t);
42-
}
43-
for (const command of Object.values(commands)) {
44-
setCommand(commandsMap, commands, command, t);
45-
commandsMap.set(command.name.split(" "), command);
46-
}
47-
return commandsMap;
48-
}
49-
50-
export function resolveCommand(
51-
commands: Commands,
52-
argv: string[],
53-
t: TranslateFn,
54-
): [Command<string | RootType> | undefined, string[] | RootType | undefined] {
55-
const commandsMap = resolveFlattenCommands(commands, t);
56-
for (const [name, command] of commandsMap.entries()) {
57-
const parsed = typeFlag(command?.flags || {}, [...argv]);
58-
const { _: args } = parsed;
59-
if (name === Root) { continue; }
60-
if (arrayStartsWith(args, name)) {
61-
return [command, name];
62-
}
63-
}
64-
if (commandsMap.has(Root)) {
65-
return [commandsMap.get(Root)!, Root];
66-
}
67-
return [undefined, undefined];
68-
}
69-
70-
export const resolveArgv = (): string[] =>
71-
IS_NODE
72-
? process.argv.slice(IS_ELECTRON ? 1 : 2)
73-
: IS_DENO
74-
// @ts-expect-error Ignore
75-
? Deno.args
76-
: [];
77-
78-
export function compose(inspectors: Inspector[]) {
79-
const inspectorMap = {
80-
pre: [] as InspectorFn[],
81-
normal: [] as InspectorFn[],
82-
post: [] as InspectorFn[],
83-
};
84-
for (const inspector of inspectors) {
85-
const objectInspector: InspectorObject = typeof inspector === "object"
86-
? inspector
87-
: { fn: inspector };
88-
const { enforce, fn } = objectInspector;
89-
if (enforce === "post" || enforce === "pre") {
90-
inspectorMap[enforce].push(fn);
91-
} else {
92-
inspectorMap.normal.push(fn);
93-
}
94-
}
95-
96-
const mergedInspectorFns = [
97-
...inspectorMap.pre,
98-
...inspectorMap.normal,
99-
...inspectorMap.post,
100-
];
101-
102-
return (ctx: InspectorContext) => {
103-
const callbacks: (() => void)[] = [];
104-
let called = 0;
105-
const dispatch = (i: number) => {
106-
called = i;
107-
const inspector = mergedInspectorFns[i];
108-
const cb = inspector(ctx, dispatch.bind(null, i + 1));
109-
if (cb) {
110-
callbacks.push(cb);
111-
}
112-
};
113-
dispatch(0);
114-
if (called + 1 === mergedInspectorFns.length) {
115-
for (const cb of callbacks) {
116-
cb();
117-
}
118-
}
119-
};
120-
}
121-
122-
const INVALID_RE = /\s\s+/;
123-
export const isValidName = (name: CommandType) =>
124-
name === Root
125-
? true
126-
: !(name.startsWith(" ") || name.endsWith(" ")) && !INVALID_RE.test(name);
127-
128-
export const withBrackets = (s: string, isOptional?: boolean) => isOptional ? `[${s}]` : `<${s}>`;
129-
130-
const ROOT = "<Root>";
131-
export const formatCommandName = (name: string | string[] | RootType) =>
132-
Array.isArray(name)
133-
? name.join(" ")
134-
: typeof name === "string"
135-
? name
136-
: ROOT;
137-
138-
export const detectLocale = () =>
139-
process.env.CLERC_LOCALE
140-
? process.env.CLERC_LOCALE
141-
: Intl.DateTimeFormat().resolvedOptions().locale;
142-
143-
export const stripFlags = (argv: string[]) => argv.filter(arg => !arg.startsWith("-"));
1+
import { arrayStartsWith, toArray } from "@clerc/utils";
2+
import { IS_DENO, IS_ELECTRON, IS_NODE } from "is-platform";
3+
import { typeFlag } from "type-flag";
4+
5+
import type { RootType } from "./cli";
6+
import { Root } from "./cli";
7+
import { CommandNameConflictError } from "./errors";
8+
import type {
9+
Command,
10+
CommandAlias,
11+
CommandType,
12+
Commands,
13+
Inspector,
14+
InspectorContext,
15+
InspectorFn,
16+
InspectorObject,
17+
TranslateFn,
18+
} from "./types";
19+
20+
function setCommand(
21+
commandsMap: Map<string[] | RootType, CommandAlias>,
22+
commands: Commands,
23+
command: Command,
24+
t: TranslateFn,
25+
) {
26+
if (command.alias) {
27+
const aliases = toArray(command.alias);
28+
for (const alias of aliases) {
29+
if (alias in commands) {
30+
throw new CommandNameConflictError(commands[alias]!.name, command.name, t);
31+
}
32+
commandsMap.set(typeof alias === "symbol" ? alias : alias.split(" "), { ...command, __isAlias: true });
33+
}
34+
}
35+
}
36+
37+
export function resolveFlattenCommands(commands: Commands, t: TranslateFn) {
38+
const commandsMap = new Map<string[] | RootType, CommandAlias>();
39+
if (commands[Root]) {
40+
commandsMap.set(Root, commands[Root]);
41+
setCommand(commandsMap, commands, commands[Root], t);
42+
}
43+
for (const command of Object.values(commands)) {
44+
setCommand(commandsMap, commands, command, t);
45+
commandsMap.set(command.name.split(" "), command);
46+
}
47+
return commandsMap;
48+
}
49+
50+
export function resolveCommand(
51+
commands: Commands,
52+
argv: string[],
53+
t: TranslateFn,
54+
): [Command<string | RootType> | undefined, string[] | RootType | undefined] {
55+
const commandsMap = resolveFlattenCommands(commands, t);
56+
for (const [name, command] of commandsMap.entries()) {
57+
const parsed = typeFlag(command?.flags ?? {}, [...argv]);
58+
const { _: args } = parsed;
59+
if (name === Root) { continue; }
60+
if (arrayStartsWith(args, name)) {
61+
return [command, name];
62+
}
63+
}
64+
if (commandsMap.has(Root)) {
65+
return [commandsMap.get(Root)!, Root];
66+
}
67+
return [undefined, undefined];
68+
}
69+
70+
export const resolveArgv = (): string[] =>
71+
IS_NODE
72+
? process.argv.slice(IS_ELECTRON ? 1 : 2)
73+
: IS_DENO
74+
// @ts-expect-error Ignore
75+
? Deno.args
76+
: [];
77+
78+
export function compose(inspectors: Inspector[]) {
79+
const inspectorMap = {
80+
pre: [] as InspectorFn[],
81+
normal: [] as InspectorFn[],
82+
post: [] as InspectorFn[],
83+
};
84+
for (const inspector of inspectors) {
85+
const objectInspector: InspectorObject = typeof inspector === "object"
86+
? inspector
87+
: { fn: inspector };
88+
const { enforce, fn } = objectInspector;
89+
if (enforce === "post" || enforce === "pre") {
90+
inspectorMap[enforce].push(fn);
91+
} else {
92+
inspectorMap.normal.push(fn);
93+
}
94+
}
95+
96+
const mergedInspectorFns = [
97+
...inspectorMap.pre,
98+
...inspectorMap.normal,
99+
...inspectorMap.post,
100+
];
101+
102+
return (ctx: InspectorContext) => {
103+
return dispatch(0);
104+
function dispatch(i: number): void {
105+
const inspector = mergedInspectorFns[i];
106+
return inspector(ctx, dispatch.bind(null, i + 1));
107+
}
108+
};
109+
}
110+
111+
const INVALID_RE = /\s\s+/;
112+
export const isValidName = (name: CommandType) =>
113+
name === Root
114+
? true
115+
: (!(name.startsWith(" ") || name.endsWith(" ")) && !INVALID_RE.test(name));
116+
117+
export const withBrackets = (s: string, isOptional?: boolean) => isOptional ? `[${s}]` : `<${s}>`;
118+
119+
const ROOT = "<Root>";
120+
export const formatCommandName = (name: string | string[] | RootType) =>
121+
Array.isArray(name)
122+
? name.join(" ")
123+
: typeof name === "string"
124+
? name
125+
: ROOT;
126+
127+
export const detectLocale = () =>
128+
process.env.CLERC_LOCALE
129+
? process.env.CLERC_LOCALE
130+
: Intl.DateTimeFormat().resolvedOptions().locale;
131+
132+
export const stripFlags = (argv: string[]) => argv.filter(arg => !arg.startsWith("-"));

0 commit comments

Comments
 (0)