@breadc/core 1.0.0-beta.2 → 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,18 @@
1
- # @breadc/core
1
+ # 🥪 Breadc
2
2
 
3
- [![version](https://img.shields.io/npm/v/breadc?label=Breadc)](https://www.npmjs.com/package/breadc) [![CI](https://github.com/yjl9903/Breadc/actions/workflows/ci.yml/badge.svg)](https://github.com/yjl9903/Breadc/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/yjl9903/Breadc/branch/main/graph/badge.svg?token=F7PGOG62EF)](https://codecov.io/gh/yjl9903/Breadc)
3
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/yjl9903/Breadc)
4
+ [![version](https://img.shields.io/npm/v/breadc?label=Breadc)](https://www.npmjs.com/package/breadc)
5
+ [![CI](https://github.com/yjl9903/Breadc/actions/workflows/ci.yml/badge.svg)](https://github.com/yjl9903/Breadc/actions/workflows/ci.yml)
6
+ [![codecov](https://codecov.io/gh/yjl9903/Breadc/branch/main/graph/badge.svg?token=F7PGOG62EF)](https://codecov.io/gh/yjl9903/Breadc)
4
7
 
5
- Yet another Command Line Application Framework with fully strong **[TypeScript](https://www.typescriptlang.org/) support**.
8
+ Yet another **Command Line Application Framework** desgined for **[TypeScript](https://www.typescriptlang.org/)**.
9
+
10
+ - **TypeScript Infer**: infer command arguments, option values, and action signatures in IDE automatically
11
+ - **Command**: support default command, command alias, and nested sub-commands like `git remote add <name> <url>`
12
+ - **Group**: organize commands by modules and build large multi-command CLI applications with clear structure
13
+ - **Option**: support boolean, required, optional, spread options, `--no-*` negation, and `--` passthrough arguments
14
+ - **Middleware**: support middleware pipeline and unknown option handling
15
+ - **Builtin CLI Features**: provide common help / version options and i18n support out of the box
6
16
 
7
17
  ![vscode](https://raw.githubusercontent.com/yjl9903/Breadc/v1.0.0-beta.1/assets/typescript.png)
8
18
 
@@ -39,8 +49,9 @@ If you are using IDEs that support TypeScript (like [Visual Studio Code](https:/
39
49
 
40
50
  ## Inspiration
41
51
 
42
- + [cac](https://github.com/cacjs/cac): Simple yet powerful framework for building command-line apps.
43
- + [TypeScript: Documentation - Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html)
52
+ - [cac](https://github.com/cacjs/cac): Simple yet powerful framework for building command-line apps.
53
+ - [Commander.js](https://github.com/tj/commander.js): Node.js command-line interfaces made easy.
54
+ - [TypeScript: Documentation - Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html)
44
55
 
45
56
  ## License
46
57
 
package/dist/index.d.mts CHANGED
@@ -321,7 +321,7 @@ type InternalCommand = Command & {
321
321
  /**
322
322
  * @internal
323
323
  */
324
- _actionFn?: Function;
324
+ _actionFn?: (...args: any[]) => unknown;
325
325
  };
326
326
  type OptionType = 'boolean' | 'required' | 'optional' | 'spread';
327
327
  type InternalOption = Option & {
@@ -529,9 +529,9 @@ type Breadc<Data extends {} = {}, Options extends Record<never, never> = {}> = {
529
529
  */
530
530
  use<Middleware extends ActionMiddleware<Data, ActionMiddlewareNextFn>>(middleware: Middleware): Breadc<InferMiddlewareData<Middleware>, Options>;
531
531
  /**
532
- * Allow unknown option middleware
532
+ * Unknown command middleware
533
533
  */
534
- onUnknownCommand(middleware?: boolean | UnknownCommandMiddleware<Data>): Breadc<Data, Options>;
534
+ onUnknownCommand(middleware?: UnknownCommandMiddleware<Data>): Breadc<Data, Options>;
535
535
  /**
536
536
  * Allow unknown option middleware
537
537
  */
@@ -567,7 +567,7 @@ type Group<Spec extends string = string, Init extends GroupInit<Spec> = GroupIni
567
567
  option<OS extends string, Initial extends NonTrueNullable<InferOptionInitialType<OS>>, OI extends NonNullableOptionInit<OS, Initial>>(spec: OS, description: string, init: OI): Group<Spec, Init, Data, Options & InferOption<OS, Initial, OI>>;
568
568
  option<OS extends string, Initial extends InferOptionInitialType<OS>, OI extends OptionInit<OS, Initial>>(spec: OS, description?: string, init?: OI): Group<Spec, Init, Data, Options & InferOption<OS, Initial, OI>>;
569
569
  command<S extends string, I extends CommandInit<S>>(spec: S, description?: string, init?: I): Command<S, I, Data, Options, InferArgumentsType<S>, unknown>;
570
- command<S extends string, I extends CommandInit<S>>(command: Command<S, I, Options>): Command<S, I, Data, Options, InferArgumentsType<S>, unknown>;
570
+ command<S extends string, I extends CommandInit<S>>(command: Command<S, I, Data, Options>): Command<S, I, Data, Options, InferArgumentsType<S>, unknown>;
571
571
  /**
572
572
  * Action middleware
573
573
  */
@@ -577,7 +577,7 @@ type Group<Spec extends string = string, Init extends GroupInit<Spec> = GroupIni
577
577
  */
578
578
  allowUnknownOption(middleware?: UnknownOptionMiddleware<Data>): Group<Spec, Init, Data, Options>;
579
579
  };
580
- type Command<Spec extends string = string, Init extends CommandInit<Spec> = CommandInit<Spec>, Data extends {} = {}, Options extends Record<never, never> = {}, Arguments extends unknown[] = InferArgumentsType<Spec>, Return extends unknown = unknown> = {
580
+ type Command<Spec extends string = string, Init extends CommandInit<Spec> = CommandInit<Spec>, Data extends {} = {}, Options extends Record<never, never> = Record<never, never>, Arguments extends unknown[] = InferArgumentsType<Spec>, Return extends unknown = unknown> = {
581
581
  spec: Spec;
582
582
  init: Init | undefined;
583
583
  /**
package/dist/index.mjs CHANGED
@@ -112,6 +112,18 @@ var ResolveOptionError = class extends BreadcError {
112
112
  }
113
113
  };
114
114
 
115
+ //#endregion
116
+ //#region src/breadc/shared.ts
117
+ function resolveOptionInput(spec, description, init) {
118
+ return typeof spec === "string" ? option(spec, description, init) : spec;
119
+ }
120
+ function defaultUnknownOptionMiddleware() {
121
+ return (_ctx, key, value) => ({
122
+ name: key,
123
+ value
124
+ });
125
+ }
126
+
115
127
  //#endregion
116
128
  //#region src/breadc/command.ts
117
129
  function command(spec, init) {
@@ -134,8 +146,7 @@ function command(spec, init) {
134
146
  return run;
135
147
  };
136
148
  run.option = (spec, description, init) => {
137
- const option$5 = typeof spec === "string" ? option(spec, description, init) : spec;
138
- options.push(option$5);
149
+ options.push(resolveOptionInput(spec, description, init));
139
150
  return run;
140
151
  };
141
152
  run.use = (middleware) => {
@@ -146,10 +157,7 @@ function command(spec, init) {
146
157
  run.allowUnknownOption = (middleware) => {
147
158
  if (!run._unknownOptionMiddlewares) run._unknownOptionMiddlewares = [];
148
159
  if (typeof middleware === "function") run._unknownOptionMiddlewares.push(middleware);
149
- else run._unknownOptionMiddlewares.push((_ctx, key, value) => ({
150
- name: key,
151
- value
152
- }));
160
+ else run._unknownOptionMiddlewares.push(defaultUnknownOptionMiddleware());
153
161
  return run;
154
162
  };
155
163
  run.action = (fn) => {
@@ -799,9 +807,9 @@ function buildVersionOption(context) {
799
807
  const { breadc } = context;
800
808
  if (breadc._version) return breadc._version;
801
809
  const spec = typeof breadc._init.builtin?.version === "object" ? breadc._init.builtin.version.spec : void 0;
802
- const option$4 = spec ? resolveOption(option(spec, "Print version")) : rawOption("-v, --version", "boolean", "version", "v", { description: "Print version" });
803
- breadc._version = option$4;
804
- return option$4;
810
+ const option$2 = spec ? resolveOption(option(spec, "Print version")) : rawOption("-v, --version", "boolean", "version", "v", { description: "Print version" });
811
+ breadc._version = option$2;
812
+ return option$2;
805
813
  }
806
814
  function printVersion(context) {
807
815
  const { breadc } = context;
@@ -849,7 +857,7 @@ function formatCommand(command) {
849
857
  const args = formatArgument(command).join(" ");
850
858
  return pieces && args ? `${pieces} ${args}` : pieces;
851
859
  }
852
- function commandMatched(command, prefix) {
860
+ function commandStartsWith(command, prefix) {
853
861
  if (prefix.length === 0) return true;
854
862
  for (const pieces of command._pieces) {
855
863
  if (pieces.length < prefix.length) continue;
@@ -862,6 +870,18 @@ function commandMatched(command, prefix) {
862
870
  }
863
871
  return false;
864
872
  }
873
+ function commandIncludes(command, prefix) {
874
+ for (const pieces of command._pieces) {
875
+ if (pieces.length > prefix.length) continue;
876
+ let ok = true;
877
+ for (let i = 0; i < pieces.length; i++) if (pieces[i] !== prefix[i]) {
878
+ ok = false;
879
+ break;
880
+ }
881
+ if (ok) return true;
882
+ }
883
+ return false;
884
+ }
865
885
  function collect(context, pieces) {
866
886
  const allCommands = [];
867
887
  const commands = [];
@@ -876,17 +896,17 @@ function collect(context, pieces) {
876
896
  resolveGroup(group);
877
897
  buildGroup(group);
878
898
  allCommands.push(...group._commands);
879
- if (commandMatched(group, pieces)) for (const option of group._options) append(option);
880
- for (const command of group._commands) if (commandMatched(command, pieces)) {
899
+ if (commandIncludes(group, pieces)) for (const option of group._options) append(option);
900
+ for (const command of group._commands) if (commandStartsWith(command, pieces)) {
881
901
  commands.push(command);
882
- for (const option of command._options) append(option);
902
+ if (commandIncludes(command, pieces)) for (const option of command._options) append(option);
883
903
  }
884
904
  } else {
885
905
  resolveCommand(command);
886
906
  allCommands.push(command);
887
- if (commandMatched(command, pieces)) {
907
+ if (commandStartsWith(command, pieces)) {
888
908
  commands.push(command);
889
- for (const option of command._options) append(option);
909
+ if (commandIncludes(command, pieces)) for (const option of command._options) append(option);
890
910
  }
891
911
  }
892
912
  if (context.breadc._init.builtin?.help !== false) append(buildHelpOption(context));
@@ -901,9 +921,9 @@ function buildHelpOption(context) {
901
921
  const { breadc } = context;
902
922
  if (breadc._help) return breadc._help;
903
923
  const spec = typeof breadc._init.builtin?.help === "object" ? breadc._init.builtin.help.spec : void 0;
904
- const option$3 = spec ? resolveOption(option(spec, "Print help")) : rawOption("-h, --help", "boolean", "help", "h", { description: "Print help" });
905
- breadc._help = option$3;
906
- return option$3;
924
+ const option$1 = spec ? resolveOption(option(spec, "Print help")) : rawOption("-h, --help", "boolean", "help", "h", { description: "Print help" });
925
+ breadc._help = option$1;
926
+ return option$1;
907
927
  }
908
928
  function printHelp(context) {
909
929
  const { breadc, pieces } = context;
@@ -1169,8 +1189,7 @@ function group(spec, init) {
1169
1189
  _actionMiddlewares: actionMiddlewares,
1170
1190
  _unknownOptionMiddlewares: unknownOptionMiddlewares,
1171
1191
  option(spec, description, init) {
1172
- const option$2 = typeof spec === "string" ? option(spec, description, init) : spec;
1173
- options.push(option$2);
1192
+ options.push(resolveOptionInput(spec, description, init));
1174
1193
  return group;
1175
1194
  },
1176
1195
  command(spec, init) {
@@ -1185,10 +1204,7 @@ function group(spec, init) {
1185
1204
  },
1186
1205
  allowUnknownOption(middleware) {
1187
1206
  if (typeof middleware === "function") unknownOptionMiddlewares.push(middleware);
1188
- else unknownOptionMiddlewares.push((_ctx, key, value) => ({
1189
- name: key,
1190
- value
1191
- }));
1207
+ else unknownOptionMiddlewares.push(defaultUnknownOptionMiddleware());
1192
1208
  return group;
1193
1209
  }
1194
1210
  };
@@ -1213,8 +1229,7 @@ function breadc(name, init = {}) {
1213
1229
  _unknownOptionMiddlewares: unknownOptionMiddlewares,
1214
1230
  _unknownCommandMiddlewares: unknownCommandMiddlewares,
1215
1231
  option(spec, description, init) {
1216
- const option$1 = typeof spec === "string" ? option(spec, description, init) : spec;
1217
- options.push(option$1);
1232
+ options.push(resolveOptionInput(spec, description, init));
1218
1233
  return app;
1219
1234
  },
1220
1235
  group(spec, init) {
@@ -1240,10 +1255,7 @@ function breadc(name, init = {}) {
1240
1255
  },
1241
1256
  allowUnknownOption(middleware) {
1242
1257
  if (typeof middleware === "function") unknownOptionMiddlewares.push(middleware);
1243
- else unknownOptionMiddlewares.push((_ctx, key, value) => ({
1244
- name: key,
1245
- value
1246
- }));
1258
+ else unknownOptionMiddlewares.push(defaultUnknownOptionMiddleware());
1247
1259
  return app;
1248
1260
  },
1249
1261
  parse(argv) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@breadc/core",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.3",
4
4
  "description": "Yet another Command Line Application Framework with fully strong TypeScript support",
5
5
  "keywords": [
6
6
  "breadc",
@@ -33,7 +33,7 @@
33
33
  "dist"
34
34
  ],
35
35
  "dependencies": {
36
- "@breadc/color": "1.0.0-beta.2"
36
+ "@breadc/color": "1.0.0-beta.3"
37
37
  },
38
38
  "size-limit": [
39
39
  {