@authhero/cloudflare-adapter 2.30.1 → 2.31.1
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/cloudflare-adapter.cjs +113 -50
- package/dist/cloudflare-adapter.d.ts +274 -1357
- package/dist/cloudflare-adapter.mjs +4311 -3430
- package/dist/tsconfig.types.tsbuildinfo +1 -0
- package/dist/types/analytics-engine-action-executions/actionExecutions.d.ts +8 -0
- package/dist/types/analytics-engine-action-executions/index.d.ts +29 -0
- package/dist/types/analytics-engine-action-executions/types.d.ts +29 -0
- package/dist/types/analytics-engine-logs/analytics.d.ts +3 -0
- package/dist/types/analytics-engine-logs/index.d.ts +53 -0
- package/dist/types/analytics-engine-logs/list.d.ts +10 -0
- package/dist/types/analytics-engine-logs/logs.d.ts +43 -0
- package/dist/types/analytics-engine-logs/query.d.ts +23 -0
- package/dist/types/analytics-engine-logs/stats.d.ts +6 -0
- package/dist/types/analytics-engine-logs/types.d.ts +39 -0
- package/dist/types/cache/index.d.ts +44 -0
- package/dist/types/code-executor/index.d.ts +106 -0
- package/dist/types/code-executor/worker-loader.d.ts +57 -0
- package/dist/types/code-executor/worker-template.d.ts +10 -0
- package/dist/types/customDomains/index.d.ts +3 -0
- package/dist/types/geo/index.d.ts +37 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/r2-sql-logs/index.d.ts +60 -0
- package/dist/types/r2-sql-logs/list.d.ts +11 -0
- package/dist/types/r2-sql-logs/logs.d.ts +8 -0
- package/dist/types/r2-sql-logs/query.d.ts +13 -0
- package/dist/types/r2-sql-logs/stats.d.ts +8 -0
- package/dist/types/r2-sql-logs/types.d.ts +45 -0
- package/dist/types/rate-limit/index.d.ts +30 -0
- package/dist/types/types/CloudflareConfig.d.ts +47 -0
- package/dist/types/types/CustomDomain.d.ts +185 -0
- package/package.json +7 -7
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { CodeExecutionResult, CodeExecutor } from "@authhero/adapter-interfaces";
|
|
2
|
+
/**
|
|
3
|
+
* Cloudflare Workers for Platforms dispatch namespace binding type.
|
|
4
|
+
* This is the type of `env.DISPATCHER` when configured in wrangler.toml:
|
|
5
|
+
*
|
|
6
|
+
* ```toml
|
|
7
|
+
* [[dispatch_namespaces]]
|
|
8
|
+
* binding = "DISPATCHER"
|
|
9
|
+
* namespace = "authhero-hooks"
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export interface DispatchNamespace {
|
|
13
|
+
get(name: string, options?: Record<string, unknown>, init?: {
|
|
14
|
+
limits?: {
|
|
15
|
+
cpuMs?: number;
|
|
16
|
+
subrequests?: number;
|
|
17
|
+
};
|
|
18
|
+
}): {
|
|
19
|
+
fetch(request: Request | string, init?: RequestInit): Promise<Response>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface DispatchNamespaceCodeExecutorConfig {
|
|
23
|
+
/** Cloudflare account ID */
|
|
24
|
+
accountId: string;
|
|
25
|
+
/** API token with Workers Scripts write permission */
|
|
26
|
+
apiToken: string;
|
|
27
|
+
/** Dispatch namespace name (e.g., "authhero-hooks") */
|
|
28
|
+
dispatchNamespace: string;
|
|
29
|
+
/**
|
|
30
|
+
* Dispatch namespace binding from the worker environment.
|
|
31
|
+
* When running inside a Cloudflare Worker, pass `env.DISPATCHER`.
|
|
32
|
+
* Enables low-latency same-origin invocation.
|
|
33
|
+
*/
|
|
34
|
+
dispatcher?: DispatchNamespace;
|
|
35
|
+
/**
|
|
36
|
+
* Fallback URL for invoking user workers when no dispatcher binding is available.
|
|
37
|
+
* The executor appends `/{scriptName}` to this URL.
|
|
38
|
+
* Only used when `dispatcher` is not provided.
|
|
39
|
+
*/
|
|
40
|
+
dispatchUrl?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Cloudflare Workers compatibility date used when deploying scripts.
|
|
43
|
+
* Defaults to "2024-11-20" if not provided.
|
|
44
|
+
*/
|
|
45
|
+
compatibilityDate?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Code executor that uses Cloudflare Workers for Platforms dispatch namespaces.
|
|
49
|
+
*
|
|
50
|
+
* User code is deployed as individual worker scripts in a dispatch namespace
|
|
51
|
+
* (via the `deploy()` method, which calls the Cloudflare API). At execution
|
|
52
|
+
* time, the pre-deployed worker is invoked via the dispatch namespace binding
|
|
53
|
+
* (in-worker) or via HTTP (external fallback).
|
|
54
|
+
*
|
|
55
|
+
* Contrast with `WorkerLoaderCodeExecutor`, which creates isolates on the fly
|
|
56
|
+
* from in-memory code via the Worker Loader binding and does not require
|
|
57
|
+
* pre-deployment.
|
|
58
|
+
*
|
|
59
|
+
* Usage:
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const codeExecutor = new DispatchNamespaceCodeExecutor({
|
|
62
|
+
* accountId: env.CF_ACCOUNT_ID,
|
|
63
|
+
* apiToken: env.CF_API_TOKEN,
|
|
64
|
+
* dispatchNamespace: "authhero-hooks",
|
|
65
|
+
* dispatcher: env.DISPATCHER,
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* const { app } = init({ dataAdapter, codeExecutor });
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare class DispatchNamespaceCodeExecutor implements CodeExecutor {
|
|
72
|
+
private config;
|
|
73
|
+
constructor(config: DispatchNamespaceCodeExecutorConfig);
|
|
74
|
+
execute(params: {
|
|
75
|
+
code: string;
|
|
76
|
+
hookCodeId?: string;
|
|
77
|
+
triggerId: string;
|
|
78
|
+
event: Record<string, unknown>;
|
|
79
|
+
/** Wall-clock timeout (ms). Used for HTTP-based fallback invocation. */
|
|
80
|
+
timeoutMs?: number;
|
|
81
|
+
/**
|
|
82
|
+
* CPU-time limit (ms) passed to the Cloudflare dispatcher binding.
|
|
83
|
+
* Unlike timeoutMs (wall-clock), this caps only actual CPU cycles;
|
|
84
|
+
* I/O wait does not count against it. Defaults to 5 000 ms.
|
|
85
|
+
*/
|
|
86
|
+
cpuLimitMs?: number;
|
|
87
|
+
}): Promise<CodeExecutionResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Deploy user code as a worker to the dispatch namespace.
|
|
90
|
+
* Wraps the code in a worker template and uploads via Cloudflare API.
|
|
91
|
+
*/
|
|
92
|
+
deploy(hookCodeId: string, code: string): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Remove a user worker from the dispatch namespace.
|
|
95
|
+
*/
|
|
96
|
+
remove(hookCodeId: string): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* @deprecated Renamed to `DispatchNamespaceCodeExecutor` to disambiguate from
|
|
100
|
+
* `WorkerLoaderCodeExecutor` (also Cloudflare-based, but using the Worker
|
|
101
|
+
* Loader binding instead of Workers for Platforms). This alias will be removed
|
|
102
|
+
* in the next major.
|
|
103
|
+
*/
|
|
104
|
+
export declare const CloudflareCodeExecutor: typeof DispatchNamespaceCodeExecutor;
|
|
105
|
+
/** @deprecated Use `DispatchNamespaceCodeExecutorConfig`. */
|
|
106
|
+
export type CloudflareCodeExecutorConfig = DispatchNamespaceCodeExecutorConfig;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { CodeExecutionResult, CodeExecutor } from "@authhero/adapter-interfaces";
|
|
2
|
+
/**
|
|
3
|
+
* Worker Loader binding type (Cloudflare Dynamic Workers).
|
|
4
|
+
* Configure in wrangler.toml:
|
|
5
|
+
* [[worker_loaders]]
|
|
6
|
+
* binding = "LOADER"
|
|
7
|
+
*/
|
|
8
|
+
interface WorkerLoader {
|
|
9
|
+
load(code: WorkerCode): WorkerStub;
|
|
10
|
+
get(id: string, callback: () => Promise<WorkerCode>): WorkerStub;
|
|
11
|
+
}
|
|
12
|
+
interface WorkerCode {
|
|
13
|
+
compatibilityDate: string;
|
|
14
|
+
mainModule: string;
|
|
15
|
+
modules: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
interface WorkerStub {
|
|
18
|
+
getEntrypoint(): {
|
|
19
|
+
fetch(request: Request): Promise<Response>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
interface WorkerLoaderCodeExecutorOptions {
|
|
23
|
+
loader: WorkerLoader;
|
|
24
|
+
compatibilityDate?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Cloudflare Dynamic Workers code executor (Worker Loader binding).
|
|
28
|
+
* Spins up isolated Workers on demand from in-memory code to execute
|
|
29
|
+
* user-authored hook code in a sandboxed v8 isolate.
|
|
30
|
+
*
|
|
31
|
+
* Uses `env.LOADER.get(id, callback)` to cache workers by hookCodeId + code hash,
|
|
32
|
+
* so the same code stays warm across requests while code updates get a fresh worker.
|
|
33
|
+
*
|
|
34
|
+
* User code can make outbound `fetch()` calls. The Worker Loader still provides
|
|
35
|
+
* process isolation (separate v8 isolate, no access to the parent worker's
|
|
36
|
+
* bindings or env), so this only widens the network boundary, not the host
|
|
37
|
+
* boundary. Plan: a future AI/static-analysis layer inspects action code on
|
|
38
|
+
* upload to flag exfiltration patterns before they reach the executor.
|
|
39
|
+
*
|
|
40
|
+
* Contrast with `DispatchNamespaceCodeExecutor`, which uses Workers for
|
|
41
|
+
* Platforms dispatch namespaces and requires user code to be pre-deployed
|
|
42
|
+
* as individual worker scripts via the Cloudflare API.
|
|
43
|
+
*/
|
|
44
|
+
export declare class WorkerLoaderCodeExecutor implements CodeExecutor {
|
|
45
|
+
private loader;
|
|
46
|
+
private compatibilityDate;
|
|
47
|
+
constructor(options: WorkerLoaderCodeExecutorOptions);
|
|
48
|
+
execute(params: {
|
|
49
|
+
code: string;
|
|
50
|
+
hookCodeId?: string;
|
|
51
|
+
triggerId: string;
|
|
52
|
+
event: Record<string, unknown>;
|
|
53
|
+
timeoutMs?: number;
|
|
54
|
+
cpuLimitMs?: number;
|
|
55
|
+
}): Promise<CodeExecutionResult>;
|
|
56
|
+
}
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a Cloudflare Worker script that wraps user-authored code.
|
|
3
|
+
*
|
|
4
|
+
* The generated worker:
|
|
5
|
+
* 1. Accepts POST requests with { triggerId, event }
|
|
6
|
+
* 2. Creates a recording API proxy that captures method calls
|
|
7
|
+
* 3. Runs the user's exported function (e.g., exports.onExecutePostLogin)
|
|
8
|
+
* 4. Returns { success, apiCalls, error, durationMs } as JSON
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateWorkerScript(userCode: string): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { GeoAdapter } from "@authhero/adapter-interfaces";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a Cloudflare geo adapter that extracts location information from
|
|
4
|
+
* Cloudflare's HTTP headers.
|
|
5
|
+
*
|
|
6
|
+
* ## Header Availability
|
|
7
|
+
*
|
|
8
|
+
* **Always available** (when IP Geolocation is enabled in Cloudflare dashboard):
|
|
9
|
+
* - `cf-ipcountry`: 2-letter ISO country code
|
|
10
|
+
*
|
|
11
|
+
* **Available with "Add visitor location headers" Managed Transform**:
|
|
12
|
+
* (Free feature in Cloudflare Rules > Transform Rules > Managed Transforms)
|
|
13
|
+
* - `cf-ipcity`: City name
|
|
14
|
+
* - `cf-ipcontinent`: 2-letter continent code
|
|
15
|
+
* - `cf-iplatitude`: Latitude coordinate
|
|
16
|
+
* - `cf-iplongitude`: Longitude coordinate
|
|
17
|
+
* - `cf-timezone`: IANA timezone identifier
|
|
18
|
+
* - `cf-region`: Region name
|
|
19
|
+
* - `cf-region-code`: Region code
|
|
20
|
+
* - `cf-metro-code`: Metro code
|
|
21
|
+
* - `cf-postal-code`: Postal code
|
|
22
|
+
*
|
|
23
|
+
* The adapter gracefully handles both scenarios - returning only country_code
|
|
24
|
+
* when the Managed Transform is not enabled, or full location data when it is.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* import { createCloudflareGeoAdapter } from "@authhero/cloudflare-adapter";
|
|
29
|
+
*
|
|
30
|
+
* const geoAdapter = createCloudflareGeoAdapter();
|
|
31
|
+
*
|
|
32
|
+
* // In your request handler, pass the headers
|
|
33
|
+
* const headers = Object.fromEntries(request.headers);
|
|
34
|
+
* const geoInfo = await geoAdapter.getGeoInfo(headers);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function createCloudflareGeoAdapter(): GeoAdapter;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { CustomDomainsAdapter, CacheAdapter, LogsDataAdapter, GeoAdapter, RateLimitAdapter, AnalyticsAdapter, ActionExecutionsAdapter } from "@authhero/adapter-interfaces";
|
|
2
|
+
import { type R2SQLLogsAdapterConfig } from "./r2-sql-logs";
|
|
3
|
+
import { type AnalyticsEngineLogsAdapterConfig, type AnalyticsEngineDataset } from "./analytics-engine-logs";
|
|
4
|
+
import { type AnalyticsEngineActionExecutionsAdapterConfig } from "./analytics-engine-action-executions";
|
|
5
|
+
import { type CloudflareRateLimitBinding, type CloudflareRateLimitBindings } from "./rate-limit";
|
|
6
|
+
import { CloudflareConfig } from "./types/CloudflareConfig";
|
|
7
|
+
export type { R2SQLLogsAdapterConfig };
|
|
8
|
+
export type { AnalyticsEngineLogsAdapterConfig, AnalyticsEngineDataset };
|
|
9
|
+
export type { AnalyticsEngineActionExecutionsAdapterConfig };
|
|
10
|
+
export type { CloudflareRateLimitBinding, CloudflareRateLimitBindings };
|
|
11
|
+
export { createCloudflareRateLimitAdapter } from "./rate-limit";
|
|
12
|
+
export type { CloudflareConfig };
|
|
13
|
+
export { DispatchNamespaceCodeExecutor, type DispatchNamespaceCodeExecutorConfig, type DispatchNamespace, CloudflareCodeExecutor, type CloudflareCodeExecutorConfig, } from "./code-executor";
|
|
14
|
+
export { generateWorkerScript } from "./code-executor/worker-template";
|
|
15
|
+
export { WorkerLoaderCodeExecutor } from "./code-executor/worker-loader";
|
|
16
|
+
export { createAnalyticsEngineLogsAdapter } from "./analytics-engine-logs";
|
|
17
|
+
export { createAnalyticsEngineStatsAdapter } from "./analytics-engine-logs";
|
|
18
|
+
export { createAnalyticsEngineAnalyticsAdapter } from "./analytics-engine-logs";
|
|
19
|
+
export { createAnalyticsEngineActionExecutionsAdapter } from "./analytics-engine-action-executions";
|
|
20
|
+
export { createR2SQLLogsAdapter } from "./r2-sql-logs";
|
|
21
|
+
export { createR2SQLStatsAdapter } from "./r2-sql-logs";
|
|
22
|
+
export interface CloudflareAdapters {
|
|
23
|
+
customDomains: CustomDomainsAdapter;
|
|
24
|
+
cache: CacheAdapter;
|
|
25
|
+
logs?: LogsDataAdapter;
|
|
26
|
+
analytics?: AnalyticsAdapter;
|
|
27
|
+
geo?: GeoAdapter;
|
|
28
|
+
rateLimit?: RateLimitAdapter;
|
|
29
|
+
actionExecutions?: ActionExecutionsAdapter;
|
|
30
|
+
}
|
|
31
|
+
export default function createAdapters(config: CloudflareConfig): CloudflareAdapters;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { LogsDataAdapter } from "@authhero/adapter-interfaces";
|
|
2
|
+
import { R2SQLLogsAdapterConfig } from "./types";
|
|
3
|
+
export type { R2SQLLogsAdapterConfig };
|
|
4
|
+
export { createR2SQLStatsAdapter } from "./stats";
|
|
5
|
+
/**
|
|
6
|
+
* Create an R2 SQL logs adapter
|
|
7
|
+
*
|
|
8
|
+
* This adapter uses Cloudflare R2 SQL and Pipelines for storing and querying logs.
|
|
9
|
+
*
|
|
10
|
+
* For passthrough mode (syncing writes to multiple destinations), use the core
|
|
11
|
+
* `createPassthroughAdapter` utility from `@authhero/adapter-interfaces` instead.
|
|
12
|
+
*
|
|
13
|
+
* @param config Configuration for the R2 SQL adapter
|
|
14
|
+
* @returns LogsDataAdapter instance
|
|
15
|
+
*
|
|
16
|
+
* @example HTTP endpoint mode
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { createR2SQLLogsAdapter } from "@authhero/cloudflare-adapter";
|
|
19
|
+
*
|
|
20
|
+
* const adapter = createR2SQLLogsAdapter({
|
|
21
|
+
* pipelineEndpoint: "https://your-stream-id.ingest.cloudflare.com",
|
|
22
|
+
* authToken: process.env.R2_SQL_AUTH_TOKEN,
|
|
23
|
+
* warehouseName: process.env.R2_WAREHOUSE_NAME,
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @example Service binding mode (Workers)
|
|
28
|
+
* ```typescript
|
|
29
|
+
* // In wrangler.toml:
|
|
30
|
+
* // [[pipelines]]
|
|
31
|
+
* // binding = "AUTH_LOGS_STREAM"
|
|
32
|
+
* // pipeline = "your-pipeline-id"
|
|
33
|
+
*
|
|
34
|
+
* const adapter = createR2SQLLogsAdapter({
|
|
35
|
+
* pipelineBinding: env.AUTH_LOGS_STREAM,
|
|
36
|
+
* authToken: env.R2_SQL_AUTH_TOKEN,
|
|
37
|
+
* warehouseName: env.R2_WAREHOUSE_NAME,
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example Passthrough mode (use core utility)
|
|
42
|
+
* ```typescript
|
|
43
|
+
* import { createPassthroughAdapter } from "@authhero/adapter-interfaces";
|
|
44
|
+
* import { createR2SQLLogsAdapter } from "@authhero/cloudflare-adapter";
|
|
45
|
+
*
|
|
46
|
+
* const primaryAdapter = createDatabaseLogsAdapter();
|
|
47
|
+
* const r2SqlAdapter = createR2SQLLogsAdapter({
|
|
48
|
+
* pipelineEndpoint: "https://your-stream-id.ingest.cloudflare.com",
|
|
49
|
+
* authToken: process.env.R2_SQL_AUTH_TOKEN,
|
|
50
|
+
* warehouseName: process.env.R2_WAREHOUSE_NAME,
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* const logsAdapter = createPassthroughAdapter({
|
|
54
|
+
* primary: primaryAdapter,
|
|
55
|
+
* secondaries: [{ adapter: { create: r2SqlAdapter.create } }],
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function createR2SQLLogsAdapter(config: R2SQLLogsAdapterConfig): LogsDataAdapter;
|
|
60
|
+
export default createR2SQLLogsAdapter;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ListParams } from "@authhero/adapter-interfaces";
|
|
2
|
+
import { Log } from "@authhero/adapter-interfaces";
|
|
3
|
+
import { R2SQLLogsAdapterConfig } from "./types";
|
|
4
|
+
interface ListLogsResponse {
|
|
5
|
+
logs: Log[];
|
|
6
|
+
start: number;
|
|
7
|
+
limit: number;
|
|
8
|
+
length: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function listLogs(config: R2SQLLogsAdapterConfig): (tenantId: string, params?: ListParams) => Promise<ListLogsResponse>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Log, LogInsert } from "@authhero/adapter-interfaces";
|
|
2
|
+
import { R2SQLLogsAdapterConfig } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Convert data from R2 SQL back to Log format
|
|
5
|
+
*/
|
|
6
|
+
export declare function formatLogFromStorage(row: Record<string, any>): Log;
|
|
7
|
+
export declare function createLog(config: R2SQLLogsAdapterConfig): (tenantId: string, log: LogInsert) => Promise<Log>;
|
|
8
|
+
export declare function getLogs(config: R2SQLLogsAdapterConfig): (tenantId: string, logId: string) => Promise<Log | null>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { R2SQLLogsAdapterConfig } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Execute a SQL query against R2 SQL
|
|
4
|
+
*/
|
|
5
|
+
export declare function executeR2SQLQuery(config: R2SQLLogsAdapterConfig, query: string): Promise<Record<string, any>[]>;
|
|
6
|
+
/**
|
|
7
|
+
* Escape a string value for SQL
|
|
8
|
+
*/
|
|
9
|
+
export declare function escapeSQLString(value: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Escape an identifier (table name, column name) for SQL
|
|
12
|
+
*/
|
|
13
|
+
export declare function escapeSQLIdentifier(identifier: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { StatsAdapter } from "@authhero/adapter-interfaces";
|
|
2
|
+
/**
|
|
3
|
+
* Create a stats adapter for R2 SQL that returns "not supported" errors
|
|
4
|
+
*
|
|
5
|
+
* R2 SQL logs does not currently support stats queries.
|
|
6
|
+
* Use the Analytics Engine stats adapter or Kysely stats adapter instead.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createR2SQLStatsAdapter(): StatsAdapter;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface R2SQLLogsAdapterConfig {
|
|
2
|
+
/**
|
|
3
|
+
* Cloudflare Pipeline HTTP endpoint URL for ingesting logs
|
|
4
|
+
* Example: "https://{stream-id}.ingest.cloudflare.com"
|
|
5
|
+
* Optional if using pipelineBinding or baseAdapter
|
|
6
|
+
*/
|
|
7
|
+
pipelineEndpoint?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Cloudflare Pipeline binding (for Workers)
|
|
10
|
+
* Use this instead of pipelineEndpoint when running in a Worker
|
|
11
|
+
* Pass the Pipeline object from env (e.g., env.AUTH_LOGS_STREAM)
|
|
12
|
+
* The Pipeline has a send() method for ingesting data
|
|
13
|
+
*/
|
|
14
|
+
pipelineBinding?: {
|
|
15
|
+
send: (data: any) => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Cloudflare account ID for R2 SQL API
|
|
19
|
+
* Required for the official API endpoint
|
|
20
|
+
* Can be passed via environment variable: CLOUDFLARE_ACCOUNT_ID
|
|
21
|
+
*/
|
|
22
|
+
accountId: string;
|
|
23
|
+
/**
|
|
24
|
+
* Cloudflare R2 SQL API token for querying logs
|
|
25
|
+
* Can be passed via environment variable: R2_SQL_AUTH_TOKEN
|
|
26
|
+
*/
|
|
27
|
+
authToken: string;
|
|
28
|
+
/**
|
|
29
|
+
* R2 warehouse name (e.g., "default")
|
|
30
|
+
* Can be passed via environment variable: R2_WAREHOUSE_NAME
|
|
31
|
+
*/
|
|
32
|
+
warehouseName: string;
|
|
33
|
+
/**
|
|
34
|
+
* Catalog database/namespace for logs (default: "default")
|
|
35
|
+
*/
|
|
36
|
+
namespace?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Catalog table name for logs (default: "logs")
|
|
39
|
+
*/
|
|
40
|
+
tableName?: string;
|
|
41
|
+
/**
|
|
42
|
+
* HTTP timeout in milliseconds (default: 30000)
|
|
43
|
+
*/
|
|
44
|
+
timeout?: number;
|
|
45
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { RateLimitAdapter, RateLimitScope } from "@authhero/adapter-interfaces";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal shape of the Cloudflare Workers Rate Limiter binding. We declare
|
|
4
|
+
* it locally rather than depending on `@cloudflare/workers-types` so the
|
|
5
|
+
* adapter package stays runtime-agnostic.
|
|
6
|
+
*
|
|
7
|
+
* Reference: https://developers.cloudflare.com/workers/runtime-apis/bindings/rate-limit/
|
|
8
|
+
*/
|
|
9
|
+
export interface CloudflareRateLimitBinding {
|
|
10
|
+
limit(options: {
|
|
11
|
+
key: string;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
success: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Map of scopes to Cloudflare Workers Rate Limiter bindings. Each binding's
|
|
18
|
+
* `limit` and `period` are configured at deploy time in `wrangler.toml` and
|
|
19
|
+
* cannot be overridden per request.
|
|
20
|
+
*
|
|
21
|
+
* Workers Rate Limiter only supports `period: 10` or `period: 60` seconds —
|
|
22
|
+
* it is a short-window burst guard, not a daily cap. For Auth0-style
|
|
23
|
+
* thresholds (e.g. 100 attempts / day) see `FUTURE: Durable Object backend`
|
|
24
|
+
* below.
|
|
25
|
+
*
|
|
26
|
+
* Any scope omitted from this map results in a permissive ("allowed: true")
|
|
27
|
+
* decision so callers can configure backends incrementally.
|
|
28
|
+
*/
|
|
29
|
+
export type CloudflareRateLimitBindings = Partial<Record<RateLimitScope, CloudflareRateLimitBinding>>;
|
|
30
|
+
export declare function createCloudflareRateLimitAdapter(bindings: CloudflareRateLimitBindings | undefined): RateLimitAdapter | undefined;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { CustomDomainsAdapter } from "@authhero/adapter-interfaces";
|
|
2
|
+
import type { R2SQLLogsAdapterConfig } from "../r2-sql-logs";
|
|
3
|
+
import type { AnalyticsEngineLogsAdapterConfig } from "../analytics-engine-logs";
|
|
4
|
+
import type { AnalyticsEngineActionExecutionsAdapterConfig } from "../analytics-engine-action-executions";
|
|
5
|
+
import type { CloudflareRateLimitBindings } from "../rate-limit";
|
|
6
|
+
export interface CloudflareConfig {
|
|
7
|
+
zoneId: string;
|
|
8
|
+
authKey: string;
|
|
9
|
+
authEmail: string;
|
|
10
|
+
enterprise?: boolean;
|
|
11
|
+
customDomainAdapter: CustomDomainsAdapter;
|
|
12
|
+
/**
|
|
13
|
+
* Cache name to use (optional, defaults to "default")
|
|
14
|
+
*/
|
|
15
|
+
cacheName?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Default TTL in seconds for cache entries (optional)
|
|
18
|
+
*/
|
|
19
|
+
defaultTtlSeconds?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Key prefix to namespace cache entries (optional)
|
|
22
|
+
*/
|
|
23
|
+
keyPrefix?: string;
|
|
24
|
+
/**
|
|
25
|
+
* R2 SQL logs adapter configuration (optional)
|
|
26
|
+
* Use this for high-volume log storage with R2 Pipelines and R2 SQL
|
|
27
|
+
*/
|
|
28
|
+
r2SqlLogs?: R2SQLLogsAdapterConfig;
|
|
29
|
+
/**
|
|
30
|
+
* Analytics Engine logs adapter configuration (optional)
|
|
31
|
+
* Use this for low-latency log writes with Cloudflare Analytics Engine
|
|
32
|
+
*/
|
|
33
|
+
analyticsEngineLogs?: AnalyticsEngineLogsAdapterConfig;
|
|
34
|
+
/**
|
|
35
|
+
* Analytics Engine action_executions adapter configuration (optional).
|
|
36
|
+
* Stores Auth0-shaped action execution records in a dedicated AE dataset
|
|
37
|
+
* so logs and the executions they reference can both live in AE.
|
|
38
|
+
*/
|
|
39
|
+
analyticsEngineActionExecutions?: AnalyticsEngineActionExecutionsAdapterConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Cloudflare Workers Rate Limiter bindings, keyed by logical scope.
|
|
42
|
+
* Each binding's `limit` and `period` are baked in at deploy time; this
|
|
43
|
+
* adapter can't override them per tenant. Bindings are optional — any
|
|
44
|
+
* unconfigured scope is treated as permissive.
|
|
45
|
+
*/
|
|
46
|
+
rateLimitBindings?: CloudflareRateLimitBindings;
|
|
47
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { z } from "@hono/zod-openapi";
|
|
2
|
+
declare const resultSchema: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
ssl: z.ZodObject<{
|
|
5
|
+
id: z.ZodString;
|
|
6
|
+
bundle_method: z.ZodOptional<z.ZodString>;
|
|
7
|
+
certificate_authority: z.ZodString;
|
|
8
|
+
custom_certificate: z.ZodOptional<z.ZodString>;
|
|
9
|
+
custom_csr_id: z.ZodOptional<z.ZodString>;
|
|
10
|
+
custom_key: z.ZodOptional<z.ZodString>;
|
|
11
|
+
expires_on: z.ZodOptional<z.ZodString>;
|
|
12
|
+
hosts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
13
|
+
issuer: z.ZodOptional<z.ZodString>;
|
|
14
|
+
method: z.ZodString;
|
|
15
|
+
serial_number: z.ZodOptional<z.ZodString>;
|
|
16
|
+
settings: z.ZodOptional<z.ZodObject<{
|
|
17
|
+
ciphers: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
18
|
+
early_hints: z.ZodOptional<z.ZodString>;
|
|
19
|
+
http2: z.ZodOptional<z.ZodString>;
|
|
20
|
+
min_tls_version: z.ZodOptional<z.ZodString>;
|
|
21
|
+
tls_1_3: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>>;
|
|
23
|
+
signature: z.ZodOptional<z.ZodString>;
|
|
24
|
+
type: z.ZodString;
|
|
25
|
+
uploaded_on: z.ZodOptional<z.ZodString>;
|
|
26
|
+
validation_errors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
27
|
+
message: z.ZodString;
|
|
28
|
+
}, z.core.$strip>>>;
|
|
29
|
+
validation_records: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
30
|
+
emails: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
31
|
+
http_body: z.ZodOptional<z.ZodString>;
|
|
32
|
+
http_url: z.ZodOptional<z.ZodString>;
|
|
33
|
+
txt_name: z.ZodOptional<z.ZodString>;
|
|
34
|
+
txt_value: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}, z.core.$strip>>>;
|
|
36
|
+
wildcard: z.ZodBoolean;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
hostname: z.ZodString;
|
|
39
|
+
custom_metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
40
|
+
custom_origin_server: z.ZodOptional<z.ZodString>;
|
|
41
|
+
custom_origin_sni: z.ZodOptional<z.ZodString>;
|
|
42
|
+
ownership_verification: z.ZodOptional<z.ZodObject<{
|
|
43
|
+
name: z.ZodString;
|
|
44
|
+
type: z.ZodString;
|
|
45
|
+
value: z.ZodString;
|
|
46
|
+
}, z.core.$strip>>;
|
|
47
|
+
ownership_verification_http: z.ZodOptional<z.ZodObject<{
|
|
48
|
+
http_body: z.ZodOptional<z.ZodString>;
|
|
49
|
+
http_url: z.ZodOptional<z.ZodString>;
|
|
50
|
+
}, z.core.$strip>>;
|
|
51
|
+
status: z.ZodString;
|
|
52
|
+
verification_errors: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
53
|
+
created_at: z.ZodString;
|
|
54
|
+
}, z.core.$strip>;
|
|
55
|
+
export type CustomDomainResult = z.infer<typeof resultSchema>;
|
|
56
|
+
export declare const customDomainResponseSchema: z.ZodObject<{
|
|
57
|
+
errors: z.ZodArray<z.ZodObject<{
|
|
58
|
+
code: z.ZodNumber;
|
|
59
|
+
message: z.ZodString;
|
|
60
|
+
}, z.core.$strip>>;
|
|
61
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
62
|
+
code: z.ZodNumber;
|
|
63
|
+
message: z.ZodString;
|
|
64
|
+
}, z.core.$strip>>;
|
|
65
|
+
success: z.ZodBoolean;
|
|
66
|
+
result: z.ZodObject<{
|
|
67
|
+
id: z.ZodString;
|
|
68
|
+
ssl: z.ZodObject<{
|
|
69
|
+
id: z.ZodString;
|
|
70
|
+
bundle_method: z.ZodOptional<z.ZodString>;
|
|
71
|
+
certificate_authority: z.ZodString;
|
|
72
|
+
custom_certificate: z.ZodOptional<z.ZodString>;
|
|
73
|
+
custom_csr_id: z.ZodOptional<z.ZodString>;
|
|
74
|
+
custom_key: z.ZodOptional<z.ZodString>;
|
|
75
|
+
expires_on: z.ZodOptional<z.ZodString>;
|
|
76
|
+
hosts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
77
|
+
issuer: z.ZodOptional<z.ZodString>;
|
|
78
|
+
method: z.ZodString;
|
|
79
|
+
serial_number: z.ZodOptional<z.ZodString>;
|
|
80
|
+
settings: z.ZodOptional<z.ZodObject<{
|
|
81
|
+
ciphers: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
82
|
+
early_hints: z.ZodOptional<z.ZodString>;
|
|
83
|
+
http2: z.ZodOptional<z.ZodString>;
|
|
84
|
+
min_tls_version: z.ZodOptional<z.ZodString>;
|
|
85
|
+
tls_1_3: z.ZodOptional<z.ZodString>;
|
|
86
|
+
}, z.core.$strip>>;
|
|
87
|
+
signature: z.ZodOptional<z.ZodString>;
|
|
88
|
+
type: z.ZodString;
|
|
89
|
+
uploaded_on: z.ZodOptional<z.ZodString>;
|
|
90
|
+
validation_errors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
91
|
+
message: z.ZodString;
|
|
92
|
+
}, z.core.$strip>>>;
|
|
93
|
+
validation_records: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
94
|
+
emails: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
95
|
+
http_body: z.ZodOptional<z.ZodString>;
|
|
96
|
+
http_url: z.ZodOptional<z.ZodString>;
|
|
97
|
+
txt_name: z.ZodOptional<z.ZodString>;
|
|
98
|
+
txt_value: z.ZodOptional<z.ZodString>;
|
|
99
|
+
}, z.core.$strip>>>;
|
|
100
|
+
wildcard: z.ZodBoolean;
|
|
101
|
+
}, z.core.$strip>;
|
|
102
|
+
hostname: z.ZodString;
|
|
103
|
+
custom_metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
104
|
+
custom_origin_server: z.ZodOptional<z.ZodString>;
|
|
105
|
+
custom_origin_sni: z.ZodOptional<z.ZodString>;
|
|
106
|
+
ownership_verification: z.ZodOptional<z.ZodObject<{
|
|
107
|
+
name: z.ZodString;
|
|
108
|
+
type: z.ZodString;
|
|
109
|
+
value: z.ZodString;
|
|
110
|
+
}, z.core.$strip>>;
|
|
111
|
+
ownership_verification_http: z.ZodOptional<z.ZodObject<{
|
|
112
|
+
http_body: z.ZodOptional<z.ZodString>;
|
|
113
|
+
http_url: z.ZodOptional<z.ZodString>;
|
|
114
|
+
}, z.core.$strip>>;
|
|
115
|
+
status: z.ZodString;
|
|
116
|
+
verification_errors: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
117
|
+
created_at: z.ZodString;
|
|
118
|
+
}, z.core.$strip>;
|
|
119
|
+
}, z.core.$strip>;
|
|
120
|
+
export declare const customDomainListResponseSchema: z.ZodObject<{
|
|
121
|
+
errors: z.ZodArray<z.ZodObject<{
|
|
122
|
+
code: z.ZodNumber;
|
|
123
|
+
message: z.ZodString;
|
|
124
|
+
}, z.core.$strip>>;
|
|
125
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
126
|
+
code: z.ZodNumber;
|
|
127
|
+
message: z.ZodString;
|
|
128
|
+
}, z.core.$strip>>;
|
|
129
|
+
success: z.ZodBoolean;
|
|
130
|
+
result: z.ZodArray<z.ZodObject<{
|
|
131
|
+
id: z.ZodString;
|
|
132
|
+
ssl: z.ZodObject<{
|
|
133
|
+
id: z.ZodString;
|
|
134
|
+
bundle_method: z.ZodOptional<z.ZodString>;
|
|
135
|
+
certificate_authority: z.ZodString;
|
|
136
|
+
custom_certificate: z.ZodOptional<z.ZodString>;
|
|
137
|
+
custom_csr_id: z.ZodOptional<z.ZodString>;
|
|
138
|
+
custom_key: z.ZodOptional<z.ZodString>;
|
|
139
|
+
expires_on: z.ZodOptional<z.ZodString>;
|
|
140
|
+
hosts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
141
|
+
issuer: z.ZodOptional<z.ZodString>;
|
|
142
|
+
method: z.ZodString;
|
|
143
|
+
serial_number: z.ZodOptional<z.ZodString>;
|
|
144
|
+
settings: z.ZodOptional<z.ZodObject<{
|
|
145
|
+
ciphers: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
146
|
+
early_hints: z.ZodOptional<z.ZodString>;
|
|
147
|
+
http2: z.ZodOptional<z.ZodString>;
|
|
148
|
+
min_tls_version: z.ZodOptional<z.ZodString>;
|
|
149
|
+
tls_1_3: z.ZodOptional<z.ZodString>;
|
|
150
|
+
}, z.core.$strip>>;
|
|
151
|
+
signature: z.ZodOptional<z.ZodString>;
|
|
152
|
+
type: z.ZodString;
|
|
153
|
+
uploaded_on: z.ZodOptional<z.ZodString>;
|
|
154
|
+
validation_errors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
155
|
+
message: z.ZodString;
|
|
156
|
+
}, z.core.$strip>>>;
|
|
157
|
+
validation_records: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
158
|
+
emails: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
159
|
+
http_body: z.ZodOptional<z.ZodString>;
|
|
160
|
+
http_url: z.ZodOptional<z.ZodString>;
|
|
161
|
+
txt_name: z.ZodOptional<z.ZodString>;
|
|
162
|
+
txt_value: z.ZodOptional<z.ZodString>;
|
|
163
|
+
}, z.core.$strip>>>;
|
|
164
|
+
wildcard: z.ZodBoolean;
|
|
165
|
+
}, z.core.$strip>;
|
|
166
|
+
hostname: z.ZodString;
|
|
167
|
+
custom_metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
168
|
+
custom_origin_server: z.ZodOptional<z.ZodString>;
|
|
169
|
+
custom_origin_sni: z.ZodOptional<z.ZodString>;
|
|
170
|
+
ownership_verification: z.ZodOptional<z.ZodObject<{
|
|
171
|
+
name: z.ZodString;
|
|
172
|
+
type: z.ZodString;
|
|
173
|
+
value: z.ZodString;
|
|
174
|
+
}, z.core.$strip>>;
|
|
175
|
+
ownership_verification_http: z.ZodOptional<z.ZodObject<{
|
|
176
|
+
http_body: z.ZodOptional<z.ZodString>;
|
|
177
|
+
http_url: z.ZodOptional<z.ZodString>;
|
|
178
|
+
}, z.core.$strip>>;
|
|
179
|
+
status: z.ZodString;
|
|
180
|
+
verification_errors: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
181
|
+
created_at: z.ZodString;
|
|
182
|
+
}, z.core.$strip>>;
|
|
183
|
+
}, z.core.$strip>;
|
|
184
|
+
export type CustomDomainResponse = z.infer<typeof customDomainResponseSchema>;
|
|
185
|
+
export {};
|