@cortexkit/antigravity-auth-core 1.0.1 → 2.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.
- package/dist/account-manager.d.ts +281 -0
- package/dist/account-manager.d.ts.map +1 -0
- package/dist/account-manager.js +1378 -0
- package/dist/account-manager.js.map +1 -0
- package/dist/account-storage.d.ts +162 -0
- package/dist/account-storage.d.ts.map +1 -0
- package/dist/account-storage.js +635 -0
- package/dist/account-storage.js.map +1 -0
- package/dist/account-types.d.ts +136 -0
- package/dist/account-types.d.ts.map +1 -0
- package/dist/account-types.js +9 -0
- package/dist/account-types.js.map +1 -0
- package/dist/agy-request-metadata.d.ts +61 -0
- package/dist/agy-request-metadata.d.ts.map +1 -0
- package/dist/agy-request-metadata.js +197 -0
- package/dist/agy-request-metadata.js.map +1 -0
- package/dist/agy-transport.d.ts +2 -2
- package/dist/agy-transport.d.ts.map +1 -1
- package/dist/agy-transport.js +88 -74
- package/dist/agy-transport.js.map +1 -1
- package/dist/antigravity/oauth.d.ts +3 -2
- package/dist/antigravity/oauth.d.ts.map +1 -1
- package/dist/antigravity/oauth.js +65 -55
- package/dist/antigravity/oauth.js.map +1 -1
- package/dist/atomic-write.d.ts +23 -0
- package/dist/atomic-write.d.ts.map +1 -0
- package/dist/atomic-write.js +47 -0
- package/dist/atomic-write.js.map +1 -0
- package/dist/auth-types.d.ts +2 -2
- package/dist/auth-types.d.ts.map +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +9 -6
- package/dist/auth.js.map +1 -1
- package/dist/constants.d.ts +19 -12
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +52 -45
- package/dist/constants.js.map +1 -1
- package/dist/fetch-timeout.d.ts +26 -0
- package/dist/fetch-timeout.d.ts.map +1 -0
- package/dist/fetch-timeout.js +43 -0
- package/dist/fetch-timeout.js.map +1 -0
- package/dist/file-lock.d.ts +79 -0
- package/dist/file-lock.d.ts.map +1 -0
- package/dist/file-lock.js +438 -0
- package/dist/file-lock.js.map +1 -0
- package/dist/fingerprint.d.ts +13 -7
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +34 -24
- package/dist/fingerprint.js.map +1 -1
- package/dist/index.d.ts +23 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -8
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +10 -10
- package/dist/logger.js.map +1 -1
- package/dist/model-registry.d.ts +6 -5
- package/dist/model-registry.d.ts.map +1 -1
- package/dist/model-registry.js +124 -91
- package/dist/model-registry.js.map +1 -1
- package/dist/project.d.ts +1 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +53 -25
- package/dist/project.js.map +1 -1
- package/dist/quota-manager.d.ts +140 -0
- package/dist/quota-manager.d.ts.map +1 -0
- package/dist/quota-manager.js +481 -0
- package/dist/quota-manager.js.map +1 -0
- package/dist/quota-types.d.ts +49 -0
- package/dist/quota-types.d.ts.map +1 -0
- package/dist/quota-types.js +10 -0
- package/dist/quota-types.js.map +1 -0
- package/dist/rotation.d.ts +175 -0
- package/dist/rotation.d.ts.map +1 -0
- package/dist/rotation.js +391 -0
- package/dist/rotation.js.map +1 -0
- package/dist/transform/claude.d.ts +1 -1
- package/dist/transform/claude.d.ts.map +1 -1
- package/dist/transform/claude.js +63 -41
- package/dist/transform/claude.js.map +1 -1
- package/dist/transform/cross-model-sanitizer.d.ts +1 -1
- package/dist/transform/cross-model-sanitizer.d.ts.map +1 -1
- package/dist/transform/cross-model-sanitizer.js +19 -16
- package/dist/transform/cross-model-sanitizer.js.map +1 -1
- package/dist/transform/gemini.d.ts +10 -3
- package/dist/transform/gemini.d.ts.map +1 -1
- package/dist/transform/gemini.js +142 -73
- package/dist/transform/gemini.js.map +1 -1
- package/dist/transform/index.d.ts +9 -9
- package/dist/transform/index.d.ts.map +1 -1
- package/dist/transform/index.js +6 -6
- package/dist/transform/index.js.map +1 -1
- package/dist/transform/model-resolver.d.ts +5 -5
- package/dist/transform/model-resolver.d.ts.map +1 -1
- package/dist/transform/model-resolver.js +118 -76
- package/dist/transform/model-resolver.js.map +1 -1
- package/dist/transform/types.d.ts +5 -5
- package/dist/transform/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +14 -16
- package/dist/version.js.map +1 -1
- package/package.json +16 -10
package/dist/constants.js
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Constants used for Antigravity OAuth flows and Cloud Code Assist API integration.
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
import { buildAntigravityHarnessUserAgent } from "./fingerprint.js";
|
|
5
|
+
export const ANTIGRAVITY_CLIENT_ID = '1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com';
|
|
5
6
|
/**
|
|
6
7
|
* Client secret issued for the Antigravity OAuth application.
|
|
7
8
|
*/
|
|
8
|
-
export const ANTIGRAVITY_CLIENT_SECRET =
|
|
9
|
+
export const ANTIGRAVITY_CLIENT_SECRET = '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';
|
|
9
10
|
/**
|
|
10
11
|
* Scopes required for Antigravity integrations.
|
|
11
12
|
*/
|
|
12
13
|
export const ANTIGRAVITY_SCOPES = [
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
'https://www.googleapis.com/auth/cloud-platform',
|
|
15
|
+
'https://www.googleapis.com/auth/userinfo.email',
|
|
16
|
+
'https://www.googleapis.com/auth/userinfo.profile',
|
|
17
|
+
'https://www.googleapis.com/auth/cclog',
|
|
18
|
+
'https://www.googleapis.com/auth/experimentsandconfigs',
|
|
18
19
|
];
|
|
19
20
|
/**
|
|
20
21
|
* OAuth redirect URI used by the local CLI callback server.
|
|
21
22
|
*/
|
|
22
|
-
export const ANTIGRAVITY_REDIRECT_URI =
|
|
23
|
+
export const ANTIGRAVITY_REDIRECT_URI = 'http://localhost:51121/oauth-callback';
|
|
23
24
|
/**
|
|
24
25
|
* Root endpoints for the Antigravity API (in fallback order).
|
|
25
|
-
* Live agy CLI 1.
|
|
26
|
+
* Live agy CLI 1.1.6 traffic uses daily-cloudcode-pa.googleapis.com.
|
|
26
27
|
*/
|
|
27
|
-
export const ANTIGRAVITY_ENDPOINT_DAILY =
|
|
28
|
-
export const ANTIGRAVITY_ENDPOINT_AUTOPUSH =
|
|
29
|
-
export const ANTIGRAVITY_ENDPOINT_PROD =
|
|
28
|
+
export const ANTIGRAVITY_ENDPOINT_DAILY = 'https://daily-cloudcode-pa.googleapis.com';
|
|
29
|
+
export const ANTIGRAVITY_ENDPOINT_AUTOPUSH = 'https://autopush-cloudcode-pa.sandbox.googleapis.com';
|
|
30
|
+
export const ANTIGRAVITY_ENDPOINT_PROD = 'https://cloudcode-pa.googleapis.com';
|
|
30
31
|
/**
|
|
31
32
|
* Endpoint fallback order (daily → prod).
|
|
32
33
|
* Autopush removed to reduce unnecessary fallback API calls — it rarely works when daily fails.
|
|
@@ -57,11 +58,13 @@ export const GEMINI_CLI_ENDPOINT = ANTIGRAVITY_ENDPOINT_PROD;
|
|
|
57
58
|
/**
|
|
58
59
|
* Hardcoded project id used when Antigravity does not return one (e.g., business/workspace accounts).
|
|
59
60
|
*/
|
|
60
|
-
export const ANTIGRAVITY_DEFAULT_PROJECT_ID =
|
|
61
|
-
export const ANTIGRAVITY_VERSION_FALLBACK =
|
|
61
|
+
export const ANTIGRAVITY_DEFAULT_PROJECT_ID = 'rising-fact-p41fc';
|
|
62
|
+
export const ANTIGRAVITY_VERSION_FALLBACK = '1.18.3';
|
|
62
63
|
let antigravityVersion = ANTIGRAVITY_VERSION_FALLBACK;
|
|
63
64
|
let versionLocked = false;
|
|
64
|
-
export function getAntigravityVersion() {
|
|
65
|
+
export function getAntigravityVersion() {
|
|
66
|
+
return antigravityVersion;
|
|
67
|
+
}
|
|
65
68
|
/**
|
|
66
69
|
* Set the runtime Antigravity version. Can only be called once (at startup).
|
|
67
70
|
* Subsequent calls are silently ignored to prevent accidental mutation.
|
|
@@ -72,26 +75,36 @@ export function setAntigravityVersion(version) {
|
|
|
72
75
|
antigravityVersion = version;
|
|
73
76
|
versionLocked = true;
|
|
74
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Test-only: reset the version lock so `setAntigravityVersion` can run again.
|
|
80
|
+
* Bun has no Vitest-style module reset hook, and module state lives in this
|
|
81
|
+
* singleton — tests that exercise the lock need a way to start clean per
|
|
82
|
+
* scenario.
|
|
83
|
+
*/
|
|
84
|
+
export function __resetAntigravityVersionForTesting() {
|
|
85
|
+
antigravityVersion = ANTIGRAVITY_VERSION_FALLBACK;
|
|
86
|
+
versionLocked = false;
|
|
87
|
+
}
|
|
75
88
|
/** @deprecated Use getAntigravityVersion() for runtime access. */
|
|
76
89
|
export const ANTIGRAVITY_VERSION = ANTIGRAVITY_VERSION_FALLBACK;
|
|
77
90
|
export function getAntigravityHeaders() {
|
|
78
91
|
return {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
'User-Agent': `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Antigravity/${getAntigravityVersion()} Chrome/138.0.7204.235 Electron/37.3.1 Safari/537.36`,
|
|
93
|
+
'X-Goog-Api-Client': 'google-cloud-sdk vscode_cloudshelleditor/0.1',
|
|
94
|
+
'Client-Metadata': `{"ideType":"ANTIGRAVITY","platform":"${process.platform === 'win32' ? 'WINDOWS' : 'MACOS'}","pluginType":"GEMINI"}`,
|
|
82
95
|
};
|
|
83
96
|
}
|
|
84
97
|
/** @deprecated Use getAntigravityHeaders() for runtime access. */
|
|
85
98
|
export const ANTIGRAVITY_HEADERS = {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
'User-Agent': `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Antigravity/${ANTIGRAVITY_VERSION} Chrome/138.0.7204.235 Electron/37.3.1 Safari/537.36`,
|
|
100
|
+
'X-Goog-Api-Client': 'google-cloud-sdk vscode_cloudshelleditor/0.1',
|
|
101
|
+
'Client-Metadata': `{"ideType":"ANTIGRAVITY","platform":"${process.platform === 'win32' ? 'WINDOWS' : 'MACOS'}","pluginType":"GEMINI"}`,
|
|
89
102
|
};
|
|
90
|
-
export const GEMINI_CLI_VERSION =
|
|
103
|
+
export const GEMINI_CLI_VERSION = '1.0.0';
|
|
91
104
|
/**
|
|
92
105
|
* Default model used in Gemini CLI User-Agent when no model is specified.
|
|
93
106
|
*/
|
|
94
|
-
export const GEMINI_CLI_DEFAULT_MODEL =
|
|
107
|
+
export const GEMINI_CLI_DEFAULT_MODEL = 'gemini-2.5-pro';
|
|
95
108
|
/**
|
|
96
109
|
* Build Gemini CLI User-Agent string matching the official google-gemini/gemini-cli format.
|
|
97
110
|
* Format: `GeminiCLI/{version}/{model} ({platform}; {arch})`
|
|
@@ -100,38 +113,32 @@ export const GEMINI_CLI_DEFAULT_MODEL = "gemini-2.5-pro";
|
|
|
100
113
|
*/
|
|
101
114
|
export function buildGeminiCliUserAgent(model) {
|
|
102
115
|
const effectiveModel = model || GEMINI_CLI_DEFAULT_MODEL;
|
|
103
|
-
const platform = process.platform ||
|
|
104
|
-
const arch = process.arch ||
|
|
116
|
+
const platform = process.platform || 'darwin';
|
|
117
|
+
const arch = process.arch || 'arm64';
|
|
105
118
|
return `GeminiCLI/${GEMINI_CLI_VERSION}/${effectiveModel} (${platform}; ${arch})`;
|
|
106
119
|
}
|
|
107
120
|
/** @deprecated Use buildGeminiCliUserAgent() for runtime access. */
|
|
108
121
|
export const GEMINI_CLI_HEADERS = {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
'User-Agent': 'google-api-nodejs-client/9.15.1',
|
|
123
|
+
'X-Goog-Api-Client': 'gl-node/22.17.0',
|
|
124
|
+
'Client-Metadata': 'ideType=IDE_UNSPECIFIED,platform=PLATFORM_UNSPECIFIED,pluginType=GEMINI',
|
|
112
125
|
};
|
|
113
|
-
function buildAntigravityPlatformArch() {
|
|
114
|
-
const platform = process.platform === "win32" ? "windows" : process.platform || "unknown";
|
|
115
|
-
const arch = process.arch === "x64" ? "amd64" : process.arch === "ia32" ? "386" : process.arch || "unknown";
|
|
116
|
-
return `${platform}/${arch}`;
|
|
117
|
-
}
|
|
118
126
|
export function getRandomizedHeaders(style, model) {
|
|
119
|
-
if (style ===
|
|
127
|
+
if (style === 'gemini-cli') {
|
|
120
128
|
return {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
'User-Agent': buildGeminiCliUserAgent(model),
|
|
130
|
+
'X-Goog-Api-Client': GEMINI_CLI_HEADERS['X-Goog-Api-Client'],
|
|
131
|
+
'Client-Metadata': GEMINI_CLI_HEADERS['Client-Metadata'],
|
|
124
132
|
};
|
|
125
133
|
}
|
|
126
|
-
const platform = buildAntigravityPlatformArch();
|
|
127
134
|
return {
|
|
128
|
-
|
|
135
|
+
'User-Agent': buildAntigravityHarnessUserAgent(),
|
|
129
136
|
};
|
|
130
137
|
}
|
|
131
138
|
/**
|
|
132
139
|
* Provider identifier shared between the plugin loader and credential store.
|
|
133
140
|
*/
|
|
134
|
-
export const ANTIGRAVITY_PROVIDER_ID =
|
|
141
|
+
export const ANTIGRAVITY_PROVIDER_ID = 'google';
|
|
135
142
|
// ============================================================================
|
|
136
143
|
// TOOL HALLUCINATION PREVENTION (Ported from LLM-API-Key-Proxy)
|
|
137
144
|
// ============================================================================
|
|
@@ -158,9 +165,9 @@ If you are unsure about a tool's parameters, YOU MUST read the schema definition
|
|
|
158
165
|
* Template for parameter signature injection into tool descriptions.
|
|
159
166
|
* {params} will be replaced with the actual parameter list.
|
|
160
167
|
*/
|
|
161
|
-
export const CLAUDE_DESCRIPTION_PROMPT =
|
|
162
|
-
export const EMPTY_SCHEMA_PLACEHOLDER_NAME =
|
|
163
|
-
export const EMPTY_SCHEMA_PLACEHOLDER_DESCRIPTION =
|
|
168
|
+
export const CLAUDE_DESCRIPTION_PROMPT = '\n\n⚠️ STRICT PARAMETERS: {params}.';
|
|
169
|
+
export const EMPTY_SCHEMA_PLACEHOLDER_NAME = '_placeholder';
|
|
170
|
+
export const EMPTY_SCHEMA_PLACEHOLDER_DESCRIPTION = 'Placeholder. Always pass true.';
|
|
164
171
|
/**
|
|
165
172
|
* Sentinel value to bypass thought signature validation.
|
|
166
173
|
*
|
|
@@ -174,7 +181,7 @@ export const EMPTY_SCHEMA_PLACEHOLDER_DESCRIPTION = "Placeholder. Always pass tr
|
|
|
174
181
|
*
|
|
175
182
|
* @see https://ai.google.dev/gemini-api/docs/thought-signatures
|
|
176
183
|
*/
|
|
177
|
-
export const SKIP_THOUGHT_SIGNATURE =
|
|
184
|
+
export const SKIP_THOUGHT_SIGNATURE = 'skip_thought_signature_validator';
|
|
178
185
|
// ============================================================================
|
|
179
186
|
// GOOGLE SEARCH TOOL CONSTANTS
|
|
180
187
|
// ============================================================================
|
|
@@ -182,7 +189,7 @@ export const SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
|
182
189
|
* Model used for Google Search grounding requests.
|
|
183
190
|
* Uses gemini-2.5-flash for fast, cost-effective search operations. (3-flash is always at capacity and doesn't support souce citation).
|
|
184
191
|
*/
|
|
185
|
-
export const SEARCH_MODEL =
|
|
192
|
+
export const SEARCH_MODEL = 'gemini-2.5-flash';
|
|
186
193
|
/**
|
|
187
194
|
* Thinking budget for deep search (more thorough analysis).
|
|
188
195
|
*/
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream-safe active-fetch timeout helper.
|
|
3
|
+
*
|
|
4
|
+
* Bounds the time spent waiting for HTTP response headers while leaving any
|
|
5
|
+
* returned response body fully readable until the caller (or its own signal)
|
|
6
|
+
* chooses to abort it. Naively forwarding `AbortSignal.timeout(...)` into
|
|
7
|
+
* `fetch()` aborts the body at the deadline even when headers arrived
|
|
8
|
+
* promptly — the helper only forwards the timeout into the request signal
|
|
9
|
+
* until the underlying fetch resolves, then drops the timeout listener so
|
|
10
|
+
* the body remains consumable.
|
|
11
|
+
*/
|
|
12
|
+
export declare const ACTIVE_FETCH_TIMEOUT_MS = 15000;
|
|
13
|
+
export type ActiveFetchOptions = {
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
fetchImpl?: typeof fetch;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Issue an HTTP fetch with a bounded active-fetch (header) wait.
|
|
19
|
+
*
|
|
20
|
+
* The `init.signal` is composed into the request abort signal so caller
|
|
21
|
+
* cancellation still propagates, but the 15s active timeout is only enforced
|
|
22
|
+
* until `fetchImpl` resolves — once headers arrive the timeout listener is
|
|
23
|
+
* removed and the returned Response body can be streamed past the deadline.
|
|
24
|
+
*/
|
|
25
|
+
export declare function fetchWithActiveTimeout(input: RequestInfo | URL, init?: RequestInit, options?: ActiveFetchOptions): Promise<Response>;
|
|
26
|
+
//# sourceMappingURL=fetch-timeout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-timeout.d.ts","sourceRoot":"","sources":["../src/fetch-timeout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,uBAAuB,QAAS,CAAA;AAE7C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,CAAA;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,QAAQ,CAAC,CAsBnB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream-safe active-fetch timeout helper.
|
|
3
|
+
*
|
|
4
|
+
* Bounds the time spent waiting for HTTP response headers while leaving any
|
|
5
|
+
* returned response body fully readable until the caller (or its own signal)
|
|
6
|
+
* chooses to abort it. Naively forwarding `AbortSignal.timeout(...)` into
|
|
7
|
+
* `fetch()` aborts the body at the deadline even when headers arrived
|
|
8
|
+
* promptly — the helper only forwards the timeout into the request signal
|
|
9
|
+
* until the underlying fetch resolves, then drops the timeout listener so
|
|
10
|
+
* the body remains consumable.
|
|
11
|
+
*/
|
|
12
|
+
export const ACTIVE_FETCH_TIMEOUT_MS = 15_000;
|
|
13
|
+
/**
|
|
14
|
+
* Issue an HTTP fetch with a bounded active-fetch (header) wait.
|
|
15
|
+
*
|
|
16
|
+
* The `init.signal` is composed into the request abort signal so caller
|
|
17
|
+
* cancellation still propagates, but the 15s active timeout is only enforced
|
|
18
|
+
* until `fetchImpl` resolves — once headers arrive the timeout listener is
|
|
19
|
+
* removed and the returned Response body can be streamed past the deadline.
|
|
20
|
+
*/
|
|
21
|
+
export async function fetchWithActiveTimeout(input, init = {}, options = {}) {
|
|
22
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
23
|
+
const timeoutMs = options.timeoutMs ?? ACTIVE_FETCH_TIMEOUT_MS;
|
|
24
|
+
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
25
|
+
const activeController = new AbortController();
|
|
26
|
+
const onTimeoutAbort = () => activeController.abort(timeoutSignal.reason);
|
|
27
|
+
if (timeoutSignal.aborted) {
|
|
28
|
+
onTimeoutAbort();
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
timeoutSignal.addEventListener('abort', onTimeoutAbort, { once: true });
|
|
32
|
+
}
|
|
33
|
+
const composedSignal = init.signal
|
|
34
|
+
? AbortSignal.any([activeController.signal, init.signal])
|
|
35
|
+
: activeController.signal;
|
|
36
|
+
try {
|
|
37
|
+
return await fetchImpl(input, { ...init, signal: composedSignal });
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
timeoutSignal.removeEventListener('abort', onTimeoutAbort);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=fetch-timeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-timeout.js","sourceRoot":"","sources":["../src/fetch-timeout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAO7C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAwB,EACxB,OAAoB,EAAE,EACtB,UAA8B,EAAE;IAEhC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAA;IACvD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,uBAAuB,CAAA;IAE9D,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACpD,MAAM,gBAAgB,GAAG,IAAI,eAAe,EAAE,CAAA;IAC9C,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;IACzE,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;QAC1B,cAAc,EAAE,CAAA;IAClB,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM;QAChC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAA;IAE3B,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAA;IACpE,CAAC;YAAS,CAAC;QACT,aAAa,CAAC,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renewable fenced file lock.
|
|
3
|
+
*
|
|
4
|
+
* The lock file at `${path}.${name}.lock` holds the JSON
|
|
5
|
+
* `{ ownerId, expiresAt }`. Acquiring it uses an exclusive `wx` write so
|
|
6
|
+
* concurrent processes race deterministically — only one wins.
|
|
7
|
+
*
|
|
8
|
+
* A contended, live lock (ownerId present, expiresAt > now) returns
|
|
9
|
+
* `null` immediately; no eviction is attempted and no destructive op
|
|
10
|
+
* touches the file. A contended, stale lock (no owner, expired, or
|
|
11
|
+
* malformed-but-old) opens an eviction protocol that uses an exclusive
|
|
12
|
+
* "evicting" marker directory at `${lockPath}.evicting/owner.json` as a
|
|
13
|
+
* fence: the file holds the in-progress evicter's ownerId. The marker
|
|
14
|
+
* is verified before every destructive seam (re-read, unlink,
|
|
15
|
+
* re-acquire) so a contender whose marker has been hijacked will see
|
|
16
|
+
* ownership has changed and back off without touching the winner's lock.
|
|
17
|
+
*
|
|
18
|
+
* The renewal timer is `setInterval(...).unref()`-ed so it does not
|
|
19
|
+
* keep the Node/Bun runtime alive. Default renewal interval is
|
|
20
|
+
* `max(1000, floor(ttlMs / 3))`.
|
|
21
|
+
*/
|
|
22
|
+
export type FileLockStep = 'stale-marker-stat' | 'stale-marker-claimed' | 'stale-lock-confirmed' | 'eviction-marker-acquired' | 'renew-read' | 'renew-committed';
|
|
23
|
+
export interface FencedFileLockOptions {
|
|
24
|
+
path: string;
|
|
25
|
+
name: string;
|
|
26
|
+
ttlMs: number;
|
|
27
|
+
/**
|
|
28
|
+
* Defaults to `true`. When false, no renewal timer is scheduled.
|
|
29
|
+
*/
|
|
30
|
+
renew?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Override the renewal cadence in milliseconds.
|
|
33
|
+
* Defaults to `max(RENEW_MIN_INTERVAL_MS, floor(ttlMs / 3))`.
|
|
34
|
+
*/
|
|
35
|
+
renewIntervalMs?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Clock injection. Defaults to `Date.now`. Tests use this to
|
|
38
|
+
* simulate elapsed time without waiting for real wall-clock ticks.
|
|
39
|
+
*/
|
|
40
|
+
now?: () => number;
|
|
41
|
+
/**
|
|
42
|
+
* Hook invoked at well-defined milestones inside the eviction
|
|
43
|
+
* protocol and the renewal tick. Used by tests to inject
|
|
44
|
+
* interleavings and simulate racing contenders:
|
|
45
|
+
*
|
|
46
|
+
* - `renew-read` — after the renewal tick reads the lock payload,
|
|
47
|
+
* before the ownership checks and the temp-write/rename commit.
|
|
48
|
+
* - `renew-committed` — after the renewal rename lands, before the
|
|
49
|
+
* verify-after-commit re-read.
|
|
50
|
+
*/
|
|
51
|
+
onStep?: (step: FileLockStep) => Promise<void> | void;
|
|
52
|
+
}
|
|
53
|
+
export interface FencedFileLock {
|
|
54
|
+
ownerId: string;
|
|
55
|
+
assertOwned(): Promise<void>;
|
|
56
|
+
release(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Resolves when the renewal loop detects the lock has been taken over
|
|
59
|
+
* by another owner (or otherwise lost before `release()`). Resolves
|
|
60
|
+
* immediately if the lock is already lost.
|
|
61
|
+
*/
|
|
62
|
+
whenLost(): Promise<void>;
|
|
63
|
+
hasLost(): boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Thrown by `assertOwned` when the lock file no longer carries our
|
|
67
|
+
* ownerId or has expired.
|
|
68
|
+
*/
|
|
69
|
+
export declare class FileLockOwnershipError extends Error {
|
|
70
|
+
readonly details: {
|
|
71
|
+
path: string;
|
|
72
|
+
expectedOwner: string;
|
|
73
|
+
observedOwner?: string;
|
|
74
|
+
observedExpiresAt?: number;
|
|
75
|
+
};
|
|
76
|
+
constructor(message: string, details: FileLockOwnershipError['details']);
|
|
77
|
+
}
|
|
78
|
+
export declare function acquireFencedFileLock(options: FencedFileLockOptions): Promise<FencedFileLock | null>;
|
|
79
|
+
//# sourceMappingURL=file-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-lock.d.ts","sourceRoot":"","sources":["../src/file-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAkBH,MAAM,MAAM,YAAY,GACpB,mBAAmB,GACnB,sBAAsB,GACtB,sBAAsB,GACtB,0BAA0B,GAC1B,YAAY,GACZ,iBAAiB,CAAA;AAErB,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CACtD;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB;;;;OAIG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,OAAO,IAAI,OAAO,CAAA;CACnB;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,OAAO,EAAE;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,aAAa,EAAE,MAAM,CAAA;QACrB,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAC3B,CAAA;gBAEW,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,CAAC,SAAS,CAAC;CAKxE;AAmFD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAqJhC"}
|