@agent-device/proxy 0.0.0-stage → 0.21.23
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/LICENSE +21 -0
- package/README.md +107 -2
- package/dist/errors.mjs +304 -0
- package/dist/index.d.mts +36 -0
- package/dist/index.mjs +463 -0
- package/dist/node-http.mjs +68 -0
- package/dist/process.mjs +1147 -0
- package/dist/version.mjs +179 -0
- package/package.json +32 -3
package/dist/version.mjs
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
//#region ../host-kit/src/internal/project-root.ts
|
|
5
|
+
function resolveAgentDeviceProjectRoot(startDirectory) {
|
|
6
|
+
let current = startDirectory;
|
|
7
|
+
let nearest = null;
|
|
8
|
+
for (let i = 0; i < 8; i += 1) {
|
|
9
|
+
const pkgPath = path.join(current, "package.json");
|
|
10
|
+
if (fs.existsSync(pkgPath)) {
|
|
11
|
+
nearest ??= current;
|
|
12
|
+
try {
|
|
13
|
+
if (JSON.parse(fs.readFileSync(pkgPath, "utf8")).name === "agent-device") return current;
|
|
14
|
+
} catch {}
|
|
15
|
+
}
|
|
16
|
+
current = path.dirname(current);
|
|
17
|
+
}
|
|
18
|
+
return nearest ?? startDirectory;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The daemon's own source, relative to a project root. One path answers two questions
|
|
22
|
+
* with it: whether a tree is a source checkout at all, and which entry a checkout
|
|
23
|
+
* launches its daemon from (`src/daemon-client/daemon-launch-spec.ts`).
|
|
24
|
+
*/
|
|
25
|
+
const DAEMON_SOURCE_ENTRY = "src/daemon.ts";
|
|
26
|
+
/**
|
|
27
|
+
* Whether `root` is a source checkout rather than an installed copy of a published
|
|
28
|
+
* version. The published package ships its `bin` and `dist` and no `src`, so the
|
|
29
|
+
* daemon's own source is what tells the two apart — and that is the difference between
|
|
30
|
+
* a tree whose code can be rebuilt under its own version and one whose version already
|
|
31
|
+
* fixes its bytes.
|
|
32
|
+
*/
|
|
33
|
+
function isSourceCheckoutProjectRoot(root) {
|
|
34
|
+
return fs.existsSync(path.join(root, "package.json")) && fs.existsSync(path.join(root, "src/daemon.ts"));
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region ../kernel/src/ttl-memo.ts
|
|
38
|
+
const processMemoResets = /* @__PURE__ */ new Set();
|
|
39
|
+
function createTtlMemo(options = {}) {
|
|
40
|
+
const entries = /* @__PURE__ */ new Map();
|
|
41
|
+
const now = options.now ?? (() => Date.now());
|
|
42
|
+
const clearEntryTimer = (entry) => {
|
|
43
|
+
if (entry?.timer) clearTimeout(entry.timer);
|
|
44
|
+
};
|
|
45
|
+
const memo = {
|
|
46
|
+
get(key) {
|
|
47
|
+
const entry = entries.get(key);
|
|
48
|
+
if (!entry) return void 0;
|
|
49
|
+
if (entry.expiresAt !== void 0 && entry.expiresAt <= now()) {
|
|
50
|
+
memo.delete(key);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
return entry.value;
|
|
54
|
+
},
|
|
55
|
+
set(key, value) {
|
|
56
|
+
clearEntryTimer(entries.get(key));
|
|
57
|
+
const expiresAt = resolveExpiresAt(options.ttlMs, now);
|
|
58
|
+
const entry = {
|
|
59
|
+
value,
|
|
60
|
+
expiresAt
|
|
61
|
+
};
|
|
62
|
+
if (options.scheduleExpiry && expiresAt !== void 0) {
|
|
63
|
+
entry.timer = setTimeout(() => {
|
|
64
|
+
entries.delete(key);
|
|
65
|
+
}, Math.max(0, expiresAt - now()));
|
|
66
|
+
entry.timer.unref?.();
|
|
67
|
+
}
|
|
68
|
+
entries.set(key, entry);
|
|
69
|
+
},
|
|
70
|
+
delete(key) {
|
|
71
|
+
const entry = entries.get(key);
|
|
72
|
+
if (!entry) return false;
|
|
73
|
+
clearEntryTimer(entry);
|
|
74
|
+
return entries.delete(key);
|
|
75
|
+
},
|
|
76
|
+
clear() {
|
|
77
|
+
for (const entry of entries.values()) clearEntryTimer(entry);
|
|
78
|
+
entries.clear();
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
processMemoResets.add(memo.clear);
|
|
82
|
+
return memo;
|
|
83
|
+
}
|
|
84
|
+
function resolveExpiresAt(ttlMs, now) {
|
|
85
|
+
if (ttlMs === void 0 || !Number.isFinite(ttlMs)) return void 0;
|
|
86
|
+
return now() + Math.max(0, ttlMs);
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region ../host-kit/src/internal/version.ts
|
|
90
|
+
const versionMemo = createTtlMemo();
|
|
91
|
+
const projectRootMemo = createTtlMemo();
|
|
92
|
+
function readVersion(root = findProjectRoot()) {
|
|
93
|
+
const memoized = versionMemo.get(root);
|
|
94
|
+
if (memoized !== void 0) return memoized;
|
|
95
|
+
let pkg;
|
|
96
|
+
try {
|
|
97
|
+
pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
98
|
+
} catch {
|
|
99
|
+
return "0.0.0";
|
|
100
|
+
}
|
|
101
|
+
const version = typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
102
|
+
versionMemo.set(root, version);
|
|
103
|
+
return version;
|
|
104
|
+
}
|
|
105
|
+
function findProjectRoot() {
|
|
106
|
+
const memoized = projectRootMemo.get("self");
|
|
107
|
+
if (memoized !== void 0) return memoized;
|
|
108
|
+
const resolved = resolveAgentDeviceProjectRoot(path.dirname(fileURLToPath(import.meta.url)));
|
|
109
|
+
projectRootMemo.set("self", resolved);
|
|
110
|
+
return resolved;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Whether `candidate` is a later release than `baseline` (see {@link compareVersions}).
|
|
114
|
+
*/
|
|
115
|
+
function isNewerVersion(candidate, baseline) {
|
|
116
|
+
return compareVersions(candidate, baseline) > 0;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* SemVer order for the versions this package publishes: numeric `major.minor.patch` first, then a
|
|
120
|
+
* release sorts after any prerelease of the same base (`0.21.13` > `0.21.13-dev`, the shape main
|
|
121
|
+
* carries between releases), and prerelease fields compare per dot-separated field, numerically
|
|
122
|
+
* when both are numbers and lexically otherwise. Build metadata is ignored. A string that is not a
|
|
123
|
+
* version at all reads as `0.0.0`, so a malformed version always compares as the oldest.
|
|
124
|
+
*/
|
|
125
|
+
function compareVersions(left, right) {
|
|
126
|
+
const a = parseVersion(left);
|
|
127
|
+
const b = parseVersion(right);
|
|
128
|
+
return compareRelease(a.release, b.release) || comparePrerelease(a.prerelease, b.prerelease);
|
|
129
|
+
}
|
|
130
|
+
const SEMVER = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
131
|
+
function parseVersion(version) {
|
|
132
|
+
const match = SEMVER.exec(version.trim());
|
|
133
|
+
if (!match) return {
|
|
134
|
+
release: [
|
|
135
|
+
0,
|
|
136
|
+
0,
|
|
137
|
+
0
|
|
138
|
+
],
|
|
139
|
+
prerelease: []
|
|
140
|
+
};
|
|
141
|
+
return {
|
|
142
|
+
release: [
|
|
143
|
+
Number(match[1]),
|
|
144
|
+
Number(match[2]),
|
|
145
|
+
Number(match[3])
|
|
146
|
+
],
|
|
147
|
+
prerelease: match[4]?.split(".") ?? []
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function compareRelease(a, b) {
|
|
151
|
+
for (let i = 0; i < 3; i += 1) if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
/** A release (no prerelease) sorts after every prerelease of the same base. */
|
|
155
|
+
function comparePrerelease(a, b) {
|
|
156
|
+
if (a.length === 0) return b.length === 0 ? 0 : 1;
|
|
157
|
+
if (b.length === 0) return -1;
|
|
158
|
+
const fields = Math.max(a.length, b.length);
|
|
159
|
+
for (let i = 0; i < fields; i += 1) {
|
|
160
|
+
const x = a[i];
|
|
161
|
+
const y = b[i];
|
|
162
|
+
if (x === void 0) return -1;
|
|
163
|
+
if (y === void 0) return 1;
|
|
164
|
+
const order = comparePrereleaseField(x, y);
|
|
165
|
+
if (order !== 0) return order;
|
|
166
|
+
}
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
169
|
+
/** Numeric fields compare as numbers and sort below alphanumeric ones; the rest compare lexically. */
|
|
170
|
+
function comparePrereleaseField(x, y) {
|
|
171
|
+
if (x === y) return 0;
|
|
172
|
+
const xNumeric = /^\d+$/.test(x);
|
|
173
|
+
const yNumeric = /^\d+$/.test(y);
|
|
174
|
+
if (xNumeric && yNumeric) return Number(x) > Number(y) ? 1 : -1;
|
|
175
|
+
if (xNumeric !== yNumeric) return xNumeric ? -1 : 1;
|
|
176
|
+
return x > y ? 1 : -1;
|
|
177
|
+
}
|
|
178
|
+
//#endregion
|
|
179
|
+
export { DAEMON_SOURCE_ENTRY, compareVersions, findProjectRoot, isNewerVersion, isSourceCheckoutProjectRoot, readVersion };
|
package/package.json
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-device/proxy",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
3
|
+
"version": "0.21.23",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Transport-neutral authenticating proxy in front of an agent-device daemon.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Callstack",
|
|
8
|
+
"homepage": "https://agent-device.dev/",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/callstack/agent-device.git",
|
|
12
|
+
"directory": "packages/proxy"
|
|
13
|
+
},
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=22.12"
|
|
16
|
+
},
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.mts",
|
|
20
|
+
"import": "./dist/index.mjs"
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@agent-device/contracts": "0.0.0",
|
|
29
|
+
"@agent-device/host-kit": "0.0.0",
|
|
30
|
+
"@agent-device/kernel": "0.0.0"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsdown --config tsdown.config.ts"
|
|
34
|
+
}
|
|
6
35
|
}
|