@gullabs/google 0.8.4 → 0.9.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.
- package/README.md +13 -0
- package/dist/index.cjs +71 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -6
- package/dist/index.d.ts +30 -6
- package/dist/index.js +71 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -23,6 +23,19 @@ pnpm add @gullabs/google @gullabs/core @google/genai
|
|
|
23
23
|
| `geminiModelDescriptors`, `gemmaModelDescriptors`, `defaultGeminiRegistry` | Built-in model descriptors + pre-built registry |
|
|
24
24
|
| `geminiPricingSource()`, `GEMINI_PRICING`, `TIER_FACTOR` | Built-in Gemini pricing snapshot and tier-factor map |
|
|
25
25
|
|
|
26
|
+
|
|
27
|
+
| `GoogleFileStore` | Files API: upload + poll ACTIVE + delete |
|
|
28
|
+
| `FileDeleteOptions` | `{ failClosed?, signal? }` — opt-in fail-closed delete (parity with `@gullabs/xai`) |
|
|
29
|
+
|
|
30
|
+
## File store delete modes
|
|
31
|
+
|
|
32
|
+
`GoogleFileStore.delete` defaults to **fail-open** (errors → `onDeleteError`, resolve). Pass `{ failClosed: true }` when the host gates durable state on known success; HTTP/SDK not-found remains success (idempotent). Empty `handle.name` always throws `bad_request`.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
await store.delete(handle) // fail-open
|
|
36
|
+
await store.delete(handle, { failClosed: true }) // throw on non-not-found failure
|
|
37
|
+
```
|
|
38
|
+
|
|
26
39
|
## Quick example
|
|
27
40
|
|
|
28
41
|
```ts
|
package/dist/index.cjs
CHANGED
|
@@ -2873,25 +2873,88 @@ var GoogleFileStore = class {
|
|
|
2873
2873
|
}
|
|
2874
2874
|
}
|
|
2875
2875
|
/**
|
|
2876
|
-
* Delete a single uploaded file.
|
|
2877
|
-
*
|
|
2876
|
+
* Delete a single uploaded file. Idempotent: not-found → success.
|
|
2877
|
+
*
|
|
2878
|
+
* Default (`failClosed` omitted/false): errors go to `onDeleteError` and
|
|
2879
|
+
* resolve (P5 fail-open). With `failClosed: true`, non-not-found errors
|
|
2880
|
+
* throw typed `LlmError` and `onDeleteError` is not called.
|
|
2881
|
+
*
|
|
2882
|
+
* Empty/blank `handle.name` always throws `bad_request`.
|
|
2878
2883
|
*/
|
|
2879
|
-
async delete(handle) {
|
|
2884
|
+
async delete(handle, opts) {
|
|
2885
|
+
const name = handle.name;
|
|
2886
|
+
if (typeof name !== "string" || name.trim() === "") {
|
|
2887
|
+
throw new core.LlmError("GoogleFileHandle.name must be a non-empty string.", {
|
|
2888
|
+
kind: "bad_request",
|
|
2889
|
+
retryable: false,
|
|
2890
|
+
provider: "google"
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2893
|
+
const failClosed = opts?.failClosed === true;
|
|
2880
2894
|
try {
|
|
2895
|
+
if (opts?.signal?.aborted === true) {
|
|
2896
|
+
throw new core.LlmError("Google file delete aborted", {
|
|
2897
|
+
kind: "aborted",
|
|
2898
|
+
retryable: false,
|
|
2899
|
+
provider: "google"
|
|
2900
|
+
});
|
|
2901
|
+
}
|
|
2881
2902
|
const client = await this.getClient();
|
|
2882
|
-
await client.delete({ name
|
|
2903
|
+
await client.delete({ name });
|
|
2883
2904
|
} catch (err) {
|
|
2884
|
-
|
|
2905
|
+
if (isGoogleNotFoundError(err)) {
|
|
2906
|
+
return;
|
|
2907
|
+
}
|
|
2908
|
+
const classified = err instanceof core.LlmError ? err : core.classifyError(err);
|
|
2909
|
+
const withProvider = classified.provider === void 0 ? new core.LlmError(classified.message, {
|
|
2910
|
+
kind: classified.kind,
|
|
2911
|
+
retryable: classified.retryable,
|
|
2912
|
+
...classified.httpStatus !== void 0 ? { httpStatus: classified.httpStatus } : {},
|
|
2913
|
+
...classified.retryAfterMs !== void 0 ? { retryAfterMs: classified.retryAfterMs } : {},
|
|
2914
|
+
provider: "google",
|
|
2915
|
+
cause: classified.cause ?? err
|
|
2916
|
+
}) : classified;
|
|
2917
|
+
if (failClosed) {
|
|
2918
|
+
throw withProvider;
|
|
2919
|
+
}
|
|
2920
|
+
this.onDeleteError(name, withProvider);
|
|
2885
2921
|
}
|
|
2886
2922
|
}
|
|
2887
2923
|
/**
|
|
2888
2924
|
* Delete multiple files.
|
|
2889
|
-
*
|
|
2925
|
+
*
|
|
2926
|
+
* Fail-open (default): `Promise.allSettled` per handle.
|
|
2927
|
+
* Fail-closed: `Promise.all` — first throw rejects; in-flight siblings are
|
|
2928
|
+
* not cancelled. Prefer per-handle delete when gating durable release state.
|
|
2890
2929
|
*/
|
|
2891
|
-
async deleteAll(handles) {
|
|
2892
|
-
|
|
2930
|
+
async deleteAll(handles, opts) {
|
|
2931
|
+
if (opts?.failClosed === true) {
|
|
2932
|
+
await Promise.all(handles.map((h) => this.delete(h, opts)));
|
|
2933
|
+
return;
|
|
2934
|
+
}
|
|
2935
|
+
await Promise.allSettled(handles.map((h) => this.delete(h, opts)));
|
|
2893
2936
|
}
|
|
2894
2937
|
};
|
|
2938
|
+
function isGoogleNotFoundError(err) {
|
|
2939
|
+
if (err instanceof core.LlmError && err.httpStatus === 404) {
|
|
2940
|
+
return true;
|
|
2941
|
+
}
|
|
2942
|
+
if (typeof err !== "object" || err === null) {
|
|
2943
|
+
return false;
|
|
2944
|
+
}
|
|
2945
|
+
const obj = err;
|
|
2946
|
+
if (obj["status"] === 404 || obj["httpStatus"] === 404 || obj["code"] === 404) {
|
|
2947
|
+
return true;
|
|
2948
|
+
}
|
|
2949
|
+
if (obj["status"] === "NOT_FOUND" || obj["code"] === "NOT_FOUND") {
|
|
2950
|
+
return true;
|
|
2951
|
+
}
|
|
2952
|
+
const msg = typeof obj["message"] === "string" ? obj["message"] : "";
|
|
2953
|
+
if (/not\s*found|404/i.test(msg) && /file/i.test(msg)) {
|
|
2954
|
+
return true;
|
|
2955
|
+
}
|
|
2956
|
+
return false;
|
|
2957
|
+
}
|
|
2895
2958
|
var DEFAULT_SKEW_SECONDS = 30;
|
|
2896
2959
|
var DEFAULT_EXTENSION_SECONDS = 3600;
|
|
2897
2960
|
async function buildCachesClient(auth) {
|