@nanoforge-dev/cli 1.5.4-beta.acc5439 → 1.5.4-beta.c7cb939

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/nf.js CHANGED
@@ -4,7 +4,7 @@ import "reflect-metadata";
4
4
  import { execSync, spawn } from "node:child_process";
5
5
  import fs, { existsSync } from "fs";
6
6
  import { join, posix, resolve } from "path";
7
- import { bgRgb, bold, green, red, yellow } from "ansis";
7
+ import { bgRgb, bold, cyan, green, red, yellow } from "ansis";
8
8
  import { get } from "node-emoji";
9
9
  import ora from "ora";
10
10
  import { watch } from "chokidar";
@@ -232,12 +232,79 @@ const Prefixes = {
232
232
  //#region src/lib/ui/spinner.ts
233
233
  const getSpinner = (message) => ora({ text: message });
234
234
  //#endregion
235
+ //#region src/lib/utils/errors.ts
236
+ var CLIError = class extends Error {
237
+ suggestion;
238
+ constructor(message, suggestion) {
239
+ super(message);
240
+ this.name = this.constructor.name;
241
+ this.suggestion = suggestion;
242
+ Object.setPrototypeOf(this, new.target.prototype);
243
+ }
244
+ };
245
+ var ConfigNotFoundError = class extends CLIError {
246
+ constructor(configPath) {
247
+ super(`Configuration file not found at path: ${configPath}.`, "Please run 'nf new' or provide a valid --config path.");
248
+ }
249
+ };
250
+ var InvalidCommandArgumentError = class extends CLIError {
251
+ constructor(argName, expected) {
252
+ super(`Invalid argument '${argName}'. Expected: ${expected}.`, "Verify the command syntax using the --help flag.");
253
+ }
254
+ };
255
+ var RegistryAuthenticationError = class extends CLIError {
256
+ constructor() {
257
+ super("You must be logged in to perform this action.", "Run 'nf login' to authenticate.");
258
+ }
259
+ };
260
+ var ManifestError = class extends CLIError {
261
+ constructor(detail) {
262
+ super(`Manifest Error: ${detail}`, "Check your nanoforge.manifest.json file for syntax or formatting errors.");
263
+ }
264
+ };
265
+ var FileSystemError = class extends CLIError {
266
+ constructor(action, targetPath) {
267
+ super(`File System Error [${action}]: ${targetPath}`, "Verify your file permissions and ensure the path exists.");
268
+ }
269
+ };
270
+ var ApiRequestError = class extends CLIError {
271
+ constructor(status, cause) {
272
+ const causeStr = cause && typeof cause === "object" ? JSON.stringify(cause, null, 2) : cause;
273
+ super(`API Request failed (Status ${status})${causeStr ? `\nDetails: ${causeStr}` : ""}`, "Check your network connection, API key, or the registry status.");
274
+ }
275
+ };
276
+ const getErrorString = (error) => {
277
+ const stack = error.stack ? error.stack : error.message;
278
+ const cause = error.cause && typeof error.cause === "object" ? JSON.stringify(error.cause, null, 2) : error.cause;
279
+ return `${stack}${cause ? `\n${cause}` : ""}`;
280
+ };
281
+ const getErrorMessage = (error) => {
282
+ if (error instanceof Error) return getErrorString(error);
283
+ if (typeof error === "string") return error;
284
+ };
285
+ const handleActionError = (context, error) => {
286
+ console.error();
287
+ console.error(red(context));
288
+ if (error instanceof CLIError) {
289
+ console.error(error.message);
290
+ if (error.suggestion) console.info(cyan(`\nšŸ’” Suggestion: ${error.suggestion}`));
291
+ process.exit(1);
292
+ }
293
+ const msg = getErrorMessage(error);
294
+ if (msg) console.error(msg);
295
+ process.exit(1);
296
+ };
297
+ const promptError = (err) => {
298
+ if (err.name === "ExitPromptError") process.exit(1);
299
+ throw err;
300
+ };
301
+ //#endregion
235
302
  //#region src/lib/input/base-inputs.ts
236
303
  const getStringInput = (input, field) => {
237
304
  const value = input.get(field)?.value;
238
305
  if (value === void 0) return void 0;
239
306
  if (typeof value === "string") return value;
240
- throw new Error(`Invalid type for ${field}`);
307
+ throw new InvalidCommandArgumentError(field, "string");
241
308
  };
242
309
  const getStringInputWithDefault = (input, field, defaultValue) => {
243
310
  return getStringInput(input, field) ?? defaultValue;
@@ -246,7 +313,7 @@ const getBooleanInput = (input, field) => {
246
313
  const value = input.get(field)?.value;
247
314
  if (value === void 0) return void 0;
248
315
  if (typeof value === "boolean") return value;
249
- throw new Error(`Invalid type for ${field}`);
316
+ throw new InvalidCommandArgumentError(field, "boolean");
250
317
  };
251
318
  const getBooleanInputWithDefault = (input, field, defaultValue) => {
252
319
  return getBooleanInput(input, field) ?? defaultValue;
@@ -255,7 +322,7 @@ const getArrayInput = (input, field) => {
255
322
  const value = input.get(field)?.value;
256
323
  if (value === void 0) return void 0;
257
324
  if (typeof value === "object" && Array.isArray(value)) return value;
258
- throw new Error(`Invalid type for ${field}`);
325
+ throw new InvalidCommandArgumentError(field, "array");
259
326
  };
260
327
  //#endregion
261
328
  //#region src/lib/input/ask-inputs.ts
@@ -264,7 +331,7 @@ const getInputOrAsk = async (baseInput, askCb, defaultValue) => {
264
331
  const res = await askCb();
265
332
  if (res !== void 0) return res;
266
333
  if (defaultValue !== void 0) return defaultValue;
267
- throw new Error("No input provided");
334
+ throw new CLIError("No input provided. Please provide a valid value.");
268
335
  };
269
336
  //#endregion
270
337
  //#region src/lib/input/inputs/directory.input.ts
@@ -283,28 +350,6 @@ const getEditorInput = (inputs) => {
283
350
  return getBooleanInputWithDefault(inputs, "editor", false);
284
351
  };
285
352
  //#endregion
286
- //#region src/lib/utils/errors.ts
287
- const getErrorMessage = (error) => {
288
- if (error instanceof Error) return getErrorString(error);
289
- if (typeof error === "string") return error;
290
- };
291
- const getErrorString = (error) => {
292
- const stack = error.stack ? error.stack : error.message;
293
- const cause = error.cause && typeof error.cause === "object" ? JSON.stringify(error.cause, null, 2) : error.cause;
294
- return `${stack}${cause ? `\n${cause}` : ""}`;
295
- };
296
- const handleActionError = (context, error) => {
297
- console.error();
298
- console.error(red(context));
299
- const msg = getErrorMessage(error);
300
- if (msg) console.error(msg);
301
- process.exit(1);
302
- };
303
- const promptError = (err) => {
304
- if (err.name === "ExitPromptError") process.exit(1);
305
- throw err;
306
- };
307
- //#endregion
308
353
  //#region src/lib/question/questions/confirm.question.ts
309
354
  const askConfirm = async (question, baseOptions) => {
310
355
  return await confirm({
@@ -396,7 +441,7 @@ const getWatchInput = (inputs) => {
396
441
  const getCreateTypeInput = (inputs) => {
397
442
  const res = getStringInput(inputs, "type");
398
443
  if (res && ["component", "system"].includes(res)) return res;
399
- throw new Error("Invalid type. Please enter 'component' or 'system'.");
444
+ throw new InvalidCommandArgumentError("type", "'component' or 'system'");
400
445
  };
401
446
  //#endregion
402
447
  //#region src/lib/input/inputs/dev/generate.input.ts
@@ -532,7 +577,7 @@ const resolveCLINodeBinaryPath = (name) => {
532
577
  base = join(base, "..");
533
578
  }
534
579
  }
535
- throw new Error("Could not find module path");
580
+ throw new FileSystemError("resolve binary", name);
536
581
  };
537
582
  //#endregion
538
583
  //#region src/lib/utils/spinner.ts
@@ -651,7 +696,7 @@ var PackageManager = class {
651
696
  return (await withSpinner(() => this.exec(args, directory), Messages.PACKAGE_MANAGER_INSTALLATION_IN_PROGRESS, Messages.PACKAGE_MANAGER_INSTALLATION_SUCCEED(), Messages.PACKAGE_MANAGER_INSTALLATION_FAILED(this.formatFailCommand(args)))).success;
652
697
  }
653
698
  assertSupports(feature) {
654
- if (!this.commands[feature]) throw new Error(`Package manager "${this.name}" does not support "${feature}"`);
699
+ if (!this.commands[feature]) throw new CLIError(`Package manager "${this.name}" does not support "${feature}"`);
655
700
  }
656
701
  buildRunArgs(script, params, flags, silent) {
657
702
  const args = [...flags, this.commands.run];
@@ -662,7 +707,7 @@ var PackageManager = class {
662
707
  return args.concat(params);
663
708
  }
664
709
  buildRunFileArgs(script, params, flags, silent) {
665
- if (!this.commands.runFile) throw new Error("Package manager does not support runFile");
710
+ if (!this.commands.runFile) throw new CLIError("Package manager does not support runFile");
666
711
  const args = [...flags, this.commands.runFile];
667
712
  if (silent) args.push(this.commands.silentFlag);
668
713
  args.push(script);
@@ -776,7 +821,7 @@ var RunnerFactory = class {
776
821
  try {
777
822
  return getModulePath("@angular-devkit/schematics-cli/bin/schematics.js");
778
823
  } catch {
779
- throw new Error("'schematics' binary path could not be found!");
824
+ throw new CLIError("'schematics' binary path could not be found!");
780
825
  }
781
826
  }
782
827
  };
@@ -868,7 +913,7 @@ const LOCK_FILE_MAP = {
868
913
  var PackageManagerFactory = class {
869
914
  static create(name) {
870
915
  const config = PM_CONFIGS[name];
871
- if (!config) throw new Error(`Package manager ${name} is not managed.`);
916
+ if (!config) throw new CLIError(`Package manager '${name}' is not managed/supported.`);
872
917
  const runner = this.createRunner(name, config.binary);
873
918
  return new PackageManager(name, config.commands, runner);
874
919
  }
@@ -892,7 +937,7 @@ var PackageManagerFactory = class {
892
937
  //#region src/lib/utils/files.ts
893
938
  const copyFiles = (from, to) => {
894
939
  if (!fs.existsSync(from)) return;
895
- if (!fs.existsSync(to)) throw new Error(`Directory ${to} does not exist`);
940
+ if (!fs.existsSync(to)) throw new FileSystemError("directory not found", to);
896
941
  fs.readdirSync(from, { recursive: true }).forEach((file) => {
897
942
  fs.copyFileSync(join(from, file.toString()), join(to, file.toString()));
898
943
  });
@@ -1119,7 +1164,7 @@ const getConfigPath = (directory, name) => {
1119
1164
  const path = join$1(directory, n);
1120
1165
  if (existsSync$1(path)) return path;
1121
1166
  }
1122
- throw new Error(`No config file found in directory: ${directory}`);
1167
+ throw new ConfigNotFoundError(join$1(directory, CONFIG_FILE_NAME));
1123
1168
  }
1124
1169
  };
1125
1170
  const loadConfig = async (directory, name, noThrow = false) => {
@@ -1131,10 +1176,10 @@ const loadConfig = async (directory, name, noThrow = false) => {
1131
1176
  } catch {
1132
1177
  rawData = noThrow ? CONFIG_DEFAULTS : null;
1133
1178
  }
1134
- if (!rawData) throw new Error(`Not able to read config file : ${path}`);
1179
+ if (!rawData) throw new FileSystemError("read config file", path);
1135
1180
  const data = plainToInstance(Config, rawData, { excludeExtraneousValues: true });
1136
1181
  const errors = await validate(data);
1137
- if (errors.length > 0) throw new Error(`Invalid config :\n${errors.toString().replace(/,/g, "\n")}`);
1182
+ if (errors.length > 0) throw new CLIError(`Invalid config:\n${errors.toString().replace(/,/g, "\n")}`);
1138
1183
  config = data;
1139
1184
  return config;
1140
1185
  };
@@ -1324,7 +1369,7 @@ var NanoforgeCollection = class NanoforgeCollection extends AbstractCollection {
1324
1369
  }
1325
1370
  validate(name) {
1326
1371
  const schematic = NanoforgeCollection.schematics.find((s) => s.name === name || s.alias === name);
1327
- if (schematic === void 0 || schematic === null) throw new Error(`Invalid schematic "${name}". Please, ensure that "${name}" exists in this collection.`);
1372
+ if (schematic === void 0 || schematic === null) throw new CLIError(`Invalid schematic "${name}". Please, ensure that "${name}" exists in this collection.`);
1328
1373
  return schematic.name;
1329
1374
  }
1330
1375
  };
@@ -1334,7 +1379,7 @@ var CollectionFactory = class {
1334
1379
  static create(collection, directory) {
1335
1380
  const schematicRunner = RunnerFactory.createSchematic();
1336
1381
  if (collection === "@nanoforge-dev/schematics") return new NanoforgeCollection(schematicRunner, directory);
1337
- throw new Error(`Unknown collection: ${collection}`);
1382
+ throw new CLIError(`Unknown collection: ${collection}`);
1338
1383
  }
1339
1384
  };
1340
1385
  //#endregion
@@ -1669,27 +1714,24 @@ var Repository = class {
1669
1714
  async runRequest(request, path, options) {
1670
1715
  const res = await this._client[request](path, options);
1671
1716
  const data = await res.json();
1672
- if (!res.ok) throw new Error(`Request failed with status code ${res.status}`, { cause: data["error"] });
1717
+ if (!res.ok) throw new ApiRequestError(res.status, data["error"]);
1673
1718
  return data;
1674
1719
  }
1675
1720
  async runFileRequest(request, path, options) {
1676
1721
  const res = await this._client[request](path, options);
1677
- if (!res.ok) throw new Error(`Request failed with status code ${res.status}`, { cause: (await res.json())["error"] });
1722
+ if (!res.ok) throw new ApiRequestError(res.status, (await res.json())["error"]);
1678
1723
  return await res.blob();
1679
1724
  }
1680
1725
  async runRequestBody(request, path, body, options) {
1681
1726
  const res = await this._client[request](path, body === void 0 ? void 0 : body instanceof FormData ? body : JSON.stringify(body), options);
1682
1727
  const data = await res.json();
1683
- if (!res.ok) throw new Error(`Request failed with status code ${res.status}`, { cause: data["error"] });
1728
+ if (!res.ok) throw new ApiRequestError(res.status, data["error"]);
1684
1729
  return data;
1685
1730
  }
1686
1731
  };
1687
1732
  new Repository(new HttpClient("https://api.nanoforge.eu"));
1688
1733
  const withAuth = (apiKey, force = false, headers = { "Content-Type": "application/json" }) => {
1689
- if (!apiKey && force) {
1690
- console.error("No registry key found. Please use `nf login` to login");
1691
- throw new Error("No apikey found. Please use `nf login` to login");
1692
- }
1734
+ if (!apiKey && force) throw new RegistryAuthenticationError();
1693
1735
  return new Repository(new HttpClient("https://api.nanoforge.eu", { headers: {
1694
1736
  Authorization: apiKey,
1695
1737
  ...headers
@@ -1765,12 +1807,12 @@ var Registry = class {
1765
1807
  }
1766
1808
  static _getPackageFile(filename, dir) {
1767
1809
  const path = join(getCwd(dir ?? "."), filename);
1768
- if (!fs.existsSync(path)) throw new Error("Package not found, please specify path in the nanoforge.manifest.json : `publish.paths.package`!");
1810
+ if (!fs.existsSync(path)) throw new CLIError("Package not found, please specify path in the nanoforge.manifest.json : `publish.paths.package`!");
1769
1811
  try {
1770
1812
  fs.accessSync(path, fs.constants.R_OK);
1771
1813
  return fs.openAsBlob(path);
1772
1814
  } catch {
1773
- throw new Error("Cannot read package file, please verify your file permissions!");
1815
+ throw new CLIError("Cannot read package file, please verify your file permissions!");
1774
1816
  }
1775
1817
  }
1776
1818
  };
@@ -2077,7 +2119,7 @@ const getManifestPath = (directory) => {
2077
2119
  const path = join$1(directory, n);
2078
2120
  if (existsSync$1(path)) return path;
2079
2121
  }
2080
- throw new Error(`No manifest file found in directory: ${directory}`);
2122
+ throw new ManifestError(`No manifest file found in directory: ${directory}`);
2081
2123
  };
2082
2124
  const loadManifest = async (directory) => {
2083
2125
  let rawData;
@@ -2087,10 +2129,10 @@ const loadManifest = async (directory) => {
2087
2129
  } catch {
2088
2130
  rawData = null;
2089
2131
  }
2090
- if (!rawData) throw new Error(`Not able to read manifest file : ${path}`);
2132
+ if (!rawData) throw new ManifestError(`Unable to read or parse file at ${path}`);
2091
2133
  const data = plainToInstance(Manifest, rawData, { excludeExtraneousValues: true });
2092
2134
  const errors = await validate(data);
2093
- if (errors.length > 0) throw new Error(`Invalid manifest\n${errors.toString().replace(/,/g, "\n")}`);
2135
+ if (errors.length > 0) throw new ManifestError(`Validation failed\n${errors.toString()}`);
2094
2136
  return data;
2095
2137
  };
2096
2138
  //#endregion
@@ -2133,8 +2175,8 @@ var StartAction = class extends AbstractAction {
2133
2175
  const cert = getStringInput(options, "cert");
2134
2176
  const key = getStringInput(options, "key");
2135
2177
  if (!cert && !key) return void 0;
2136
- if (!cert) throw new Error("No cert entered for SSL. Please enter a key with --cert.");
2137
- if (!key) throw new Error("No key entered for SSL. Please enter a key with --key.");
2178
+ if (!cert) throw new CLIError("No cert entered for SSL. Please enter a cert with --cert.");
2179
+ if (!key) throw new CLIError("No key entered for SSL. Please enter a key with --key.");
2138
2180
  return {
2139
2181
  cert,
2140
2182
  key
@@ -2453,7 +2495,7 @@ var CommandLoader = class {
2453
2495
  };
2454
2496
  //#endregion
2455
2497
  //#region package.json
2456
- var version = "1.5.4-beta.acc5439";
2498
+ var version = "1.5.4-beta.c7cb939";
2457
2499
  //#endregion
2458
2500
  //#region src/bin/nf.ts
2459
2501
  const bootstrap = async () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@nanoforge-dev/cli",
4
- "version": "1.5.4-beta.acc5439",
4
+ "version": "1.5.4-beta.c7cb939",
5
5
  "description": "NanoForge CLI",
6
6
  "keywords": [
7
7
  "nanoforge",