@unlimitechcloud/devlink 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.
Files changed (186) hide show
  1. package/AGENTS.md +880 -0
  2. package/LICENSE +21 -0
  3. package/README.md +335 -0
  4. package/dist/__tests__/e2e.spec.d.ts +8 -0
  5. package/dist/__tests__/e2e.spec.d.ts.map +1 -0
  6. package/dist/__tests__/e2e.spec.js +253 -0
  7. package/dist/__tests__/e2e.spec.js.map +1 -0
  8. package/dist/__tests__/integration.spec.d.ts +8 -0
  9. package/dist/__tests__/integration.spec.d.ts.map +1 -0
  10. package/dist/__tests__/integration.spec.js +274 -0
  11. package/dist/__tests__/integration.spec.js.map +1 -0
  12. package/dist/cli.d.ts +6 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +610 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/commands/consumers.d.ts +37 -0
  17. package/dist/commands/consumers.d.ts.map +1 -0
  18. package/dist/commands/consumers.js +107 -0
  19. package/dist/commands/consumers.js.map +1 -0
  20. package/dist/commands/docs.d.ts +59 -0
  21. package/dist/commands/docs.d.ts.map +1 -0
  22. package/dist/commands/docs.js +262 -0
  23. package/dist/commands/docs.js.map +1 -0
  24. package/dist/commands/docs.spec.d.ts +5 -0
  25. package/dist/commands/docs.spec.d.ts.map +1 -0
  26. package/dist/commands/docs.spec.js +213 -0
  27. package/dist/commands/docs.spec.js.map +1 -0
  28. package/dist/commands/index.d.ts +13 -0
  29. package/dist/commands/index.d.ts.map +1 -0
  30. package/dist/commands/index.js +13 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/install.d.ts +31 -0
  33. package/dist/commands/install.d.ts.map +1 -0
  34. package/dist/commands/install.js +234 -0
  35. package/dist/commands/install.js.map +1 -0
  36. package/dist/commands/list.d.ts +22 -0
  37. package/dist/commands/list.d.ts.map +1 -0
  38. package/dist/commands/list.js +45 -0
  39. package/dist/commands/list.js.map +1 -0
  40. package/dist/commands/list.spec.d.ts +5 -0
  41. package/dist/commands/list.spec.d.ts.map +1 -0
  42. package/dist/commands/list.spec.js +95 -0
  43. package/dist/commands/list.spec.js.map +1 -0
  44. package/dist/commands/prune.d.ts +27 -0
  45. package/dist/commands/prune.d.ts.map +1 -0
  46. package/dist/commands/prune.js +74 -0
  47. package/dist/commands/prune.js.map +1 -0
  48. package/dist/commands/publish.d.ts +16 -0
  49. package/dist/commands/publish.d.ts.map +1 -0
  50. package/dist/commands/publish.js +225 -0
  51. package/dist/commands/publish.js.map +1 -0
  52. package/dist/commands/publish.spec.d.ts +5 -0
  53. package/dist/commands/publish.spec.d.ts.map +1 -0
  54. package/dist/commands/publish.spec.js +98 -0
  55. package/dist/commands/publish.spec.js.map +1 -0
  56. package/dist/commands/push.d.ts +16 -0
  57. package/dist/commands/push.d.ts.map +1 -0
  58. package/dist/commands/push.js +164 -0
  59. package/dist/commands/push.js.map +1 -0
  60. package/dist/commands/remove.d.ts +24 -0
  61. package/dist/commands/remove.d.ts.map +1 -0
  62. package/dist/commands/remove.js +80 -0
  63. package/dist/commands/remove.js.map +1 -0
  64. package/dist/commands/remove.spec.d.ts +5 -0
  65. package/dist/commands/remove.spec.d.ts.map +1 -0
  66. package/dist/commands/remove.spec.js +87 -0
  67. package/dist/commands/remove.spec.js.map +1 -0
  68. package/dist/commands/resolve.d.ts +20 -0
  69. package/dist/commands/resolve.d.ts.map +1 -0
  70. package/dist/commands/resolve.js +52 -0
  71. package/dist/commands/resolve.js.map +1 -0
  72. package/dist/commands/resolve.spec.d.ts +5 -0
  73. package/dist/commands/resolve.spec.d.ts.map +1 -0
  74. package/dist/commands/resolve.spec.js +87 -0
  75. package/dist/commands/resolve.spec.js.map +1 -0
  76. package/dist/commands/verify.d.ts +32 -0
  77. package/dist/commands/verify.d.ts.map +1 -0
  78. package/dist/commands/verify.js +127 -0
  79. package/dist/commands/verify.js.map +1 -0
  80. package/dist/config.d.ts +22 -0
  81. package/dist/config.d.ts.map +1 -0
  82. package/dist/config.js +70 -0
  83. package/dist/config.js.map +1 -0
  84. package/dist/constants.d.ts +65 -0
  85. package/dist/constants.d.ts.map +1 -0
  86. package/dist/constants.js +116 -0
  87. package/dist/constants.js.map +1 -0
  88. package/dist/constants.spec.d.ts +5 -0
  89. package/dist/constants.spec.d.ts.map +1 -0
  90. package/dist/constants.spec.js +72 -0
  91. package/dist/constants.spec.js.map +1 -0
  92. package/dist/core/index.d.ts +9 -0
  93. package/dist/core/index.d.ts.map +1 -0
  94. package/dist/core/index.js +9 -0
  95. package/dist/core/index.js.map +1 -0
  96. package/dist/core/installations.d.ts +79 -0
  97. package/dist/core/installations.d.ts.map +1 -0
  98. package/dist/core/installations.js +207 -0
  99. package/dist/core/installations.js.map +1 -0
  100. package/dist/core/installations.spec.d.ts +5 -0
  101. package/dist/core/installations.spec.d.ts.map +1 -0
  102. package/dist/core/installations.spec.js +261 -0
  103. package/dist/core/installations.spec.js.map +1 -0
  104. package/dist/core/lock.d.ts +37 -0
  105. package/dist/core/lock.d.ts.map +1 -0
  106. package/dist/core/lock.js +198 -0
  107. package/dist/core/lock.js.map +1 -0
  108. package/dist/core/lock.spec.d.ts +5 -0
  109. package/dist/core/lock.spec.d.ts.map +1 -0
  110. package/dist/core/lock.spec.js +161 -0
  111. package/dist/core/lock.spec.js.map +1 -0
  112. package/dist/core/registry.d.ts +80 -0
  113. package/dist/core/registry.d.ts.map +1 -0
  114. package/dist/core/registry.js +231 -0
  115. package/dist/core/registry.js.map +1 -0
  116. package/dist/core/registry.spec.d.ts +5 -0
  117. package/dist/core/registry.spec.d.ts.map +1 -0
  118. package/dist/core/registry.spec.js +281 -0
  119. package/dist/core/registry.spec.js.map +1 -0
  120. package/dist/core/resolver.d.ts +55 -0
  121. package/dist/core/resolver.d.ts.map +1 -0
  122. package/dist/core/resolver.js +127 -0
  123. package/dist/core/resolver.js.map +1 -0
  124. package/dist/core/resolver.spec.d.ts +5 -0
  125. package/dist/core/resolver.spec.d.ts.map +1 -0
  126. package/dist/core/resolver.spec.js +202 -0
  127. package/dist/core/resolver.spec.js.map +1 -0
  128. package/dist/core/store.d.ts +65 -0
  129. package/dist/core/store.d.ts.map +1 -0
  130. package/dist/core/store.js +245 -0
  131. package/dist/core/store.js.map +1 -0
  132. package/dist/core/store.spec.d.ts +5 -0
  133. package/dist/core/store.spec.d.ts.map +1 -0
  134. package/dist/core/store.spec.js +195 -0
  135. package/dist/core/store.spec.js.map +1 -0
  136. package/dist/formatters/flat.d.ts +41 -0
  137. package/dist/formatters/flat.d.ts.map +1 -0
  138. package/dist/formatters/flat.js +131 -0
  139. package/dist/formatters/flat.js.map +1 -0
  140. package/dist/formatters/flat.spec.d.ts +5 -0
  141. package/dist/formatters/flat.spec.d.ts.map +1 -0
  142. package/dist/formatters/flat.spec.js +130 -0
  143. package/dist/formatters/flat.spec.js.map +1 -0
  144. package/dist/formatters/index.d.ts +6 -0
  145. package/dist/formatters/index.d.ts.map +1 -0
  146. package/dist/formatters/index.js +6 -0
  147. package/dist/formatters/index.js.map +1 -0
  148. package/dist/formatters/tree.d.ts +29 -0
  149. package/dist/formatters/tree.d.ts.map +1 -0
  150. package/dist/formatters/tree.js +256 -0
  151. package/dist/formatters/tree.js.map +1 -0
  152. package/dist/formatters/tree.spec.d.ts +5 -0
  153. package/dist/formatters/tree.spec.d.ts.map +1 -0
  154. package/dist/formatters/tree.spec.js +127 -0
  155. package/dist/formatters/tree.spec.js.map +1 -0
  156. package/dist/index.d.ts +11 -0
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +13 -0
  159. package/dist/index.js.map +1 -0
  160. package/dist/installer.d.ts +13 -0
  161. package/dist/installer.d.ts.map +1 -0
  162. package/dist/installer.js +171 -0
  163. package/dist/installer.js.map +1 -0
  164. package/dist/store.d.ts +78 -0
  165. package/dist/store.d.ts.map +1 -0
  166. package/dist/store.js +344 -0
  167. package/dist/store.js.map +1 -0
  168. package/dist/types.d.ts +235 -0
  169. package/dist/types.d.ts.map +1 -0
  170. package/dist/types.js +5 -0
  171. package/dist/types.js.map +1 -0
  172. package/docs/README.md +68 -0
  173. package/docs/inspection/consumers.md +178 -0
  174. package/docs/inspection/list.md +182 -0
  175. package/docs/inspection/resolve.md +172 -0
  176. package/docs/installation/configuration.md +238 -0
  177. package/docs/installation/install.md +184 -0
  178. package/docs/maintenance/prune.md +159 -0
  179. package/docs/maintenance/remove.md +174 -0
  180. package/docs/maintenance/verify.md +174 -0
  181. package/docs/publishing/publish.md +146 -0
  182. package/docs/publishing/push.md +146 -0
  183. package/docs/store/locking.md +118 -0
  184. package/docs/store/namespaces.md +141 -0
  185. package/docs/store/structure.md +163 -0
  186. package/package.json +58 -0
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Lock - File locking para serializar operaciones de escritura
3
+ */
4
+ import fs from "fs/promises";
5
+ import { constants } from "fs";
6
+ import { getStorePath, getLockPath, DEFAULT_LOCK_TIMEOUT, DEFAULT_LOCK_RETRY_INTERVAL, DEFAULT_LOCK_STALE_TIME, } from "../constants.js";
7
+ const DEFAULT_OPTIONS = {
8
+ timeout: DEFAULT_LOCK_TIMEOUT,
9
+ retryInterval: DEFAULT_LOCK_RETRY_INTERVAL,
10
+ stale: DEFAULT_LOCK_STALE_TIME,
11
+ };
12
+ /**
13
+ * Sleep helper
14
+ */
15
+ function sleep(ms) {
16
+ return new Promise((resolve) => setTimeout(resolve, ms));
17
+ }
18
+ /**
19
+ * Write lock info to file
20
+ */
21
+ export async function writeLockInfo(lockPath, info) {
22
+ await fs.writeFile(lockPath, JSON.stringify(info, null, 2));
23
+ }
24
+ /**
25
+ * Read lock info from file
26
+ */
27
+ export async function readLockInfo(lockPath) {
28
+ try {
29
+ const content = await fs.readFile(lockPath, "utf-8");
30
+ return JSON.parse(content);
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ /**
37
+ * Check if a process is alive
38
+ */
39
+ function isProcessAlive(pid) {
40
+ try {
41
+ process.kill(pid, 0);
42
+ return true;
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ }
48
+ /**
49
+ * Check if lock is stale (process dead or too old)
50
+ */
51
+ export async function isLockStale(lockPath, staleTime) {
52
+ try {
53
+ const info = await readLockInfo(lockPath);
54
+ if (!info)
55
+ return true;
56
+ // Check if process is still alive
57
+ if (!isProcessAlive(info.pid)) {
58
+ return true;
59
+ }
60
+ // Check if lock is too old
61
+ const lockAge = Date.now() - new Date(info.acquired).getTime();
62
+ if (lockAge > staleTime) {
63
+ return true;
64
+ }
65
+ return false;
66
+ }
67
+ catch {
68
+ return true;
69
+ }
70
+ }
71
+ /**
72
+ * Try to acquire lock (non-blocking)
73
+ */
74
+ async function tryAcquireLock(lockPath) {
75
+ try {
76
+ // Try to create file exclusively
77
+ const handle = await fs.open(lockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY);
78
+ await handle.close();
79
+ return true;
80
+ }
81
+ catch (error) {
82
+ if (error.code === "EEXIST") {
83
+ return false;
84
+ }
85
+ throw error;
86
+ }
87
+ }
88
+ /**
89
+ * Acquire exclusive lock on the store
90
+ */
91
+ export async function acquireLock(options = {}) {
92
+ const opts = { ...DEFAULT_OPTIONS, ...options };
93
+ const storePath = getStorePath();
94
+ const lockPath = getLockPath();
95
+ // Ensure store directory exists
96
+ await fs.mkdir(storePath, { recursive: true });
97
+ const startTime = Date.now();
98
+ let attempt = 0;
99
+ let shownWaiting = false;
100
+ while (true) {
101
+ // Try to acquire lock
102
+ const acquired = await tryAcquireLock(lockPath);
103
+ if (acquired) {
104
+ // Write lock info
105
+ const info = {
106
+ pid: process.pid,
107
+ acquired: new Date().toISOString(),
108
+ command: process.argv.slice(2).join(" "),
109
+ };
110
+ await writeLockInfo(lockPath, info);
111
+ return {
112
+ fd: 0, // Not using fd in this implementation
113
+ release: async () => {
114
+ try {
115
+ await fs.unlink(lockPath);
116
+ }
117
+ catch {
118
+ // Ignore errors on release
119
+ }
120
+ },
121
+ };
122
+ }
123
+ // Lock is held by someone else
124
+ const elapsed = Date.now() - startTime;
125
+ if (elapsed >= opts.timeout) {
126
+ const info = await readLockInfo(lockPath);
127
+ throw new Error(`Timeout waiting for store lock after ${opts.timeout}ms.\n` +
128
+ `Lock held by PID ${info?.pid || "unknown"} (${info?.command || "unknown"})\n` +
129
+ `Acquired at: ${info?.acquired || "unknown"}\n\n` +
130
+ `If the process is stuck, you can manually remove:\n` +
131
+ ` rm ${lockPath}`);
132
+ }
133
+ // Check if lock is stale
134
+ if (await isLockStale(lockPath, opts.stale)) {
135
+ console.log("⚠️ Removing stale lock file...");
136
+ try {
137
+ await fs.unlink(lockPath);
138
+ }
139
+ catch {
140
+ // Ignore, might have been removed by another process
141
+ }
142
+ continue;
143
+ }
144
+ // Show waiting message (only once)
145
+ if (!shownWaiting) {
146
+ const info = await readLockInfo(lockPath);
147
+ console.log(`⏳ Store locked by PID ${info?.pid || "unknown"}, waiting...`);
148
+ shownWaiting = true;
149
+ }
150
+ attempt++;
151
+ await sleep(opts.retryInterval);
152
+ }
153
+ }
154
+ /**
155
+ * Execute operation with exclusive lock
156
+ */
157
+ export async function withStoreLock(operation, options) {
158
+ const lock = await acquireLock(options);
159
+ try {
160
+ return await operation();
161
+ }
162
+ finally {
163
+ await lock.release();
164
+ }
165
+ }
166
+ /**
167
+ * Check if store is currently locked
168
+ */
169
+ export async function isStoreLocked() {
170
+ const lockPath = getLockPath();
171
+ try {
172
+ await fs.access(lockPath);
173
+ return true;
174
+ }
175
+ catch {
176
+ return false;
177
+ }
178
+ }
179
+ /**
180
+ * Get current lock info (if locked)
181
+ */
182
+ export async function getCurrentLockInfo() {
183
+ const lockPath = getLockPath();
184
+ return readLockInfo(lockPath);
185
+ }
186
+ /**
187
+ * Force remove lock (use with caution)
188
+ */
189
+ export async function forceRemoveLock() {
190
+ const lockPath = getLockPath();
191
+ try {
192
+ await fs.unlink(lockPath);
193
+ }
194
+ catch {
195
+ // Ignore if doesn't exist
196
+ }
197
+ }
198
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/core/lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Lock - Unit tests
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=lock.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.spec.d.ts","sourceRoot":"","sources":["../../src/core/lock.spec.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Lock - Unit tests
3
+ */
4
+ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
5
+ import fs from "fs/promises";
6
+ import path from "path";
7
+ import os from "os";
8
+ import { acquireLock, writeLockInfo, readLockInfo, isLockStale, withStoreLock, isStoreLocked, getCurrentLockInfo, forceRemoveLock, } from "./lock.js";
9
+ // Mock the constants module to use temp directory
10
+ const TEST_STORE_PATH = path.join(os.tmpdir(), "devlink-test-" + Date.now());
11
+ vi.mock("../constants.js", () => ({
12
+ getStorePath: () => TEST_STORE_PATH,
13
+ getLockPath: () => path.join(TEST_STORE_PATH, ".lock"),
14
+ DEFAULT_LOCK_TIMEOUT: 5000,
15
+ DEFAULT_LOCK_RETRY_INTERVAL: 50,
16
+ DEFAULT_LOCK_STALE_TIME: 2000,
17
+ }));
18
+ describe("Lock", () => {
19
+ beforeEach(async () => {
20
+ await fs.mkdir(TEST_STORE_PATH, { recursive: true });
21
+ });
22
+ afterEach(async () => {
23
+ await fs.rm(TEST_STORE_PATH, { recursive: true, force: true });
24
+ });
25
+ describe("writeLockInfo / readLockInfo", () => {
26
+ it("should write and read lock info", async () => {
27
+ const lockPath = path.join(TEST_STORE_PATH, ".lock");
28
+ const info = {
29
+ pid: 12345,
30
+ acquired: "2026-02-12T10:00:00Z",
31
+ command: "publish",
32
+ };
33
+ await writeLockInfo(lockPath, info);
34
+ const read = await readLockInfo(lockPath);
35
+ expect(read).toEqual(info);
36
+ });
37
+ it("should return null for non-existent lock file", async () => {
38
+ const lockPath = path.join(TEST_STORE_PATH, "nonexistent.lock");
39
+ const read = await readLockInfo(lockPath);
40
+ expect(read).toBeNull();
41
+ });
42
+ });
43
+ describe("isLockStale", () => {
44
+ it("should return true for non-existent lock", async () => {
45
+ const lockPath = path.join(TEST_STORE_PATH, "nonexistent.lock");
46
+ const stale = await isLockStale(lockPath, 10000);
47
+ expect(stale).toBe(true);
48
+ });
49
+ it("should return true for dead process", async () => {
50
+ const lockPath = path.join(TEST_STORE_PATH, ".lock");
51
+ const info = {
52
+ pid: 999999999, // Non-existent PID
53
+ acquired: new Date().toISOString(),
54
+ command: "test",
55
+ };
56
+ await writeLockInfo(lockPath, info);
57
+ const stale = await isLockStale(lockPath, 10000);
58
+ expect(stale).toBe(true);
59
+ });
60
+ it("should return false for current process", async () => {
61
+ const lockPath = path.join(TEST_STORE_PATH, ".lock");
62
+ const info = {
63
+ pid: process.pid,
64
+ acquired: new Date().toISOString(),
65
+ command: "test",
66
+ };
67
+ await writeLockInfo(lockPath, info);
68
+ const stale = await isLockStale(lockPath, 10000);
69
+ expect(stale).toBe(false);
70
+ });
71
+ it("should return true for old lock", async () => {
72
+ const lockPath = path.join(TEST_STORE_PATH, ".lock");
73
+ const oldDate = new Date(Date.now() - 20000).toISOString();
74
+ const info = {
75
+ pid: process.pid,
76
+ acquired: oldDate,
77
+ command: "test",
78
+ };
79
+ await writeLockInfo(lockPath, info);
80
+ const stale = await isLockStale(lockPath, 1000);
81
+ expect(stale).toBe(true);
82
+ });
83
+ });
84
+ describe("acquireLock", () => {
85
+ it("should acquire lock successfully", async () => {
86
+ const lock = await acquireLock();
87
+ expect(lock).toBeDefined();
88
+ expect(typeof lock.release).toBe("function");
89
+ // Verify lock file exists
90
+ const locked = await isStoreLocked();
91
+ expect(locked).toBe(true);
92
+ await lock.release();
93
+ });
94
+ it("should release lock properly", async () => {
95
+ const lock = await acquireLock();
96
+ await lock.release();
97
+ const locked = await isStoreLocked();
98
+ expect(locked).toBe(false);
99
+ });
100
+ it("should write correct lock info", async () => {
101
+ const lock = await acquireLock();
102
+ const info = await getCurrentLockInfo();
103
+ expect(info).toBeDefined();
104
+ expect(info?.pid).toBe(process.pid);
105
+ expect(info?.acquired).toBeDefined();
106
+ await lock.release();
107
+ });
108
+ });
109
+ describe("withStoreLock", () => {
110
+ it("should execute operation with lock", async () => {
111
+ let executed = false;
112
+ await withStoreLock(async () => {
113
+ executed = true;
114
+ const locked = await isStoreLocked();
115
+ expect(locked).toBe(true);
116
+ });
117
+ expect(executed).toBe(true);
118
+ // Lock should be released
119
+ const locked = await isStoreLocked();
120
+ expect(locked).toBe(false);
121
+ });
122
+ it("should release lock on error", async () => {
123
+ await expect(withStoreLock(async () => {
124
+ throw new Error("Test error");
125
+ })).rejects.toThrow("Test error");
126
+ // Lock should be released
127
+ const locked = await isStoreLocked();
128
+ expect(locked).toBe(false);
129
+ });
130
+ it("should return operation result", async () => {
131
+ const result = await withStoreLock(async () => {
132
+ return 42;
133
+ });
134
+ expect(result).toBe(42);
135
+ });
136
+ });
137
+ describe("isStoreLocked", () => {
138
+ it("should return false when not locked", async () => {
139
+ const locked = await isStoreLocked();
140
+ expect(locked).toBe(false);
141
+ });
142
+ it("should return true when locked", async () => {
143
+ const lock = await acquireLock();
144
+ const locked = await isStoreLocked();
145
+ expect(locked).toBe(true);
146
+ await lock.release();
147
+ });
148
+ });
149
+ describe("forceRemoveLock", () => {
150
+ it("should remove lock file", async () => {
151
+ const lock = await acquireLock();
152
+ await forceRemoveLock();
153
+ const locked = await isStoreLocked();
154
+ expect(locked).toBe(false);
155
+ });
156
+ it("should not throw if lock doesn't exist", async () => {
157
+ await expect(forceRemoveLock()).resolves.not.toThrow();
158
+ });
159
+ });
160
+ });
161
+ //# sourceMappingURL=lock.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.spec.js","sourceRoot":"","sources":["../../src/core/lock.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Registry - Gestión del registry.json
3
+ */
4
+ import type { Registry, PackageEntry, VersionEntry } from "../types.js";
5
+ /**
6
+ * Create an empty registry
7
+ */
8
+ export declare function createEmptyRegistry(): Registry;
9
+ /**
10
+ * Read registry from disk
11
+ * Returns empty registry if file doesn't exist
12
+ */
13
+ export declare function readRegistry(): Promise<Registry>;
14
+ /**
15
+ * Write registry to disk (atomic write)
16
+ */
17
+ export declare function writeRegistry(registry: Registry): Promise<void>;
18
+ /**
19
+ * Ensure a namespace exists in the registry
20
+ */
21
+ export declare function ensureNamespaceInRegistry(registry: Registry, namespace: string): void;
22
+ /**
23
+ * Add or update a package version in the registry
24
+ */
25
+ export declare function addPackageToRegistry(registry: Registry, namespace: string, packageName: string, version: string, entry: VersionEntry): void;
26
+ /**
27
+ * Remove a package version from the registry
28
+ * Returns true if something was removed
29
+ */
30
+ export declare function removePackageFromRegistry(registry: Registry, namespace: string, packageName: string, version?: string): boolean;
31
+ /**
32
+ * Get a package entry from the registry
33
+ */
34
+ export declare function getPackageFromRegistry(registry: Registry, namespace: string, packageName: string): PackageEntry | null;
35
+ /**
36
+ * Get a specific version entry from the registry
37
+ */
38
+ export declare function getVersionFromRegistry(registry: Registry, namespace: string, packageName: string, version: string): VersionEntry | null;
39
+ /**
40
+ * Check if a namespace exists in the registry
41
+ */
42
+ export declare function namespaceExistsInRegistry(registry: Registry, namespace: string): boolean;
43
+ /**
44
+ * Get all namespaces from the registry
45
+ * Returns global first, then alphabetically sorted
46
+ */
47
+ export declare function getNamespacesFromRegistry(registry: Registry): string[];
48
+ /**
49
+ * Get all packages in a namespace
50
+ */
51
+ export declare function getPackagesInNamespace(registry: Registry, namespace: string): string[];
52
+ /**
53
+ * Get all versions of a package in a namespace
54
+ */
55
+ export declare function getVersionsInNamespace(registry: Registry, namespace: string, packageName: string): string[];
56
+ /**
57
+ * Remove a namespace from the registry
58
+ * Cannot remove the global namespace
59
+ */
60
+ export declare function removeNamespaceFromRegistry(registry: Registry, namespace: string): boolean;
61
+ /**
62
+ * Get total package count across all namespaces
63
+ */
64
+ export declare function getTotalPackageCount(registry: Registry): number;
65
+ /**
66
+ * Find all namespaces containing a specific package
67
+ */
68
+ export declare function findPackageInAllNamespaces(registry: Registry, packageName: string): {
69
+ namespace: string;
70
+ versions: string[];
71
+ }[];
72
+ /**
73
+ * Find all packages matching a scope (e.g., @webforgeai)
74
+ */
75
+ export declare function findPackagesByScope(registry: Registry, scope: string): {
76
+ namespace: string;
77
+ package: string;
78
+ versions: string[];
79
+ }[];
80
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAkB,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQxF;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CAU9C;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,CAsBtD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrE;AAGD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,GAChB,IAAI,CAON;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,YAAY,GAClB,IAAI,CAUN;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAsBT;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,YAAY,GAAG,IAAI,CAKrB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,YAAY,GAAG,IAAI,CAKrB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,CAQtE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,GAChB,MAAM,EAAE,CAKV;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,MAAM,EAAE,CAKV;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAWT;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAQ/D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,GAClB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAmB7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,GACZ;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAiB9D"}