@cef-ai/cli 2.9.1 → 3.0.0

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.
@@ -1,192 +0,0 @@
1
- import { mkdtemp, readdir, readFile, rm, stat } from "node:fs/promises";
2
- import os from "node:os";
3
- import path from "node:path";
4
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
- import { CREDENTIAL_REFRESH_MARGIN_MS, ddcTokenCannotOpenStore, fileCredentialCache, mintGatewayCredentials, mintedCredentials, resolveGatewayAccess, } from "./eval-auth.js";
6
- let dir;
7
- beforeEach(async () => {
8
- dir = await mkdtemp(path.join(os.tmpdir(), "cef-eval-auth-"));
9
- });
10
- afterEach(async () => {
11
- await rm(dir, { recursive: true, force: true });
12
- });
13
- const HOUR = 3600_000;
14
- /** A mint that hands out `k1`, `k2`, … each valid for an hour from `now()`. */
15
- function minter(now) {
16
- let n = 0;
17
- const mint = async () => {
18
- n++;
19
- return { accessKeyId: `k${n}`, secretAccessKey: `s${n}`, expiresAt: now() + HOUR };
20
- };
21
- return { mint, count: () => n };
22
- }
23
- describe("a minted credential", () => {
24
- it("is reused while it has time left, and replaced before it expires", async () => {
25
- let t = 0;
26
- const m = minter(() => t);
27
- const source = mintedCredentials({ mint: m.mint, now: () => t });
28
- expect((await source.get()).accessKeyId).toBe("k1");
29
- t = HOUR - CREDENTIAL_REFRESH_MARGIN_MS - 1;
30
- expect((await source.get()).accessKeyId).toBe("k1");
31
- // Inside the margin: a long run must not carry it to the gateway's 403.
32
- t = HOUR - CREDENTIAL_REFRESH_MARGIN_MS + 1;
33
- expect((await source.get()).accessKeyId).toBe("k2");
34
- expect(m.count()).toBe(2);
35
- });
36
- it("is minted once for callers asking at the same time", async () => {
37
- const m = minter(() => 0);
38
- const source = mintedCredentials({ mint: m.mint, now: () => 0 });
39
- const got = await Promise.all([source.get(), source.get(), source.get()]);
40
- expect(got.map((c) => c.accessKeyId)).toEqual(["k1", "k1", "k1"]);
41
- expect(m.count()).toBe(1);
42
- });
43
- it("is replaced after the gateway refused it", async () => {
44
- const m = minter(() => 0);
45
- const source = mintedCredentials({ mint: m.mint, now: () => 0 });
46
- await source.get();
47
- expect(await source.invalidate()).toBe(true);
48
- expect((await source.get()).accessKeyId).toBe("k2");
49
- });
50
- it("is shared between commands through an owner-only cache file", async () => {
51
- const file = path.join(dir, "nested", "creds.json");
52
- const t = Date.now();
53
- const m = minter(() => t);
54
- const first = mintedCredentials({ mint: m.mint, now: () => t, cache: fileCredentialCache(file, "gw|alice") });
55
- expect((await first.get()).accessKeyId).toBe("k1");
56
- // A second command: same gateway and wallet, no new mint.
57
- const second = mintedCredentials({ mint: m.mint, now: () => t, cache: fileCredentialCache(file, "gw|alice") });
58
- expect((await second.get()).accessKeyId).toBe("k1");
59
- expect(m.count()).toBe(1);
60
- // Another wallet does not get alice's.
61
- const other = mintedCredentials({ mint: m.mint, now: () => t, cache: fileCredentialCache(file, "gw|bob") });
62
- expect((await other.get()).accessKeyId).toBe("k2");
63
- expect((await stat(file)).mode & 0o777).toBe(0o600);
64
- // A refused credential leaves the cache, so the next command does not pick it up again.
65
- await second.invalidate();
66
- expect(Object.keys(JSON.parse(await readFile(file, "utf8")))).toEqual(["gw|bob"]);
67
- });
68
- it("keeps every entry when several commands write the cache at once", async () => {
69
- const file = path.join(dir, "creds.json");
70
- const expiresAt = Date.now() + HOUR;
71
- const wallets = Array.from({ length: 8 }, (_, i) => `gw|w${i}`);
72
- // Each write is a read-modify-write of the whole file; unserialised, they drop each other's entries.
73
- await Promise.all(wallets.map((k) => fileCredentialCache(file, k).write({ accessKeyId: k, secretAccessKey: "s", expiresAt })));
74
- expect(Object.keys(JSON.parse(await readFile(file, "utf8"))).sort()).toEqual(wallets);
75
- expect((await stat(file)).mode & 0o777).toBe(0o600);
76
- expect((await readdir(dir)).sort()).toEqual(["creds.json"]);
77
- });
78
- it("is not reused from the cache when it is about to expire", async () => {
79
- const file = path.join(dir, "creds.json");
80
- let t = Date.now();
81
- const m = minter(() => t);
82
- await mintedCredentials({ mint: m.mint, now: () => t, cache: fileCredentialCache(file, "k") }).get();
83
- t += HOUR - CREDENTIAL_REFRESH_MARGIN_MS + 1;
84
- expect((await mintedCredentials({ mint: m.mint, now: () => t, cache: fileCredentialCache(file, "k") }).get()).accessKeyId).toBe("k2");
85
- });
86
- });
87
- describe("resolving gateway access", () => {
88
- const signer = { address: "5Alice" };
89
- it("mints through the source and keeps the bucket the AS pubkey names", async () => {
90
- let n = 0;
91
- const access = await resolveGatewayAccess({ asPubkey: `0x${"ab".repeat(32)}`, endpoint: "https://gw.example/" }, signer, {
92
- cacheFile: null,
93
- mint: async () => ({ endpoint: "x", bucket: "x", accessKeyId: `k${++n}`, secretAccessKey: "s", expiresAt: Date.now() + HOUR }),
94
- });
95
- expect(access).toMatchObject({ endpoint: "https://gw.example", bucket: `as-${"ab".repeat(30)}` });
96
- expect((await access.credentials.get()).accessKeyId).toBe("k1");
97
- expect(n).toBe(1);
98
- });
99
- it("serves explicit keys as given, and cannot replace them", async () => {
100
- const access = await resolveGatewayAccess({ accessKey: "AK", secret: "SK", bucket: "b", endpoint: "https://gw" });
101
- expect(await access.credentials.get()).toEqual({ accessKeyId: "AK", secretAccessKey: "SK" });
102
- expect(await access.credentials.invalidate()).toBe(false);
103
- });
104
- it.each([
105
- [{ accessKey: "AK" }, /--access-key is set but --secret \(or \$CEF_EVAL_SECRET\) is not/],
106
- [{ secret: "SK" }, /--secret is set but --access-key \(or \$CEF_EVAL_KEY\) is not/],
107
- ])("refuses half of an explicit key pair instead of falling through to the wallet (%o)", async (half, error) => {
108
- const saved = { key: process.env.CEF_EVAL_KEY, secret: process.env.CEF_EVAL_SECRET };
109
- delete process.env.CEF_EVAL_KEY;
110
- delete process.env.CEF_EVAL_SECRET;
111
- try {
112
- // A wallet is present, so without the check this would quietly mint and ignore the flag.
113
- await expect(resolveGatewayAccess({ asPubkey: `0x${"ab".repeat(32)}`, endpoint: "https://gw", ...half }, signer, {
114
- cacheFile: null,
115
- mint: async () => ({ endpoint: "x", bucket: "x", accessKeyId: "minted", secretAccessKey: "s", expiresAt: Date.now() + HOUR }),
116
- })).rejects.toThrow(error);
117
- }
118
- finally {
119
- if (saved.key !== undefined)
120
- process.env.CEF_EVAL_KEY = saved.key;
121
- if (saved.secret !== undefined)
122
- process.env.CEF_EVAL_SECRET = saved.secret;
123
- }
124
- });
125
- });
126
- describe("choosing a credential when $CEF_DDC_ACCESS_TOKEN is set", () => {
127
- const ENV = ["CEF_DDC_ACCESS_TOKEN", "CEF_KEYSTORE", "CEF_SECRET_PHRASE", "CEF_EVAL_KEY", "CEF_EVAL_SECRET"];
128
- const saved = {};
129
- let registryToken = "";
130
- beforeEach(async () => {
131
- for (const k of ENV) {
132
- saved[k] = process.env[k];
133
- delete process.env[k];
134
- }
135
- // What ROC's Access tab mints for `cef push`: full access, one bucket, no subject.
136
- const ddc = (await import("@cere-ddc-sdk/ddc-client"));
137
- const owner = new ddc.UriSigner("//cef-eval-test-owner");
138
- await owner.isReady();
139
- registryToken = (await ddc.AuthToken.fullAccess({ bucketId: 4044n }).sign(owner)).toString();
140
- process.env.CEF_DDC_ACCESS_TOKEN = registryToken;
141
- });
142
- afterEach(() => {
143
- for (const k of ENV) {
144
- if (saved[k] === undefined)
145
- delete process.env[k];
146
- else
147
- process.env[k] = saved[k];
148
- }
149
- });
150
- const AS = `0x${"cd".repeat(32)}`;
151
- const neverMint = async () => { throw new Error("must not mint"); };
152
- it("refuses the token alone, naming its bucket, the dataset bucket, and what to use instead", async () => {
153
- const err = await resolveGatewayAccess({ asPubkey: AS, endpoint: "https://gw" }, undefined, { cacheFile: null, mint: neverMint })
154
- .then(() => undefined, (e) => e);
155
- expect(err?.message).toMatch(/\$CEF_DDC_ACCESS_TOKEN .*cannot open dataset storage/);
156
- expect(err?.message).toContain("limited to DDC bucket 4044");
157
- expect(err?.message).toContain("cannot be delegated");
158
- expect(err?.message).toContain(`as-${"cd".repeat(30)}`);
159
- expect(err?.message).toContain("--access-key/--secret");
160
- });
161
- it("uses explicit keys over the token", async () => {
162
- const access = await resolveGatewayAccess({ asPubkey: AS, accessKey: "AK", secret: "SK", endpoint: "https://gw" });
163
- expect(await access.credentials.get()).toEqual({ accessKeyId: "AK", secretAccessKey: "SK" });
164
- });
165
- it("mints with a wallet when one is given beside the token", async () => {
166
- let minted = 0;
167
- const access = await resolveGatewayAccess({ asPubkey: AS, endpoint: "https://gw" }, { address: "5Alice" }, {
168
- cacheFile: null,
169
- mint: async () => ({ endpoint: "x", bucket: "x", accessKeyId: `k${++minted}`, secretAccessKey: "s", expiresAt: Date.now() + HOUR }),
170
- });
171
- expect((await access.credentials.get()).accessKeyId).toBe("k1");
172
- });
173
- it("still explains a string that is not a token", () => {
174
- expect(ddcTokenCannotOpenStore("not a token!", "as-x").message).toMatch(/cannot open dataset storage: datasets live in the S3 gateway bucket as-x/);
175
- });
176
- });
177
- describe("minting at the credential cap", () => {
178
- it("says what to do instead of surfacing the gateway's 400", async () => {
179
- const { UriSigner } = (await import("@cere-ddc-sdk/ddc-client"));
180
- const wallet = new UriSigner("//Alice", { type: "ed25519" });
181
- await wallet.isReady();
182
- const fetchImpl = (async (url) => {
183
- if (String(url).endsWith("/auth/info")) {
184
- return new Response(JSON.stringify({ gateway_public_key: "11".repeat(32) }), { status: 200 });
185
- }
186
- return new Response("credential limit reached", { status: 400 });
187
- });
188
- await expect(mintGatewayCredentials({ endpoint: "https://gw", asPubKey: "0x00", signer: wallet, fetchImpl }))
189
- .rejects.toThrow(/already holds as many live S3 credentials as the gateway allows.*--access-key\/--secret/s);
190
- });
191
- });
192
- //# sourceMappingURL=eval-auth.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eval-auth.test.js","sourceRoot":"","sources":["../../src/lib/eval-auth.test.ts"],"names":[],"mappings":"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"}
@@ -1,62 +0,0 @@
1
- /**
2
- * S3-gateway-backed `EvalStore`.
3
- *
4
- * Datasets live on the S3 gateway, NOT on the DDC content gateway that
5
- * `cef push` writes to. ROC's own `agentServiceAccess/wellKnown.ts` states why
6
- * these cannot be the same path: "the content gateway cannot resolve S3 keys:
7
- * the S3 gateway addresses objects through its own Postgres key->CID index,
8
- * which the CDN knows nothing about." They are two systems with two key spaces,
9
- * which is also why `cef eval push` is its own command rather than a flag on
10
- * `cef push`.
11
- */
12
- import { S3Client } from "@aws-sdk/client-s3";
13
- import type { EvalStore } from "@cef-ai/eval";
14
- import type { CredentialSource } from "./eval-auth.js";
15
- export interface S3StoreOptions {
16
- bucket: string;
17
- client: S3Client;
18
- /** Key prefix within the bucket. Defaults to none. */
19
- root?: string;
20
- /**
21
- * The gateway refused `failed`'s credential (403): a client with a fresh
22
- * one, or undefined when there is none. Each request is retried once.
23
- */
24
- renew?: (failed: S3Client) => Promise<S3Client | undefined>;
25
- }
26
- /** A refused credential: expired, revoked, or never valid. */
27
- export declare function isAuthFailure(err: unknown): boolean;
28
- export declare function s3Store(opts: S3StoreOptions): EvalStore;
29
- /**
30
- * Build an S3 client for a gateway endpoint. With a `CredentialSource` the
31
- * client asks it for a credential, carrying its expiry, so the SDK asks again
32
- * inside its refresh window (5 min before expiry) and the source mints anew.
33
- */
34
- export declare function gatewayClient(cfg: {
35
- endpoint: string;
36
- region?: string;
37
- } & ({
38
- accessKeyId: string;
39
- secretAccessKey: string;
40
- sessionToken?: string;
41
- credentials?: never;
42
- } | {
43
- credentials: CredentialSource;
44
- })): S3Client;
45
- /**
46
- * The store `cef eval` uses: a gateway client over a credential source, and
47
- * on a 403 one fresh client per refused credential — concurrent requests that
48
- * fail together share it instead of minting one each.
49
- */
50
- export declare function gatewayStore(opts: {
51
- endpoint: string;
52
- bucket: string;
53
- region?: string;
54
- credentials: CredentialSource;
55
- root?: string;
56
- makeClient?: (cfg: {
57
- endpoint: string;
58
- region?: string;
59
- credentials: CredentialSource;
60
- }) => S3Client;
61
- }): EvalStore;
62
- //# sourceMappingURL=eval-store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eval-store.d.ts","sourceRoot":"","sources":["../../src/lib/eval-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAML,QAAQ,EAET,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,CAAC;IACjB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;CAC7D;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAInD;AAuBD,wBAAgB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,CA8NvD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,CACA;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,KAAK,CAAA;CAAE,GAC5F;IAAE,WAAW,EAAE,gBAAgB,CAAA;CAAE,CACpC,GAAG,QAAQ,CA+CX;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,gBAAgB,CAAA;KAAE,KAAK,QAAQ,CAAC;CACtG,GAAG,SAAS,CAwBZ"}
@@ -1,334 +0,0 @@
1
- /**
2
- * S3-gateway-backed `EvalStore`.
3
- *
4
- * Datasets live on the S3 gateway, NOT on the DDC content gateway that
5
- * `cef push` writes to. ROC's own `agentServiceAccess/wellKnown.ts` states why
6
- * these cannot be the same path: "the content gateway cannot resolve S3 keys:
7
- * the S3 gateway addresses objects through its own Postgres key->CID index,
8
- * which the CDN knows nothing about." They are two systems with two key spaces,
9
- * which is also why `cef eval push` is its own command rather than a flag on
10
- * `cef push`.
11
- */
12
- import { GetObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
13
- /** A refused credential: expired, revoked, or never valid. */
14
- export function isAuthFailure(err) {
15
- const e = err;
16
- return e?.$metadata?.httpStatusCode === 403
17
- || e?.name === "InvalidAccessKeyId" || e?.name === "ExpiredToken" || e?.name === "AccessDenied";
18
- }
19
- /**
20
- * `listObjects` on the gateway caps a page at 1000 keys and does NOT signal
21
- * truncation to a naive caller — a known ceiling recorded in the design. So
22
- * this paginates explicitly with the continuation token rather than trusting a
23
- * single response, and every caller gets the whole prefix or an error.
24
- *
25
- * Silent truncation is the dangerous shape: a dataset that quietly
26
- * stops at 1000 cases cuts a version missing the rest, and the experiment
27
- * built from it looks complete.
28
- */
29
- /** The endpoint host, for a warning that has to say WHICH gateway misbehaved. */
30
- async function endpointLabel(client) {
31
- try {
32
- const endpoint = client.config
33
- .endpoint;
34
- return (await endpoint?.())?.hostname ?? "the S3 endpoint";
35
- }
36
- catch {
37
- return "the S3 endpoint";
38
- }
39
- }
40
- export function s3Store(opts) {
41
- const { bucket } = opts;
42
- let client = opts.client;
43
- /*
44
- * ONE RETRY ON A REFUSED CREDENTIAL. The client re-asks its credential
45
- * provider before expiry on its own; this covers the rest (revoked, a clock
46
- * that disagrees with the gateway's) without turning a real permission
47
- * error into a loop.
48
- */
49
- const send = async (command) => {
50
- const used = client;
51
- try {
52
- return (await used.send(command));
53
- }
54
- catch (err) {
55
- if (!opts.renew || !isAuthFailure(err))
56
- throw err;
57
- const fresh = await opts.renew(used);
58
- if (!fresh)
59
- throw err;
60
- client = fresh;
61
- return (await fresh.send(command));
62
- }
63
- };
64
- const root = opts.root ? opts.root.replace(/\/*$/, "/") : "";
65
- const full = (key) => `${root}${key}`;
66
- const get = async (key) => {
67
- try {
68
- const res = await send(new GetObjectCommand({ Bucket: bucket, Key: full(key) }));
69
- return (await res.Body?.transformToString()) ?? null;
70
- }
71
- catch (err) {
72
- const name = err.name;
73
- // A genuinely absent object is `null`; anything else (auth, network,
74
- // a bad bucket) must propagate — swallowing it would make `putCase`'s
75
- // written-once check silently pass and overwrite a real case.
76
- if (name === "NoSuchKey" || name === "NotFound")
77
- return null;
78
- throw err;
79
- }
80
- };
81
- return {
82
- async list(prefix) {
83
- const keys = [];
84
- let token;
85
- do {
86
- const page = await send(new ListObjectsV2Command({
87
- Bucket: bucket,
88
- Prefix: full(prefix),
89
- ContinuationToken: token,
90
- }));
91
- for (const obj of page.Contents ?? []) {
92
- if (obj.Key)
93
- keys.push(root ? obj.Key.slice(root.length) : obj.Key);
94
- }
95
- // Truncated with nowhere to continue from is the exact silent
96
- // truncation this function exists to prevent: returning the short list
97
- // reads as a complete one, and the version cut from it is missing cases
98
- // nobody will notice are gone.
99
- if (page.IsTruncated && !page.NextContinuationToken) {
100
- throw new Error(`[eval] listing "${full(prefix)}" in bucket "${bucket}" came back ` +
101
- `TRUNCATED after ${keys.length} key(s) with no ` +
102
- `NextContinuationToken, so the rest of the prefix cannot be ` +
103
- `fetched. Refusing to return a short list — a set that quietly ` +
104
- `stops cuts a version missing cases, and the experiment built ` +
105
- `from it looks complete.`);
106
- }
107
- token = page.IsTruncated ? page.NextContinuationToken : undefined;
108
- } while (token);
109
- return keys.sort();
110
- },
111
- /**
112
- * Child prefixes through `Delimiter: "/"`, paged the same way and with the
113
- * same refusal of a truncated page that has nowhere to continue — what
114
- * lets `listDatasets`/`findExperiment` skip every run record in the bucket.
115
- */
116
- async listPrefixes(prefix) {
117
- const out = new Set();
118
- let token;
119
- do {
120
- const page = await send(new ListObjectsV2Command({
121
- Bucket: bucket,
122
- Prefix: full(prefix),
123
- Delimiter: "/",
124
- ContinuationToken: token,
125
- }));
126
- for (const p of page.CommonPrefixes ?? []) {
127
- if (p.Prefix)
128
- out.add(root ? p.Prefix.slice(root.length) : p.Prefix);
129
- }
130
- if (page.IsTruncated && !page.NextContinuationToken) {
131
- throw new Error(`[eval] listing the prefixes of "${full(prefix)}" in bucket "${bucket}" came back TRUNCATED ` +
132
- `with no NextContinuationToken — refusing to return a short list.`);
133
- }
134
- token = page.IsTruncated ? page.NextContinuationToken : undefined;
135
- } while (token);
136
- return [...out].sort();
137
- },
138
- get,
139
- async put(key, body) {
140
- await send(new PutObjectCommand({
141
- Bucket: bucket,
142
- Key: full(key),
143
- Body: body,
144
- ContentType: "application/json",
145
- }));
146
- },
147
- /**
148
- * Write-if-absent. A real compare-and-set on every store this runs against,
149
- * including Cere's DDC S3 gateway — verified, not assumed.
150
- *
151
- * Two layers, in order:
152
- *
153
- * 1. READ FIRST, and return `false` without attempting any write. Catches
154
- * every collision older than one round trip, and — because it never
155
- * writes on that path — it is also what keeps a store that ignored the
156
- * header from corrupting rather than merely losing a cut.
157
- *
158
- * 2. `If-None-Match: "*"` on the PUT, with `412` read as "taken". This is
159
- * the part that actually closes the race, step 1 or no step 1.
160
- *
161
- * Step 2 was believed inert on the DDC gateway: it is a hand-written Go
162
- * service whose documented PutObject path is "stream to DDC, then UPSERT
163
- * the index row" with no precondition step, its published error model lists
164
- * no `412`, and nothing in this repo or ROC had ever sent the header. Two
165
- * company ADR paragraphs contradicted each other on it.
166
- *
167
- * Probed against dev rather than left as a caveat: the first conditional
168
- * PUT succeeded, the SECOND returned `PreconditionFailed` / 412, and the
169
- * stored bytes were still the first writer's. The gateway honours it, and
170
- * the ADR paragraph claiming conditional writes exist is the correct one.
171
- *
172
- * The unconditional fallback below stays for a store that rejects the
173
- * header outright with 501 — one unknown header must not be able to take
174
- * `eval push --cut` down entirely — and step 1 still guards that path. NOT
175
- * 400: that covers a malformed key, a bad body, a signing problem and much
176
- * else, and downgrading on it would let two concurrent cutters both
177
- * believe they won while step 2 was never really tried.
178
- */
179
- async putIfAbsent(key, body) {
180
- if ((await get(key)) !== null)
181
- return false;
182
- const command = (conditional) => new PutObjectCommand({
183
- Bucket: bucket,
184
- Key: full(key),
185
- Body: body,
186
- ContentType: "application/json",
187
- ...(conditional ? { IfNoneMatch: "*" } : {}),
188
- });
189
- try {
190
- await send(command(true));
191
- return true;
192
- }
193
- catch (err) {
194
- const code = err.$metadata
195
- ?.httpStatusCode;
196
- // 412: the key was taken. 409 (`ConditionalRequestConflict`) means a
197
- // concurrent write collided and AWS says to retry — reporting it as
198
- // "taken" sends the caller back to re-list and try the next number,
199
- // which is the same recovery and is self-correcting if the key turns
200
- // out to be free after all.
201
- if (err.name === "PreconditionFailed")
202
- return false;
203
- if (code === 412 || code === 409)
204
- return false;
205
- // A server that does not IMPLEMENT the header must not take the whole
206
- // feature down with it: `cef eval push --cut` has to keep working
207
- // against a gateway that answers 501. 501 ONLY — a 400 is "your request
208
- // was wrong", which covers a malformed key, a bad body, a signing
209
- // problem and much else, and downgrading on it means two cutters both
210
- // believe they won while step 2 was never really tried. And the
211
- // downgrade is announced: a gateway that regresses out of conditional
212
- // writes must be visible, not a comment nobody reads.
213
- if (code === 501) {
214
- console.warn(`[eval] ${await endpointLabel(client)} answered 501 to a conditional ` +
215
- `PUT (If-None-Match: *) on "${full(key)}" — falling back to an ` +
216
- `UNCONDITIONAL write. The read check above still stands, but two ` +
217
- `concurrent writers can now both believe they won a version or a ` +
218
- `revision. This gateway no longer supports write-once.`);
219
- await send(command(false));
220
- return true;
221
- }
222
- throw err;
223
- }
224
- },
225
- /**
226
- * The claim `storeConformance` refuses to run without, and the one the
227
- * doc comment above spends forty lines earning: the SERVER adjudicates,
228
- * through `If-None-Match: "*"` with 412/409 read as "taken".
229
- *
230
- * Pinned, not asserted-by-comment: `eval-store.test.ts` drives this
231
- * `putIfAbsent` and reads the header off the `PutObjectCommand` the store
232
- * actually sent. Change the mechanism and that test goes red next to this
233
- * word.
234
- *
235
- * One honest caveat, and it is wider than "one write": the 501 branch
236
- * above is in a per-call `catch`, so against a gateway that answers 501 it
237
- * fires on EVERY `putIfAbsent` for as long as that lasts. The whole
238
- * process is writing unconditionally, with only step 1's read between two
239
- * cutters and a silently replaced manifest. The per-call `console.warn` is
240
- * the right mitigation precisely because of that — it names the endpoint
241
- * every time rather than once — but nobody should read this as a single
242
- * degraded write.
243
- *
244
- * The declaration stays `conditional-write` regardless, because it
245
- * describes what this store SENDS. A store whose declared mechanism
246
- * flipped mid-run would be a claim nobody could check against the code,
247
- * which is the one thing the word has to be.
248
- */
249
- atomicity: "conditional-write",
250
- };
251
- }
252
- /**
253
- * Build an S3 client for a gateway endpoint. With a `CredentialSource` the
254
- * client asks it for a credential, carrying its expiry, so the SDK asks again
255
- * inside its refresh window (5 min before expiry) and the source mints anew.
256
- */
257
- export function gatewayClient(cfg) {
258
- const credentials = "credentials" in cfg && cfg.credentials
259
- ? async () => {
260
- const c = await cfg.credentials.get();
261
- return {
262
- accessKeyId: c.accessKeyId,
263
- secretAccessKey: c.secretAccessKey,
264
- ...(c.expiresAt !== undefined ? { expiration: new Date(c.expiresAt) } : {}),
265
- };
266
- }
267
- : {
268
- accessKeyId: cfg.accessKeyId,
269
- secretAccessKey: cfg.secretAccessKey,
270
- ...(cfg.sessionToken ? { sessionToken: cfg.sessionToken } : {}),
271
- };
272
- const config = {
273
- endpoint: cfg.endpoint,
274
- region: cfg.region ?? "us-east-1",
275
- // The gateway addresses buckets by path, not by virtual host.
276
- forcePathStyle: true,
277
- credentials,
278
- };
279
- const client = new S3Client(config);
280
- // The gateway routes on `/<bucket>/<key>` and reads the empty last segment of
281
- // a bucket-level path (`/<bucket>/`, which is what the AWS SDK sends under
282
- // `forcePathStyle`) as a key, answering `400 InvalidArgument: key is
283
- // required`. Keyed commands are left alone: an object key may legitimately
284
- // end in `/`. Keying off the command input rather than the path shape also
285
- // survives a `--endpoint` that carries a path prefix, where `/s3/<bucket>/`
286
- // is indistinguishable from a bucket-and-key path by pattern alone.
287
- //
288
- // ROC needs this too and has `removeTrailingBucketSlashForDdcGateway` in
289
- // `browserBucketStorage.ts`; that one matches on the path shape, so it is the
290
- // same behaviour for the bare-host endpoints both use.
291
- client.middlewareStack.add((next) => (args) => {
292
- const request = args.request;
293
- const keyed = typeof args.input === "object" && args.input !== null && "Key" in args.input;
294
- if (request?.path && request.path.length > 1 && request.path.endsWith("/") && !keyed) {
295
- request.path = request.path.replace(/\/+$/, "");
296
- }
297
- return next(args);
298
- }, { name: "removeTrailingBucketSlashForDdcGateway", step: "build" });
299
- return client;
300
- }
301
- /**
302
- * The store `cef eval` uses: a gateway client over a credential source, and
303
- * on a 403 one fresh client per refused credential — concurrent requests that
304
- * fail together share it instead of minting one each.
305
- */
306
- export function gatewayStore(opts) {
307
- const make = () => (opts.makeClient ?? gatewayClient)({
308
- endpoint: opts.endpoint, ...(opts.region ? { region: opts.region } : {}), credentials: opts.credentials,
309
- });
310
- let current = make();
311
- let renewing;
312
- return s3Store({
313
- bucket: opts.bucket,
314
- client: current,
315
- ...(opts.root ? { root: opts.root } : {}),
316
- renew: async (failed) => {
317
- if (failed !== current)
318
- return current;
319
- renewing ??= (async () => {
320
- try {
321
- if (!(await opts.credentials.invalidate()))
322
- return undefined;
323
- current = make();
324
- return current;
325
- }
326
- finally {
327
- renewing = undefined;
328
- }
329
- })();
330
- return renewing;
331
- },
332
- });
333
- }
334
- //# sourceMappingURL=eval-store.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eval-store.js","sourceRoot":"","sources":["../../src/lib/eval-store.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=eval-store.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eval-store.test.d.ts","sourceRoot":"","sources":["../../src/lib/eval-store.test.ts"],"names":[],"mappings":""}