@moewolf/moe-icons-cli 0.0.1

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.
Files changed (103) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +32 -0
  3. package/bin/moeicons.js +20 -0
  4. package/dist/api/client.d.ts +42 -0
  5. package/dist/api/client.js +105 -0
  6. package/dist/auth/callback.d.ts +37 -0
  7. package/dist/auth/callback.js +72 -0
  8. package/dist/auth/device-login.d.ts +29 -0
  9. package/dist/auth/device-login.js +74 -0
  10. package/dist/auth/login.d.ts +41 -0
  11. package/dist/auth/login.js +85 -0
  12. package/dist/auth/open-browser.d.ts +2 -0
  13. package/dist/auth/open-browser.js +15 -0
  14. package/dist/auth/pkce.d.ts +17 -0
  15. package/dist/auth/pkce.js +20 -0
  16. package/dist/auth/token-store.d.ts +38 -0
  17. package/dist/auth/token-store.js +126 -0
  18. package/dist/catalog/catalog.d.ts +32 -0
  19. package/dist/catalog/catalog.js +80 -0
  20. package/dist/catalog/catalog.json +9371 -0
  21. package/dist/cli.d.ts +23 -0
  22. package/dist/cli.js +507 -0
  23. package/dist/commands/parser.d.ts +41 -0
  24. package/dist/commands/parser.js +146 -0
  25. package/dist/core/auth.d.ts +32 -0
  26. package/dist/core/auth.js +131 -0
  27. package/dist/core/bitmap-assets.d.ts +29 -0
  28. package/dist/core/bitmap-assets.js +77 -0
  29. package/dist/core/cli-update.d.ts +43 -0
  30. package/dist/core/cli-update.js +71 -0
  31. package/dist/core/context.d.ts +22 -0
  32. package/dist/core/context.js +1 -0
  33. package/dist/core/free-download.d.ts +66 -0
  34. package/dist/core/free-download.js +193 -0
  35. package/dist/core/generate.d.ts +33 -0
  36. package/dist/core/generate.js +285 -0
  37. package/dist/core/icon-names.d.ts +14 -0
  38. package/dist/core/icon-names.js +54 -0
  39. package/dist/core/init.d.ts +12 -0
  40. package/dist/core/init.js +23 -0
  41. package/dist/core/install.d.ts +67 -0
  42. package/dist/core/install.js +117 -0
  43. package/dist/core/library-update.d.ts +24 -0
  44. package/dist/core/library-update.js +161 -0
  45. package/dist/core/manage.d.ts +24 -0
  46. package/dist/core/manage.js +38 -0
  47. package/dist/core/pro-download.d.ts +29 -0
  48. package/dist/core/pro-download.js +112 -0
  49. package/dist/core/pro-install.d.ts +24 -0
  50. package/dist/core/pro-install.js +72 -0
  51. package/dist/core/release-descriptor.d.ts +40 -0
  52. package/dist/core/release-descriptor.js +114 -0
  53. package/dist/core/resource-variant.d.ts +35 -0
  54. package/dist/core/resource-variant.js +70 -0
  55. package/dist/core/signed-artifact.d.ts +29 -0
  56. package/dist/core/signed-artifact.js +81 -0
  57. package/dist/core/target-subtree.d.ts +49 -0
  58. package/dist/core/target-subtree.js +132 -0
  59. package/dist/core/update-policy.d.ts +31 -0
  60. package/dist/core/update-policy.js +27 -0
  61. package/dist/core/version-service.d.ts +26 -0
  62. package/dist/core/version-service.js +71 -0
  63. package/dist/core/wizard.d.ts +49 -0
  64. package/dist/core/wizard.js +71 -0
  65. package/dist/errors/errors.d.ts +34 -0
  66. package/dist/errors/errors.js +39 -0
  67. package/dist/errors/index.d.ts +1 -0
  68. package/dist/errors/index.js +1 -0
  69. package/dist/generator/cn.d.ts +5 -0
  70. package/dist/generator/cn.js +14 -0
  71. package/dist/generator/generate.d.ts +34 -0
  72. package/dist/generator/generate.js +562 -0
  73. package/dist/generator/theme-resolve.d.ts +26 -0
  74. package/dist/generator/theme-resolve.js +100 -0
  75. package/dist/mcp/server.d.ts +58 -0
  76. package/dist/mcp/server.js +176 -0
  77. package/dist/project/config.d.ts +74 -0
  78. package/dist/project/config.js +353 -0
  79. package/dist/project/detect.d.ts +26 -0
  80. package/dist/project/detect.js +104 -0
  81. package/dist/project/install-metadata.d.ts +29 -0
  82. package/dist/project/install-metadata.js +108 -0
  83. package/dist/project/install.d.ts +115 -0
  84. package/dist/project/install.js +537 -0
  85. package/dist/project/project-lock.d.ts +11 -0
  86. package/dist/project/project-lock.js +81 -0
  87. package/dist/project/tailwind.d.ts +51 -0
  88. package/dist/project/tailwind.js +188 -0
  89. package/dist/project/tar-gz.d.ts +12 -0
  90. package/dist/project/tar-gz.js +100 -0
  91. package/dist/tui/primitives.d.ts +36 -0
  92. package/dist/tui/primitives.js +88 -0
  93. package/dist/ui/banner.d.ts +11 -0
  94. package/dist/ui/banner.js +105 -0
  95. package/dist/ui/clack.d.ts +8 -0
  96. package/dist/ui/clack.js +53 -0
  97. package/dist/ui/create-ui.d.ts +14 -0
  98. package/dist/ui/create-ui.js +16 -0
  99. package/dist/ui/non-interactive.d.ts +5 -0
  100. package/dist/ui/non-interactive.js +30 -0
  101. package/dist/ui/stream.d.ts +11 -0
  102. package/dist/ui/stream.js +50 -0
  103. package/package.json +70 -0
