@zeke-02/tinfoil 0.0.11 → 1.1.3
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/ai-sdk-provider.d.ts +43 -4
- package/dist/ai-sdk-provider.d.ts.map +1 -0
- package/dist/ai-sdk-provider.js +51 -23
- package/dist/ai-sdk-provider.js.map +1 -0
- package/dist/atc.d.ts +23 -0
- package/dist/atc.d.ts.map +1 -0
- package/dist/atc.js +59 -0
- package/dist/atc.js.map +1 -0
- package/dist/config.d.ts +5 -4
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +6 -8
- package/dist/config.js.map +1 -0
- package/dist/encrypted-body-fetch.d.ts +30 -9
- package/dist/encrypted-body-fetch.d.ts.map +1 -0
- package/dist/encrypted-body-fetch.js +110 -68
- package/dist/encrypted-body-fetch.js.map +1 -0
- package/dist/env.d.ts +4 -1
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +28 -5
- package/dist/env.js.map +1 -0
- package/dist/index.browser.d.ts +13 -7
- package/dist/index.browser.d.ts.map +1 -0
- package/dist/index.browser.js +13 -29
- package/dist/index.browser.js.map +1 -0
- package/dist/index.d.ts +12 -8
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -48
- package/dist/index.js.map +1 -0
- package/dist/pinned-tls-fetch.browser.d.ts +2 -0
- package/dist/pinned-tls-fetch.browser.d.ts.map +1 -0
- package/dist/pinned-tls-fetch.browser.js +13 -0
- package/dist/pinned-tls-fetch.browser.js.map +1 -0
- package/dist/pinned-tls-fetch.d.ts +2 -1
- package/dist/pinned-tls-fetch.d.ts.map +1 -0
- package/dist/pinned-tls-fetch.js +76 -33
- package/dist/pinned-tls-fetch.js.map +1 -0
- package/dist/secure-client.d.ts +155 -8
- package/dist/secure-client.d.ts.map +1 -0
- package/dist/secure-client.js +222 -136
- package/dist/secure-client.js.map +1 -0
- package/dist/secure-fetch.d.ts +12 -1
- package/dist/secure-fetch.d.ts.map +1 -0
- package/dist/secure-fetch.js +29 -10
- package/dist/secure-fetch.js.map +1 -0
- package/dist/tinfoil-ai.d.ts +145 -0
- package/dist/tinfoil-ai.d.ts.map +1 -0
- package/dist/{esm/tinfoilai.mjs → tinfoil-ai.js} +83 -45
- package/dist/tinfoil-ai.js.map +1 -0
- package/dist/unsafe.browser.d.ts +3 -0
- package/dist/unsafe.browser.d.ts.map +1 -0
- package/dist/unsafe.browser.js +3 -0
- package/dist/unsafe.browser.js.map +1 -0
- package/dist/unsafe.d.ts +3 -0
- package/dist/unsafe.d.ts.map +1 -0
- package/dist/unsafe.js +3 -0
- package/dist/unsafe.js.map +1 -0
- package/dist/unverified-client.d.ts +7 -6
- package/dist/unverified-client.d.ts.map +1 -0
- package/dist/unverified-client.js +36 -32
- package/dist/unverified-client.js.map +1 -0
- package/dist/verifier.d.ts +2 -141
- package/dist/verifier.d.ts.map +1 -0
- package/dist/verifier.js +2 -570
- package/dist/verifier.js.map +1 -0
- package/package.json +54 -64
- package/LICENSE +0 -661
- package/README.md +0 -183
- package/dist/__tests__/test-utils.d.ts +0 -1
- package/dist/__tests__/test-utils.js +0 -44
- package/dist/esm/__tests__/test-utils.d.ts +0 -1
- package/dist/esm/__tests__/test-utils.mjs +0 -38
- package/dist/esm/ai-sdk-provider.d.ts +0 -7
- package/dist/esm/ai-sdk-provider.mjs +0 -26
- package/dist/esm/config.d.ts +0 -13
- package/dist/esm/config.mjs +0 -13
- package/dist/esm/encrypted-body-fetch.d.ts +0 -13
- package/dist/esm/encrypted-body-fetch.mjs +0 -105
- package/dist/esm/env.d.ts +0 -5
- package/dist/esm/env.mjs +0 -17
- package/dist/esm/fetch-adapter.d.ts +0 -21
- package/dist/esm/fetch-adapter.mjs +0 -23
- package/dist/esm/index.browser.d.ts +0 -7
- package/dist/esm/index.browser.mjs +0 -8
- package/dist/esm/index.d.ts +0 -9
- package/dist/esm/index.mjs +0 -13
- package/dist/esm/pinned-tls-fetch.d.ts +0 -1
- package/dist/esm/pinned-tls-fetch.mjs +0 -110
- package/dist/esm/router.d.ts +0 -11
- package/dist/esm/router.mjs +0 -33
- package/dist/esm/secure-client.d.ts +0 -21
- package/dist/esm/secure-client.mjs +0 -162
- package/dist/esm/secure-fetch.browser.d.ts +0 -1
- package/dist/esm/secure-fetch.browser.mjs +0 -10
- package/dist/esm/secure-fetch.d.ts +0 -1
- package/dist/esm/secure-fetch.mjs +0 -12
- package/dist/esm/tinfoilai.d.ts +0 -54
- package/dist/esm/unverified-client.d.ts +0 -18
- package/dist/esm/unverified-client.mjs +0 -61
- package/dist/esm/verifier.d.ts +0 -141
- package/dist/esm/verifier.mjs +0 -532
- package/dist/esm/wasm-exec.js +0 -668
- package/dist/esm/wasm-exec.mjs +0 -668
- package/dist/fetch-adapter.d.ts +0 -21
- package/dist/fetch-adapter.js +0 -27
- package/dist/router.d.ts +0 -11
- package/dist/router.js +0 -36
- package/dist/secure-fetch.browser.d.ts +0 -1
- package/dist/secure-fetch.browser.js +0 -13
- package/dist/tinfoilai.d.ts +0 -54
- package/dist/tinfoilai.js +0 -143
- package/dist/wasm-exec.js +0 -668
|
@@ -1,7 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Options for creating a Tinfoil AI SDK provider.
|
|
3
|
+
*/
|
|
4
|
+
export interface CreateTinfoilAIOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Override the base URL for API requests.
|
|
7
|
+
* Useful for proxying requests through your own backend.
|
|
8
|
+
*/
|
|
2
9
|
baseURL?: string;
|
|
3
|
-
|
|
10
|
+
/** GitHub repo for code verification. */
|
|
4
11
|
configRepo?: string;
|
|
12
|
+
/** URL to fetch the attestation bundle from. */
|
|
13
|
+
attestationBundleURL?: string;
|
|
5
14
|
}
|
|
6
|
-
|
|
7
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Create a Tinfoil provider for the Vercel AI SDK.
|
|
17
|
+
*
|
|
18
|
+
* This performs enclave verification and returns an OpenAI-compatible provider
|
|
19
|
+
* that can be used with Vercel AI SDK functions like `generateText` and `streamText`.
|
|
20
|
+
*
|
|
21
|
+
* @param apiKey - Your Tinfoil API key. Falls back to TINFOIL_API_KEY env var if not provided.
|
|
22
|
+
* @param options - Optional configuration
|
|
23
|
+
* @returns An AI SDK provider for Tinfoil
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { createTinfoilAI } from "tinfoil";
|
|
28
|
+
* import { generateText } from "ai";
|
|
29
|
+
*
|
|
30
|
+
* // Uses TINFOIL_API_KEY env var
|
|
31
|
+
* const tinfoil = await createTinfoilAI();
|
|
32
|
+
*
|
|
33
|
+
* // Or pass API key explicitly
|
|
34
|
+
* const tinfoil = await createTinfoilAI("your-api-key");
|
|
35
|
+
*
|
|
36
|
+
* const { text } = await generateText({
|
|
37
|
+
* model: tinfoil("llama3-3-70b"),
|
|
38
|
+
* prompt: "Hello!",
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @see https://docs.tinfoil.sh/sdk/javascript-sdk
|
|
43
|
+
* @see https://sdk.vercel.ai/ - Vercel AI SDK documentation
|
|
44
|
+
*/
|
|
45
|
+
export declare function createTinfoilAI(apiKey?: string, options?: CreateTinfoilAIOptions): Promise<import("@ai-sdk/openai-compatible").OpenAICompatibleProvider<string, string, string, string>>;
|
|
46
|
+
//# sourceMappingURL=ai-sdk-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-provider.d.ts","sourceRoot":"","sources":["../src/ai-sdk-provider.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,gDAAgD;IAChD,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,yGAwB1F"}
|
package/dist/ai-sdk-provider.js
CHANGED
|
@@ -1,29 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
2
|
+
import { SecureClient } from "./secure-client.js";
|
|
3
|
+
import { isRealBrowser } from "./env.js";
|
|
4
|
+
import { ConfigurationError } from "./verifier.js";
|
|
5
|
+
/**
|
|
6
|
+
* Create a Tinfoil provider for the Vercel AI SDK.
|
|
7
|
+
*
|
|
8
|
+
* This performs enclave verification and returns an OpenAI-compatible provider
|
|
9
|
+
* that can be used with Vercel AI SDK functions like `generateText` and `streamText`.
|
|
10
|
+
*
|
|
11
|
+
* @param apiKey - Your Tinfoil API key. Falls back to TINFOIL_API_KEY env var if not provided.
|
|
12
|
+
* @param options - Optional configuration
|
|
13
|
+
* @returns An AI SDK provider for Tinfoil
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { createTinfoilAI } from "tinfoil";
|
|
18
|
+
* import { generateText } from "ai";
|
|
19
|
+
*
|
|
20
|
+
* // Uses TINFOIL_API_KEY env var
|
|
21
|
+
* const tinfoil = await createTinfoilAI();
|
|
22
|
+
*
|
|
23
|
+
* // Or pass API key explicitly
|
|
24
|
+
* const tinfoil = await createTinfoilAI("your-api-key");
|
|
25
|
+
*
|
|
26
|
+
* const { text } = await generateText({
|
|
27
|
+
* model: tinfoil("llama3-3-70b"),
|
|
28
|
+
* prompt: "Hello!",
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @see https://docs.tinfoil.sh/sdk/javascript-sdk
|
|
33
|
+
* @see https://sdk.vercel.ai/ - Vercel AI SDK documentation
|
|
34
|
+
*/
|
|
35
|
+
export async function createTinfoilAI(apiKey, options = {}) {
|
|
36
|
+
// Resolve API key: use provided value, or fall back to env var (non-browser only)
|
|
37
|
+
let resolvedApiKey = apiKey;
|
|
38
|
+
if (!resolvedApiKey && !isRealBrowser() && typeof process !== 'undefined' && process.env.TINFOIL_API_KEY) {
|
|
39
|
+
resolvedApiKey = process.env.TINFOIL_API_KEY;
|
|
40
|
+
}
|
|
41
|
+
if (!resolvedApiKey) {
|
|
42
|
+
throw new ConfigurationError("API key is required. Provide apiKey parameter or set TINFOIL_API_KEY environment variable.");
|
|
43
|
+
}
|
|
44
|
+
const secureClient = new SecureClient({
|
|
45
|
+
baseURL: options.baseURL,
|
|
46
|
+
configRepo: options.configRepo,
|
|
47
|
+
attestationBundleURL: options.attestationBundleURL,
|
|
15
48
|
});
|
|
16
49
|
await secureClient.ready();
|
|
17
|
-
|
|
18
|
-
const finalBaseURL = baseURL || secureClient.getBaseURL();
|
|
19
|
-
if (!finalBaseURL) {
|
|
20
|
-
throw new Error("Unable to determine baseURL for AI SDK provider");
|
|
21
|
-
}
|
|
22
|
-
return (0, openai_compatible_1.createOpenAICompatible)({
|
|
50
|
+
return createOpenAICompatible({
|
|
23
51
|
name: "tinfoil",
|
|
24
|
-
baseURL:
|
|
25
|
-
apiKey:
|
|
52
|
+
baseURL: secureClient.getBaseURL(),
|
|
53
|
+
apiKey: resolvedApiKey,
|
|
26
54
|
fetch: secureClient.fetch,
|
|
27
|
-
headers,
|
|
28
55
|
});
|
|
29
56
|
}
|
|
57
|
+
//# sourceMappingURL=ai-sdk-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-provider.js","sourceRoot":"","sources":["../src/ai-sdk-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAmBnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAe,EAAE,UAAkC,EAAE;IACzF,kFAAkF;IAClF,IAAI,cAAc,GAAG,MAAM,CAAC;IAC5B,IAAI,CAAC,cAAc,IAAI,CAAC,aAAa,EAAE,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QACzG,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC/C,CAAC;IACD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,kBAAkB,CAAC,4FAA4F,CAAC,CAAC;IAC7H,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;QACpC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;KACnD,CAAC,CAAC;IAEH,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAE3B,OAAO,sBAAsB,CAAC;QAC5B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,YAAY,CAAC,UAAU,EAAG;QACnC,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,YAAY,CAAC,KAAK;KAC1B,CAAC,CAAC;AACL,CAAC"}
|
package/dist/atc.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AttestationBundle } from "./verifier.js";
|
|
2
|
+
export interface FetchAttestationBundleOptions {
|
|
3
|
+
atcBaseUrl?: string;
|
|
4
|
+
enclaveURL?: string;
|
|
5
|
+
configRepo?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Fetches a complete attestation bundle from ATC.
|
|
9
|
+
*
|
|
10
|
+
* When enclaveURL or configRepo are provided, issues a POST so ATC builds a
|
|
11
|
+
* bundle for the specified enclave/repo. Otherwise issues a GET for the
|
|
12
|
+
* default router behaviour.
|
|
13
|
+
*/
|
|
14
|
+
export declare function fetchAttestationBundle(options?: FetchAttestationBundleOptions): Promise<AttestationBundle>;
|
|
15
|
+
/**
|
|
16
|
+
* Fetches the list of available routers and returns a randomly selected address.
|
|
17
|
+
*
|
|
18
|
+
* @param atcBaseUrl - Base URL for the attestation endpoint (defaults to TINFOIL_CONFIG.ATC_BASE_URL)
|
|
19
|
+
* @returns A randomly selected router address
|
|
20
|
+
* @throws Error if no routers are found or if the request fails
|
|
21
|
+
*/
|
|
22
|
+
export declare function fetchRouter(atcBaseUrl?: string): Promise<string>;
|
|
23
|
+
//# sourceMappingURL=atc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atc.d.ts","sourceRoot":"","sources":["../src/atc.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGvD,MAAM,WAAW,6BAA6B;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,GAAE,6BAAkC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkCpH;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,UAAU,GAAE,MAAoC,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBnG"}
|
package/dist/atc.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { TINFOIL_CONFIG } from "./config.js";
|
|
2
|
+
import { FetchError } from "./verifier.js";
|
|
3
|
+
/**
|
|
4
|
+
* Fetches a complete attestation bundle from ATC.
|
|
5
|
+
*
|
|
6
|
+
* When enclaveURL or configRepo are provided, issues a POST so ATC builds a
|
|
7
|
+
* bundle for the specified enclave/repo. Otherwise issues a GET for the
|
|
8
|
+
* default router behaviour.
|
|
9
|
+
*/
|
|
10
|
+
export async function fetchAttestationBundle(options = {}) {
|
|
11
|
+
const baseUrl = options.atcBaseUrl ?? TINFOIL_CONFIG.ATC_BASE_URL;
|
|
12
|
+
const url = `${baseUrl}/attestation`;
|
|
13
|
+
const usePost = !!(options.enclaveURL || options.configRepo);
|
|
14
|
+
const response = usePost
|
|
15
|
+
? await fetch(url, {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
headers: { 'Content-Type': 'application/json' },
|
|
18
|
+
body: JSON.stringify({
|
|
19
|
+
enclaveUrl: options.enclaveURL,
|
|
20
|
+
repo: options.configRepo,
|
|
21
|
+
}),
|
|
22
|
+
})
|
|
23
|
+
: await fetch(url);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new FetchError(`Failed to fetch attestation bundle from ${baseUrl}: HTTP ${response.status} ${response.statusText}`);
|
|
26
|
+
}
|
|
27
|
+
const bundle = await response.json();
|
|
28
|
+
return {
|
|
29
|
+
domain: bundle.domain,
|
|
30
|
+
enclaveAttestationReport: {
|
|
31
|
+
format: bundle.enclaveAttestationReport.format,
|
|
32
|
+
body: bundle.enclaveAttestationReport.body,
|
|
33
|
+
},
|
|
34
|
+
digest: bundle.digest,
|
|
35
|
+
sigstoreBundle: bundle.sigstoreBundle,
|
|
36
|
+
vcek: bundle.vcek,
|
|
37
|
+
enclaveCert: bundle.enclaveCert,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetches the list of available routers and returns a randomly selected address.
|
|
42
|
+
*
|
|
43
|
+
* @param atcBaseUrl - Base URL for the attestation endpoint (defaults to TINFOIL_CONFIG.ATC_BASE_URL)
|
|
44
|
+
* @returns A randomly selected router address
|
|
45
|
+
* @throws Error if no routers are found or if the request fails
|
|
46
|
+
*/
|
|
47
|
+
export async function fetchRouter(atcBaseUrl = TINFOIL_CONFIG.ATC_BASE_URL) {
|
|
48
|
+
const routersUrl = `${atcBaseUrl}/routers?platform=snp`;
|
|
49
|
+
const response = await fetch(routersUrl);
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
throw new FetchError(`Failed to fetch router list from ${atcBaseUrl}: HTTP ${response.status} ${response.statusText}`);
|
|
52
|
+
}
|
|
53
|
+
const routers = await response.json();
|
|
54
|
+
if (!Array.isArray(routers) || routers.length === 0) {
|
|
55
|
+
throw new FetchError("No available routers found in the response");
|
|
56
|
+
}
|
|
57
|
+
return routers[Math.floor(Math.random() * routers.length)];
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=atc.js.map
|
package/dist/atc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atc.js","sourceRoot":"","sources":["../src/atc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,UAAyC,EAAE;IACtF,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,IAAI,cAAc,CAAC,YAAY,CAAC;IAClE,MAAM,GAAG,GAAG,GAAG,OAAO,cAAc,CAAC;IAErC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAE7D,MAAM,QAAQ,GAAG,OAAO;QACtB,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,EAAE;YACf,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,IAAI,EAAE,OAAO,CAAC,UAAU;aACzB,CAAC;SACH,CAAC;QACJ,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAErB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAAC,2CAA2C,OAAO,UAAU,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7H,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAErC,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,wBAAwB,EAAE;YACxB,MAAM,EAAE,MAAM,CAAC,wBAAwB,CAAC,MAAM;YAC9C,IAAI,EAAE,MAAM,CAAC,wBAAwB,CAAC,IAAI;SAC3C;QACD,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,aAAqB,cAAc,CAAC,YAAY;IAChF,MAAM,UAAU,GAAG,GAAG,UAAU,uBAAuB,CAAC;IAExD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;IAEzC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAAC,oCAAoC,UAAU,UAAU,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACzH,CAAC;IAED,MAAM,OAAO,GAAa,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEhD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,UAAU,CAAC,4CAA4C,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7D,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare const TINFOIL_CONFIG: {
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Base URL for the attestation endpoint
|
|
7
7
|
*/
|
|
8
|
-
readonly
|
|
8
|
+
readonly ATC_BASE_URL: "https://atc.tinfoil.sh";
|
|
9
9
|
/**
|
|
10
|
-
* The
|
|
10
|
+
* The GitHub repository for the router code attestation
|
|
11
11
|
*/
|
|
12
|
-
readonly
|
|
12
|
+
readonly DEFAULT_ROUTER_REPO: "tinfoilsh/confidential-model-router";
|
|
13
13
|
};
|
|
14
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,cAAc;IACzB;;OAEG;;IAGH;;OAEG;;CAEK,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TINFOIL_CONFIG = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Configuration constants for the Tinfoil Node SDK
|
|
6
3
|
*/
|
|
7
|
-
|
|
4
|
+
export const TINFOIL_CONFIG = {
|
|
8
5
|
/**
|
|
9
|
-
*
|
|
6
|
+
* Base URL for the attestation endpoint
|
|
10
7
|
*/
|
|
11
|
-
|
|
8
|
+
ATC_BASE_URL: "https://atc.tinfoil.sh",
|
|
12
9
|
/**
|
|
13
|
-
* The
|
|
10
|
+
* The GitHub repository for the router code attestation
|
|
14
11
|
*/
|
|
15
|
-
|
|
12
|
+
DEFAULT_ROUTER_REPO: "tinfoilsh/confidential-model-router",
|
|
16
13
|
};
|
|
14
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B;;OAEG;IACH,YAAY,EAAE,wBAAwB;IAEtC;;OAEG;IACH,mBAAmB,EAAE,qCAAqC;CAClD,CAAC"}
|
|
@@ -1,13 +1,34 @@
|
|
|
1
|
-
import
|
|
2
|
-
export
|
|
1
|
+
import { Identity, Transport, type SessionRecoveryToken } from "ehbp";
|
|
2
|
+
export type { SessionRecoveryToken } from "ehbp";
|
|
3
|
+
export { decryptResponseWithToken } from "ehbp";
|
|
4
|
+
export interface SecureTransport {
|
|
5
|
+
fetch: typeof fetch;
|
|
6
|
+
getSessionRecoveryToken(): Promise<SessionRecoveryToken>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Fetch and parse server identity from the HPKE keys endpoint.
|
|
10
|
+
* Returns the server Identity which can be used to create a Transport.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getServerIdentity(enclaveURL: string): Promise<Identity>;
|
|
3
13
|
export declare function normalizeEncryptedBodyRequestArgs(input: RequestInfo | URL, init?: RequestInit): {
|
|
4
14
|
url: string;
|
|
5
15
|
init?: RequestInit;
|
|
6
16
|
};
|
|
7
|
-
export declare function encryptedBodyRequest(input: RequestInfo | URL, hpkePublicKey
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
export declare function encryptedBodyRequest(input: RequestInfo | URL, hpkePublicKey: string, init?: RequestInit, transportInstance?: Transport): Promise<Response>;
|
|
18
|
+
export declare function createEncryptedBodyFetch(baseURL: string, hpkePublicKey: string, enclaveURL?: string): SecureTransport;
|
|
19
|
+
/**
|
|
20
|
+
* WARNING: THIS FUNCTION IS INSECURE.
|
|
21
|
+
*
|
|
22
|
+
* Creates an encrypted body fetch that fetches the HPKE key from the server without
|
|
23
|
+
* attestation verification. This is vulnerable to man-in-the-middle attacks where
|
|
24
|
+
* a malicious server could provide its own key.
|
|
25
|
+
*
|
|
26
|
+
* This function is useful for testing the EHBP protocol against a local development
|
|
27
|
+
* server that doesn't have attestation set up. For production, use createEncryptedBodyFetch
|
|
28
|
+
* with a key obtained through attestation verification.
|
|
29
|
+
*
|
|
30
|
+
* @param baseURL - Base URL for API requests
|
|
31
|
+
* @param keyOrigin - Origin URL for fetching the HPKE public key. If not provided, derived from baseURL.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createUnverifiedEncryptedBodyFetch(baseURL: string, keyOrigin?: string): SecureTransport;
|
|
34
|
+
//# sourceMappingURL=encrypted-body-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encrypted-body-fetch.d.ts","sourceRoot":"","sources":["../src/encrypted-body-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAY,KAAK,oBAAoB,EAAE,MAAM,MAAM,CAAC;AAGhF,YAAY,EAAE,oBAAoB,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,MAAM,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,uBAAuB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC1D;AAUD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoB7E;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,GACjB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAAE,CAuBrC;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,WAAW,EAClB,iBAAiB,CAAC,EAAE,SAAS,GAC5B,OAAO,CAAC,QAAQ,CAAC,CAgBnB;AAID,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,eAAe,CAoCrH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,eAAe,CA2CvG"}
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import { Identity, Transport, PROTOCOL } from "ehbp";
|
|
2
|
+
import { ConfigurationError, FetchError } from "./verifier.js";
|
|
3
|
+
export { decryptResponseWithToken } from "ehbp";
|
|
4
|
+
/**
|
|
5
|
+
* Create an Identity from a raw public key hex string.
|
|
6
|
+
* This avoids fetching from the server when the key is already known.
|
|
7
|
+
*/
|
|
8
|
+
async function createIdentityFromPublicKeyHex(publicKeyHex) {
|
|
9
|
+
return Identity.fromPublicKeyHex(publicKeyHex);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Fetch and parse server identity from the HPKE keys endpoint.
|
|
13
|
+
* Returns the server Identity which can be used to create a Transport.
|
|
14
|
+
*/
|
|
15
|
+
export async function getServerIdentity(enclaveURL) {
|
|
16
|
+
const keysURL = new URL(PROTOCOL.KEYS_PATH, enclaveURL);
|
|
17
|
+
if (keysURL.protocol !== 'https:') {
|
|
18
|
+
throw new ConfigurationError(`HTTPS is required for key retrieval. Got ${keysURL.protocol}`);
|
|
16
19
|
}
|
|
17
|
-
const
|
|
18
|
-
const response = await fetchFn(keysURL.toString());
|
|
20
|
+
const response = await fetch(keysURL.toString());
|
|
19
21
|
if (!response.ok) {
|
|
20
|
-
throw new
|
|
22
|
+
throw new FetchError(`Failed to fetch HPKE public key from enclave: HTTP ${response.status}`);
|
|
21
23
|
}
|
|
22
|
-
const contentType = response.headers.get(
|
|
23
|
-
if (contentType !==
|
|
24
|
-
throw new
|
|
24
|
+
const contentType = response.headers.get('content-type');
|
|
25
|
+
if (contentType !== PROTOCOL.KEYS_MEDIA_TYPE) {
|
|
26
|
+
throw new FetchError(`Invalid response from HPKE key endpoint: Expected content-type "${PROTOCOL.KEYS_MEDIA_TYPE}", got "${contentType}"`);
|
|
25
27
|
}
|
|
26
28
|
const keysData = new Uint8Array(await response.arrayBuffer());
|
|
27
|
-
|
|
28
|
-
return serverIdentity.getPublicKey();
|
|
29
|
+
return await Identity.unmarshalPublicConfig(keysData);
|
|
29
30
|
}
|
|
30
|
-
function normalizeEncryptedBodyRequestArgs(input, init) {
|
|
31
|
+
export function normalizeEncryptedBodyRequestArgs(input, init) {
|
|
31
32
|
if (typeof input === "string") {
|
|
32
33
|
return { url: input, init };
|
|
33
34
|
}
|
|
@@ -47,66 +48,107 @@ function normalizeEncryptedBodyRequestArgs(input, init) {
|
|
|
47
48
|
init: { ...derivedInit, ...init },
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
|
-
async function encryptedBodyRequest(input, hpkePublicKey, init,
|
|
51
|
+
export async function encryptedBodyRequest(input, hpkePublicKey, init, transportInstance) {
|
|
51
52
|
const { url: requestUrl, init: requestInit } = normalizeEncryptedBodyRequestArgs(input, init);
|
|
52
53
|
let actualTransport;
|
|
53
54
|
if (transportInstance) {
|
|
54
|
-
// Use provided transport instance
|
|
55
55
|
actualTransport = transportInstance;
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
|
-
// Create a new transport for this request
|
|
59
58
|
const u = new URL(requestUrl);
|
|
60
|
-
|
|
61
|
-
const keyOrigin = enclaveURL ? new URL(enclaveURL).origin : origin;
|
|
62
|
-
actualTransport = await getTransportForOrigin(origin, keyOrigin);
|
|
63
|
-
}
|
|
64
|
-
if (hpkePublicKey) {
|
|
65
|
-
const transportKeyHash = await actualTransport.getServerPublicKeyHex();
|
|
66
|
-
if (transportKeyHash !== hpkePublicKey) {
|
|
67
|
-
throw new Error(`HPKE public key mismatch. Expected: ${hpkePublicKey}, Got: ${transportKeyHash}`);
|
|
68
|
-
}
|
|
59
|
+
actualTransport = await getTransportForOrigin(u.origin, hpkePublicKey);
|
|
69
60
|
}
|
|
70
61
|
return actualTransport.request(requestUrl, requestInit);
|
|
71
62
|
}
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
const ENCLAVE_URL_HEADER = 'X-Tinfoil-Enclave-Url';
|
|
64
|
+
export function createEncryptedBodyFetch(baseURL, hpkePublicKey, enclaveURL) {
|
|
65
|
+
const baseOrigin = new URL(baseURL).origin;
|
|
66
|
+
const needsEnclaveHeader = !!enclaveURL && new URL(enclaveURL).origin !== baseOrigin;
|
|
74
67
|
let transportPromise = null;
|
|
75
|
-
const getOrCreateTransport =
|
|
68
|
+
const getOrCreateTransport = () => {
|
|
76
69
|
if (!transportPromise) {
|
|
77
|
-
|
|
78
|
-
const keyOrigin = enclaveURL
|
|
79
|
-
? new URL(enclaveURL).origin
|
|
80
|
-
: baseUrl.origin;
|
|
81
|
-
transportPromise = getTransportForOrigin(baseUrl.origin, keyOrigin);
|
|
70
|
+
transportPromise = getTransportForOrigin(baseOrigin, hpkePublicKey);
|
|
82
71
|
}
|
|
83
72
|
return transportPromise;
|
|
84
73
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
74
|
+
return {
|
|
75
|
+
fetch: async (input, init) => {
|
|
76
|
+
const normalized = normalizeEncryptedBodyRequestArgs(input, init);
|
|
77
|
+
const targetUrl = new URL(normalized.url, baseURL);
|
|
78
|
+
const headers = new Headers(normalized.init?.headers);
|
|
79
|
+
if (needsEnclaveHeader) {
|
|
80
|
+
headers.set(ENCLAVE_URL_HEADER, enclaveURL);
|
|
81
|
+
}
|
|
82
|
+
const initWithHeader = { ...normalized.init, headers };
|
|
83
|
+
const transportInstance = await getOrCreateTransport();
|
|
84
|
+
return encryptedBodyRequest(targetUrl.toString(), hpkePublicKey, initWithHeader, transportInstance);
|
|
85
|
+
},
|
|
86
|
+
async getSessionRecoveryToken() {
|
|
87
|
+
if (!transportPromise) {
|
|
88
|
+
throw new Error('No session recovery token available — no request has been made yet');
|
|
89
|
+
}
|
|
90
|
+
const transport = await transportPromise;
|
|
91
|
+
return transport.getSessionRecoveryToken();
|
|
92
|
+
},
|
|
93
|
+
};
|
|
96
94
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
95
|
+
/**
|
|
96
|
+
* WARNING: THIS FUNCTION IS INSECURE.
|
|
97
|
+
*
|
|
98
|
+
* Creates an encrypted body fetch that fetches the HPKE key from the server without
|
|
99
|
+
* attestation verification. This is vulnerable to man-in-the-middle attacks where
|
|
100
|
+
* a malicious server could provide its own key.
|
|
101
|
+
*
|
|
102
|
+
* This function is useful for testing the EHBP protocol against a local development
|
|
103
|
+
* server that doesn't have attestation set up. For production, use createEncryptedBodyFetch
|
|
104
|
+
* with a key obtained through attestation verification.
|
|
105
|
+
*
|
|
106
|
+
* @param baseURL - Base URL for API requests
|
|
107
|
+
* @param keyOrigin - Origin URL for fetching the HPKE public key. If not provided, derived from baseURL.
|
|
108
|
+
*/
|
|
109
|
+
export function createUnverifiedEncryptedBodyFetch(baseURL, keyOrigin) {
|
|
110
|
+
console.warn("[tinfoil] WARNING: createUnverifiedEncryptedBodyFetch is insecure. " +
|
|
111
|
+
"The HPKE key is fetched from the server without attestation verification. " +
|
|
112
|
+
"Only use for local development and testing of the EHBP protocol.");
|
|
113
|
+
const baseOrigin = new URL(baseURL).origin;
|
|
114
|
+
const resolvedKeyOrigin = keyOrigin ? new URL(keyOrigin).origin : baseOrigin;
|
|
115
|
+
const needsEnclaveHeader = !!keyOrigin && resolvedKeyOrigin !== baseOrigin;
|
|
116
|
+
let transportPromise = null;
|
|
117
|
+
const getOrCreateTransport = async () => {
|
|
118
|
+
if (!transportPromise) {
|
|
119
|
+
transportPromise = getUnverifiedTransportForOrigin(baseOrigin, resolvedKeyOrigin);
|
|
106
120
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
121
|
+
return transportPromise;
|
|
122
|
+
};
|
|
123
|
+
return {
|
|
124
|
+
fetch: async (input, init) => {
|
|
125
|
+
const normalized = normalizeEncryptedBodyRequestArgs(input, init);
|
|
126
|
+
const targetUrl = new URL(normalized.url, baseURL);
|
|
127
|
+
const headers = new Headers(normalized.init?.headers);
|
|
128
|
+
if (needsEnclaveHeader) {
|
|
129
|
+
headers.set(ENCLAVE_URL_HEADER, keyOrigin);
|
|
130
|
+
}
|
|
131
|
+
const initWithEnclaveHeader = { ...normalized.init, headers };
|
|
132
|
+
const transportInstance = await getOrCreateTransport();
|
|
133
|
+
return transportInstance.request(targetUrl.toString(), initWithEnclaveHeader);
|
|
134
|
+
},
|
|
135
|
+
async getSessionRecoveryToken() {
|
|
136
|
+
if (!transportPromise) {
|
|
137
|
+
throw new Error('No session recovery token available — no request has been made yet');
|
|
138
|
+
}
|
|
139
|
+
const transport = await transportPromise;
|
|
140
|
+
return transport.getSessionRecoveryToken();
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
async function getUnverifiedTransportForOrigin(origin, keyOrigin) {
|
|
145
|
+
const serverIdentity = await getServerIdentity(keyOrigin);
|
|
146
|
+
const requestHost = new URL(origin).host;
|
|
147
|
+
return new Transport(serverIdentity, requestHost);
|
|
148
|
+
}
|
|
149
|
+
async function getTransportForOrigin(origin, hpkePublicKeyHex) {
|
|
150
|
+
const serverIdentity = await createIdentityFromPublicKeyHex(hpkePublicKeyHex);
|
|
110
151
|
const requestHost = new URL(origin).host;
|
|
111
|
-
return new
|
|
152
|
+
return new Transport(serverIdentity, requestHost);
|
|
112
153
|
}
|
|
154
|
+
//# sourceMappingURL=encrypted-body-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encrypted-body-fetch.js","sourceRoot":"","sources":["../src/encrypted-body-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAA6B,MAAM,MAAM,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,MAAM,CAAC;AAOhD;;;GAGG;AACH,KAAK,UAAU,8BAA8B,CAAC,YAAoB;IAChE,OAAO,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAkB;IACxD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAExD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,IAAI,kBAAkB,CAAC,4CAA4C,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEjD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAAC,sDAAsD,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACzD,IAAI,WAAW,KAAK,QAAQ,CAAC,eAAe,EAAE,CAAC;QAC7C,MAAM,IAAI,UAAU,CAAC,mEAAmE,QAAQ,CAAC,eAAe,WAAW,WAAW,GAAG,CAAC,CAAC;IAC7I,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9D,OAAO,MAAM,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC/C,KAAwB,EACxB,IAAkB;IAElB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK,YAAY,GAAG,EAAE,CAAC;QACzB,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,OAAO,GAAG,KAAgB,CAAC;IACjC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAE/B,MAAM,WAAW,GAAgB;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;QACpC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,SAAS;QAC9B,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;IAEF,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,IAAI,EAAE,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,EAAE;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAwB,EACxB,aAAqB,EACrB,IAAkB,EAClB,iBAA6B;IAE7B,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,iCAAiC,CAC9E,KAAK,EACL,IAAI,CACL,CAAC;IAEF,IAAI,eAA0B,CAAC;IAE/B,IAAI,iBAAiB,EAAE,CAAC;QACtB,eAAe,GAAG,iBAAiB,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9B,eAAe,GAAG,MAAM,qBAAqB,CAAC,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,eAAe,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AAEnD,MAAM,UAAU,wBAAwB,CAAC,OAAe,EAAE,aAAqB,EAAE,UAAmB;IAClG,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC3C,MAAM,kBAAkB,GAAG,CAAC,CAAC,UAAU,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC;IAErF,IAAI,gBAAgB,GAA8B,IAAI,CAAC;IAEvD,MAAM,oBAAoB,GAAG,GAAuB,EAAE;QACpD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,gBAAgB,GAAG,qBAAqB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,KAAwB,EAAE,IAAkB,EAAE,EAAE;YAC5D,MAAM,UAAU,GAAG,iCAAiC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAClE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACtD,IAAI,kBAAkB,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,UAAW,CAAC,CAAC;YAC/C,CAAC;YACD,MAAM,cAAc,GAAG,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;YAEvD,MAAM,iBAAiB,GAAG,MAAM,oBAAoB,EAAE,CAAC;YACvD,OAAO,oBAAoB,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC;QACtG,CAAC;QAED,KAAK,CAAC,uBAAuB;YAC3B,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;YACxF,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC;YACzC,OAAO,SAAS,CAAC,uBAAuB,EAAE,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kCAAkC,CAAC,OAAe,EAAE,SAAkB;IACpF,OAAO,CAAC,IAAI,CACV,qEAAqE;QACrE,4EAA4E;QAC5E,kEAAkE,CACnE,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC3C,MAAM,iBAAiB,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7E,MAAM,kBAAkB,GAAG,CAAC,CAAC,SAAS,IAAI,iBAAiB,KAAK,UAAU,CAAC;IAE3E,IAAI,gBAAgB,GAA8B,IAAI,CAAC;IAEvD,MAAM,oBAAoB,GAAG,KAAK,IAAwB,EAAE;QAC1D,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,gBAAgB,GAAG,+BAA+B,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;QACpF,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,KAAwB,EAAE,IAAkB,EAAE,EAAE;YAC5D,MAAM,UAAU,GAAG,iCAAiC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAClE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAEnD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACtD,IAAI,kBAAkB,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,SAAU,CAAC,CAAC;YAC9C,CAAC;YACD,MAAM,qBAAqB,GAAG,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;YAE9D,MAAM,iBAAiB,GAAG,MAAM,oBAAoB,EAAE,CAAC;YACvD,OAAO,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,qBAAqB,CAAC,CAAC;QAChF,CAAC;QAED,KAAK,CAAC,uBAAuB;YAC3B,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;YACxF,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC;YACzC,OAAO,SAAS,CAAC,uBAAuB,EAAE,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,+BAA+B,CAAC,MAAc,EAAE,SAAiB;IAC9E,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC1D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;IACzC,OAAO,IAAI,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,MAAc,EAAE,gBAAwB;IAC3E,MAAM,cAAc,GAAG,MAAM,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;IAC9E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;IACzC,OAAO,IAAI,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AACpD,CAAC"}
|
package/dist/env.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
export declare function isBun(): boolean;
|
|
1
2
|
/**
|
|
2
3
|
* Detects if the code is running in a real browser environment.
|
|
3
|
-
* Returns false for Node.js
|
|
4
|
+
* Returns false for server-side runtimes (Node.js, Bun, Deno, edge runtimes).
|
|
5
|
+
* Only returns true when we can positively identify a browser environment.
|
|
4
6
|
*/
|
|
5
7
|
export declare function isRealBrowser(): boolean;
|
|
8
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,IAAI,OAAO,CAI/B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAuCvC"}
|
package/dist/env.js
CHANGED
|
@@ -1,20 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export function isBun() {
|
|
2
|
+
return typeof process !== "undefined" &&
|
|
3
|
+
!!process.versions &&
|
|
4
|
+
!!process.versions.bun;
|
|
5
|
+
}
|
|
4
6
|
/**
|
|
5
7
|
* Detects if the code is running in a real browser environment.
|
|
6
|
-
* Returns false for Node.js
|
|
8
|
+
* Returns false for server-side runtimes (Node.js, Bun, Deno, edge runtimes).
|
|
9
|
+
* Only returns true when we can positively identify a browser environment.
|
|
7
10
|
*/
|
|
8
|
-
function isRealBrowser() {
|
|
11
|
+
export function isRealBrowser() {
|
|
12
|
+
// Check for Node.js
|
|
9
13
|
if (typeof process !== "undefined" &&
|
|
10
14
|
process.versions &&
|
|
11
15
|
process.versions.node) {
|
|
12
16
|
return false;
|
|
13
17
|
}
|
|
18
|
+
// Check for Bun
|
|
19
|
+
if (isBun()) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
// Check for Deno
|
|
23
|
+
if (typeof globalThis.Deno !== "undefined") {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
// Check for Cloudflare Workers (has 'Cloudflare-Workers' userAgent when global_navigator flag is set)
|
|
27
|
+
if (typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers") {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
// Check for Cloudflare Workers via caches.default (alternative detection)
|
|
31
|
+
if (typeof caches !== "undefined" && caches.default !== undefined) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
// Check for real browser: must have window, document, and a real userAgent
|
|
14
35
|
if (typeof window !== "undefined" && typeof window.document !== "undefined") {
|
|
15
36
|
if (typeof navigator !== "undefined" && navigator.userAgent) {
|
|
16
37
|
return true;
|
|
17
38
|
}
|
|
18
39
|
}
|
|
40
|
+
// Unknown runtime - treat as server-side (safer default)
|
|
19
41
|
return false;
|
|
20
42
|
}
|
|
43
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,KAAK;IACnB,OAAO,OAAO,OAAO,KAAK,WAAW;QACnC,CAAC,CAAE,OAAe,CAAC,QAAQ;QAC3B,CAAC,CAAE,OAAe,CAAC,QAAQ,CAAC,GAAG,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,oBAAoB;IACpB,IACE,OAAO,OAAO,KAAK,WAAW;QAC7B,OAAe,CAAC,QAAQ;QACxB,OAAe,CAAC,QAAQ,CAAC,IAAI,EAC9B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gBAAgB;IAChB,IAAI,KAAK,EAAE,EAAE,CAAC;QACZ,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iBAAiB;IACjB,IAAI,OAAQ,UAAkB,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,sGAAsG;IACtG,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,SAAS,KAAK,oBAAoB,EAAE,CAAC;QACrF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0EAA0E;IAC1E,IAAI,OAAO,MAAM,KAAK,WAAW,IAAK,MAAc,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2EAA2E;IAC3E,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC5E,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,OAAO,KAAK,CAAC;AACf,CAAC"}
|