@kamaras/venpm 0.0.1 → 0.1.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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +204 -0
  3. package/actions/publish-index/action.yml +50 -0
  4. package/dist/cli/config-cmd.d.ts +3 -0
  5. package/dist/cli/config-cmd.d.ts.map +1 -0
  6. package/dist/cli/config-cmd.js +101 -0
  7. package/dist/cli/config-cmd.js.map +1 -0
  8. package/dist/cli/context.d.ts +3 -0
  9. package/dist/cli/context.d.ts.map +1 -0
  10. package/dist/cli/context.js +153 -0
  11. package/dist/cli/context.js.map +1 -0
  12. package/dist/cli/create.d.ts +23 -0
  13. package/dist/cli/create.d.ts.map +1 -0
  14. package/dist/cli/create.js +230 -0
  15. package/dist/cli/create.js.map +1 -0
  16. package/dist/cli/doctor.d.ts +3 -0
  17. package/dist/cli/doctor.d.ts.map +1 -0
  18. package/dist/cli/doctor.js +68 -0
  19. package/dist/cli/doctor.js.map +1 -0
  20. package/dist/cli/info.d.ts +5 -0
  21. package/dist/cli/info.d.ts.map +1 -0
  22. package/dist/cli/info.js +105 -0
  23. package/dist/cli/info.js.map +1 -0
  24. package/dist/cli/install.d.ts +5 -0
  25. package/dist/cli/install.d.ts.map +1 -0
  26. package/dist/cli/install.js +252 -0
  27. package/dist/cli/install.js.map +1 -0
  28. package/dist/cli/list.d.ts +5 -0
  29. package/dist/cli/list.d.ts.map +1 -0
  30. package/dist/cli/list.js +41 -0
  31. package/dist/cli/list.js.map +1 -0
  32. package/dist/cli/rebuild.d.ts +3 -0
  33. package/dist/cli/rebuild.d.ts.map +1 -0
  34. package/dist/cli/rebuild.js +84 -0
  35. package/dist/cli/rebuild.js.map +1 -0
  36. package/dist/cli/repo.d.ts +3 -0
  37. package/dist/cli/repo.d.ts.map +1 -0
  38. package/dist/cli/repo.js +93 -0
  39. package/dist/cli/repo.js.map +1 -0
  40. package/dist/cli/search.d.ts +5 -0
  41. package/dist/cli/search.d.ts.map +1 -0
  42. package/dist/cli/search.js +50 -0
  43. package/dist/cli/search.js.map +1 -0
  44. package/dist/cli/uninstall.d.ts +5 -0
  45. package/dist/cli/uninstall.d.ts.map +1 -0
  46. package/dist/cli/uninstall.js +68 -0
  47. package/dist/cli/uninstall.js.map +1 -0
  48. package/dist/cli/update.d.ts +5 -0
  49. package/dist/cli/update.d.ts.map +1 -0
  50. package/dist/cli/update.js +156 -0
  51. package/dist/cli/update.js.map +1 -0
  52. package/dist/cli/validate.d.ts +3 -0
  53. package/dist/cli/validate.d.ts.map +1 -0
  54. package/dist/cli/validate.js +99 -0
  55. package/dist/cli/validate.js.map +1 -0
  56. package/dist/core/builder.d.ts +32 -0
  57. package/dist/core/builder.d.ts.map +1 -0
  58. package/dist/core/builder.js +76 -0
  59. package/dist/core/builder.js.map +1 -0
  60. package/dist/core/cache.d.ts +17 -0
  61. package/dist/core/cache.d.ts.map +1 -0
  62. package/dist/core/cache.js +36 -0
  63. package/dist/core/cache.js.map +1 -0
  64. package/dist/core/config.d.ts +7 -0
  65. package/dist/core/config.d.ts.map +1 -0
  66. package/dist/core/config.js +32 -0
  67. package/dist/core/config.js.map +1 -0
  68. package/dist/core/detect.d.ts +28 -0
  69. package/dist/core/detect.d.ts.map +1 -0
  70. package/dist/core/detect.js +100 -0
  71. package/dist/core/detect.js.map +1 -0
  72. package/dist/core/fetcher.d.ts +21 -0
  73. package/dist/core/fetcher.d.ts.map +1 -0
  74. package/dist/core/fetcher.js +92 -0
  75. package/dist/core/fetcher.js.map +1 -0
  76. package/dist/core/json.d.ts +9 -0
  77. package/dist/core/json.d.ts.map +1 -0
  78. package/dist/core/json.js +10 -0
  79. package/dist/core/json.js.map +1 -0
  80. package/dist/core/lockfile.d.ts +9 -0
  81. package/dist/core/lockfile.d.ts.map +1 -0
  82. package/dist/core/lockfile.js +30 -0
  83. package/dist/core/lockfile.js.map +1 -0
  84. package/dist/core/log.d.ts +8 -0
  85. package/dist/core/log.d.ts.map +1 -0
  86. package/dist/core/log.js +24 -0
  87. package/dist/core/log.js.map +1 -0
  88. package/dist/core/paths.d.ts +4 -0
  89. package/dist/core/paths.d.ts.map +1 -0
  90. package/dist/core/paths.js +33 -0
  91. package/dist/core/paths.js.map +1 -0
  92. package/dist/core/prompt.d.ts +6 -0
  93. package/dist/core/prompt.d.ts.map +1 -0
  94. package/dist/core/prompt.js +78 -0
  95. package/dist/core/prompt.js.map +1 -0
  96. package/dist/core/registry.d.ts +52 -0
  97. package/dist/core/registry.d.ts.map +1 -0
  98. package/dist/core/registry.js +134 -0
  99. package/dist/core/registry.js.map +1 -0
  100. package/dist/core/resolver.d.ts +47 -0
  101. package/dist/core/resolver.d.ts.map +1 -0
  102. package/dist/core/resolver.js +153 -0
  103. package/dist/core/resolver.js.map +1 -0
  104. package/dist/core/schema.d.ts +8 -0
  105. package/dist/core/schema.d.ts.map +1 -0
  106. package/dist/core/schema.js +47 -0
  107. package/dist/core/schema.js.map +1 -0
  108. package/dist/core/types.d.ts +208 -0
  109. package/dist/core/types.d.ts.map +1 -0
  110. package/dist/core/types.js +3 -0
  111. package/dist/core/types.js.map +1 -0
  112. package/dist/index.d.ts +3 -0
  113. package/dist/index.d.ts.map +1 -0
  114. package/dist/index.js +40 -0
  115. package/dist/index.js.map +1 -0
  116. package/package.json +42 -6
  117. package/schemas/v1/config.schema.json +53 -0
  118. package/schemas/v1/lockfile.schema.json +43 -0
  119. package/schemas/v1/plugins.schema.json +69 -0