@@ -0,0 +1,126 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { execFileSync } from "node:child_process";
5
+ function parseSession(value) {
6
+ try {
7
+ const session = JSON.parse(value);
8
+ return typeof session.accountId === "string" && typeof session.accessToken === "string" &&
9
+ typeof session.refreshToken === "string" && typeof session.expiresAt === "number" &&
10
+ typeof session.scope === "string" && typeof session.storedAt === "number"
11
+ ? session : undefined;
12
+ }
13
+ catch {
14
+ return undefined;
15
+ }
16
+ }
17
+ /**
18
+ * File-backed fallback store (mode 0600). Used only when no OS keychain is
19
+ * available and the owner approves the fallback. Never logs token values.
20
+ */
21
+ export function createFileTokenStore(options = {}) {
22
+ const root = options.rootDir ?? join(homedir(), ".moeicons");
23
+ const file = join(root, "token-store.json");
24
+ function readAll() {
25
+ if (!existsSync(file))
26
+ return {};
27
+ try {
28
+ const raw = JSON.parse(readFileSync(file, "utf8"));
29
+ if (typeof raw === "object" && raw !== null)
30
+ return raw;
31
+ }
32
+ catch {
33
+ // corrupt store; treat as empty
34
+ }
35
+ return {};
36
+ }
37
+ function writeAll(data) {
38
+ mkdirSync(root, { recursive: true });
39
+ writeFileSync(file, JSON.stringify(data, null, 2), { mode: 0o600 });
40
+ chmodSync(file, 0o600);
41
+ }
42
+ return {
43
+ get(accountId) {
44
+ return readAll()[accountId];
45
+ },
46
+ getActive() {
47
+ return Object.values(readAll()).sort((a, b) => b.storedAt - a.storedAt)[0];
48
+ },
49
+ set(session) {
50
+ const all = readAll();
51
+ all[session.accountId] = session;
52
+ writeAll(all);
53
+ },
54
+ delete(accountId) {
55
+ const all = readAll();
56
+ delete all[accountId];
57
+ writeAll(all);
58
+ },
59
+ clear() { writeAll({}); },
60
+ };
61
+ }
62
+ /** Use the native credential store when the platform provides a supported CLI. */
63
+ export function createSystemTokenStore(options = {}) {
64
+ const platform = options.platform ?? process.platform;
65
+ const run = options.execFile ?? execFileSync;
66
+ const service = "moeicons";
67
+ const account = "active-session";
68
+ const invoke = (command, args, input) => String(run(command, args, { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"], ...(input ? { input } : {}) })).trim();
69
+ let read;
70
+ let write;
71
+ let remove;
72
+ if (platform === "darwin") {
73
+ read = () => invoke("security", ["find-generic-password", "-s", service, "-a", account, "-w"]);
74
+ write = (value) => { invoke("security", ["add-generic-password", "-U", "-s", service, "-a", account, "-w", value]); };
75
+ remove = () => { invoke("security", ["delete-generic-password", "-s", service, "-a", account]); };
76
+ }
77
+ else if (platform === "linux") {
78
+ try {
79
+ invoke("secret-tool", ["--help"]);
80
+ }
81
+ catch {
82
+ return undefined;
83
+ }
84
+ read = () => invoke("secret-tool", ["lookup", "service", service, "account", account]);
85
+ write = (value) => { invoke("secret-tool", ["store", "--label=Moeicons CLI", "service", service, "account", account], value); };
86
+ remove = () => { invoke("secret-tool", ["clear", "service", service, "account", account]); };
87
+ }
88
+ else if (platform === "win32") {
89
+ const prefix = "[void][Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime];$v=[Windows.Security.Credentials.PasswordVault]::new();";
90
+ read = () => invoke("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", `${prefix}$c=$v.Retrieve('${service}','${account}');$c.RetrievePassword();[Console]::Out.Write($c.Password)`]);
91
+ write = (value) => { invoke("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", `${prefix}$p=[Console]::In.ReadToEnd();try{$v.Remove($v.Retrieve('${service}','${account}'))}catch{};$v.Add([Windows.Security.Credentials.PasswordCredential]::new('${service}','${account}',$p))`], value); };
92
+ remove = () => { invoke("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", `${prefix}try{$v.Remove($v.Retrieve('${service}','${account}'))}catch{}`]); };
93
+ }
94
+ else {
95
+ return undefined;
96
+ }
97
+ const active = () => { try {
98
+ return parseSession(read());
99
+ }
100
+ catch {
101
+ return undefined;
102
+ } };
103
+ return {
104
+ get: (accountId) => { const value = active(); return value?.accountId === accountId ? value : undefined; },
105
+ getActive: active,
106
+ set: (session) => { write(JSON.stringify(session)); },
107
+ delete: (accountId) => { if (active()?.accountId === accountId) {
108
+ try {
109
+ remove();
110
+ }
111
+ catch { /* already absent */ }
112
+ } },
113
+ clear: () => { try {
114
+ remove();
115
+ }
116
+ catch { /* already absent */ } },
117
+ };
118
+ }
119
+ /** Redact a session for logging: never expose tokens. */
120
+ export function redactSession(session) {
121
+ return {
122
+ accountId: session.accountId,
123
+ scope: session.scope,
124
+ expiresAt: session.expiresAt,
125
+ };
126
+ }
@@ -0,0 +1,32 @@
1
+ export type CatalogStyleGroupType = "outline" | "solid" | "mixed" | "bitmap";
2
+ export type CatalogTier = "free" | "pro";
3
+ export type CatalogFormat = "svg" | "webp" | "png";
4
+ export interface CatalogStyleGroup {
5
+ readonly id: string;
6
+ readonly type: CatalogStyleGroupType;
7
+ readonly tiers: readonly CatalogTier[];
8
+ readonly formats: readonly CatalogFormat[];
9
+ readonly imageSizes: readonly number[];
10
+ }
11
+ export interface CatalogIcon {
12
+ readonly id: string;
13
+ readonly prefix: string;
14
+ readonly label: string;
15
+ readonly aliases: readonly string[];
16
+ readonly deprecatedAt?: string;
17
+ readonly replacedBy?: string;
18
+ readonly availableIn: readonly string[];
19
+ }
20
+ export interface IconCatalog {
21
+ readonly schemaVersion: 1;
22
+ readonly catalogVersion: string;
23
+ readonly sourceVersion: string;
24
+ readonly sourceCommit: string;
25
+ readonly generatorCommit: string;
26
+ readonly styleGroups: readonly CatalogStyleGroup[];
27
+ readonly icons: readonly CatalogIcon[];
28
+ }
29
+ export declare function parseCatalog(value: unknown): IconCatalog;
30
+ export declare const catalog: IconCatalog;
31
+ export declare function findCatalogStyleGroup(id: string, source?: IconCatalog): CatalogStyleGroup | undefined;
32
+ export declare function findCatalogIcon(id: string, source?: IconCatalog): CatalogIcon | undefined;
@@ -0,0 +1,80 @@
1
+ import bundledCatalog from "./catalog.json" with { type: "json" };
2
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3
+ function isStringArray(value) {
4
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
5
+ }
6
+ export function parseCatalog(value) {
7
+ if (!isRecord(value) || value.schemaVersion !== 1) {
8
+ throw new Error("unsupported catalog schema; reinstall a compatible moeicons package");
9
+ }
10
+ for (const field of ["catalogVersion", "sourceVersion", "sourceCommit", "generatorCommit"]) {
11
+ if (typeof value[field] !== "string" || value[field].length === 0) {
12
+ throw new Error(`catalog field ${field} must be a non-empty string`);
13
+ }
14
+ }
15
+ const catalogVersion = value.catalogVersion;
16
+ const sourceVersion = value.sourceVersion;
17
+ const sourceCommit = value.sourceCommit;
18
+ const generatorCommit = value.generatorCommit;
19
+ if (!Array.isArray(value.styleGroups) || !Array.isArray(value.icons)) {
20
+ throw new Error("catalog styleGroups and icons must be arrays");
21
+ }
22
+ const groups = value.styleGroups.map((group) => {
23
+ if (!isRecord(group) || typeof group.id !== "string" || typeof group.type !== "string") {
24
+ throw new Error("catalog style group is invalid");
25
+ }
26
+ if (!isStringArray(group.tiers) || !group.tiers.every((tier) => tier === "free" || tier === "pro")) {
27
+ throw new Error(`catalog style group ${group.id} has invalid tiers`);
28
+ }
29
+ if (!isStringArray(group.formats) || !group.formats.every((format) => ["svg", "webp", "png"].includes(format))) {
30
+ throw new Error(`catalog style group ${group.id} has invalid formats`);
31
+ }
32
+ if (!Array.isArray(group.imageSizes) || !group.imageSizes.every((size) => typeof size === "number")) {
33
+ throw new Error(`catalog style group ${group.id} has invalid imageSizes`);
34
+ }
35
+ if (!["outline", "solid", "mixed", "bitmap"].includes(group.type)) {
36
+ throw new Error(`catalog style group ${group.id} has invalid type`);
37
+ }
38
+ return {
39
+ id: group.id,
40
+ type: group.type,
41
+ tiers: group.tiers,
42
+ formats: group.formats,
43
+ imageSizes: group.imageSizes,
44
+ };
45
+ });
46
+ const groupIds = new Set(groups.map((group) => group.id));
47
+ const icons = value.icons.map((icon) => {
48
+ if (!isRecord(icon) || typeof icon.id !== "string" || typeof icon.prefix !== "string" || typeof icon.label !== "string") {
49
+ throw new Error("catalog icon is invalid");
50
+ }
51
+ if (!isStringArray(icon.aliases) || !isStringArray(icon.availableIn) || !icon.availableIn.every((id) => groupIds.has(id))) {
52
+ throw new Error(`catalog icon ${icon.id} has invalid availability`);
53
+ }
54
+ return {
55
+ id: icon.id,
56
+ prefix: icon.prefix,
57
+ label: icon.label,
58
+ aliases: icon.aliases,
59
+ ...(typeof icon.deprecatedAt === "string" ? { deprecatedAt: icon.deprecatedAt } : {}),
60
+ ...(typeof icon.replacedBy === "string" ? { replacedBy: icon.replacedBy } : {}),
61
+ availableIn: icon.availableIn,
62
+ };
63
+ });
64
+ return {
65
+ schemaVersion: 1,
66
+ catalogVersion,
67
+ sourceVersion,
68
+ sourceCommit,
69
+ generatorCommit,
70
+ styleGroups: groups,
71
+ icons,
72
+ };
73
+ }
74
+ export const catalog = parseCatalog(bundledCatalog);
75
+ export function findCatalogStyleGroup(id, source = catalog) {
76
+ return source.styleGroups.find((group) => group.id === id);
77
+ }
78
+ export function findCatalogIcon(id, source = catalog) {
79
+ return source.icons.find((icon) => icon.id === id);
80
+ }