@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.
- package/AGENTS.md +880 -0
- package/LICENSE +21 -0
- package/README.md +335 -0
- package/dist/__tests__/e2e.spec.d.ts +8 -0
- package/dist/__tests__/e2e.spec.d.ts.map +1 -0
- package/dist/__tests__/e2e.spec.js +253 -0
- package/dist/__tests__/e2e.spec.js.map +1 -0
- package/dist/__tests__/integration.spec.d.ts +8 -0
- package/dist/__tests__/integration.spec.d.ts.map +1 -0
- package/dist/__tests__/integration.spec.js +274 -0
- package/dist/__tests__/integration.spec.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +610 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/consumers.d.ts +37 -0
- package/dist/commands/consumers.d.ts.map +1 -0
- package/dist/commands/consumers.js +107 -0
- package/dist/commands/consumers.js.map +1 -0
- package/dist/commands/docs.d.ts +59 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +262 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/docs.spec.d.ts +5 -0
- package/dist/commands/docs.spec.d.ts.map +1 -0
- package/dist/commands/docs.spec.js +213 -0
- package/dist/commands/docs.spec.js.map +1 -0
- package/dist/commands/index.d.ts +13 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +13 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/install.d.ts +31 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +234 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/list.d.ts +22 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +45 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/list.spec.d.ts +5 -0
- package/dist/commands/list.spec.d.ts.map +1 -0
- package/dist/commands/list.spec.js +95 -0
- package/dist/commands/list.spec.js.map +1 -0
- package/dist/commands/prune.d.ts +27 -0
- package/dist/commands/prune.d.ts.map +1 -0
- package/dist/commands/prune.js +74 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/commands/publish.d.ts +16 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +225 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/publish.spec.d.ts +5 -0
- package/dist/commands/publish.spec.d.ts.map +1 -0
- package/dist/commands/publish.spec.js +98 -0
- package/dist/commands/publish.spec.js.map +1 -0
- package/dist/commands/push.d.ts +16 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +164 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/remove.d.ts +24 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +80 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/remove.spec.d.ts +5 -0
- package/dist/commands/remove.spec.d.ts.map +1 -0
- package/dist/commands/remove.spec.js +87 -0
- package/dist/commands/remove.spec.js.map +1 -0
- package/dist/commands/resolve.d.ts +20 -0
- package/dist/commands/resolve.d.ts.map +1 -0
- package/dist/commands/resolve.js +52 -0
- package/dist/commands/resolve.js.map +1 -0
- package/dist/commands/resolve.spec.d.ts +5 -0
- package/dist/commands/resolve.spec.d.ts.map +1 -0
- package/dist/commands/resolve.spec.js +87 -0
- package/dist/commands/resolve.spec.js.map +1 -0
- package/dist/commands/verify.d.ts +32 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +127 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +70 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +65 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +116 -0
- package/dist/constants.js.map +1 -0
- package/dist/constants.spec.d.ts +5 -0
- package/dist/constants.spec.d.ts.map +1 -0
- package/dist/constants.spec.js +72 -0
- package/dist/constants.spec.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/installations.d.ts +79 -0
- package/dist/core/installations.d.ts.map +1 -0
- package/dist/core/installations.js +207 -0
- package/dist/core/installations.js.map +1 -0
- package/dist/core/installations.spec.d.ts +5 -0
- package/dist/core/installations.spec.d.ts.map +1 -0
- package/dist/core/installations.spec.js +261 -0
- package/dist/core/installations.spec.js.map +1 -0
- package/dist/core/lock.d.ts +37 -0
- package/dist/core/lock.d.ts.map +1 -0
- package/dist/core/lock.js +198 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/lock.spec.d.ts +5 -0
- package/dist/core/lock.spec.d.ts.map +1 -0
- package/dist/core/lock.spec.js +161 -0
- package/dist/core/lock.spec.js.map +1 -0
- package/dist/core/registry.d.ts +80 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +231 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/registry.spec.d.ts +5 -0
- package/dist/core/registry.spec.d.ts.map +1 -0
- package/dist/core/registry.spec.js +281 -0
- package/dist/core/registry.spec.js.map +1 -0
- package/dist/core/resolver.d.ts +55 -0
- package/dist/core/resolver.d.ts.map +1 -0
- package/dist/core/resolver.js +127 -0
- package/dist/core/resolver.js.map +1 -0
- package/dist/core/resolver.spec.d.ts +5 -0
- package/dist/core/resolver.spec.d.ts.map +1 -0
- package/dist/core/resolver.spec.js +202 -0
- package/dist/core/resolver.spec.js.map +1 -0
- package/dist/core/store.d.ts +65 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +245 -0
- package/dist/core/store.js.map +1 -0
- package/dist/core/store.spec.d.ts +5 -0
- package/dist/core/store.spec.d.ts.map +1 -0
- package/dist/core/store.spec.js +195 -0
- package/dist/core/store.spec.js.map +1 -0
- package/dist/formatters/flat.d.ts +41 -0
- package/dist/formatters/flat.d.ts.map +1 -0
- package/dist/formatters/flat.js +131 -0
- package/dist/formatters/flat.js.map +1 -0
- package/dist/formatters/flat.spec.d.ts +5 -0
- package/dist/formatters/flat.spec.d.ts.map +1 -0
- package/dist/formatters/flat.spec.js +130 -0
- package/dist/formatters/flat.spec.js.map +1 -0
- package/dist/formatters/index.d.ts +6 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +6 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/tree.d.ts +29 -0
- package/dist/formatters/tree.d.ts.map +1 -0
- package/dist/formatters/tree.js +256 -0
- package/dist/formatters/tree.js.map +1 -0
- package/dist/formatters/tree.spec.d.ts +5 -0
- package/dist/formatters/tree.spec.d.ts.map +1 -0
- package/dist/formatters/tree.spec.js +127 -0
- package/dist/formatters/tree.spec.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/installer.d.ts +13 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +171 -0
- package/dist/installer.js.map +1 -0
- package/dist/store.d.ts +78 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +344 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +235 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/docs/README.md +68 -0
- package/docs/inspection/consumers.md +178 -0
- package/docs/inspection/list.md +182 -0
- package/docs/inspection/resolve.md +172 -0
- package/docs/installation/configuration.md +238 -0
- package/docs/installation/install.md +184 -0
- package/docs/maintenance/prune.md +159 -0
- package/docs/maintenance/remove.md +174 -0
- package/docs/maintenance/verify.md +174 -0
- package/docs/publishing/publish.md +146 -0
- package/docs/publishing/push.md +146 -0
- package/docs/store/locking.md +118 -0
- package/docs/store/namespaces.md +141 -0
- package/docs/store/structure.md +163 -0
- 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 @@
|
|
|
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"}
|