@@ -0,0 +1,68 @@
1
+ import { join } from "node:path";
2
+ import { loadConfig } from "../core/config.js";
3
+ import { loadLockfile, saveLockfile, isInstalled, removeInstalled } from "../core/lockfile.js";
4
+ import { getConfigPath, getLockfilePath } from "../core/paths.js";
5
+ import { fetchAllIndexes, resolvePlugin } from "../core/registry.js";
6
+ import { loadCache, saveCache } from "../core/cache.js";
7
+ import { jsonSuccess, jsonError, writeJson } from "../core/json.js";
8
+ import { createRealIOContext } from "./context.js";
9
+ export async function executeUninstall(ctx, pluginName, options) {
10
+ const configPath = options.config ?? getConfigPath();
11
+ const lockfilePath = getLockfilePath();
12
+ const config = await loadConfig(ctx.fs, configPath);
13
+ let lockfile = await loadLockfile(ctx.fs, lockfilePath);
14
+ if (!isInstalled(lockfile, pluginName)) {
15
+ if (options.json) {
16
+ process.exitCode = 1;
17
+ writeJson(jsonError(`Plugin "${pluginName}" is not installed.`));
18
+ return;
19
+ }
20
+ ctx.logger.error(`Plugin "${pluginName}" is not installed.`);
21
+ process.exitCode = 1;
22
+ return;
23
+ }
24
+ // Warn if other installed plugins depend on this one
25
+ const cache = await loadCache(ctx.fs);
26
+ const { results: fetchedIndexes, updatedCache } = await fetchAllIndexes(ctx.http, config.repos, { cache });
27
+ await saveCache(ctx.fs, updatedCache);
28
+ const otherInstalled = Object.keys(lockfile.installed).filter(n => n !== pluginName);
29
+ for (const other of otherInstalled) {
30
+ const match = resolvePlugin(fetchedIndexes, other);
31
+ if (match?.entry.dependencies?.includes(pluginName)) {
32
+ ctx.logger.warn(`"${other}" depends on this plugin`);
33
+ }
34
+ }
35
+ const confirmed = await ctx.prompter.confirm(`Remove plugin "${pluginName}"?`, true);
36
+ if (!confirmed) {
37
+ ctx.logger.info("Uninstall cancelled.");
38
+ return;
39
+ }
40
+ if (config.vencord.path !== null) {
41
+ const pluginDir = join(config.vencord.path, "src", "userplugins", pluginName);
42
+ await ctx.fs.rm(pluginDir, { recursive: true, force: true });
43
+ ctx.logger.success(`Removed plugin directory: ${pluginDir}`);
44
+ }
45
+ lockfile = removeInstalled(lockfile, pluginName);
46
+ await saveLockfile(ctx.fs, lockfilePath, lockfile);
47
+ if (options.json) {
48
+ writeJson(jsonSuccess({ removed: pluginName }));
49
+ return;
50
+ }
51
+ ctx.logger.success(`Uninstalled "${pluginName}".`);
52
+ }
53
+ export function registerUninstallCommand(program) {
54
+ program
55
+ .command("uninstall <plugin>")
56
+ .description("Uninstall a plugin")
57
+ .option("-y, --yes", "Skip confirmation prompt")
58
+ .action(async (plugin, cmdOptions) => {
59
+ const parentOpts = program.opts();
60
+ const globalOptions = {
61
+ ...parentOpts,
62
+ yes: parentOpts.yes || cmdOptions.yes,
63
+ };
64
+ const ctx = createRealIOContext(globalOptions);
65
+ await executeUninstall(ctx, plugin, globalOptions);
66
+ });
67
+ }
68
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/cli/uninstall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Command } from "commander";
2
+ import type { IOContext, GlobalOptions } from "../core/types.js";
3
+ export declare function executeUpdate(ctx: IOContext, pluginName: string | undefined, options: GlobalOptions): Promise<void>;
4
+ export declare function registerUpdateCommand(program: Command): void;
5
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/cli/update.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAoB,MAAM,kBAAkB,CAAC;AAWnF,wBAAsB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsJzH;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAS5D"}
@@ -0,0 +1,156 @@
1
+ import { join } from "node:path";
2
+ import { loadConfig } from "../core/config.js";
3
+ import { loadLockfile, saveLockfile, getInstalled, addInstalled, removeInstalled } from "../core/lockfile.js";
4
+ import { getConfigPath, getLockfilePath } from "../core/paths.js";
5
+ import { fetchAllIndexes, resolvePlugin } from "../core/registry.js";
6
+ import { loadCache, saveCache } from "../core/cache.js";
7
+ import { fetchPlugin } from "../core/fetcher.js";
8
+ import { jsonSuccess, jsonError, writeJson } from "../core/json.js";
9
+ import { createRealIOContext } from "./context.js";
10
+ import { selectMethodFromSource } from "../core/resolver.js";
11
+ export async function executeUpdate(ctx, pluginName, options) {
12
+ const configPath = options.config ?? getConfigPath();
13
+ const lockfilePath = getLockfilePath();
14
+ const config = await loadConfig(ctx.fs, configPath);
15
+ let lockfile = await loadLockfile(ctx.fs, lockfilePath);
16
+ const installedEntries = Object.entries(lockfile.installed);
17
+ if (installedEntries.length === 0) {
18
+ if (options.json) {
19
+ writeJson(jsonSuccess({ updated: [], skipped: [] }));
20
+ return;
21
+ }
22
+ ctx.logger.info("No plugins installed.");
23
+ return;
24
+ }
25
+ // Determine which plugins to update
26
+ let targets;
27
+ if (pluginName !== undefined) {
28
+ const info = getInstalled(lockfile, pluginName);
29
+ if (!info) {
30
+ if (options.json) {
31
+ writeJson(jsonError(`Plugin "${pluginName}" is not installed.`));
32
+ process.exitCode = 1;
33
+ return;
34
+ }
35
+ ctx.logger.error(`Plugin "${pluginName}" is not installed.`);
36
+ process.exitCode = 1;
37
+ return;
38
+ }
39
+ targets = [pluginName];
40
+ }
41
+ else {
42
+ targets = installedEntries.map(([name]) => name);
43
+ }
44
+ // Filter out pinned and local plugins
45
+ const updateable = targets.filter(name => {
46
+ const info = getInstalled(lockfile, name);
47
+ if (info.pinned) {
48
+ ctx.logger.info(`Skipping pinned plugin: ${name}`);
49
+ return false;
50
+ }
51
+ if (info.method === "local") {
52
+ ctx.logger.info(`Skipping local plugin: ${name}`);
53
+ return false;
54
+ }
55
+ return true;
56
+ });
57
+ if (updateable.length === 0) {
58
+ if (options.json) {
59
+ writeJson(jsonSuccess({ updated: [], skipped: [] }));
60
+ return;
61
+ }
62
+ ctx.logger.info("Nothing to update.");
63
+ return;
64
+ }
65
+ const cache = await loadCache(ctx.fs);
66
+ const { results: indexes, updatedCache } = await fetchAllIndexes(ctx.http, config.repos, { cache });
67
+ await saveCache(ctx.fs, updatedCache);
68
+ for (const fi of indexes) {
69
+ if (fi.error) {
70
+ ctx.logger.warn(`Failed to fetch index from "${fi.repoName}": ${fi.error}`);
71
+ }
72
+ }
73
+ const gitAvailable = await ctx.git.available();
74
+ let updatedCount = 0;
75
+ const updatedEntries = [];
76
+ const skippedNames = [];
77
+ for (const name of updateable) {
78
+ const installedInfo = getInstalled(lockfile, name);
79
+ const match = resolvePlugin(indexes, name, installedInfo.repo);
80
+ if (!match) {
81
+ ctx.logger.warn(`Plugin "${name}" not found in repo "${installedInfo.repo}" — skipping`);
82
+ skippedNames.push(name);
83
+ continue;
84
+ }
85
+ const latestVersion = match.entry.version;
86
+ if (latestVersion === installedInfo.version) {
87
+ ctx.logger.verbose(`${name} is up to date (${installedInfo.version})`);
88
+ skippedNames.push(name);
89
+ continue;
90
+ }
91
+ ctx.logger.info(`Updating ${name}: ${installedInfo.version} → ${latestVersion}`);
92
+ // Remove old plugin directory if vencord.path is configured
93
+ if (config.vencord.path !== null) {
94
+ const oldDir = join(config.vencord.path, "src", "userplugins", name);
95
+ await ctx.fs.rm(oldDir, { recursive: true, force: true });
96
+ }
97
+ // Remove from lockfile before re-fetching
98
+ lockfile = removeInstalled(lockfile, name);
99
+ // Resolve fetch method from current source metadata
100
+ const resolvedMethod = selectMethodFromSource(match.entry.source, gitAvailable);
101
+ // Fetch the new version
102
+ const planEntry = {
103
+ name,
104
+ version: latestVersion,
105
+ repo: match.repoName,
106
+ source: match.entry.source,
107
+ method: resolvedMethod,
108
+ isDependency: false,
109
+ };
110
+ if (config.vencord.path !== null) {
111
+ const userpluginDir = join(config.vencord.path, "src", "userplugins");
112
+ const fetchResult = await fetchPlugin(planEntry, userpluginDir, ctx);
113
+ lockfile = addInstalled(lockfile, name, {
114
+ version: latestVersion,
115
+ repo: match.repoName,
116
+ method: fetchResult.method,
117
+ pinned: false,
118
+ git_ref: fetchResult.git_ref,
119
+ installed_at: new Date().toISOString(),
120
+ path: fetchResult.path,
121
+ });
122
+ }
123
+ else {
124
+ // No vencord path configured — just update lockfile version
125
+ lockfile = addInstalled(lockfile, name, {
126
+ ...installedInfo,
127
+ version: latestVersion,
128
+ });
129
+ }
130
+ ctx.logger.success(`Updated ${name} to ${latestVersion}`);
131
+ updatedEntries.push({ name, from: installedInfo.version, to: latestVersion });
132
+ updatedCount++;
133
+ }
134
+ await saveLockfile(ctx.fs, lockfilePath, lockfile);
135
+ if (options.json) {
136
+ writeJson(jsonSuccess({ updated: updatedEntries, skipped: skippedNames }));
137
+ return;
138
+ }
139
+ if (updatedCount === 0) {
140
+ ctx.logger.info("All plugins are up to date.");
141
+ }
142
+ else {
143
+ ctx.logger.success(`Updated ${updatedCount} plugin(s).`);
144
+ }
145
+ }
146
+ export function registerUpdateCommand(program) {
147
+ program
148
+ .command("update [plugin]")
149
+ .description("Update a plugin or all plugins")
150
+ .action(async (plugin) => {
151
+ const globalOptions = program.opts();
152
+ const ctx = createRealIOContext(globalOptions);
153
+ await executeUpdate(ctx, plugin, globalOptions);
154
+ });
155
+ }
156
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/cli/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerValidateCommand(program: Command): void;
3
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoG9D"}
@@ -0,0 +1,99 @@
1
+ import { join } from "node:path";
2
+ import { validateIndex } from "../core/schema.js";
3
+ import { jsonSuccess, jsonError, writeJson } from "../core/json.js";
4
+ import { createRealIOContext } from "./context.js";
5
+ export function registerValidateCommand(program) {
6
+ program
7
+ .command("validate [path]")
8
+ .description("Validate a plugin index JSON file")
9
+ .option("--strict", "Also check dependency references and tarball URLs")
10
+ .action(async (filePath, options) => {
11
+ const globalOpts = program.opts();
12
+ const ctx = createRealIOContext(globalOpts);
13
+ const targetPath = filePath ?? join(process.cwd(), "plugins.json");
14
+ let raw;
15
+ try {
16
+ raw = await ctx.fs.readFile(targetPath, "utf-8");
17
+ }
18
+ catch {
19
+ if (globalOpts.json) {
20
+ writeJson(jsonError(`Cannot read file: ${targetPath}`));
21
+ return;
22
+ }
23
+ ctx.logger.error(`Cannot read file: ${targetPath}`);
24
+ process.exitCode = 1;
25
+ return;
26
+ }
27
+ let data;
28
+ try {
29
+ data = JSON.parse(raw);
30
+ }
31
+ catch (err) {
32
+ if (globalOpts.json) {
33
+ writeJson(jsonError(`Invalid JSON: ${err.message}`));
34
+ return;
35
+ }
36
+ ctx.logger.error(`Invalid JSON: ${err.message}`);
37
+ process.exitCode = 1;
38
+ return;
39
+ }
40
+ const result = validateIndex(data);
41
+ const allErrors = [...result.errors];
42
+ if (result.valid && options.strict) {
43
+ const index = data;
44
+ const plugins = index.plugins ?? {};
45
+ const pluginNames = new Set(Object.keys(plugins));
46
+ for (const [name, entry] of Object.entries(plugins)) {
47
+ if (entry.dependencies) {
48
+ for (const dep of entry.dependencies) {
49
+ if (!pluginNames.has(dep)) {
50
+ allErrors.push(`${name}: dependency "${dep}" is not in the index`);
51
+ }
52
+ }
53
+ }
54
+ if (entry.versions) {
55
+ for (const [ver, vEntry] of Object.entries(entry.versions)) {
56
+ const tarball = vEntry.tarball;
57
+ if (tarball) {
58
+ try {
59
+ const res = await ctx.http.fetch(tarball, {});
60
+ if (!res.ok) {
61
+ allErrors.push(`${name}@${ver}: tarball URL returned ${res.status}: ${tarball}`);
62
+ }
63
+ }
64
+ catch (err) {
65
+ allErrors.push(`${name}@${ver}: tarball URL unreachable: ${tarball} (${err.message})`);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ if (entry.source?.tarball) {
71
+ try {
72
+ const res = await ctx.http.fetch(entry.source.tarball, {});
73
+ if (!res.ok) {
74
+ allErrors.push(`${name}: source tarball returned ${res.status}: ${entry.source.tarball}`);
75
+ }
76
+ }
77
+ catch (err) {
78
+ allErrors.push(`${name}: source tarball unreachable: ${entry.source.tarball} (${err.message})`);
79
+ }
80
+ }
81
+ }
82
+ }
83
+ const valid = result.valid && allErrors.length === 0;
84
+ if (globalOpts.json) {
85
+ writeJson(jsonSuccess({ path: targetPath, valid, errors: allErrors }));
86
+ return;
87
+ }
88
+ if (!valid) {
89
+ ctx.logger.error(`Validation failed (${allErrors.length} error(s)):`);
90
+ for (const e of allErrors) {
91
+ ctx.logger.error(` ${e}`);
92
+ }
93
+ process.exitCode = 1;
94
+ return;
95
+ }
96
+ ctx.logger.success(`${targetPath} is valid`);
97
+ });
98
+ }
99
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/cli/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACpD,OAAO;SACF,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,UAAU,EAAE,mDAAmD,CAAC;SACvE,MAAM,CAAC,KAAK,EAAE,QAA4B,EAAE,OAA6B,EAAE,EAAE;QAC1E,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAiB,CAAC;QACjD,MAAM,GAAG,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;QAEnE,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACD,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACL,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBAClB,SAAS,CAAC,SAAS,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC,CAAC;gBACxD,OAAO;YACX,CAAC;YACD,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACX,CAAC;QAED,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBAClB,SAAS,CAAC,SAAS,CAAC,iBAAkB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAChE,OAAO;YACX,CAAC;YACD,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAkB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACX,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAErC,IAAI,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,IAAmB,CAAC;YAClC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAElD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAA4B,EAAE,CAAC;gBAC7E,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;oBACrB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;wBACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;4BACxB,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,iBAAiB,GAAG,uBAAuB,CAAC,CAAC;wBACvE,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACjB,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACzD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;wBAC/B,IAAI,OAAO,EAAE,CAAC;4BACV,IAAI,CAAC;gCACD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gCAC9C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;oCACV,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,GAAG,0BAA0B,GAAG,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;gCACrF,CAAC;4BACL,CAAC;4BAAC,OAAO,GAAG,EAAE,CAAC;gCACX,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,GAAG,8BAA8B,OAAO,KAAM,GAAa,CAAC,OAAO,GAAG,CAAC,CAAC;4BACtG,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;oBACxB,IAAI,CAAC;wBACD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;wBAC3D,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;4BACV,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,6BAA6B,GAAG,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;wBAC9F,CAAC;oBACL,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACX,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,iCAAiC,KAAK,CAAC,MAAM,CAAC,OAAO,KAAM,GAAa,CAAC,OAAO,GAAG,CAAC,CAAC;oBAC/G,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;QAErD,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YAClB,SAAS,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;YACvE,OAAO;QACX,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,SAAS,CAAC,MAAM,aAAa,CAAC,CAAC;YACtE,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBACxB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACX,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,UAAU,WAAW,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { FileSystem, ShellRunner } from "./types.js";
2
+ export declare const DEPLOY_PATHS: Record<"linux" | "darwin" | "win32", string>;
3
+ export interface DeployResult {
4
+ deployed: boolean;
5
+ deployPath?: string;
6
+ restarted: boolean;
7
+ }
8
+ /**
9
+ * Run `pnpm build` inside `vencordPath`.
10
+ * Throws an error if the build exits with a non-zero code.
11
+ */
12
+ export declare function buildVencord(shell: ShellRunner, vencordPath: string): Promise<void>;
13
+ /**
14
+ * Copy `<vencordPath>/dist/` to the platform-specific deployed location.
15
+ * Skips silently when the deployed directory does not exist on disk.
16
+ */
17
+ export declare function deployDist(fs: FileSystem, vencordPath: string): Promise<DeployResult>;
18
+ /**
19
+ * Kill Discord via `pkill`, wait briefly, then spawn the binary detached.
20
+ * If pkill reports the process is not running (exit code 1) the kill step is
21
+ * skipped — Discord is still spawned so the caller can open it fresh.
22
+ */
23
+ export declare function restartDiscord(shell: ShellRunner, discordBinary: string): Promise<void>;
24
+ export interface BuildAndDeployOptions {
25
+ restart?: boolean;
26
+ discordBinary?: string;
27
+ }
28
+ /**
29
+ * Orchestrate build → deploy → (optional) restart.
30
+ */
31
+ export declare function buildAndDeploy(fs: FileSystem, shell: ShellRunner, vencordPath: string, options?: BuildAndDeployOptions): Promise<DeployResult>;
32
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/core/builder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI1D,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,OAAO,GAAG,QAAQ,GAAG,OAAO,EAAE,MAAM,CAIrE,CAAC;AAIF,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACtB;AAID;;;GAGG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzF;AAID;;;GAGG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAa3F;AAID;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B7F;AAID,MAAM,WAAW,qBAAqB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAChC,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,qBAA0B,GACpC,OAAO,CAAC,YAAY,CAAC,CAWvB"}
@@ -0,0 +1,76 @@
1
+ import { homedir } from "node:os";
2
+ import { basename, join } from "node:path";
3
+ // ─── Deploy Paths ─────────────────────────────────────────────────────────────
4
+ export const DEPLOY_PATHS = {
5
+ linux: join(homedir(), ".config", "Vencord", "dist"),
6
+ darwin: join(homedir(), "Library", "Application Support", "Vencord", "dist"),
7
+ win32: join(process.env.APPDATA ?? join(homedir(), "AppData", "Roaming"), "Vencord", "dist"),
8
+ };
9
+ // ─── Build ────────────────────────────────────────────────────────────────────
10
+ /**
11
+ * Run `pnpm build` inside `vencordPath`.
12
+ * Throws an error if the build exits with a non-zero code.
13
+ */
14
+ export async function buildVencord(shell, vencordPath) {
15
+ const result = await shell.exec("pnpm", ["build"], { cwd: vencordPath });
16
+ if (result.exitCode !== 0) {
17
+ throw new Error(`pnpm build failed (exit ${result.exitCode}):\n${result.stderr || result.stdout}`);
18
+ }
19
+ }
20
+ // ─── Deploy ───────────────────────────────────────────────────────────────────
21
+ /**
22
+ * Copy `<vencordPath>/dist/` to the platform-specific deployed location.
23
+ * Skips silently when the deployed directory does not exist on disk.
24
+ */
25
+ export async function deployDist(fs, vencordPath) {
26
+ const platform = process.platform;
27
+ const deployPath = DEPLOY_PATHS[platform] ?? DEPLOY_PATHS.linux;
28
+ const deployedDirExists = await fs.exists(deployPath);
29
+ if (!deployedDirExists) {
30
+ return { deployed: false, restarted: false };
31
+ }
32
+ const srcDist = join(vencordPath, "dist");
33
+ await fs.copyDir(srcDist, deployPath);
34
+ return { deployed: true, deployPath, restarted: false };
35
+ }
36
+ // ─── Restart ──────────────────────────────────────────────────────────────────
37
+ /**
38
+ * Kill Discord via `pkill`, wait briefly, then spawn the binary detached.
39
+ * If pkill reports the process is not running (exit code 1) the kill step is
40
+ * skipped — Discord is still spawned so the caller can open it fresh.
41
+ */
42
+ export async function restartDiscord(shell, discordBinary) {
43
+ const processName = basename(discordBinary);
44
+ if (process.platform === "win32") {
45
+ // taskkill /IM matches image name; /F forces termination.
46
+ // Exit code 128 = process not found (not an error for us).
47
+ const killResult = await shell.exec("taskkill", ["/IM", `${processName}.exe`, "/F"]);
48
+ if (killResult.exitCode !== 0 && killResult.exitCode !== 128) {
49
+ throw new Error(`taskkill failed (exit ${killResult.exitCode}): ${killResult.stderr}`);
50
+ }
51
+ }
52
+ else {
53
+ // pkill returns 0 if at least one process was signalled, 1 if none found.
54
+ // -x = exact name match, -i = case-insensitive (binary is "discord", comm is "Discord").
55
+ const killResult = await shell.exec("pkill", ["-xi", processName]);
56
+ if (killResult.exitCode !== 0 && killResult.exitCode !== 1) {
57
+ throw new Error(`pkill failed (exit ${killResult.exitCode}): ${killResult.stderr}`);
58
+ }
59
+ }
60
+ // Give the process a moment to fully exit before relaunching.
61
+ await new Promise(resolve => setTimeout(resolve, 500));
62
+ await shell.spawn(discordBinary, [], { detached: true });
63
+ }
64
+ /**
65
+ * Orchestrate build → deploy → (optional) restart.
66
+ */
67
+ export async function buildAndDeploy(fs, shell, vencordPath, options = {}) {
68
+ await buildVencord(shell, vencordPath);
69
+ const result = await deployDist(fs, vencordPath);
70
+ if (options.restart && options.discordBinary) {
71
+ await restartDiscord(shell, options.discordBinary);
72
+ result.restarted = true;
73
+ }
74
+ return result;
75
+ }
76
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/core/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { FileSystem } from "./types.js";
2
+ export interface CacheEntry {
3
+ url: string;
4
+ etag?: string;
5
+ lastModified?: string;
6
+ body: string;
7
+ cachedAt: string;
8
+ }
9
+ export interface IndexCache {
10
+ entries: Record<string, CacheEntry>;
11
+ }
12
+ export declare function getCachePath(): string;
13
+ export declare function loadCache(fs: FileSystem): Promise<IndexCache>;
14
+ export declare function saveCache(fs: FileSystem, cache: IndexCache): Promise<void>;
15
+ export declare function getCachedEntry(cache: IndexCache, url: string): CacheEntry | undefined;
16
+ export declare function setCachedEntry(cache: IndexCache, url: string, entry: CacheEntry): IndexCache;
17
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,WAAW,UAAU;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACvC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAsB,SAAS,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAUnE;AAED,wBAAsB,SAAS,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAErF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,UAAU,CAQ5F"}
@@ -0,0 +1,36 @@
1
+ import { dirname, join } from "node:path";
2
+ import { getConfigDir } from "./paths.js";
3
+ export function getCachePath() {
4
+ return join(getConfigDir(), "index-cache.json");
5
+ }
6
+ export async function loadCache(fs) {
7
+ const path = getCachePath();
8
+ const exists = await fs.exists(path);
9
+ if (!exists)
10
+ return { entries: {} };
11
+ const raw = await fs.readFile(path, "utf-8");
12
+ try {
13
+ return JSON.parse(raw);
14
+ }
15
+ catch {
16
+ return { entries: {} };
17
+ }
18
+ }
19
+ export async function saveCache(fs, cache) {
20
+ const path = getCachePath();
21
+ await fs.mkdir(dirname(path), { recursive: true });
22
+ await fs.writeFile(path, JSON.stringify(cache, null, 2) + "\n");
23
+ }
24
+ export function getCachedEntry(cache, url) {
25
+ return cache.entries[url];
26
+ }
27
+ export function setCachedEntry(cache, url, entry) {
28
+ return {
29
+ ...cache,
30
+ entries: {
31
+ ...cache.entries,
32
+ [url]: entry,
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAc1C,MAAM,UAAU,YAAY;IACxB,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAc;IAC1C,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC3B,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAc,EAAE,KAAiB;IAC7D,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAC5B,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAiB,EAAE,GAAW;IACzD,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAiB,EAAE,GAAW,EAAE,KAAiB;IAC5E,OAAO;QACH,GAAG,KAAK;QACR,OAAO,EAAE;YACL,GAAG,KAAK,CAAC,OAAO;YAChB,CAAC,GAAG,CAAC,EAAE,KAAK;SACf;KACJ,CAAC;AACN,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Config, FileSystem } from "./types.js";
2
+ export declare const DEFAULT_REPO_URL = "https://github.com/theokyr/vencord-plugins/releases/latest/download/plugins.json";
3
+ export declare const DEFAULT_CONFIG: Config;
4
+ export declare function mergeConfig(partial: Partial<Config>): Config;
5
+ export declare function loadConfig(fs: FileSystem, configPath: string): Promise<Config>;
6
+ export declare function saveConfig(fs: FileSystem, configPath: string, config: Config): Promise<void>;
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAErD,eAAO,MAAM,gBAAgB,qFAAqF,CAAC;AAEnH,eAAO,MAAM,cAAc,EAAE,MAK5B,CAAC;AAEF,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAU5D;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpF;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlG"}
@@ -0,0 +1,32 @@
1
+ import { dirname } from "node:path";
2
+ export const DEFAULT_REPO_URL = "https://github.com/theokyr/vencord-plugins/releases/latest/download/plugins.json";
3
+ export const DEFAULT_CONFIG = {
4
+ repos: [{ name: "kamaras", url: DEFAULT_REPO_URL }],
5
+ vencord: { path: null },
6
+ rebuild: "ask",
7
+ discord: { restart: "ask", binary: null },
8
+ };
9
+ export function mergeConfig(partial) {
10
+ return {
11
+ repos: partial.repos ?? DEFAULT_CONFIG.repos,
12
+ vencord: { path: partial.vencord?.path ?? DEFAULT_CONFIG.vencord.path },
13
+ rebuild: partial.rebuild ?? DEFAULT_CONFIG.rebuild,
14
+ discord: {
15
+ restart: partial.discord?.restart ?? DEFAULT_CONFIG.discord.restart,
16
+ binary: partial.discord?.binary ?? DEFAULT_CONFIG.discord.binary,
17
+ },
18
+ };
19
+ }
20
+ export async function loadConfig(fs, configPath) {
21
+ const exists = await fs.exists(configPath);
22
+ if (!exists)
23
+ return { ...DEFAULT_CONFIG };
24
+ const raw = await fs.readFile(configPath, "utf-8");
25
+ const parsed = JSON.parse(raw);
26
+ return mergeConfig(parsed);
27
+ }
28
+ export async function saveConfig(fs, configPath, config) {
29
+ await fs.mkdir(dirname(configPath), { recursive: true });
30
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
31
+ }
32
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,kFAAkF,CAAC;AAEnH,MAAM,CAAC,MAAM,cAAc,GAAW;IAClC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC;IACnD,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACvB,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE;CAC5C,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,OAAwB;IAChD,OAAO;QACH,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC,KAAK;QAC5C,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,IAAI,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE;QACvE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;QAClD,OAAO,EAAE;YACL,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,OAAO;YACnE,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM;SACnE;KACJ,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAc,EAAE,UAAkB;IAC/D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;IAClD,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAc,EAAE,UAAkB,EAAE,MAAc;IAC/E,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { FileSystem, ShellRunner } from "./types.js";
2
+ export declare const VENCORD_SEARCH_PATHS: string[];
3
+ /** Replace a leading `~` with the user's home directory. */
4
+ export declare function resolveTilde(p: string): string;
5
+ /**
6
+ * Detect the Vencord source checkout path.
7
+ *
8
+ * Checks `$VENPM_VENCORD_PATH` first, then scans VENCORD_SEARCH_PATHS.
9
+ * A path is valid when `<path>/package.json` exists.
10
+ *
11
+ * @returns Absolute path string or null when not found.
12
+ */
13
+ export declare function detectVencordPath(fs: FileSystem): Promise<string | null>;
14
+ /**
15
+ * Detect the Discord binary path.
16
+ *
17
+ * Returns the first candidate that exists on disk, or null.
18
+ */
19
+ export declare function detectDiscordBinary(fs: FileSystem): Promise<string | null>;
20
+ /**
21
+ * Check whether `git` is available on PATH.
22
+ */
23
+ export declare function checkGitAvailable(shell: ShellRunner): Promise<boolean>;
24
+ /**
25
+ * Check whether `pnpm` is available on PATH.
26
+ */
27
+ export declare function checkPnpmAvailable(shell: ShellRunner): Promise<boolean>;
28
+ //# sourceMappingURL=detect.d.ts.map