@kubb/cli 1.0.0 → 1.0.2

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/dist/index.cjs CHANGED
@@ -1,26 +1,48 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- var module$1 = require('module');
4
+ var mod = require('module');
5
+ var pathParser = require('path');
5
6
  var commander = require('commander');
6
- var pc3 = require('picocolors');
7
+ var pc = require('picocolors');
7
8
  var ora = require('ora');
8
9
  var execa = require('execa');
9
10
  var stringArgv = require('string-argv');
11
+ var PrettyError = require('pretty-error');
10
12
  var core = require('@kubb/core');
11
- var moduleImporter = require('@humanwhocodes/module-importer');
12
- var isObject = require('lodash.isobject');
13
+ var url = require('url');
13
14
  var cosmiconfig = require('cosmiconfig');
14
- var cosmiconfigTypescriptLoader = require('cosmiconfig-typescript-loader');
15
+ var yaml = require('yaml');
16
+ var tsNode = require('ts-node');
15
17
 
16
18
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
19
 
18
- var pc3__default = /*#__PURE__*/_interopDefault(pc3);
20
+ var mod__default = /*#__PURE__*/_interopDefault(mod);
21
+ var pathParser__default = /*#__PURE__*/_interopDefault(pathParser);
22
+ var pc__default = /*#__PURE__*/_interopDefault(pc);
19
23
  var ora__default = /*#__PURE__*/_interopDefault(ora);
20
- var isObject__default = /*#__PURE__*/_interopDefault(isObject);
24
+ var PrettyError__default = /*#__PURE__*/_interopDefault(PrettyError);
25
+ var yaml__default = /*#__PURE__*/_interopDefault(yaml);
26
+ var tsNode__default = /*#__PURE__*/_interopDefault(tsNode);
21
27
 
