@moewolf/moe-icons-cli 0.0.28 → 0.0.29

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/cli.js CHANGED
@@ -976,6 +976,9 @@ async function runInstall(group, runtime, json, noTailwind, sourceVersion, expec
976
976
  if (!result.ok && result.reason === "checksum-mismatch") {
977
977
  throw new CliError("VALIDATION_ERROR", result.message);
978
978
  }
979
+ if (!result.ok && result.reason === "forbidden") {
980
+ throw new CliError("FORBIDDEN", result.message);
981
+ }
979
982
  if (!result.ok && (result.reason === "network" || result.reason === "offline-no-cache")) {
980
983
  throw new CliError("NETWORK_ERROR", result.message);
981
984
  }
@@ -54,6 +54,10 @@ export type InstallResult = {
54
54
  readonly ok: false;
55
55
  readonly reason: "disk-full";
56
56
  readonly message: string;
57
+ } | {
58
+ readonly ok: false;
59
+ readonly reason: "forbidden";
60
+ readonly message: string;
57
61
  } | {
58
62
  readonly ok: false;
59
63
  readonly reason: "validation";
@@ -63,6 +67,13 @@ export type InstallResult = {
63
67
  readonly reason: "write-failed";
64
68
  readonly message: string;
65
69
  };
70
+ /**
71
+ * Map a package-install failure message to its user-facing reason. A 403 from
72
+ * the Pro package-set endpoint is an entitlement denial (FORBIDDEN), not an
73
+ * unexpected write failure; denied accounts must see the same code as the
74
+ * documented Pro authorization contract.
75
+ */
76
+ export declare function classifyInstallError(message: string): "cancelled" | "disk-full" | "not-found" | "forbidden" | "network" | "checksum-mismatch" | "validation" | "write-failed";
66
77
  export interface InstallUseCaseDeps {
67
78
  readonly fs: TransactionalFs;
68
79
  readonly download: Omit<FreeDownloadIo, "signal">;
@@ -10,6 +10,29 @@ import { configuredComponentFiles, selectTargetSubtreeAsync, selectTargetSubtree
10
10
  import { parseCatalog } from "../catalog/catalog.js";
11
11
  import { posix } from "node:path";
12
12
  import { runSmallPackageInstall } from "./small-package-install.js";
13
+ /**
14
+ * Map a package-install failure message to its user-facing reason. A 403 from
15
+ * the Pro package-set endpoint is an entitlement denial (FORBIDDEN), not an
16
+ * unexpected write failure; denied accounts must see the same code as the
17
+ * documented Pro authorization contract.
18
+ */
19
+ export function classifyInstallError(message) {
20
+ if (/CANCELLED|cancelled/i.test(message))
21
+ return "cancelled";
22
+ if (/ENOSPC|no space left/i.test(message))
23
+ return "disk-full";
24
+ if (/HTTP_ERROR[^\n]*\b404\b/i.test(message))
25
+ return "not-found";
26
+ if (/HTTP_ERROR[^\n]*\b403\b|FORBIDDEN|active pro entitlement required/i.test(message))
27
+ return "forbidden";
28
+ if (/HTTP_ERROR[^\n]*\b5\d\d\b|NETWORK_ERROR|network|fetch failed|timed out/i.test(message))
29
+ return "network";
30
+ if (/checksum|SHA-256|digest mismatch|differs from immutable version pointer/i.test(message))
31
+ return "checksum-mismatch";
32
+ if (/config changed|unsafe|invalid|requires downloadMode|candidate-set:|config package plan:|small package install currently/i.test(message))
33
+ return "validation";
34
+ return "write-failed";
35
+ }
13
36
  /**
14
37
  * P0-3: the project `types.ts` must re-export a type that actually exists in the
15
38
  * installed `moe-icons` package. Assets have no component type, so it is empty.
@@ -147,17 +170,7 @@ export async function runInstallUseCase(context, deps, options) {
147
170
  const message = error instanceof Error ? error.message : String(error);
148
171
  if (context.signal?.aborted || /CANCELLED|cancelled/i.test(message))
149
172
  return { ok: false, reason: "cancelled", message };
150
- if (/ENOSPC|no space left/i.test(message))
151
- return { ok: false, reason: "disk-full", message };
152
- if (/HTTP_ERROR[^\n]*\b404\b/i.test(message))
153
- return { ok: false, reason: "not-found", message };
154
- if (/HTTP_ERROR[^\n]*\b5\d\d\b|NETWORK_ERROR|network|fetch failed|timed out/i.test(message))
155
- return { ok: false, reason: "network", message };
156
- if (/checksum|SHA-256|digest mismatch|differs from immutable version pointer/i.test(message))
157
- return { ok: false, reason: "checksum-mismatch", message };
158
- if (/config changed|unsafe|invalid|requires downloadMode|candidate-set:|config package plan:|small package install currently/i.test(message))
159
- return { ok: false, reason: "validation", message };
160
- return { ok: false, reason: "write-failed", message };
173
+ return { ok: false, reason: classifyInstallError(message), message };
161
174
  }
162
175
  }
163
176
  const downloaded = await downloadFreeRelease({ ...deps.download, signal: context.signal }, options.sourceVersion ?? bundledSourceVersion(), config.kind === "ok"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moewolf/moe-icons-cli",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "description": "Moeicons CLI: install React, Vue, Vanilla, or Assets icon targets, manage releases and login, and expose an MCP server.",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",
@@ -74,5 +74,5 @@
74
74
  "fflate": "^0.8.2",
75
75
  "jsonc-parser": "^3.3.1"
76
76
  },
77
- "payloadHash": "adda4e2bebb295dd0a168588442faa4371cb354e40b09ef1c2f6c7885dcfe03b"
77
+ "payloadHash": "92f5cb75a02cfc420a2d63a18b61f609d44b0f58b27e8370bb33433278e503ac"
78
78
  }