@arcjet/astro 1.0.0-beta.9 → 1.1.0-rc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -166
- package/index.d.ts +285 -30
- package/index.js +329 -51
- package/internal.d.ts +84 -26
- package/internal.js +52 -49
- package/package.json +18 -17
package/internal.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import core__default from 'arcjet';
|
|
2
2
|
export * from 'arcjet';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
3
|
+
import { readBodyWeb } from '@arcjet/body';
|
|
4
|
+
import findIp, { parseProxy } from '@arcjet/ip';
|
|
5
|
+
import { ArcjetHeaders } from '@arcjet/headers';
|
|
6
|
+
import { logLevel, isDevelopment, baseUrl, platform } from '@arcjet/env';
|
|
6
7
|
import { Logger } from '@arcjet/logger';
|
|
7
8
|
import { createClient } from '@arcjet/protocol/client.js';
|
|
8
9
|
import { createTransport } from '@arcjet/transport';
|
|
9
|
-
import { VERCEL, FLY_APP_NAME, ARCJET_LOG_LEVEL, ARCJET_KEY, ARCJET_ENV, ARCJET_BASE_URL } from 'astro:env/server';
|
|
10
|
+
import { VERCEL, RENDER, FLY_APP_NAME, FIREBASE_CONFIG, ARCJET_LOG_LEVEL, ARCJET_KEY, ARCJET_ENV, ARCJET_BASE_URL } from 'astro:env/server';
|
|
10
11
|
|
|
12
|
+
let warnedForAutomaticBodyRead = false;
|
|
11
13
|
// We use a middleware to store the IP address on a `Request` with this symbol.
|
|
12
14
|
// This is due to Astro inconsistently using `Symbol.for("astro.clientAddress")`
|
|
13
15
|
// to store the client address and not exporting it from their module.
|
|
@@ -17,36 +19,28 @@ const env = {
|
|
|
17
19
|
ARCJET_ENV,
|
|
18
20
|
ARCJET_KEY,
|
|
19
21
|
ARCJET_LOG_LEVEL,
|
|
22
|
+
FIREBASE_CONFIG,
|
|
20
23
|
FLY_APP_NAME,
|
|
21
|
-
VERCEL,
|
|
22
24
|
// `MODE` is only set on `import.meta.env`.
|
|
23
25
|
MODE: import.meta.env.MODE,
|
|
26
|
+
RENDER,
|
|
27
|
+
VERCEL,
|
|
24
28
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
typeof err.message === "string") {
|
|
34
|
-
return err.message;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return "Unknown problem";
|
|
38
|
-
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a remote client.
|
|
31
|
+
*
|
|
32
|
+
* @param options
|
|
33
|
+
* Configuration (optional).
|
|
34
|
+
* @returns
|
|
35
|
+
* Client.
|
|
36
|
+
*/
|
|
39
37
|
function createRemoteClient(options) {
|
|
40
|
-
// The base URL for the Arcjet API. Will default to the standard production
|
|
41
|
-
// API unless environment variable `ARCJET_BASE_URL` is set.
|
|
42
38
|
const url = options?.baseUrl ?? baseUrl(env);
|
|
43
|
-
// The timeout for the Arcjet API in milliseconds. This is set to a low value
|
|
44
|
-
// in production so calls fail open.
|
|
45
39
|
const timeout = options?.timeout ?? (isDevelopment(env) ? 1000 : 500);
|
|
46
40
|
// Transport is the HTTP client that the client uses to make requests.
|
|
47
41
|
const transport = createTransport(url);
|
|
48
42
|
const sdkStack = "ASTRO";
|
|
49
|
-
const sdkVersion = "1.
|
|
43
|
+
const sdkVersion = "1.1.0-rc";
|
|
50
44
|
return createClient({
|
|
51
45
|
transport,
|
|
52
46
|
baseUrl: url,
|
|
@@ -56,12 +50,16 @@ function createRemoteClient(options) {
|
|
|
56
50
|
});
|
|
57
51
|
}
|
|
58
52
|
/**
|
|
59
|
-
* Create a new
|
|
60
|
-
* outside of a request handler so it persists across requests. If you need to
|
|
61
|
-
* augment a client inside a handler, call the `withRule()` function on the base
|
|
62
|
-
* client.
|
|
53
|
+
* Create a new Astro integration of Arcjet.
|
|
63
54
|
*
|
|
64
|
-
* @
|
|
55
|
+
* @template Rules
|
|
56
|
+
* List of rules.
|
|
57
|
+
* @template Characteristics
|
|
58
|
+
* Characteristics to track a user by.
|
|
59
|
+
* @param options
|
|
60
|
+
* Configuration.
|
|
61
|
+
* @returns
|
|
62
|
+
* Astro integration of Arcjet.
|
|
65
63
|
*/
|
|
66
64
|
function createArcjetClient(options) {
|
|
67
65
|
const client = options.client ?? createRemoteClient();
|
|
@@ -81,14 +79,15 @@ function createArcjetClient(options) {
|
|
|
81
79
|
if (!clientAddress) {
|
|
82
80
|
throw new Error("`protect()` cannot be used in prerendered pages");
|
|
83
81
|
}
|
|
84
|
-
const cookies = request.headers.get("cookie") ??
|
|
82
|
+
const cookies = request.headers.get("cookie") ?? "";
|
|
85
83
|
// We construct an ArcjetHeaders to normalize over Headers
|
|
86
84
|
const headers = new ArcjetHeaders(request.headers);
|
|
87
85
|
const url = new URL(request.url);
|
|
88
|
-
|
|
89
|
-
ip
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
const xArcjetIp = isDevelopment(env)
|
|
87
|
+
? headers.get("x-arcjet-ip")
|
|
88
|
+
: undefined;
|
|
89
|
+
let ip = xArcjetIp ||
|
|
90
|
+
findIp({ ip: clientAddress, headers }, { platform: platform(env), proxies });
|
|
92
91
|
if (ip === "") {
|
|
93
92
|
// If the `ip` is empty but we're in development mode, we default the IP
|
|
94
93
|
// so the request doesn't fail.
|
|
@@ -112,31 +111,35 @@ function createArcjetClient(options) {
|
|
|
112
111
|
};
|
|
113
112
|
}
|
|
114
113
|
function withClient(aj) {
|
|
115
|
-
|
|
114
|
+
const client = {
|
|
116
115
|
withRule(rule) {
|
|
117
116
|
const client = aj.withRule(rule);
|
|
118
117
|
return withClient(client);
|
|
119
118
|
},
|
|
120
|
-
async protect(request,
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
// the definition of `props` in the signature but it's hard to track down
|
|
124
|
-
const req = toArcjetRequest(request, props ?? {});
|
|
119
|
+
async protect(request, props) {
|
|
120
|
+
// Cast of `{}` because here we switch from `undefined` to `Properties`.
|
|
121
|
+
const req = toArcjetRequest(request, props || {});
|
|
125
122
|
const getBody = async () => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
const clonedRequest = request.clone();
|
|
124
|
+
let expectedLength;
|
|
125
|
+
const expectedLengthString = request.headers.get("content-length");
|
|
126
|
+
if (typeof expectedLengthString === "string") {
|
|
127
|
+
expectedLength = parseInt(expectedLengthString, 10);
|
|
131
128
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
// HEAD and GET requests do not have a body.
|
|
130
|
+
if (!clonedRequest.body) {
|
|
131
|
+
throw new Error("Cannot read body: body is missing");
|
|
135
132
|
}
|
|
133
|
+
if (!warnedForAutomaticBodyRead) {
|
|
134
|
+
warnedForAutomaticBodyRead = true;
|
|
135
|
+
log.warn("Automatically reading the request body is deprecated; please pass an explicit `sensitiveInfoValue` field. See <https://docs.arcjet.com/upgrading/sdk-migration>.");
|
|
136
|
+
}
|
|
137
|
+
return readBodyWeb(clonedRequest.body, { expectedLength });
|
|
136
138
|
};
|
|
137
139
|
return aj.protect({ getBody }, req);
|
|
138
140
|
},
|
|
139
|
-
}
|
|
141
|
+
};
|
|
142
|
+
return Object.freeze(client);
|
|
140
143
|
}
|
|
141
144
|
const aj = core__default({ ...options, client, log });
|
|
142
145
|
return withClient(aj);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcjet/astro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0-rc",
|
|
4
4
|
"description": "Arcjet helps developers protect their Astro sites in just a few lines of code. Bot detection. Rate limiting. Email validation. Attack protection. Data redaction. A developer-first approach to security.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"analyze",
|
|
@@ -46,29 +46,30 @@
|
|
|
46
46
|
"scripts": {
|
|
47
47
|
"build": "rollup --config rollup.config.js",
|
|
48
48
|
"lint": "eslint .",
|
|
49
|
-
"
|
|
50
|
-
"test": "
|
|
49
|
+
"test-api": "node --test -- test/*.test.js",
|
|
50
|
+
"test-coverage": "node --experimental-test-coverage --test -- test/*.test.js",
|
|
51
|
+
"test": "npm run build && npm run lint && npm run test-coverage"
|
|
51
52
|
},
|
|
52
53
|
"dependencies": {
|
|
53
|
-
"@arcjet/
|
|
54
|
-
"@arcjet/
|
|
55
|
-
"@arcjet/
|
|
56
|
-
"@arcjet/
|
|
57
|
-
"@arcjet/
|
|
58
|
-
"@arcjet/
|
|
59
|
-
"arcjet": "1.
|
|
54
|
+
"@arcjet/body": "1.1.0-rc",
|
|
55
|
+
"@arcjet/env": "1.1.0-rc",
|
|
56
|
+
"@arcjet/headers": "1.1.0-rc",
|
|
57
|
+
"@arcjet/ip": "1.1.0-rc",
|
|
58
|
+
"@arcjet/logger": "1.1.0-rc",
|
|
59
|
+
"@arcjet/protocol": "1.1.0-rc",
|
|
60
|
+
"@arcjet/transport": "1.1.0-rc",
|
|
61
|
+
"arcjet": "1.1.0-rc"
|
|
60
62
|
},
|
|
61
63
|
"peerDependencies": {
|
|
62
64
|
"astro": "^5.9.3"
|
|
63
65
|
},
|
|
64
66
|
"devDependencies": {
|
|
65
|
-
"@arcjet/eslint-config": "1.
|
|
66
|
-
"@arcjet/rollup-config": "1.
|
|
67
|
-
"@
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"typescript": "5.8.3"
|
|
67
|
+
"@arcjet/eslint-config": "1.1.0-rc",
|
|
68
|
+
"@arcjet/rollup-config": "1.1.0-rc",
|
|
69
|
+
"@rollup/wasm-node": "4.57.0",
|
|
70
|
+
"astro": "5.16.15",
|
|
71
|
+
"eslint": "9.39.2",
|
|
72
|
+
"typescript": "5.9.3"
|
|
72
73
|
},
|
|
73
74
|
"publishConfig": {
|
|
74
75
|
"access": "public",
|