22
- module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('out.js', document.baseURI).href)));
28
+ const require$1 = mod.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('out.js', document.baseURI).href)));
29
+ var __require = /* @__PURE__ */ ((x) => typeof require$1 !== "undefined" ? require$1 : typeof Proxy !== "undefined" ? new Proxy(x, {
30
+ get: (a, b) => (typeof require$1 !== "undefined" ? require$1 : a)[b]
31
+ }) : x)(function(x) {
32
+ if (typeof require$1 !== "undefined")
33
+ return require$1.apply(this, arguments);
34
+ throw new Error('Dynamic require of "' + x + '" is not supported');
35
+ });
36
+
37
+ // src/utils/parseHrtimeToSeconds.ts
38
+ function parseHrtimeToSeconds(hrtime) {
39
+ const seconds = (hrtime[0] + hrtime[1] / 1e9).toFixed(3);
40
+ return seconds;
41
+ }
42
+
43
+ // src/run.ts
23
44
  async function run({ config, options, spinner: spinner2 }) {
45
+ const hrstart = process.hrtime();
24
46
  const logger = {
25
47
  log(message, logLevel) {
26
48
  if (logLevel === "error") {
@@ -41,7 +63,6 @@ async function run({ config, options, spinner: spinner2 }) {
41
63
  if (!hooks?.done) {
42
64
  return;
43
65
  }
44
- spinner2.start("\u{1FA82} Running hooks");
45
66
  let commands = [];
46
67
  if (typeof hooks?.done === "string") {
47
68
  commands = [hooks.done];
@@ -50,18 +71,77 @@ async function run({ config, options, spinner: spinner2 }) {
50
71
  }
51
72
  const promises = commands.map(async (command) => {
52
73
  const [cmd, ..._args] = [...stringArgv.parseArgsStringToArgv(command)];
53
- return execa.execa(cmd, _args);
74
+ spinner2.start(`\u{1FA82} Executing hooks(${pc__default.default.yellow("done")}) ${pc__default.default.dim(command)}`);
75
+ await execa.execa(cmd, _args);
76
+ spinner2.succeed(`\u{1FA82} Executed hooks(${pc__default.default.yellow("done")}) ${pc__default.default.dim(command)}`);
54
77
  });
55
78
  await Promise.all(promises);
56
- spinner2.succeed("\u{1FA82} Hooks runned");
79
+ };
80
+ const printSummary = (pluginManager, status) => {
81
+ const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(hrstart));
82
+ const buildStartPlugins = [
83
+ ...new Set(pluginManager.executed.filter((item) => item.hookName === "buildStart" && item.plugin.name !== "core").map((item) => item.plugin.name))
84
+ ];
85
+ const pluginsCount = config.plugins?.length || 0;
86
+ const files = pluginManager.fileManager.files.sort((a, b) => {
87
+ if (!a.meta?.pluginName || !b.meta?.pluginName) {
88
+ return 0;
89
+ }
90
+ if (a.meta?.pluginName.length < b.meta?.pluginName.length)
91
+ return 1;
92
+ if (a.meta?.pluginName.length > b.meta?.pluginName.length)
93
+ return -1;
94
+ return 0;
95
+ });
96
+ const meta = {
97
+ plugins: status === "success" ? `${pc__default.default.green(`${buildStartPlugins.length} successful`)}, ${pluginsCount} total` : `${pc__default.default.red(`${pluginsCount - buildStartPlugins.length} failed`)}, ${pluginsCount} total`,
98
+ filesCreated: files.length,
99
+ time: pc__default.default.yellow(`${elapsedSeconds}s`),
100
+ output: pathParser__default.default.resolve(config.root, config.output.path)
101
+ };
102
+ console.log(`
103
+ ${pc__default.default.bold("Plugins:")} ${meta.plugins}
104
+ ${pc__default.default.bold("Generated:")} ${meta.filesCreated} files
105
+ ${pc__default.default.bold("Time:")} ${meta.time}
106
+ ${pc__default.default.bold("Output:")} ${meta.output}
107
+ `);
108
+ if (options.debug) {
109
+ console.log(`${pc__default.default.bold("Generated files:")}`);
110
+ console.log(`${files.map((file) => `${pc__default.default.blue(file.meta?.pluginName)} ${file.path}`).join("\n")}`);
111
+ }
112
+ };
113
+ const printErrors = (error) => {
114
+ const pe = new PrettyError__default.default();
115
+ if (error instanceof core.ParallelPluginError) {
116
+ error.errors.map((e) => printErrors(e));
117
+ return;
118
+ }
119
+ if (options.debug) {
120
+ spinner2.fail(pc__default.default.red(`Something went wrong
121
+
122
+ `));
123
+ const causedError = error?.cause;
124
+ console.log(pe.render(error));
125
+ if (causedError) {
126
+ console.log(pe.render(causedError));
127
+ }
128
+ } else {
129
+ spinner2.fail(pc__default.default.red(`Something went wrong
130
+
131
+ ${error?.message}`));
132
+ }
57
133
  };
58
134
  try {
59
- spinner2.start("\u{1F680} Building");
60
135
  const { root, ...userConfig } = config;
61
- await core.build({
136
+ spinner2.start(`\u{1F680} Building(${pc__default.default.dim(options.input ?? userConfig.input.path)})`);
137
+ const output = await core.build({
62
138
  config: {
63
139
  root: process.cwd(),
64
140
  ...userConfig,
141
+ input: {
142
+ ...userConfig.input,
143
+ path: options.input ?? userConfig.input.path
144
+ },
65
145
  output: {
66
146
  write: true,
67
147
  ...userConfig.output
@@ -69,55 +149,46 @@ async function run({ config, options, spinner: spinner2 }) {
69
149
  },
70
150
  logger
71
151
  });
72
- spinner2.succeed(pc3__default.default.blue("\u{1F308} Generation complete"));
152
+ spinner2.succeed(`\u{1F680} Build completed(${pc__default.default.dim(options.input ?? userConfig.input.path)})`);
73
153
  await onDone(config.hooks);
74
- } catch (err) {
75
- if (options.debug) {
76
- spinner2.fail(`Something went wrong
77
- `);
78
- const causedError = err?.cause;
79
- console.log(causedError || err);
80
- console.log("\n");
81
- if (causedError) {
82
- console.log(err);
83
- }
84
- } else {
85
- spinner2.fail(`Something went wrong
86
- ${err?.message}`);
154
+ printSummary(output.pluginManager, "success");
155
+ } catch (error) {
156
+ printErrors(error);
157
+ if (error instanceof core.PluginError || error instanceof core.ParallelPluginError) {
158
+ printSummary(error.pluginManager, "failed");
87
159
  }
160
+ throw error;
88
161
  }
89
- return true;
90
162
  }
91
- async function startWatcher(cb, options) {
92
- const { spinner: spinner2, path } = options;
93
- const { watch } = await import('chokidar');
94
- const ignored = ["**/{.git,node_modules}/**"];
95
- const watcher = watch(path, {
96
- ignorePermissionErrors: true,
97
- ignored
98
- });
99
- watcher.on("all", async (type, file) => {
100
- spinner2.succeed(pc3__default.default.yellow(pc3__default.default.bold(`Change detected: ${type} ${file}`)));
101
- spinner2.spinner = "clock";
102
- try {
103
- await cb(options.path);
104
- } catch (e) {
105
- spinner2.warn(pc3__default.default.red("Watcher failed"));
106
- }
107
- });
163
+ var SLASHES = /* @__PURE__ */ new Set(["/", "\\"]);
164
+ function normalizeDirectory(directory) {
165
+ if (!SLASHES.has(directory[directory.length - 1])) {
166
+ return `${directory}/`;
167
+ }
168
+ return directory;
169
+ }
170
+ async function importModule(path, cwd) {
171
+ let location = path;
172
+ if (cwd) {
173
+ const require2 = mod__default.default.createRequire(normalizeDirectory(cwd));
174
+ location = require2.resolve(path);
175
+ }
176
+ const module = await import(url.pathToFileURL(location).href);
177
+ return module.default;
108
178
  }
179
+
180
+ // src/utils/getPlugins.ts
109
181
  function isJSONPlugins(plugins) {
110
182
  return !!plugins?.some((plugin) => {
111
183
  return typeof plugin?.[0] === "string";
112
184
  });
113
185
  }
114
186
  function isObjectPlugins(plugins) {
115
- return isObject__default.default(plugins) && !Array.isArray(plugins);
187
+ return plugins instanceof Object && !Array.isArray(plugins);
116
188
  }
117
189
  async function importPlugin(name, options) {
118
- const importer = new moduleImporter.ModuleImporter(process.cwd());
119
- const importedPlugin = process.env.NODE_ENV === "test" ? await import(name) : await importer.import(name);
120
- return importedPlugin?.default?.default ? importedPlugin.default.default(options) : importedPlugin.default(options);
190
+ const importedPlugin = process.env.NODE_ENV === "test" ? await import(name) : await importModule(name, process.cwd());
191
+ return importedPlugin?.default ? importedPlugin.default(options) : importedPlugin(options);
121
192
  }
122
193
  function getPlugins(plugins) {
123
194
  if (isObjectPlugins(plugins)) {
@@ -154,6 +225,49 @@ async function getConfig(result, options) {
154
225
  };
155
226
  return JSONConfig;
156
227
  }
228
+ async function startWatcher(cb, options) {
229
+ const { spinner: spinner2, path } = options;
230
+ const { watch } = await import('chokidar');
231
+ const ignored = ["**/{.git,node_modules}/**"];
232
+ const watcher = watch(path, {
233
+ ignorePermissionErrors: true,
234
+ ignored
235
+ });
236
+ watcher.on("all", async (type, file) => {
237
+ spinner2.succeed(pc__default.default.yellow(pc__default.default.bold(`Change detected: ${type} ${file}`)));
238
+ spinner2.spinner = "clock";
239
+ try {
240
+ await cb(options.path);
241
+ } catch (e) {
242
+ spinner2.warn(pc__default.default.red("Watcher failed"));
243
+ }
244
+ });
245
+ }
246
+ var jsLoader = async (configFile) => {
247
+ return importModule(configFile);
248
+ };
249
+ var tsLoader = async (configFile) => {
250
+ let registerer = { enabled() {
251
+ } };
252
+ try {
253
+ registerer = tsNode__default.default.register({
254
+ compilerOptions: { module: "commonjs" },
255
+ swc: true,
256
+ typeCheck: false
257
+ });
258
+ const module = __require(configFile);
259
+ return module.default;
260
+ } catch (err) {
261
+ if (err.code === "MODULE_NOT_FOUND") {
262
+ throw new Error(`'ts-node' is required for the TypeScript configuration files. Make sure it is installed
263
+ Error: ${err.message}`);
264
+ }
265
+ console.log(err);
266
+ throw err;
267
+ } finally {
268
+ registerer.enabled();
269
+ }
270
+ };
157
271
  async function getCosmiConfig(moduleName2, config) {
158
272
  const explorer = cosmiconfig.cosmiconfig(moduleName2, {
159
273
  cache: false,
@@ -161,21 +275,27 @@ async function getCosmiConfig(moduleName2, config) {
161
275
  "package.json",
162
276
  `.${moduleName2}rc`,
163
277
  `.${moduleName2}rc.json`,
164
- // commonjs
278
+ `.${moduleName2}rc.yaml`,
279
+ `.${moduleName2}rc.yml`,
280
+ // TODO fix tsLoader
281
+ `.${moduleName2}rc.ts`,
165
282
  `.${moduleName2}rc.js`,
166
283
  `.${moduleName2}rc.cjs`,
284
+ `.${moduleName2}rc.mjs`,
285
+ // TODO fix tsLoader
286
+ `${moduleName2}.config.ts`,
167
287
  `${moduleName2}.config.js`,
168
288
  `${moduleName2}.config.cjs`,
169
- // esm and typescript
170
- `.${moduleName2}rc.ts`,
171
- `${moduleName2}.config.ts`
289
+ `${moduleName2}.config.mjs`
172
290
  ],
173
291
  loaders: {
174
- ".ts": cosmiconfigTypescriptLoader.TypeScriptLoader({
175
- swc: true,
176
- typeCheck: false
177
- }),
178
- noExt: cosmiconfig.defaultLoaders[".js"]
292
+ ".yaml": (filepath, content) => yaml__default.default.parse(content),
293
+ ".yml": (filepath, content) => yaml__default.default.parse(content),
294
+ ".js": jsLoader,
295
+ ".cjs": jsLoader,
296
+ ".mjs": jsLoader,
297
+ ".ts": tsLoader,
298
+ noExt: jsLoader
179
299
  }
180
300
  });
181
301
  const result = config ? await explorer.load(config) : await explorer.search();
@@ -186,27 +306,27 @@ async function getCosmiConfig(moduleName2, config) {
186
306
  }
187
307
 
188
308
  // package.json
189
- var version = "1.0.0";
309
+ var version = "1.0.2";
190
310
 
191
311
  // src/index.ts
192
312
  var moduleName = "kubb";
193
313
  var spinner = ora__default.default({
194
314
  color: "blue",
195
- text: pc3__default.default.blue("\u{1F3CE}\uFE0F Kubb generation started"),
315
+ text: pc__default.default.blue("\u{1F3CE}\uFE0F Kubb generation started"),
196
316
  spinner: "clock"
197
317
  }).start();
198
318
  var program = new commander.Command(moduleName).description("Kubb").action(async (options) => {
199
319
  try {
200
320
  spinner.start("\u{1F4BE} Loading config");
201
321
  const result = await getCosmiConfig(moduleName, options.config);
202
- spinner.succeed("\u{1F4BE} Config loaded");
322
+ spinner.succeed(`\u{1F4BE} Config loaded(${pc__default.default.dim(pathParser__default.default.relative(process.cwd(), result.filepath))})`);
203
323
  if (options.watch) {
204
324
  const config = await getConfig(result, options);
205
325
  startWatcher(
206
326
  async (paths) => {
207
327
  await run({ config, spinner, options });
208
328
  spinner.spinner = "simpleDotsScrolling";
209
- spinner.start(pc3__default.default.yellow(pc3__default.default.bold(`Watching for changes in ${paths.join(" and ")}`)));
329
+ spinner.start(pc__default.default.yellow(pc__default.default.bold(`Watching for changes in ${paths.join(" and ")}`)));
210
330
  },
211
331
  {
212
332
  spinner,
@@ -218,9 +338,7 @@ var program = new commander.Command(moduleName).description("Kubb").action(async
218
338
  await run({ config, spinner, options });
219
339
  }
220
340
  } catch (e) {
221
- spinner.fail(pc3__default.default.red(e.message));
341
+ process.exit(1);
222
342
  }
223
- }).addOption(new commander.Option("-c, --config <path>", "Path to the Kubb config")).addOption(new commander.Option("-d, --debug", "Debug mode").default(false)).addOption(new commander.Option("-w, --watch", "Watch mode based on the input file"));
343
+ }).addOption(new commander.Option("-c, --config <path>", "Path to the Kubb config")).addOption(new commander.Option("-i, --input <path>", "Path of the input file(overrides the on in `kubb.config.js`)")).addOption(new commander.Option("-d, --debug", "Debug mode").default(false)).addOption(new commander.Option("-w, --watch", "Watch mode based on the input file"));
224
344
  program.name(moduleName).description("Generate").version(version, "-v").parse();
225
- //# sourceMappingURL=out.js.map
226
- //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -1,18 +1,37 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'module';
3
+ import pathParser from 'node:path';
3
4
  import { Command, Option } from 'commander';
4
- import pc3 from 'picocolors';
5
+ import pc from 'picocolors';
5
6
  import ora from 'ora';
6
7
  import { execa } from 'execa';
7
8
  import { parseArgsStringToArgv } from 'string-argv';
8
- import { build, isPromise } from '@kubb/core';
9
- import { ModuleImporter } from '@humanwhocodes/module-importer';
10
- import isObject from 'lodash.isobject';
11
- import { cosmiconfig, defaultLoaders } from 'cosmiconfig';
12
- import { TypeScriptLoader } from 'cosmiconfig-typescript-loader';
9
+ import PrettyError from 'pretty-error';
10
+ import { build, PluginError, ParallelPluginError, isPromise } from '@kubb/core';
11
+ import { pathToFileURL } from 'node:url';
12
+ import mod from 'node:module';
13
+ import { cosmiconfig } from 'cosmiconfig';
14
+ import yaml from 'yaml';
15
+ import tsNode from 'ts-node';
13
16
 
14
- createRequire(import.meta.url);
17
+ const require = createRequire(import.meta.url);
18
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
19
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
20
+ }) : x)(function(x) {
21
+ if (typeof require !== "undefined")
22
+ return require.apply(this, arguments);
23
+ throw new Error('Dynamic require of "' + x + '" is not supported');
24
+ });
25
+
26
+ // src/utils/parseHrtimeToSeconds.ts
27
+ function parseHrtimeToSeconds(hrtime) {
28
+ const seconds = (hrtime[0] + hrtime[1] / 1e9).toFixed(3);
29
+ return seconds;
30
+ }
31
+
32
+ // src/run.ts
15
33
  async function run({ config, options, spinner: spinner2 }) {
34
+ const hrstart = process.hrtime();
16
35
  const logger = {
17
36
  log(message, logLevel) {
18
37
  if (logLevel === "error") {
@@ -33,7 +52,6 @@ async function run({ config, options, spinner: spinner2 }) {
33
52
  if (!hooks?.done) {
34
53
  return;
35
54
  }
36
- spinner2.start("\u{1FA82} Running hooks");
37
55
  let commands = [];
38
56
  if (typeof hooks?.done === "string") {
39
57
  commands = [hooks.done];
@@ -42,18 +60,77 @@ async function run({ config, options, spinner: spinner2 }) {
42
60
  }
43
61
  const promises = commands.map(async (command) => {
44
62
  const [cmd, ..._args] = [...parseArgsStringToArgv(command)];
45
- return execa(cmd, _args);
63
+ spinner2.start(`\u{1FA82} Executing hooks(${pc.yellow("done")}) ${pc.dim(command)}`);
64
+ await execa(cmd, _args);
65
+ spinner2.succeed(`\u{1FA82} Executed hooks(${pc.yellow("done")}) ${pc.dim(command)}`);
46
66
  });
47
67
  await Promise.all(promises);
48
- spinner2.succeed("\u{1FA82} Hooks runned");
68
+ };
69
+ const printSummary = (pluginManager, status) => {
70
+ const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(hrstart));
71
+ const buildStartPlugins = [
72
+ ...new Set(pluginManager.executed.filter((item) => item.hookName === "buildStart" && item.plugin.name !== "core").map((item) => item.plugin.name))
73
+ ];
74
+ const pluginsCount = config.plugins?.length || 0;
75
+ const files = pluginManager.fileManager.files.sort((a, b) => {
76
+ if (!a.meta?.pluginName || !b.meta?.pluginName) {
77
+ return 0;
78
+ }
79
+ if (a.meta?.pluginName.length < b.meta?.pluginName.length)
80
+ return 1;
81
+ if (a.meta?.pluginName.length > b.meta?.pluginName.length)
82
+ return -1;
83
+ return 0;
84
+ });
85
+ const meta = {
86
+ plugins: status === "success" ? `${pc.green(`${buildStartPlugins.length} successful`)}, ${pluginsCount} total` : `${pc.red(`${pluginsCount - buildStartPlugins.length} failed`)}, ${pluginsCount} total`,
87
+ filesCreated: files.length,
88
+ time: pc.yellow(`${elapsedSeconds}s`),
89
+ output: pathParser.resolve(config.root, config.output.path)
90
+ };
91
+ console.log(`
92
+ ${pc.bold("Plugins:")} ${meta.plugins}
93
+ ${pc.bold("Generated:")} ${meta.filesCreated} files
94
+ ${pc.bold("Time:")} ${meta.time}
95
+ ${pc.bold("Output:")} ${meta.output}
96
+ `);
97
+ if (options.debug) {
98
+ console.log(`${pc.bold("Generated files:")}`);
99
+ console.log(`${files.map((file) => `${pc.blue(file.meta?.pluginName)} ${file.path}`).join("\n")}`);
100
+ }
101
+ };
102
+ const printErrors = (error) => {
103
+ const pe = new PrettyError();
104
+ if (error instanceof ParallelPluginError) {
105
+ error.errors.map((e) => printErrors(e));
106
+ return;
107
+ }
108
+ if (options.debug) {
109
+ spinner2.fail(pc.red(`Something went wrong
110
+
111
+ `));
112
+ const causedError = error?.cause;
113
+ console.log(pe.render(error));
114
+ if (causedError) {
115
+ console.log(pe.render(causedError));
116
+ }
117
+ } else {
118
+ spinner2.fail(pc.red(`Something went wrong
119
+
120
+ ${error?.message}`));
121
+ }
49
122
  };
50
123
  try {
51
- spinner2.start("\u{1F680} Building");
52
124
  const { root, ...userConfig } = config;
53
- await build({
125
+ spinner2.start(`\u{1F680} Building(${pc.dim(options.input ?? userConfig.input.path)})`);
126
+ const output = await build({
54
127
  config: {
55
128
  root: process.cwd(),
56
129
  ...userConfig,
130
+ input: {
131
+ ...userConfig.input,
132
+ path: options.input ?? userConfig.input.path
133
+ },
57
134
  output: {
58
135
  write: true,
59
136
  ...userConfig.output
@@ -61,55 +138,46 @@ async function run({ config, options, spinner: spinner2 }) {
61
138
  },
62
139
  logger
63
140
  });
64
- spinner2.succeed(pc3.blue("\u{1F308} Generation complete"));
141
+ spinner2.succeed(`\u{1F680} Build completed(${pc.dim(options.input ?? userConfig.input.path)})`);
65
142
  await onDone(config.hooks);
66
- } catch (err) {
67
- if (options.debug) {
68
- spinner2.fail(`Something went wrong
69
- `);
70
- const causedError = err?.cause;
71
- console.log(causedError || err);
72
- console.log("\n");
73
- if (causedError) {
74
- console.log(err);
75
- }
76
- } else {
77
- spinner2.fail(`Something went wrong
78
- ${err?.message}`);
143
+ printSummary(output.pluginManager, "success");
144
+ } catch (error) {
145
+ printErrors(error);
146
+ if (error instanceof PluginError || error instanceof ParallelPluginError) {
147
+ printSummary(error.pluginManager, "failed");
79
148
  }
149
+ throw error;
80
150
  }
81
- return true;
82
151
  }
83
- async function startWatcher(cb, options) {
84
- const { spinner: spinner2, path } = options;
85
- const { watch } = await import('chokidar');
86
- const ignored = ["**/{.git,node_modules}/**"];
87
- const watcher = watch(path, {
88
- ignorePermissionErrors: true,
89
- ignored
90
- });
91
- watcher.on("all", async (type, file) => {
92
- spinner2.succeed(pc3.yellow(pc3.bold(`Change detected: ${type} ${file}`)));
93
- spinner2.spinner = "clock";
94
- try {
95
- await cb(options.path);
96
- } catch (e) {
97
- spinner2.warn(pc3.red("Watcher failed"));
98
- }
99
- });
152
+ var SLASHES = /* @__PURE__ */ new Set(["/", "\\"]);
153
+ function normalizeDirectory(directory) {
154
+ if (!SLASHES.has(directory[directory.length - 1])) {
155
+ return `${directory}/`;
156
+ }
157
+ return directory;
158
+ }
159
+ async function importModule(path, cwd) {
160
+ let location = path;
161
+ if (cwd) {
162
+ const require2 = mod.createRequire(normalizeDirectory(cwd));
163
+ location = require2.resolve(path);
164
+ }
165
+ const module = await import(pathToFileURL(location).href);
166
+ return module.default;
100
167
  }
168
+
169
+ // src/utils/getPlugins.ts
101
170
  function isJSONPlugins(plugins) {
102
171
  return !!plugins?.some((plugin) => {
103
172
  return typeof plugin?.[0] === "string";
104
173
  });
105
174
  }
106
175
  function isObjectPlugins(plugins) {
107
- return isObject(plugins) && !Array.isArray(plugins);
176
+ return plugins instanceof Object && !Array.isArray(plugins);
108
177
  }
109
178
  async function importPlugin(name, options) {
110
- const importer = new ModuleImporter(process.cwd());
111
- const importedPlugin = process.env.NODE_ENV === "test" ? await import(name) : await importer.import(name);
112
- return importedPlugin?.default?.default ? importedPlugin.default.default(options) : importedPlugin.default(options);
179
+ const importedPlugin = process.env.NODE_ENV === "test" ? await import(name) : await importModule(name, process.cwd());
180
+ return importedPlugin?.default ? importedPlugin.default(options) : importedPlugin(options);
113
181
  }
114
182
  function getPlugins(plugins) {
115
183
  if (isObjectPlugins(plugins)) {
@@ -146,6 +214,49 @@ async function getConfig(result, options) {
146
214
  };
147
215
  return JSONConfig;
148
216
  }
217
+ async function startWatcher(cb, options) {
218
+ const { spinner: spinner2, path } = options;
219
+ const { watch } = await import('chokidar');
220
+ const ignored = ["**/{.git,node_modules}/**"];
221
+ const watcher = watch(path, {
222
+ ignorePermissionErrors: true,
223
+ ignored
224
+ });
225
+ watcher.on("all", async (type, file) => {
226
+ spinner2.succeed(pc.yellow(pc.bold(`Change detected: ${type} ${file}`)));
227
+ spinner2.spinner = "clock";
228
+ try {
229
+ await cb(options.path);
230
+ } catch (e) {
231
+ spinner2.warn(pc.red("Watcher failed"));
232
+ }
233
+ });
234
+ }
235
+ var jsLoader = async (configFile) => {
236
+ return importModule(configFile);
237
+ };
238
+ var tsLoader = async (configFile) => {
239
+ let registerer = { enabled() {
240
+ } };
241
+ try {
242
+ registerer = tsNode.register({
243
+ compilerOptions: { module: "commonjs" },
244
+ swc: true,
245
+ typeCheck: false
246
+ });
247
+ const module = __require(configFile);
248
+ return module.default;
249
+ } catch (err) {
250
+ if (err.code === "MODULE_NOT_FOUND") {
251
+ throw new Error(`'ts-node' is required for the TypeScript configuration files. Make sure it is installed
252
+ Error: ${err.message}`);
253
+ }
254
+ console.log(err);
255
+ throw err;
256
+ } finally {
257
+ registerer.enabled();
258
+ }
259
+ };
149
260
  async function getCosmiConfig(moduleName2, config) {
150
261
  const explorer = cosmiconfig(moduleName2, {
151
262
  cache: false,
@@ -153,21 +264,27 @@ async function getCosmiConfig(moduleName2, config) {
153
264
  "package.json",
154
265
  `.${moduleName2}rc`,
155
266
  `.${moduleName2}rc.json`,
156
- // commonjs
267
+ `.${moduleName2}rc.yaml`,
268
+ `.${moduleName2}rc.yml`,
269
+ // TODO fix tsLoader
270
+ `.${moduleName2}rc.ts`,
157
271
  `.${moduleName2}rc.js`,
158
272
  `.${moduleName2}rc.cjs`,
273
+ `.${moduleName2}rc.mjs`,
274
+ // TODO fix tsLoader
275
+ `${moduleName2}.config.ts`,
159
276
  `${moduleName2}.config.js`,
160
277
  `${moduleName2}.config.cjs`,
161
- // esm and typescript
162
- `.${moduleName2}rc.ts`,
163
- `${moduleName2}.config.ts`
278
+ `${moduleName2}.config.mjs`
164
279
  ],
165
280
  loaders: {
166
- ".ts": TypeScriptLoader({
167
- swc: true,
168
- typeCheck: false
169
- }),
170
- noExt: defaultLoaders[".js"]
281
+ ".yaml": (filepath, content) => yaml.parse(content),
282
+ ".yml": (filepath, content) => yaml.parse(content),
283
+ ".js": jsLoader,
284
+ ".cjs": jsLoader,
285
+ ".mjs": jsLoader,
286
+ ".ts": tsLoader,
287
+ noExt: jsLoader
171
288
  }
172
289
  });
173
290
  const result = config ? await explorer.load(config) : await explorer.search();
@@ -178,27 +295,27 @@ async function getCosmiConfig(moduleName2, config) {
178
295
  }
179
296
 
180
297
  // package.json
181
- var version = "1.0.0";
298
+ var version = "1.0.2";
182
299
 
183
300
  // src/index.ts
184
301
  var moduleName = "kubb";
185
302
  var spinner = ora({
186
303
  color: "blue",
187
- text: pc3.blue("\u{1F3CE}\uFE0F Kubb generation started"),
304
+ text: pc.blue("\u{1F3CE}\uFE0F Kubb generation started"),
188
305
  spinner: "clock"
189
306
  }).start();
190
307
  var program = new Command(moduleName).description("Kubb").action(async (options) => {
191
308
  try {
192
309
  spinner.start("\u{1F4BE} Loading config");
193
310
  const result = await getCosmiConfig(moduleName, options.config);
194
- spinner.succeed("\u{1F4BE} Config loaded");
311
+ spinner.succeed(`\u{1F4BE} Config loaded(${pc.dim(pathParser.relative(process.cwd(), result.filepath))})`);
195
312
  if (options.watch) {
196
313
  const config = await getConfig(result, options);
197
314
  startWatcher(
198
315
  async (paths) => {
199
316
  await run({ config, spinner, options });
200
317
  spinner.spinner = "simpleDotsScrolling";
201
- spinner.start(pc3.yellow(pc3.bold(`Watching for changes in ${paths.join(" and ")}`)));
318
+ spinner.start(pc.yellow(pc.bold(`Watching for changes in ${paths.join(" and ")}`)));
202
319
  },
203
320
  {
204
321
  spinner,
@@ -210,9 +327,7 @@ var program = new Command(moduleName).description("Kubb").action(async (options)
210
327
  await run({ config, spinner, options });
211
328
  }
212
329
  } catch (e) {
213
- spinner.fail(pc3.red(e.message));
330
+ process.exit(1);
214
331
  }
215
- }).addOption(new Option("-c, --config <path>", "Path to the Kubb config")).addOption(new Option("-d, --debug", "Debug mode").default(false)).addOption(new Option("-w, --watch", "Watch mode based on the input file"));
332
+ }).addOption(new Option("-c, --config <path>", "Path to the Kubb config")).addOption(new Option("-i, --input <path>", "Path of the input file(overrides the on in `kubb.config.js`)")).addOption(new Option("-d, --debug", "Debug mode").default(false)).addOption(new Option("-w, --watch", "Watch mode based on the input file"));
216
333
  program.name(moduleName).description("Generate").version(version, "-v").parse();
217
- //# sourceMappingURL=out.js.map
218
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Generator cli",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,33 +32,32 @@
32
32
  "!/**/__tests__/**"
33
33
  ],
34
34
  "dependencies": {
35
- "@humanwhocodes/module-importer": "^1.0.1",
36
- "@kubb/core": "1.0.0",
37
35
  "chokidar": "^3.5.3",
38
36
  "commander": "^10.0.1",
39
37
  "cosmiconfig": "^8.1.3",
40
- "cosmiconfig-typescript-loader": "^4.3.0",
41
38
  "execa": "^7.1.1",
42
39
  "ora": "^6.3.1",
43
40
  "picocolors": "^1.0.0",
44
- "lodash.isobject": "^3.0.2",
45
41
  "string-argv": "^0.3.2",
46
42
  "ts-node": "^10.9.1",
47
- "@swc/core": "^1.3.61"
43
+ "yaml": "^2.3.1",
44
+ "@swc/core": "^1.3.62",
45
+ "pretty-error": "^4.0.0",
46
+ "@kubb/core": "1.0.2"
48
47
  },
49
48
  "devDependencies": {
50
- "@kubb/swagger": "1.0.0",
51
49
  "@types/node": "^20.2.5",
52
- "@types/lodash.isobject": "^3.0.7",
53
50
  "tsup": "^6.7.0",
54
- "typescript": "^5.1.3"
51
+ "typescript": "^5.1.3",
52
+ "@kubb/swagger": "1.0.2"
55
53
  },
56
54
  "publishConfig": {
57
55
  "access": "public",
58
56
  "registry": "https://registry.npmjs.org/"
59
57
  },
60
58
  "engines": {
61
- "node": "^12.17.0 || ^14.13 || >=16.0.0"
59
+ "node": ">=16",
60
+ "pnpm": ">=8"
62
61
  },
63
62
  "scripts": {
64
63
  "build": "tsup",
@@ -69,6 +68,6 @@
69
68
  "test": "vitest --passWithNoTests",
70
69
  "upgrade": "ncu -u",
71
70
  "upgrade:local": "ncu --interactive --doctor",
72
- "typecheck": "tsc -p ./tsconfig.json --noEmit"
71
+ "typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false"
73
72
  }
74
73
  }
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /* eslint-disable no-console */
3
+ import pathParser from 'node:path'
3
4
 
4
5
  import { Command, Option } from 'commander'
5
6
  import pc from 'picocolors'
@@ -7,9 +8,8 @@ import ora from 'ora'
7
8
 
8
9
  import type { CLIOptions } from '@kubb/core'
9
10
 
10
- import { run } from './run'
11
- import { startWatcher } from './utils/watcher'
12
- import { getConfig, getCosmiConfig } from './utils'
11
+ import { run } from './run.ts'
12
+ import { startWatcher, getConfig, getCosmiConfig } from './utils/index.ts'
13
13
 
14
14
  import { version } from '../package.json'
15
15
 
@@ -26,10 +26,9 @@ const program = new Command(moduleName)
26
26
  .action(async (options: CLIOptions) => {
27
27
  try {
28
28
  // CONFIG
29
-
30
29
  spinner.start('💾 Loading config')
31
30
  const result = await getCosmiConfig(moduleName, options.config)
32
- spinner.succeed('💾 Config loaded')
31
+ spinner.succeed(`💾 Config loaded(${pc.dim(pathParser.relative(process.cwd(), result.filepath))})`)
33
32
 
34
33
  // END CONFIG
35
34
 
@@ -53,10 +52,11 @@ const program = new Command(moduleName)
53
52
  await run({ config, spinner, options })
54
53
  }
55
54
  } catch (e) {
56
- spinner.fail(pc.red((e as Error).message))
55
+ process.exit(1)
57
56
  }
58
57
  })
59
58
  .addOption(new Option('-c, --config <path>', 'Path to the Kubb config'))
59
+ .addOption(new Option('-i, --input <path>', 'Path of the input file(overrides the on in `kubb.config.js`)'))
60
60
  .addOption(new Option('-d, --debug', 'Debug mode').default(false))
61
61
  .addOption(new Option('-w, --watch', 'Watch mode based on the input file'))
62
62
 
package/src/run.ts CHANGED
@@ -1,10 +1,15 @@
1
1
  /* eslint-disable no-console */
2
+ import pathParser from 'node:path'
3
+
2
4
  import pc from 'picocolors'
3
5
  import { execa } from 'execa'
4
6
  import { parseArgsStringToArgv } from 'string-argv'
7
+ import PrettyError from 'pretty-error'
8
+
9
+ import { ParallelPluginError, PluginError, build } from '@kubb/core'
10
+ import type { Logger, CLIOptions, KubbConfig, BuildOutput } from '@kubb/core'
5
11
 
6
- import { build } from '@kubb/core'
7
- import type { Logger, CLIOptions, KubbConfig } from '@kubb/core'
12
+ import { parseHrtimeToSeconds } from './utils/parseHrtimeToSeconds.ts'
8
13
 
9
14
  import type { Ora } from 'ora'
10
15
 
@@ -14,7 +19,8 @@ type RunProps = {
14
19
  options: CLIOptions
15
20
  }
16
21
 
17
- export async function run({ config, options, spinner }: RunProps) {
22
+ export async function run({ config, options, spinner }: RunProps): Promise<void> {
23
+ const hrstart = process.hrtime()
18
24
  const logger: Logger = {
19
25
  log(message, logLevel) {
20
26
  if (logLevel === 'error') {
@@ -38,7 +44,6 @@ export async function run({ config, options, spinner }: RunProps) {
38
44
  if (!hooks?.done) {
39
45
  return
40
46
  }
41
- spinner.start('🪂 Running hooks')
42
47
 
43
48
  let commands: string[] = []
44
49
  if (typeof hooks?.done === 'string') {
@@ -49,24 +54,90 @@ export async function run({ config, options, spinner }: RunProps) {
49
54
 
50
55
  const promises = commands.map(async (command) => {
51
56
  const [cmd, ..._args] = [...parseArgsStringToArgv(command)]
52
- return execa(cmd, _args)
57
+ spinner.start(`🪂 Executing hooks(${pc.yellow('done')}) ${pc.dim(command)}`)
58
+ await execa(cmd, _args)
59
+ spinner.succeed(`🪂 Executed hooks(${pc.yellow('done')}) ${pc.dim(command)}`)
53
60
  })
54
61
 
55
62
  await Promise.all(promises)
63
+ }
56
64
 
57
- spinner.succeed('🪂 Hooks runned')
65
+ const printSummary = (pluginManager: BuildOutput['pluginManager'], status: 'success' | 'failed') => {
66
+ const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(hrstart))
67
+
68
+ const buildStartPlugins = [
69
+ ...new Set(pluginManager.executed.filter((item) => item.hookName === 'buildStart' && item.plugin.name !== 'core').map((item) => item.plugin.name)),
70
+ ]
71
+ const pluginsCount = config.plugins?.length || 0
72
+ const files = pluginManager.fileManager.files.sort((a, b) => {
73
+ if (!a.meta?.pluginName || !b.meta?.pluginName) {
74
+ return 0
75
+ }
76
+ if (a.meta?.pluginName.length < b.meta?.pluginName.length) return 1
77
+ if (a.meta?.pluginName.length > b.meta?.pluginName.length) return -1
78
+ return 0
79
+ })
80
+
81
+ const meta = {
82
+ plugins:
83
+ status === 'success'
84
+ ? `${pc.green(`${buildStartPlugins.length} successful`)}, ${pluginsCount} total`
85
+ : `${pc.red(`${pluginsCount - buildStartPlugins.length} failed`)}, ${pluginsCount} total`,
86
+ filesCreated: files.length,
87
+ time: pc.yellow(`${elapsedSeconds}s`),
88
+ output: pathParser.resolve(config.root, config.output.path),
89
+ } as const
90
+
91
+ console.log(`
92
+ ${pc.bold('Plugins:')} ${meta.plugins}
93
+ ${pc.bold('Generated:')} ${meta.filesCreated} files
94
+ ${pc.bold('Time:')} ${meta.time}
95
+ ${pc.bold('Output:')} ${meta.output}
96
+ `)
97
+
98
+ if (options.debug) {
99
+ console.log(`${pc.bold('Generated files:')}`)
100
+ console.log(`${files.map((file) => `${pc.blue(file.meta?.pluginName)} ${file.path}`).join('\n')}`)
101
+ }
58
102
  }
59
103
 
60
- try {
61
- spinner.start('🚀 Building')
104
+ const printErrors = (error: Error) => {
105
+ const pe = new PrettyError()
106
+
107
+ if (error instanceof ParallelPluginError) {
108
+ error.errors.map((e) => printErrors(e))
109
+
110
+ return
111
+ }
112
+
113
+ if (options.debug) {
114
+ spinner.fail(pc.red(`Something went wrong\n\n`))
115
+ const causedError = (error as Error)?.cause as Error
62
116
 
117
+ console.log(pe.render(error))
118
+
119
+ if (causedError) {
120
+ console.log(pe.render(causedError))
121
+ }
122
+ } else {
123
+ spinner.fail(pc.red(`Something went wrong\n\n${(error as Error)?.message}`))
124
+ }
125
+ }
126
+
127
+ try {
63
128
  // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
64
129
  const { root, ...userConfig } = config
65
130
 
66
- await build({
131
+ spinner.start(`🚀 Building(${pc.dim(options.input ?? userConfig.input.path)})`)
132
+
133
+ const output = await build({
67
134
  config: {
68
135
  root: process.cwd(),
69
136
  ...userConfig,
137
+ input: {
138
+ ...userConfig.input,
139
+ path: options.input ?? userConfig.input.path,
140
+ },
70
141
  output: {
71
142
  write: true,
72
143
  ...userConfig.output,
@@ -75,23 +146,18 @@ export async function run({ config, options, spinner }: RunProps) {
75
146
  logger,
76
147
  })
77
148
 
78
- spinner.succeed(pc.blue('🌈 Generation complete'))
149
+ spinner.succeed(`🚀 Build completed(${pc.dim(options.input ?? userConfig.input.path)})`)
79
150
 
80
151
  await onDone(config.hooks)
81
- } catch (err) {
82
- if (options.debug) {
83
- spinner.fail(`Something went wrong\n`)
84
- const causedError = (err as Error)?.cause
85
- console.log(causedError || err)
86
- console.log('\n')
87
152
 
88
- if (causedError) {
89
- console.log(err)
90
- }
91
- } else {
92
- spinner.fail(`Something went wrong\n${(err as Error)?.message}`)
153
+ printSummary(output.pluginManager, 'success')
154
+ } catch (error: any) {
155
+ printErrors(error)
156
+
157
+ if (error instanceof PluginError || error instanceof ParallelPluginError) {
158
+ printSummary(error.pluginManager, 'failed')
93
159
  }
94
- }
95
160
 
96
- return true
161
+ throw error
162
+ }
97
163
  }
@@ -1,9 +1,9 @@
1
1
  import type { KubbUserConfig, KubbConfig, CLIOptions } from '@kubb/core'
2
2
  import { isPromise } from '@kubb/core'
3
3
 
4
- import { getPlugins } from './getPlugins'
4
+ import { getPlugins } from './getPlugins.ts'
5
5
 
6
- import type { CosmiconfigResult } from '../types'
6
+ import type { CosmiconfigResult } from '../types.ts'
7
7
 
8
8
  export async function getConfig(result: CosmiconfigResult, options: CLIOptions): Promise<KubbConfig> {
9
9
  const config = result?.config
@@ -1,8 +1,41 @@
1
- /* eslint-disable consistent-return */
2
- import { cosmiconfig, defaultLoaders } from 'cosmiconfig'
3
- import { TypeScriptLoader } from 'cosmiconfig-typescript-loader'
1
+ import { cosmiconfig } from 'cosmiconfig'
2
+ import yaml from 'yaml'
3
+ import tsNode from 'ts-node'
4
4
 
5
- import type { CosmiconfigResult } from '../types'
5
+ import { importModule } from './importModule.ts'
6
+
7
+ import type { CosmiconfigResult } from '../types.ts'
8
+
9
+ const jsLoader = async (configFile: string) => {
10
+ return importModule(configFile)
11
+ }
12
+ // TODO fix tsLoader for node 20
13
+ // https://github.com/TypeStrong/ts-node/issues/1997
14
+ const tsLoader = async (configFile: string) => {
15
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
16
+ let registerer = { enabled() {} }
17
+
18
+ try {
19
+ // Register TypeScript compiler instance
20
+ registerer = tsNode.register({
21
+ compilerOptions: { module: 'commonjs' },
22
+ swc: true,
23
+ typeCheck: false,
24
+ })
25
+
26
+ const module = require(configFile)
27
+ return module.default
28
+ } catch (err: any) {
29
+ if (err.code === 'MODULE_NOT_FOUND') {
30
+ throw new Error(`'ts-node' is required for the TypeScript configuration files. Make sure it is installed\nError: ${err.message}`)
31
+ }
32
+ console.log(err)
33
+
34
+ throw err
35
+ } finally {
36
+ registerer.enabled()
37
+ }
38
+ }
6
39
 
7
40
  export async function getCosmiConfig(moduleName: string, config?: string) {
8
41
  const explorer = cosmiconfig(moduleName, {
@@ -11,21 +44,27 @@ export async function getCosmiConfig(moduleName: string, config?: string) {
11
44
  'package.json',
12
45
  `.${moduleName}rc`,
13
46
  `.${moduleName}rc.json`,
14
- // commonjs
47
+ `.${moduleName}rc.yaml`,
48
+ `.${moduleName}rc.yml`,
49
+ // TODO fix tsLoader
50
+ `.${moduleName}rc.ts`,
15
51
  `.${moduleName}rc.js`,
16
52
  `.${moduleName}rc.cjs`,
53
+ `.${moduleName}rc.mjs`,
54
+ // TODO fix tsLoader
55
+ `${moduleName}.config.ts`,
17
56
  `${moduleName}.config.js`,
18
57
  `${moduleName}.config.cjs`,
19
- // esm and typescript
20
- `.${moduleName}rc.ts`,
21
- `${moduleName}.config.ts`,
58
+ `${moduleName}.config.mjs`,
22
59
  ],
23
60
  loaders: {
24
- '.ts': TypeScriptLoader({
25
- swc: true,
26
- typeCheck: false,
27
- }),
28
- noExt: defaultLoaders['.js'],
61
+ '.yaml': (filepath, content) => yaml.parse(content),
62
+ '.yml': (filepath, content) => yaml.parse(content),
63
+ '.js': jsLoader,
64
+ '.cjs': jsLoader,
65
+ '.mjs': jsLoader,
66
+ '.ts': tsLoader,
67
+ noExt: jsLoader,
29
68
  },
30
69
  })
31
70
 
@@ -1,9 +1,10 @@
1
- import { ModuleImporter } from '@humanwhocodes/module-importer'
2
- import isObject from 'lodash.isobject'
3
- // see https://github.com/eslint/eslint/blob/740b20826fadc5322ea5547c1ba41793944e571d/lib/cli.js
1
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
+ // @ts-nocheck
4
3
 
5
4
  import type { KubbUserConfig, KubbJSONPlugin, KubbObjectPlugin } from '@kubb/core'
6
5
 
6
+ import { importModule } from './importModule.ts'
7
+
7
8
  function isJSONPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): plugins is KubbJSONPlugin[] {
8
9
  return !!(plugins as KubbJSONPlugin[])?.some((plugin) => {
9
10
  return typeof plugin?.[0] === 'string'
@@ -11,15 +12,13 @@ function isJSONPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): p
11
12
  }
12
13
 
13
14
  function isObjectPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): plugins is KubbObjectPlugin {
14
- return isObject(plugins) && !Array.isArray(plugins)
15
+ return plugins instanceof Object && !Array.isArray(plugins)
15
16
  }
16
17
 
17
18
  async function importPlugin(name: string, options: object) {
18
- const importer = new ModuleImporter(process.cwd())
19
-
20
- const importedPlugin = process.env.NODE_ENV === 'test' ? await import(name) : await importer.import(name)
19
+ const importedPlugin = process.env.NODE_ENV === 'test' ? await import(name) : await importModule(name, process.cwd())
21
20
 
22
- return importedPlugin?.default?.default ? importedPlugin.default.default(options) : importedPlugin.default(options)
21
+ return importedPlugin?.default ? importedPlugin.default(options) : importedPlugin(options)
23
22
  }
24
23
 
25
24
  export function getPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): Promise<KubbUserConfig['plugins']> {
@@ -0,0 +1,35 @@
1
+ import { pathToFileURL } from 'node:url'
2
+ import mod from 'node:module'
3
+
4
+ const SLASHES = new Set(['/', '\\'])
5
+
6
+ /**
7
+ * Normalizes directories to have a trailing slash.
8
+ * Resolve is pretty finicky -- if the directory name doesn't have
9
+ * a trailing slash then it tries to look in the parent directory.
10
+ * i.e., if the directory is "/usr/nzakas/foo" it will start the
11
+ * search in /usr/nzakas. However, if the directory is "/user/nzakas/foo/",
12
+ * then it will start the search in /user/nzakas/foo.
13
+ * @param {string} directory The directory to check.
14
+ * @returns {string} The normalized directory.
15
+ */
16
+ function normalizeDirectory(directory: string) {
17
+ if (!SLASHES.has(directory[directory.length - 1])) {
18
+ return `${directory}/`
19
+ }
20
+
21
+ return directory
22
+ }
23
+
24
+ export async function importModule(path: string, cwd?: string) {
25
+ let location = path
26
+
27
+ if (cwd) {
28
+ const require = mod.createRequire(normalizeDirectory(cwd))
29
+ location = require.resolve(path)
30
+ }
31
+
32
+ const module = await import(pathToFileURL(location).href)
33
+
34
+ return module.default
35
+ }
@@ -1,4 +1,6 @@
1
- export * from './getConfig'
2
- export * from './getPlugins'
3
- export * from './watcher'
4
- export * from './getCosmiConfig'
1
+ export * from './getConfig.ts'
2
+ export * from './getPlugins.ts'
3
+ export * from './watcher.ts'
4
+ export * from './getCosmiConfig.ts'
5
+ export * from './importModule.ts'
6
+ export * from './parseHrtimeToSeconds.ts'
@@ -0,0 +1,4 @@
1
+ export function parseHrtimeToSeconds(hrtime: [number, number]) {
2
+ const seconds = (hrtime[0] + hrtime[1] / 1e9).toFixed(3)
3
+ return seconds
4
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/run.ts","../src/utils/watcher.ts","../src/utils/getConfig.ts","../src/utils/getPlugins.ts","../src/utils/getCosmiConfig.ts","../package.json"],"names":["pc","spinner","moduleName"],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/* eslint-disable no-console */\n\nimport { Command, Option } from 'commander'\nimport pc from 'picocolors'\nimport ora from 'ora'\n\nimport type { CLIOptions } from '@kubb/core'\n\nimport { run } from './run'\nimport { startWatcher } from './utils/watcher'\nimport { getConfig, getCosmiConfig } from './utils'\n\nimport { version } from '../package.json'\n\nconst moduleName = 'kubb'\n\nconst spinner = ora({\n color: 'blue',\n text: pc.blue('🏎️ Kubb generation started'),\n spinner: 'clock',\n}).start()\n\nconst program = new Command(moduleName)\n .description('Kubb')\n .action(async (options: CLIOptions) => {\n try {\n // CONFIG\n\n spinner.start('💾 Loading config')\n const result = await getCosmiConfig(moduleName, options.config)\n spinner.succeed('💾 Config loaded')\n\n // END CONFIG\n\n if (options.watch) {\n const config = await getConfig(result, options)\n\n startWatcher(\n async (paths) => {\n await run({ config, spinner, options })\n spinner.spinner = 'simpleDotsScrolling'\n spinner.start(pc.yellow(pc.bold(`Watching for changes in ${paths.join(' and ')}`)))\n },\n {\n spinner,\n path: [config.input.path],\n }\n )\n } else {\n const config = await getConfig(result, options)\n\n await run({ config, spinner, options })\n }\n } catch (e) {\n spinner.fail(pc.red((e as Error).message))\n }\n })\n .addOption(new Option('-c, --config <path>', 'Path to the Kubb config'))\n .addOption(new Option('-d, --debug', 'Debug mode').default(false))\n .addOption(new Option('-w, --watch', 'Watch mode based on the input file'))\n\nprogram.name(moduleName).description('Generate').version(version, '-v').parse()\n","/* eslint-disable no-console */\nimport pc from 'picocolors'\nimport { execa } from 'execa'\nimport { parseArgsStringToArgv } from 'string-argv'\n\nimport { build } from '@kubb/core'\nimport type { Logger, CLIOptions, KubbConfig } from '@kubb/core'\n\nimport type { Ora } from 'ora'\n\ntype RunProps = {\n config: KubbConfig\n spinner: Ora\n options: CLIOptions\n}\n\nexport async function run({ config, options, spinner }: RunProps) {\n const logger: Logger = {\n log(message, logLevel) {\n if (logLevel === 'error') {\n spinner.fail(message)\n }\n\n switch (logLevel) {\n case 'error':\n spinner.fail(message)\n break\n\n default:\n spinner.info(message)\n break\n }\n },\n spinner,\n }\n\n const onDone = async (hooks: KubbConfig['hooks']) => {\n if (!hooks?.done) {\n return\n }\n spinner.start('🪂 Running hooks')\n\n let commands: string[] = []\n if (typeof hooks?.done === 'string') {\n commands = [hooks.done]\n } else {\n commands = hooks.done\n }\n\n const promises = commands.map(async (command) => {\n const [cmd, ..._args] = [...parseArgsStringToArgv(command)]\n return execa(cmd, _args)\n })\n\n await Promise.all(promises)\n\n spinner.succeed('🪂 Hooks runned')\n }\n\n try {\n spinner.start('🚀 Building')\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars\n const { root, ...userConfig } = config\n\n await build({\n config: {\n root: process.cwd(),\n ...userConfig,\n output: {\n write: true,\n ...userConfig.output,\n },\n },\n logger,\n })\n\n spinner.succeed(pc.blue('🌈 Generation complete'))\n\n await onDone(config.hooks)\n } catch (err) {\n if (options.debug) {\n spinner.fail(`Something went wrong\\n`)\n const causedError = (err as Error)?.cause\n console.log(causedError || err)\n console.log('\\n')\n\n if (causedError) {\n console.log(err)\n }\n } else {\n spinner.fail(`Something went wrong\\n${(err as Error)?.message}`)\n }\n }\n\n return true\n}\n","import pc from 'picocolors'\n\nimport type { Ora } from 'ora'\n\ntype Options = {\n path: string[]\n spinner: Ora\n}\nexport async function startWatcher(cb: (path: string[]) => Promise<void>, options: Options) {\n const { spinner, path } = options\n const { watch } = await import('chokidar')\n\n const ignored = ['**/{.git,node_modules}/**']\n\n const watcher = watch(path, {\n ignorePermissionErrors: true,\n ignored,\n })\n watcher.on('all', async (type, file) => {\n spinner.succeed(pc.yellow(pc.bold(`Change detected: ${type} ${file}`)))\n // revert back\n spinner.spinner = 'clock'\n\n try {\n await cb(options.path)\n } catch (e) {\n spinner.warn(pc.red('Watcher failed'))\n }\n })\n}\n","import type { KubbUserConfig, KubbConfig, CLIOptions } from '@kubb/core'\nimport { isPromise } from '@kubb/core'\n\nimport { getPlugins } from './getPlugins'\n\nimport type { CosmiconfigResult } from '../types'\n\nexport async function getConfig(result: CosmiconfigResult, options: CLIOptions): Promise<KubbConfig> {\n const config = result?.config\n let kubbUserConfig: Promise<KubbUserConfig> = Promise.resolve(config) as Promise<KubbUserConfig>\n\n // for ts or js files\n if (typeof config === 'function') {\n const possiblePromise = config(options)\n if (isPromise(possiblePromise)) {\n kubbUserConfig = possiblePromise\n }\n kubbUserConfig = Promise.resolve(possiblePromise)\n }\n\n let JSONConfig = await kubbUserConfig\n JSONConfig = {\n ...JSONConfig,\n plugins: JSONConfig.plugins ? await getPlugins(JSONConfig.plugins) : undefined,\n }\n\n return JSONConfig as KubbConfig\n}\n","import { ModuleImporter } from '@humanwhocodes/module-importer'\nimport isObject from 'lodash.isobject'\n// see https://github.com/eslint/eslint/blob/740b20826fadc5322ea5547c1ba41793944e571d/lib/cli.js\n\nimport type { KubbUserConfig, KubbJSONPlugin, KubbObjectPlugin } from '@kubb/core'\n\nfunction isJSONPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): plugins is KubbJSONPlugin[] {\n return !!(plugins as KubbJSONPlugin[])?.some((plugin) => {\n return typeof plugin?.[0] === 'string'\n })\n}\n\nfunction isObjectPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): plugins is KubbObjectPlugin {\n return isObject(plugins) && !Array.isArray(plugins)\n}\n\nasync function importPlugin(name: string, options: object) {\n const importer = new ModuleImporter(process.cwd())\n\n const importedPlugin = process.env.NODE_ENV === 'test' ? await import(name) : await importer.import(name)\n\n return importedPlugin?.default?.default ? importedPlugin.default.default(options) : importedPlugin.default(options)\n}\n\nexport function getPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): Promise<KubbUserConfig['plugins']> {\n if (isObjectPlugins(plugins)) {\n const promises = Object.keys(plugins).map(async (name) => {\n return importPlugin(name, plugins[name as keyof typeof plugins])\n })\n return Promise.all(promises)\n }\n\n if (isJSONPlugins(plugins)) {\n const promises = plugins.map(async (plugin) => {\n const [name, options = {}] = plugin\n return importPlugin(name, options)\n })\n return Promise.all(promises)\n }\n return Promise.resolve(plugins)\n}\n","/* eslint-disable consistent-return */\nimport { cosmiconfig, defaultLoaders } from 'cosmiconfig'\nimport { TypeScriptLoader } from 'cosmiconfig-typescript-loader'\n\nimport type { CosmiconfigResult } from '../types'\n\nexport async function getCosmiConfig(moduleName: string, config?: string) {\n const explorer = cosmiconfig(moduleName, {\n cache: false,\n searchPlaces: [\n 'package.json',\n `.${moduleName}rc`,\n `.${moduleName}rc.json`,\n // commonjs\n `.${moduleName}rc.js`,\n `.${moduleName}rc.cjs`,\n `${moduleName}.config.js`,\n `${moduleName}.config.cjs`,\n // esm and typescript\n `.${moduleName}rc.ts`,\n `${moduleName}.config.ts`,\n ],\n loaders: {\n '.ts': TypeScriptLoader({\n swc: true,\n typeCheck: false,\n }),\n noExt: defaultLoaders['.js'],\n },\n })\n\n const result = config ? await explorer.load(config) : await explorer.search()\n\n if (result?.isEmpty || !result || !result.config) {\n throw new Error('Config not defined, create a kubb.config.js or pass through your config with the option --config')\n }\n\n return result as CosmiconfigResult\n}\n","{\n \"name\": \"@kubb/cli\",\n \"version\": \"1.0.0\",\n \"description\": \"Generator cli\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/kubb-project/kubb.git\",\n \"directory\": \"packages/cli\"\n },\n \"license\": \"MIT\",\n \"author\": \"Stijn Van Hulle <stijn@stijnvanhulle.be\",\n \"keywords\": [\n \"typescript\",\n \"plugins\",\n \"kubb\",\n \"codegen\",\n \"cli\"\n ],\n \"sideEffects\": false,\n \"type\": \"module\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"kubb\": \"dist/index.js\"\n },\n \"preferGlobal\": true,\n \"files\": [\n \"dist\",\n \"src\",\n \"!/**/**.test.**\",\n \"!/**/__tests__/**\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"start\": \"tsup --watch\",\n \"release\": \"pnpm publish --no-git-check\",\n \"prepack\": \"pnpm build\",\n \"pre-commit\": \"echo 'pre-commit not configured'\",\n \"pre-push\": \"pnpm typecheck\",\n \"test\": \"vitest --passWithNoTests\",\n \"upgrade\": \"ncu -u\",\n \"upgrade:local\": \"ncu --interactive --doctor\",\n \"typecheck\": \"tsc -p ./tsconfig.json --noEmit\"\n },\n \"dependencies\": {\n \"@humanwhocodes/module-importer\": \"^1.0.1\",\n \"@kubb/core\": \"workspace:*\",\n \"chokidar\": \"^3.5.3\",\n \"commander\": \"^10.0.1\",\n \"cosmiconfig\": \"^8.1.3\",\n \"cosmiconfig-typescript-loader\": \"^4.3.0\",\n \"execa\": \"^7.1.1\",\n \"ora\": \"^6.3.1\",\n \"picocolors\": \"^1.0.0\",\n \"lodash.isobject\": \"^3.0.2\",\n \"string-argv\": \"^0.3.2\",\n \"ts-node\": \"^10.9.1\",\n \"@swc/core\": \"^1.3.61\"\n },\n \"devDependencies\": {\n \"@kubb/swagger\": \"workspace:*\",\n \"@types/node\": \"^20.2.5\",\n \"@types/lodash.isobject\": \"^3.0.7\",\n \"tsup\": \"^6.7.0\",\n \"typescript\": \"^5.1.3\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"engines\": {\n \"node\": \"^12.17.0 || ^14.13 || >=16.0.0\"\n }\n}\n"]}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/run.ts","../src/utils/watcher.ts","../src/utils/getConfig.ts","../src/utils/getPlugins.ts","../src/utils/getCosmiConfig.ts","../package.json"],"names":["pc","spinner","moduleName"],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/* eslint-disable no-console */\n\nimport { Command, Option } from 'commander'\nimport pc from 'picocolors'\nimport ora from 'ora'\n\nimport type { CLIOptions } from '@kubb/core'\n\nimport { run } from './run'\nimport { startWatcher } from './utils/watcher'\nimport { getConfig, getCosmiConfig } from './utils'\n\nimport { version } from '../package.json'\n\nconst moduleName = 'kubb'\n\nconst spinner = ora({\n color: 'blue',\n text: pc.blue('🏎️ Kubb generation started'),\n spinner: 'clock',\n}).start()\n\nconst program = new Command(moduleName)\n .description('Kubb')\n .action(async (options: CLIOptions) => {\n try {\n // CONFIG\n\n spinner.start('💾 Loading config')\n const result = await getCosmiConfig(moduleName, options.config)\n spinner.succeed('💾 Config loaded')\n\n // END CONFIG\n\n if (options.watch) {\n const config = await getConfig(result, options)\n\n startWatcher(\n async (paths) => {\n await run({ config, spinner, options })\n spinner.spinner = 'simpleDotsScrolling'\n spinner.start(pc.yellow(pc.bold(`Watching for changes in ${paths.join(' and ')}`)))\n },\n {\n spinner,\n path: [config.input.path],\n }\n )\n } else {\n const config = await getConfig(result, options)\n\n await run({ config, spinner, options })\n }\n } catch (e) {\n spinner.fail(pc.red((e as Error).message))\n }\n })\n .addOption(new Option('-c, --config <path>', 'Path to the Kubb config'))\n .addOption(new Option('-d, --debug', 'Debug mode').default(false))\n .addOption(new Option('-w, --watch', 'Watch mode based on the input file'))\n\nprogram.name(moduleName).description('Generate').version(version, '-v').parse()\n","/* eslint-disable no-console */\nimport pc from 'picocolors'\nimport { execa } from 'execa'\nimport { parseArgsStringToArgv } from 'string-argv'\n\nimport { build } from '@kubb/core'\nimport type { Logger, CLIOptions, KubbConfig } from '@kubb/core'\n\nimport type { Ora } from 'ora'\n\ntype RunProps = {\n config: KubbConfig\n spinner: Ora\n options: CLIOptions\n}\n\nexport async function run({ config, options, spinner }: RunProps) {\n const logger: Logger = {\n log(message, logLevel) {\n if (logLevel === 'error') {\n spinner.fail(message)\n }\n\n switch (logLevel) {\n case 'error':\n spinner.fail(message)\n break\n\n default:\n spinner.info(message)\n break\n }\n },\n spinner,\n }\n\n const onDone = async (hooks: KubbConfig['hooks']) => {\n if (!hooks?.done) {\n return\n }\n spinner.start('🪂 Running hooks')\n\n let commands: string[] = []\n if (typeof hooks?.done === 'string') {\n commands = [hooks.done]\n } else {\n commands = hooks.done\n }\n\n const promises = commands.map(async (command) => {\n const [cmd, ..._args] = [...parseArgsStringToArgv(command)]\n return execa(cmd, _args)\n })\n\n await Promise.all(promises)\n\n spinner.succeed('🪂 Hooks runned')\n }\n\n try {\n spinner.start('🚀 Building')\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars\n const { root, ...userConfig } = config\n\n await build({\n config: {\n root: process.cwd(),\n ...userConfig,\n output: {\n write: true,\n ...userConfig.output,\n },\n },\n logger,\n })\n\n spinner.succeed(pc.blue('🌈 Generation complete'))\n\n await onDone(config.hooks)\n } catch (err) {\n if (options.debug) {\n spinner.fail(`Something went wrong\\n`)\n const causedError = (err as Error)?.cause\n console.log(causedError || err)\n console.log('\\n')\n\n if (causedError) {\n console.log(err)\n }\n } else {\n spinner.fail(`Something went wrong\\n${(err as Error)?.message}`)\n }\n }\n\n return true\n}\n","import pc from 'picocolors'\n\nimport type { Ora } from 'ora'\n\ntype Options = {\n path: string[]\n spinner: Ora\n}\nexport async function startWatcher(cb: (path: string[]) => Promise<void>, options: Options) {\n const { spinner, path } = options\n const { watch } = await import('chokidar')\n\n const ignored = ['**/{.git,node_modules}/**']\n\n const watcher = watch(path, {\n ignorePermissionErrors: true,\n ignored,\n })\n watcher.on('all', async (type, file) => {\n spinner.succeed(pc.yellow(pc.bold(`Change detected: ${type} ${file}`)))\n // revert back\n spinner.spinner = 'clock'\n\n try {\n await cb(options.path)\n } catch (e) {\n spinner.warn(pc.red('Watcher failed'))\n }\n })\n}\n","import type { KubbUserConfig, KubbConfig, CLIOptions } from '@kubb/core'\nimport { isPromise } from '@kubb/core'\n\nimport { getPlugins } from './getPlugins'\n\nimport type { CosmiconfigResult } from '../types'\n\nexport async function getConfig(result: CosmiconfigResult, options: CLIOptions): Promise<KubbConfig> {\n const config = result?.config\n let kubbUserConfig: Promise<KubbUserConfig> = Promise.resolve(config) as Promise<KubbUserConfig>\n\n // for ts or js files\n if (typeof config === 'function') {\n const possiblePromise = config(options)\n if (isPromise(possiblePromise)) {\n kubbUserConfig = possiblePromise\n }\n kubbUserConfig = Promise.resolve(possiblePromise)\n }\n\n let JSONConfig = await kubbUserConfig\n JSONConfig = {\n ...JSONConfig,\n plugins: JSONConfig.plugins ? await getPlugins(JSONConfig.plugins) : undefined,\n }\n\n return JSONConfig as KubbConfig\n}\n","import { ModuleImporter } from '@humanwhocodes/module-importer'\nimport isObject from 'lodash.isobject'\n// see https://github.com/eslint/eslint/blob/740b20826fadc5322ea5547c1ba41793944e571d/lib/cli.js\n\nimport type { KubbUserConfig, KubbJSONPlugin, KubbObjectPlugin } from '@kubb/core'\n\nfunction isJSONPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): plugins is KubbJSONPlugin[] {\n return !!(plugins as KubbJSONPlugin[])?.some((plugin) => {\n return typeof plugin?.[0] === 'string'\n })\n}\n\nfunction isObjectPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): plugins is KubbObjectPlugin {\n return isObject(plugins) && !Array.isArray(plugins)\n}\n\nasync function importPlugin(name: string, options: object) {\n const importer = new ModuleImporter(process.cwd())\n\n const importedPlugin = process.env.NODE_ENV === 'test' ? await import(name) : await importer.import(name)\n\n return importedPlugin?.default?.default ? importedPlugin.default.default(options) : importedPlugin.default(options)\n}\n\nexport function getPlugins(plugins: KubbUserConfig['plugins'] | KubbJSONPlugin[]): Promise<KubbUserConfig['plugins']> {\n if (isObjectPlugins(plugins)) {\n const promises = Object.keys(plugins).map(async (name) => {\n return importPlugin(name, plugins[name as keyof typeof plugins])\n })\n return Promise.all(promises)\n }\n\n if (isJSONPlugins(plugins)) {\n const promises = plugins.map(async (plugin) => {\n const [name, options = {}] = plugin\n return importPlugin(name, options)\n })\n return Promise.all(promises)\n }\n return Promise.resolve(plugins)\n}\n","/* eslint-disable consistent-return */\nimport { cosmiconfig, defaultLoaders } from 'cosmiconfig'\nimport { TypeScriptLoader } from 'cosmiconfig-typescript-loader'\n\nimport type { CosmiconfigResult } from '../types'\n\nexport async function getCosmiConfig(moduleName: string, config?: string) {\n const explorer = cosmiconfig(moduleName, {\n cache: false,\n searchPlaces: [\n 'package.json',\n `.${moduleName}rc`,\n `.${moduleName}rc.json`,\n // commonjs\n `.${moduleName}rc.js`,\n `.${moduleName}rc.cjs`,\n `${moduleName}.config.js`,\n `${moduleName}.config.cjs`,\n // esm and typescript\n `.${moduleName}rc.ts`,\n `${moduleName}.config.ts`,\n ],\n loaders: {\n '.ts': TypeScriptLoader({\n swc: true,\n typeCheck: false,\n }),\n noExt: defaultLoaders['.js'],\n },\n })\n\n const result = config ? await explorer.load(config) : await explorer.search()\n\n if (result?.isEmpty || !result || !result.config) {\n throw new Error('Config not defined, create a kubb.config.js or pass through your config with the option --config')\n }\n\n return result as CosmiconfigResult\n}\n","{\n \"name\": \"@kubb/cli\",\n \"version\": \"1.0.0\",\n \"description\": \"Generator cli\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/kubb-project/kubb.git\",\n \"directory\": \"packages/cli\"\n },\n \"license\": \"MIT\",\n \"author\": \"Stijn Van Hulle <stijn@stijnvanhulle.be\",\n \"keywords\": [\n \"typescript\",\n \"plugins\",\n \"kubb\",\n \"codegen\",\n \"cli\"\n ],\n \"sideEffects\": false,\n \"type\": \"module\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"bin\": {\n \"kubb\": \"dist/index.js\"\n },\n \"preferGlobal\": true,\n \"files\": [\n \"dist\",\n \"src\",\n \"!/**/**.test.**\",\n \"!/**/__tests__/**\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"start\": \"tsup --watch\",\n \"release\": \"pnpm publish --no-git-check\",\n \"prepack\": \"pnpm build\",\n \"pre-commit\": \"echo 'pre-commit not configured'\",\n \"pre-push\": \"pnpm typecheck\",\n \"test\": \"vitest --passWithNoTests\",\n \"upgrade\": \"ncu -u\",\n \"upgrade:local\": \"ncu --interactive --doctor\",\n \"typecheck\": \"tsc -p ./tsconfig.json --noEmit\"\n },\n \"dependencies\": {\n \"@humanwhocodes/module-importer\": \"^1.0.1\",\n \"@kubb/core\": \"workspace:*\",\n \"chokidar\": \"^3.5.3\",\n \"commander\": \"^10.0.1\",\n \"cosmiconfig\": \"^8.1.3\",\n \"cosmiconfig-typescript-loader\": \"^4.3.0\",\n \"execa\": \"^7.1.1\",\n \"ora\": \"^6.3.1\",\n \"picocolors\": \"^1.0.0\",\n \"lodash.isobject\": \"^3.0.2\",\n \"string-argv\": \"^0.3.2\",\n \"ts-node\": \"^10.9.1\",\n \"@swc/core\": \"^1.3.61\"\n },\n \"devDependencies\": {\n \"@kubb/swagger\": \"workspace:*\",\n \"@types/node\": \"^20.2.5\",\n \"@types/lodash.isobject\": \"^3.0.7\",\n \"tsup\": \"^6.7.0\",\n \"typescript\": \"^5.1.3\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"engines\": {\n \"node\": \"^12.17.0 || ^14.13 || >=16.0.0\"\n }\n}\n"]}