@aexol/spectral 0.9.244 → 0.9.246
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/dist/cli.js +6 -0
- package/dist/commands/secret.d.ts +16 -0
- package/dist/commands/secret.d.ts.map +1 -0
- package/dist/commands/secret.js +153 -0
- package/dist/extensions/list-secrets.d.ts +14 -0
- package/dist/extensions/list-secrets.d.ts.map +1 -0
- package/dist/extensions/list-secrets.js +63 -0
- package/dist/relay/routing.d.ts +1 -1
- package/dist/relay/routing.d.ts.map +1 -1
- package/dist/relay/routing.js +93 -17
- package/dist/sdk/coding-agent/utils/shell.d.ts.map +1 -1
- package/dist/sdk/coding-agent/utils/shell.js +15 -1
- package/dist/secrets/index.d.ts +11 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +10 -0
- package/dist/secrets/store.d.ts +109 -0
- package/dist/secrets/store.d.ts.map +1 -0
- package/dist/secrets/store.js +415 -0
- package/dist/server/agent-bridge.d.ts.map +1 -1
- package/dist/server/agent-bridge.js +7 -0
- package/dist/server/handlers/secrets.d.ts +40 -0
- package/dist/server/handlers/secrets.d.ts.map +1 -0
- package/dist/server/handlers/secrets.js +78 -0
- package/package.json +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REST handlers for the local secret store.
|
|
3
|
+
*
|
|
4
|
+
* Contract (shared with the landing frontend):
|
|
5
|
+
* - `GET /api/secrets` → `{ secrets: SecretMeta[] }` — metadata only,
|
|
6
|
+
* values are NEVER returned by anything.
|
|
7
|
+
* - `POST /api/secrets` → `{ secret: SecretMeta }` — body
|
|
8
|
+
* `{ name, value }`.
|
|
9
|
+
* - `DELETE /api/secrets/:name` → `{ ok: true }`.
|
|
10
|
+
*
|
|
11
|
+
* Name normalization/validation and the 64 KiB value cap live in
|
|
12
|
+
* `src/secrets/store.ts`. Errors follow the existing handler error shape
|
|
13
|
+
* (`BadRequestError`/`NotFoundError` → 400/404 in the relay rest loop).
|
|
14
|
+
*
|
|
15
|
+
* SECURITY: no handler here (or anywhere in the relay loop) logs a request or
|
|
16
|
+
* response value. Only names appear in error messages, and only after they
|
|
17
|
+
* have passed `normalizeSecretName` (letters/digits/underscores).
|
|
18
|
+
*/
|
|
19
|
+
import { SecretNameError, SecretValueError, deleteSecret, listSecrets, normalizeSecretName, setSecret, } from "../../secrets/index.js";
|
|
20
|
+
import { BadRequestError, NotFoundError } from "./errors.js";
|
|
21
|
+
function toBadRequest(err) {
|
|
22
|
+
if (err instanceof SecretNameError || err instanceof SecretValueError) {
|
|
23
|
+
return new BadRequestError(err.message);
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* `GET /api/secrets` — list secrets as metadata only.
|
|
29
|
+
*/
|
|
30
|
+
export function handleListSecrets() {
|
|
31
|
+
return { secrets: listSecrets() };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `POST /api/secrets` — create or update a secret. Body: `{ name, value }`.
|
|
35
|
+
* Returns the metadata-only view; the stored value is never echoed back.
|
|
36
|
+
*/
|
|
37
|
+
export function handleSetSecret(body) {
|
|
38
|
+
if (typeof body.name !== "string" || body.name.trim() === "") {
|
|
39
|
+
throw new BadRequestError("name (string) is required");
|
|
40
|
+
}
|
|
41
|
+
if (typeof body.value !== "string") {
|
|
42
|
+
throw new BadRequestError("value (string) is required");
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const secret = setSecret(body.name, body.value);
|
|
46
|
+
return { secret };
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
const mapped = toBadRequest(err);
|
|
50
|
+
if (mapped)
|
|
51
|
+
throw mapped;
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* `DELETE /api/secrets/:name` — delete a secret. Throws `NotFoundError` (404)
|
|
57
|
+
* when the name is not stored.
|
|
58
|
+
*/
|
|
59
|
+
export function handleDeleteSecret(rawName) {
|
|
60
|
+
if (typeof rawName !== "string" || rawName.trim() === "") {
|
|
61
|
+
throw new BadRequestError("name (string) is required");
|
|
62
|
+
}
|
|
63
|
+
let name;
|
|
64
|
+
try {
|
|
65
|
+
name = normalizeSecretName(rawName);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const mapped = toBadRequest(err);
|
|
69
|
+
if (mapped)
|
|
70
|
+
throw mapped;
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
const deleted = deleteSecret(name);
|
|
74
|
+
if (!deleted) {
|
|
75
|
+
throw new NotFoundError(`Secret ${name} not found`);
|
|
76
|
+
}
|
|
77
|
+
return { ok: true };
|
|
78
|
+
}
|