@arcjet/bun 1.7.0-rc.1 → 1.7.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/index.d.ts +140 -0
- package/index.js +156 -0
- package/package.json +33 -36
- package/dist/index.d.ts +0 -134
- package/dist/index.js +0 -119
package/index.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { ArcjetDecision, ArcjetOptions as CoreOptions, ArcjetRule, Primitive, Product, ExtraProps, CharacteristicProps } from "arcjet";
|
|
2
|
+
import { type ProxyService } from "@arcjet/ip";
|
|
3
|
+
export { cloudflare } from "@arcjet/ip";
|
|
4
|
+
export type { ProxyService } from "@arcjet/ip";
|
|
5
|
+
import type { Server } from "bun";
|
|
6
|
+
export * from "arcjet";
|
|
7
|
+
type Simplify<T> = {
|
|
8
|
+
[KeyType in keyof T]: T[KeyType];
|
|
9
|
+
} & {};
|
|
10
|
+
declare const emptyObjectSymbol: unique symbol;
|
|
11
|
+
type PlainObject = {
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Dynamically generate whether zero or one `properties` object must or can be passed.
|
|
16
|
+
*/
|
|
17
|
+
type MaybeProperties<T> = {
|
|
18
|
+
[P in keyof T]?: T[P];
|
|
19
|
+
} extends T ? T extends {
|
|
20
|
+
[emptyObjectSymbol]?: never;
|
|
21
|
+
} ? [
|
|
22
|
+
] : [
|
|
23
|
+
properties?: T
|
|
24
|
+
] : [
|
|
25
|
+
properties: T
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Configuration for {@linkcode createRemoteClient}.
|
|
29
|
+
*/
|
|
30
|
+
export type RemoteClientOptions = {
|
|
31
|
+
/**
|
|
32
|
+
* Base URI for HTTP requests to Decide API (optional).
|
|
33
|
+
*
|
|
34
|
+
* Defaults to the environment variable `ARCJET_BASE_URL` (if that value
|
|
35
|
+
* is known and allowed) and the standard production API otherwise.
|
|
36
|
+
*/
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Timeout in milliseconds for the Decide API (optional).
|
|
40
|
+
*
|
|
41
|
+
* Defaults to `500` in production and `1000` in development.
|
|
42
|
+
*/
|
|
43
|
+
timeout?: number;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Create a remote client.
|
|
47
|
+
*
|
|
48
|
+
* @param options
|
|
49
|
+
* Configuration (optional).
|
|
50
|
+
* @returns
|
|
51
|
+
* Client.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createRemoteClient(options?: RemoteClientOptions): import("@arcjet/protocol/client.js").Client;
|
|
54
|
+
/**
|
|
55
|
+
* Configuration for the Bun integration of Arcjet.
|
|
56
|
+
*
|
|
57
|
+
* @template Rules
|
|
58
|
+
* List of rules.
|
|
59
|
+
* @template Characteristics
|
|
60
|
+
* Characteristics to track a user by.
|
|
61
|
+
*/
|
|
62
|
+
export type ArcjetOptions<Rules extends [...Array<Primitive | Product>], Characteristics extends readonly string[]> = Simplify<CoreOptions<Rules, Characteristics> & {
|
|
63
|
+
/**
|
|
64
|
+
* IP addresses and CIDR ranges of trusted load balancers and proxies
|
|
65
|
+
* (optional, example: `["100.100.100.100", "100.100.100.0/24"]`).
|
|
66
|
+
*
|
|
67
|
+
* Proxy services such as {@linkcode cloudflare} can also be included to read
|
|
68
|
+
* the real client IP from a service-specific header when the request comes
|
|
69
|
+
* from that service.
|
|
70
|
+
*/
|
|
71
|
+
proxies?: Array<string | ProxyService>;
|
|
72
|
+
}>;
|
|
73
|
+
/**
|
|
74
|
+
* Instance of the Bun integration of Arcjet.
|
|
75
|
+
*
|
|
76
|
+
* Primarily has a `protect()` method to make a decision about how a Bun request
|
|
77
|
+
* should be handled.
|
|
78
|
+
*
|
|
79
|
+
* @template Props
|
|
80
|
+
* Configuration.
|
|
81
|
+
*/
|
|
82
|
+
export interface ArcjetBun<Props extends PlainObject> {
|
|
83
|
+
/**
|
|
84
|
+
* Make a decision about how to handle a request.
|
|
85
|
+
*
|
|
86
|
+
* This will analyze the request locally where possible and otherwise call
|
|
87
|
+
* the Arcjet decision API.
|
|
88
|
+
*
|
|
89
|
+
* @param ctx
|
|
90
|
+
* Additional context for this function call.
|
|
91
|
+
* @param request
|
|
92
|
+
* Details about the {@linkcode Request} that Arcjet needs to make a
|
|
93
|
+
* decision.
|
|
94
|
+
* @param props
|
|
95
|
+
* Additional properties required for running rules against a request.
|
|
96
|
+
* @returns
|
|
97
|
+
* Promise that resolves to an {@linkcode ArcjetDecision} indicating
|
|
98
|
+
* Arcjet’s decision about the request.
|
|
99
|
+
*/
|
|
100
|
+
protect(request: Request, ...properties: MaybeProperties<Props & {
|
|
101
|
+
correlationId?: string;
|
|
102
|
+
}>): Promise<ArcjetDecision>;
|
|
103
|
+
/**
|
|
104
|
+
* Augment the client with another rule.
|
|
105
|
+
*
|
|
106
|
+
* Useful for varying rules based on criteria in your handler such as
|
|
107
|
+
* different rate limit for logged in users.
|
|
108
|
+
*
|
|
109
|
+
* @template Rule
|
|
110
|
+
* Type of rule.
|
|
111
|
+
* @param rule
|
|
112
|
+
* Rule to add to Arcjet.
|
|
113
|
+
* @returns
|
|
114
|
+
* Arcjet instance augmented with the given rule.
|
|
115
|
+
*/
|
|
116
|
+
withRule<Rule extends ArcjetRule>(rule: Array<Rule>): ArcjetBun<Props & (Rule extends ArcjetRule<infer P> ? P : {})>;
|
|
117
|
+
/**
|
|
118
|
+
* Wrap the Bun `fetch` handler to provide additional details when calling
|
|
119
|
+
* the `protect()` method.
|
|
120
|
+
*
|
|
121
|
+
* @param fetch
|
|
122
|
+
* Original `fetch` from Bun.
|
|
123
|
+
* @returns
|
|
124
|
+
* Wrapped `fetch` handler.
|
|
125
|
+
*/
|
|
126
|
+
handler(fetch: (this: Server<any>, request: Request, server: Server<any>) => Response | Promise<Response>): (this: Server<any>, request: Request, server: Server<any>) => Response | Promise<Response>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create a new Bun integration of Arcjet.
|
|
130
|
+
*
|
|
131
|
+
* @template Rules
|
|
132
|
+
* List of rules.
|
|
133
|
+
* @template Characteristics
|
|
134
|
+
* Characteristics to track a user by.
|
|
135
|
+
* @param options
|
|
136
|
+
* Configuration.
|
|
137
|
+
* @returns
|
|
138
|
+
* Bun integration of Arcjet.
|
|
139
|
+
*/
|
|
140
|
+
export default function arcjet<const Rules extends (Primitive | Product)[], const Characteristics extends readonly string[]>(options: ArcjetOptions<Rules, Characteristics>): ArcjetBun<ExtraProps<Rules> & CharacteristicProps<Characteristics>>;
|
package/index.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import * as core from 'arcjet';
|
|
2
|
+
import core__default from 'arcjet';
|
|
3
|
+
export * from 'arcjet';
|
|
4
|
+
import { parseProxies, findIp } from '@arcjet/ip';
|
|
5
|
+
export { cloudflare } from '@arcjet/ip';
|
|
6
|
+
import { ArcjetHeaders } from '@arcjet/headers';
|
|
7
|
+
import { env } from 'bun';
|
|
8
|
+
import { readBodyWeb } from '@arcjet/body';
|
|
9
|
+
import { logLevel, isDevelopment, baseUrl, platform } from '@arcjet/env';
|
|
10
|
+
import { Logger } from '@arcjet/logger';
|
|
11
|
+
import { createClient } from '@arcjet/protocol/client.js';
|
|
12
|
+
import { createTransport } from '@arcjet/transport';
|
|
13
|
+
|
|
14
|
+
/// <reference types="bun-types" />
|
|
15
|
+
let warnedForAutomaticBodyRead = false;
|
|
16
|
+
/**
|
|
17
|
+
* Create a remote client.
|
|
18
|
+
*
|
|
19
|
+
* @param options
|
|
20
|
+
* Configuration (optional).
|
|
21
|
+
* @returns
|
|
22
|
+
* Client.
|
|
23
|
+
*/
|
|
24
|
+
function createRemoteClient(options) {
|
|
25
|
+
const url = options?.baseUrl ?? baseUrl(env);
|
|
26
|
+
const timeout = options?.timeout ?? (isDevelopment(env) ? 1000 : 500);
|
|
27
|
+
// Transport is the HTTP client that the client uses to make requests.
|
|
28
|
+
const transport = createTransport(url);
|
|
29
|
+
const sdkStack = "BUN";
|
|
30
|
+
const sdkVersion = "1.7.0";
|
|
31
|
+
return createClient({
|
|
32
|
+
transport,
|
|
33
|
+
baseUrl: url,
|
|
34
|
+
timeout,
|
|
35
|
+
sdkStack,
|
|
36
|
+
sdkVersion,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create a new Bun integration of Arcjet.
|
|
41
|
+
*
|
|
42
|
+
* @template Rules
|
|
43
|
+
* List of rules.
|
|
44
|
+
* @template Characteristics
|
|
45
|
+
* Characteristics to track a user by.
|
|
46
|
+
* @param options
|
|
47
|
+
* Configuration.
|
|
48
|
+
* @returns
|
|
49
|
+
* Bun integration of Arcjet.
|
|
50
|
+
*/
|
|
51
|
+
function arcjet(options) {
|
|
52
|
+
const client = options.client ?? createRemoteClient();
|
|
53
|
+
// Assuming the `handler()` function was used around Bun's fetch handler this
|
|
54
|
+
// WeakMap should be populated with IP addresses inspected via
|
|
55
|
+
// `server.requestIP()`
|
|
56
|
+
const ipCache = new WeakMap();
|
|
57
|
+
const log = options.log
|
|
58
|
+
? options.log
|
|
59
|
+
: new Logger({
|
|
60
|
+
level: logLevel(env),
|
|
61
|
+
});
|
|
62
|
+
const proxies = Array.isArray(options.proxies)
|
|
63
|
+
? parseProxies(options.proxies)
|
|
64
|
+
: undefined;
|
|
65
|
+
if (isDevelopment(env)) {
|
|
66
|
+
log.warn("Arcjet will use 127.0.0.1 when missing public IP address in development mode");
|
|
67
|
+
}
|
|
68
|
+
function toArcjetRequest(request, props) {
|
|
69
|
+
const cookies = request.headers.get("cookie") ?? "";
|
|
70
|
+
// We construct an ArcjetHeaders to normalize over Headers
|
|
71
|
+
const headers = new ArcjetHeaders(request.headers);
|
|
72
|
+
const url = new URL(request.url);
|
|
73
|
+
const xArcjetIp = isDevelopment(env)
|
|
74
|
+
? headers.get("x-arcjet-ip")
|
|
75
|
+
: undefined;
|
|
76
|
+
let ip = xArcjetIp ||
|
|
77
|
+
findIp({
|
|
78
|
+
// This attempts to lookup the IP in the `ipCache`. This is primarily a
|
|
79
|
+
// workaround to the API design in Bun that requires access to the
|
|
80
|
+
// `Server` to lookup an IP.
|
|
81
|
+
ip: ipCache.get(request),
|
|
82
|
+
headers,
|
|
83
|
+
}, { platform: platform(env), proxies });
|
|
84
|
+
if (ip === "") {
|
|
85
|
+
// If the `ip` is empty but we're in development mode, we default the IP
|
|
86
|
+
// so the request doesn't fail.
|
|
87
|
+
if (isDevelopment(env)) {
|
|
88
|
+
ip = "127.0.0.1";
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
log.warn(`Client IP address is missing. If this is a dev environment set the ARCJET_ENV env var to "development"`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
...props,
|
|
96
|
+
ip,
|
|
97
|
+
method: request.method,
|
|
98
|
+
protocol: url.protocol,
|
|
99
|
+
host: url.host,
|
|
100
|
+
path: url.pathname,
|
|
101
|
+
headers,
|
|
102
|
+
cookies,
|
|
103
|
+
query: url.search,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function withClient(aj) {
|
|
107
|
+
const client = {
|
|
108
|
+
withRule(rule) {
|
|
109
|
+
const client = aj.withRule(rule);
|
|
110
|
+
return withClient(client);
|
|
111
|
+
},
|
|
112
|
+
async protect(request, props) {
|
|
113
|
+
// `correlationId` is a request-independent option, not a rule prop, so
|
|
114
|
+
// pull it out before building the request from the rule properties.
|
|
115
|
+
const { correlationId, ...properties } = props ?? {};
|
|
116
|
+
// Cast of `{}` because here we switch from `undefined` to `Properties`.
|
|
117
|
+
const req = toArcjetRequest(request, (properties || {}));
|
|
118
|
+
const getBody = async () => {
|
|
119
|
+
if (request.bodyUsed) {
|
|
120
|
+
throw new Error("Cannot read body: already read");
|
|
121
|
+
}
|
|
122
|
+
const clonedRequest = request.clone();
|
|
123
|
+
let expectedLength;
|
|
124
|
+
const expectedLengthString = request.headers.get("content-length");
|
|
125
|
+
if (typeof expectedLengthString === "string") {
|
|
126
|
+
expectedLength = parseInt(expectedLengthString, 10);
|
|
127
|
+
}
|
|
128
|
+
// HEAD and GET requests do not have a body.
|
|
129
|
+
if (!clonedRequest.body) {
|
|
130
|
+
throw new Error("Cannot read body: body is missing");
|
|
131
|
+
}
|
|
132
|
+
if (!warnedForAutomaticBodyRead) {
|
|
133
|
+
warnedForAutomaticBodyRead = true;
|
|
134
|
+
log.warn("Automatically reading the request body is deprecated; please pass an explicit `sensitiveInfoValue` field. See <https://docs.arcjet.com/upgrading/sdk-migration>.");
|
|
135
|
+
}
|
|
136
|
+
return readBodyWeb(clonedRequest.body, { expectedLength });
|
|
137
|
+
};
|
|
138
|
+
return aj.protect({ getBody }, { ...req, correlationId });
|
|
139
|
+
},
|
|
140
|
+
handler(fetch) {
|
|
141
|
+
return async function (request, server) {
|
|
142
|
+
const socketAddress = server.requestIP(request);
|
|
143
|
+
if (socketAddress) {
|
|
144
|
+
ipCache.set(request, socketAddress.address);
|
|
145
|
+
}
|
|
146
|
+
return fetch.call(server, request, server);
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
return Object.freeze(client);
|
|
151
|
+
}
|
|
152
|
+
const aj = core__default({ ...options, client, log });
|
|
153
|
+
return withClient(aj);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export { createRemoteClient, arcjet as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcjet/bun",
|
|
3
|
-
"version": "1.7.0
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Arcjet runtime security SDK for Bun — bot protection, rate limiting, prompt injection detection, PII blocking, and WAF",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -21,59 +21,56 @@
|
|
|
21
21
|
"verify",
|
|
22
22
|
"waf"
|
|
23
23
|
],
|
|
24
|
+
"license": "Apache-2.0",
|
|
24
25
|
"homepage": "https://arcjet.com",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/arcjet/arcjet-js.git",
|
|
29
|
+
"directory": "arcjet-bun"
|
|
30
|
+
},
|
|
25
31
|
"bugs": {
|
|
26
32
|
"url": "https://github.com/arcjet/arcjet-js/issues",
|
|
27
33
|
"email": "support@arcjet.com"
|
|
28
34
|
},
|
|
29
|
-
"license": "Apache-2.0",
|
|
30
35
|
"author": {
|
|
31
36
|
"name": "Arcjet",
|
|
32
37
|
"email": "support@arcjet.com",
|
|
33
38
|
"url": "https://arcjet.com"
|
|
34
39
|
},
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
},
|
|
40
|
+
"engines": {},
|
|
41
|
+
"type": "module",
|
|
42
|
+
"main": "./index.js",
|
|
43
|
+
"types": "./index.d.ts",
|
|
40
44
|
"files": [
|
|
41
|
-
"
|
|
45
|
+
"index.d.ts",
|
|
46
|
+
"index.js"
|
|
42
47
|
],
|
|
43
|
-
"type": "module",
|
|
44
|
-
"main": "./dist/index.js",
|
|
45
|
-
"types": "./dist/index.d.ts",
|
|
46
|
-
"exports": {
|
|
47
|
-
".": {
|
|
48
|
-
"types": "./dist/index.d.ts",
|
|
49
|
-
"default": "./dist/index.js"
|
|
50
|
-
},
|
|
51
|
-
"./package.json": "./package.json"
|
|
52
|
-
},
|
|
53
|
-
"publishConfig": {
|
|
54
|
-
"access": "public",
|
|
55
|
-
"tag": "latest"
|
|
56
|
-
},
|
|
57
48
|
"scripts": {
|
|
58
|
-
"build": "
|
|
59
|
-
"
|
|
60
|
-
"test": "npm run build"
|
|
49
|
+
"build": "rollup --config rollup.config.js",
|
|
50
|
+
"lint": "eslint .",
|
|
51
|
+
"test": "npm run build && npm run lint"
|
|
61
52
|
},
|
|
62
53
|
"dependencies": {
|
|
63
|
-
"@arcjet/body": "1.7.0
|
|
64
|
-
"@arcjet/env": "1.7.0
|
|
65
|
-
"@arcjet/headers": "1.7.0
|
|
66
|
-
"@arcjet/ip": "1.7.0
|
|
67
|
-
"@arcjet/logger": "1.7.0
|
|
68
|
-
"@arcjet/protocol": "1.7.0
|
|
69
|
-
"@arcjet/transport": "1.7.0
|
|
70
|
-
"arcjet": "1.7.0
|
|
54
|
+
"@arcjet/body": "1.7.0",
|
|
55
|
+
"@arcjet/env": "1.7.0",
|
|
56
|
+
"@arcjet/headers": "1.7.0",
|
|
57
|
+
"@arcjet/ip": "1.7.0",
|
|
58
|
+
"@arcjet/logger": "1.7.0",
|
|
59
|
+
"@arcjet/protocol": "1.7.0",
|
|
60
|
+
"@arcjet/transport": "1.7.0",
|
|
61
|
+
"arcjet": "1.7.0"
|
|
71
62
|
},
|
|
72
63
|
"devDependencies": {
|
|
64
|
+
"@arcjet/eslint-config": "1.7.0",
|
|
65
|
+
"@arcjet/rollup-config": "1.7.0",
|
|
66
|
+
"@rollup/wasm-node": "4.62.2",
|
|
73
67
|
"bun-types": "1.3.14",
|
|
74
|
-
"
|
|
75
|
-
"typescript": "
|
|
68
|
+
"eslint": "9.39.4",
|
|
69
|
+
"typescript": "5.9.3",
|
|
76
70
|
"undici-types": "7.28.0"
|
|
77
71
|
},
|
|
78
|
-
"
|
|
72
|
+
"publishConfig": {
|
|
73
|
+
"access": "public",
|
|
74
|
+
"tag": "latest"
|
|
75
|
+
}
|
|
79
76
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { ProxyService, ProxyService as ProxyService$1, cloudflare } from "@arcjet/ip";
|
|
2
|
-
import { ArcjetDecision, ArcjetOptions as ArcjetOptions$1, ArcjetRule, CharacteristicProps, ExtraProps, Primitive, Product } from "arcjet";
|
|
3
|
-
import { createClient } from "@arcjet/protocol/client.js";
|
|
4
|
-
import { Server } from "bun";
|
|
5
|
-
export * from "arcjet";
|
|
6
|
-
|
|
7
|
-
//#region src/index.d.ts
|
|
8
|
-
type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};
|
|
9
|
-
declare const emptyObjectSymbol: unique symbol;
|
|
10
|
-
type PlainObject = {
|
|
11
|
-
[key: string]: unknown;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Dynamically generate whether zero or one `properties` object must or can be passed.
|
|
15
|
-
*/
|
|
16
|
-
type MaybeProperties<T> = { [P in keyof T]?: T[P] } extends T ? T extends {
|
|
17
|
-
[emptyObjectSymbol]?: never;
|
|
18
|
-
} ? [] : [properties?: T] : [properties: T];
|
|
19
|
-
/**
|
|
20
|
-
* Configuration for {@linkcode createRemoteClient}.
|
|
21
|
-
*/
|
|
22
|
-
type RemoteClientOptions = {
|
|
23
|
-
/**
|
|
24
|
-
* Base URI for HTTP requests to Decide API (optional).
|
|
25
|
-
*
|
|
26
|
-
* Defaults to the environment variable `ARCJET_BASE_URL` (if that value
|
|
27
|
-
* is known and allowed) and the standard production API otherwise.
|
|
28
|
-
*/
|
|
29
|
-
baseUrl?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Timeout in milliseconds for the Decide API (optional).
|
|
32
|
-
*
|
|
33
|
-
* Defaults to `500` in production and `1000` in development.
|
|
34
|
-
*/
|
|
35
|
-
timeout?: number;
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* Create a remote client.
|
|
39
|
-
*
|
|
40
|
-
* @param options
|
|
41
|
-
* Configuration (optional).
|
|
42
|
-
* @returns
|
|
43
|
-
* Client.
|
|
44
|
-
*/
|
|
45
|
-
declare function createRemoteClient(options?: RemoteClientOptions): ReturnType<typeof createClient>;
|
|
46
|
-
/**
|
|
47
|
-
* Configuration for the Bun integration of Arcjet.
|
|
48
|
-
*
|
|
49
|
-
* @template Rules
|
|
50
|
-
* List of rules.
|
|
51
|
-
* @template Characteristics
|
|
52
|
-
* Characteristics to track a user by.
|
|
53
|
-
*/
|
|
54
|
-
type ArcjetOptions<Rules extends [...Array<Primitive | Product>], Characteristics extends readonly string[]> = Simplify<ArcjetOptions$1<Rules, Characteristics> & {
|
|
55
|
-
/**
|
|
56
|
-
* IP addresses and CIDR ranges of trusted load balancers and proxies
|
|
57
|
-
* (optional, example: `["100.100.100.100", "100.100.100.0/24"]`).
|
|
58
|
-
*
|
|
59
|
-
* Proxy services such as {@linkcode cloudflare} can also be included to read
|
|
60
|
-
* the real client IP from a service-specific header when the request comes
|
|
61
|
-
* from that service.
|
|
62
|
-
*/
|
|
63
|
-
proxies?: Array<string | ProxyService$1>;
|
|
64
|
-
}>;
|
|
65
|
-
/**
|
|
66
|
-
* Instance of the Bun integration of Arcjet.
|
|
67
|
-
*
|
|
68
|
-
* Primarily has a `protect()` method to make a decision about how a Bun request
|
|
69
|
-
* should be handled.
|
|
70
|
-
*
|
|
71
|
-
* @template Props
|
|
72
|
-
* Configuration.
|
|
73
|
-
*/
|
|
74
|
-
interface ArcjetBun<Props extends PlainObject> {
|
|
75
|
-
/**
|
|
76
|
-
* Make a decision about how to handle a request.
|
|
77
|
-
*
|
|
78
|
-
* This will analyze the request locally where possible and otherwise call
|
|
79
|
-
* the Arcjet decision API.
|
|
80
|
-
*
|
|
81
|
-
* @param ctx
|
|
82
|
-
* Additional context for this function call.
|
|
83
|
-
* @param request
|
|
84
|
-
* Details about the {@linkcode Request} that Arcjet needs to make a
|
|
85
|
-
* decision.
|
|
86
|
-
* @param props
|
|
87
|
-
* Additional properties required for running rules against a request.
|
|
88
|
-
* @returns
|
|
89
|
-
* Promise that resolves to an {@linkcode ArcjetDecision} indicating
|
|
90
|
-
* Arcjet’s decision about the request.
|
|
91
|
-
*/
|
|
92
|
-
protect(request: Request, ...properties: MaybeProperties<Props & {
|
|
93
|
-
correlationId?: string;
|
|
94
|
-
}>): Promise<ArcjetDecision>;
|
|
95
|
-
/**
|
|
96
|
-
* Augment the client with another rule.
|
|
97
|
-
*
|
|
98
|
-
* Useful for varying rules based on criteria in your handler such as
|
|
99
|
-
* different rate limit for logged in users.
|
|
100
|
-
*
|
|
101
|
-
* @template Rule
|
|
102
|
-
* Type of rule.
|
|
103
|
-
* @param rule
|
|
104
|
-
* Rule to add to Arcjet.
|
|
105
|
-
* @returns
|
|
106
|
-
* Arcjet instance augmented with the given rule.
|
|
107
|
-
*/
|
|
108
|
-
withRule<Rule extends ArcjetRule>(rule: Array<Rule>): ArcjetBun<Props & (Rule extends ArcjetRule<infer P> ? P : {})>;
|
|
109
|
-
/**
|
|
110
|
-
* Wrap the Bun `fetch` handler to provide additional details when calling
|
|
111
|
-
* the `protect()` method.
|
|
112
|
-
*
|
|
113
|
-
* @param fetch
|
|
114
|
-
* Original `fetch` from Bun.
|
|
115
|
-
* @returns
|
|
116
|
-
* Wrapped `fetch` handler.
|
|
117
|
-
*/
|
|
118
|
-
handler(fetch: (this: Server<any>, request: Request, server: Server<any>) => Response | Promise<Response>): (this: Server<any>, request: Request, server: Server<any>) => Response | Promise<Response>;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Create a new Bun integration of Arcjet.
|
|
122
|
-
*
|
|
123
|
-
* @template Rules
|
|
124
|
-
* List of rules.
|
|
125
|
-
* @template Characteristics
|
|
126
|
-
* Characteristics to track a user by.
|
|
127
|
-
* @param options
|
|
128
|
-
* Configuration.
|
|
129
|
-
* @returns
|
|
130
|
-
* Bun integration of Arcjet.
|
|
131
|
-
*/
|
|
132
|
-
declare function arcjet<const Rules extends (Primitive | Product)[], const Characteristics extends readonly string[]>(options: ArcjetOptions<Rules, Characteristics>): ArcjetBun<ExtraProps<Rules> & CharacteristicProps<Characteristics>>;
|
|
133
|
-
//#endregion
|
|
134
|
-
export { ArcjetBun, ArcjetOptions, type ProxyService, RemoteClientOptions, cloudflare, createRemoteClient, arcjet as default };
|
package/dist/index.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { cloudflare, findIp, parseProxies } from "@arcjet/ip";
|
|
2
|
-
import core from "arcjet";
|
|
3
|
-
import { readBodyWeb } from "@arcjet/body";
|
|
4
|
-
import { baseUrl, isDevelopment, logLevel, platform } from "@arcjet/env";
|
|
5
|
-
import { ArcjetHeaders } from "@arcjet/headers";
|
|
6
|
-
import { Logger } from "@arcjet/logger";
|
|
7
|
-
import { createClient } from "@arcjet/protocol/client.js";
|
|
8
|
-
import { createTransport } from "@arcjet/transport";
|
|
9
|
-
import { env } from "bun";
|
|
10
|
-
export * from "arcjet";
|
|
11
|
-
//#region src/index.ts
|
|
12
|
-
/** SDK version. Updated by the release process. */
|
|
13
|
-
const VERSION = "1.7.0-rc.1";
|
|
14
|
-
let warnedForAutomaticBodyRead = false;
|
|
15
|
-
/**
|
|
16
|
-
* Create a remote client.
|
|
17
|
-
*
|
|
18
|
-
* @param options
|
|
19
|
-
* Configuration (optional).
|
|
20
|
-
* @returns
|
|
21
|
-
* Client.
|
|
22
|
-
*/
|
|
23
|
-
function createRemoteClient(options) {
|
|
24
|
-
const url = options?.baseUrl ?? baseUrl(env);
|
|
25
|
-
const timeout = options?.timeout ?? (isDevelopment(env) ? 1e3 : 500);
|
|
26
|
-
return createClient({
|
|
27
|
-
transport: createTransport(url),
|
|
28
|
-
baseUrl: url,
|
|
29
|
-
timeout,
|
|
30
|
-
sdkStack: "BUN",
|
|
31
|
-
sdkVersion: VERSION
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Create a new Bun integration of Arcjet.
|
|
36
|
-
*
|
|
37
|
-
* @template Rules
|
|
38
|
-
* List of rules.
|
|
39
|
-
* @template Characteristics
|
|
40
|
-
* Characteristics to track a user by.
|
|
41
|
-
* @param options
|
|
42
|
-
* Configuration.
|
|
43
|
-
* @returns
|
|
44
|
-
* Bun integration of Arcjet.
|
|
45
|
-
*/
|
|
46
|
-
function arcjet(options) {
|
|
47
|
-
const client = options.client ?? createRemoteClient();
|
|
48
|
-
const ipCache = /* @__PURE__ */ new WeakMap();
|
|
49
|
-
const log = options.log ? options.log : new Logger({ level: logLevel(env) });
|
|
50
|
-
const proxies = Array.isArray(options.proxies) ? parseProxies(options.proxies) : void 0;
|
|
51
|
-
if (isDevelopment(env)) log.warn("Arcjet will use 127.0.0.1 when missing public IP address in development mode");
|
|
52
|
-
function toArcjetRequest(request, props) {
|
|
53
|
-
const cookies = request.headers.get("cookie") ?? "";
|
|
54
|
-
const headers = new ArcjetHeaders(request.headers);
|
|
55
|
-
const url = new URL(request.url);
|
|
56
|
-
let ip = (isDevelopment(env) ? headers.get("x-arcjet-ip") : void 0) || findIp({
|
|
57
|
-
ip: ipCache.get(request),
|
|
58
|
-
headers
|
|
59
|
-
}, {
|
|
60
|
-
platform: platform(env),
|
|
61
|
-
proxies
|
|
62
|
-
});
|
|
63
|
-
if (ip === "") if (isDevelopment(env)) ip = "127.0.0.1";
|
|
64
|
-
else log.warn(`Client IP address is missing. If this is a dev environment set the ARCJET_ENV env var to "development"`);
|
|
65
|
-
return {
|
|
66
|
-
...props,
|
|
67
|
-
ip,
|
|
68
|
-
method: request.method,
|
|
69
|
-
protocol: url.protocol,
|
|
70
|
-
host: url.host,
|
|
71
|
-
path: url.pathname,
|
|
72
|
-
headers,
|
|
73
|
-
cookies,
|
|
74
|
-
query: url.search
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
function withClient(aj) {
|
|
78
|
-
return Object.freeze({
|
|
79
|
-
withRule(rule) {
|
|
80
|
-
return withClient(aj.withRule(rule));
|
|
81
|
-
},
|
|
82
|
-
async protect(request, props) {
|
|
83
|
-
const { correlationId, ...properties } = props ?? {};
|
|
84
|
-
const req = toArcjetRequest(request, properties || {});
|
|
85
|
-
const getBody = async () => {
|
|
86
|
-
if (request.bodyUsed) throw new Error("Cannot read body: already read");
|
|
87
|
-
const clonedRequest = request.clone();
|
|
88
|
-
let expectedLength;
|
|
89
|
-
const expectedLengthString = request.headers.get("content-length");
|
|
90
|
-
if (typeof expectedLengthString === "string") expectedLength = parseInt(expectedLengthString, 10);
|
|
91
|
-
if (!clonedRequest.body) throw new Error("Cannot read body: body is missing");
|
|
92
|
-
if (!warnedForAutomaticBodyRead) {
|
|
93
|
-
warnedForAutomaticBodyRead = true;
|
|
94
|
-
log.warn("Automatically reading the request body is deprecated; please pass an explicit `sensitiveInfoValue` field. See <https://docs.arcjet.com/upgrading/sdk-migration>.");
|
|
95
|
-
}
|
|
96
|
-
return readBodyWeb(clonedRequest.body, { expectedLength });
|
|
97
|
-
};
|
|
98
|
-
return aj.protect({ getBody }, {
|
|
99
|
-
...req,
|
|
100
|
-
correlationId
|
|
101
|
-
});
|
|
102
|
-
},
|
|
103
|
-
handler(fetch) {
|
|
104
|
-
return async function(request, server) {
|
|
105
|
-
const socketAddress = server.requestIP(request);
|
|
106
|
-
if (socketAddress) ipCache.set(request, socketAddress.address);
|
|
107
|
-
return fetch.call(server, request, server);
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
return withClient(core({
|
|
113
|
-
...options,
|
|
114
|
-
client,
|
|
115
|
-
log
|
|
116
|
-
}));
|
|
117
|
-
}
|
|
118
|
-
//#endregion
|
|
119
|
-
export { cloudflare, createRemoteClient, arcjet as default };
|