@arcjet/astro 1.6.1 → 1.7.0-rc.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 → dist/index.d.ts} +103 -101
- package/dist/index.js +584 -0
- package/dist/internal.d.ts +118 -0
- package/dist/internal.js +118 -0
- package/dist/middleware.d.ts +4 -0
- package/dist/middleware.js +9 -0
- package/package.json +42 -43
- package/index.js +0 -681
- package/internal.d.ts +0 -123
- package/internal.js +0 -148
- package/middleware.d.ts +0 -1
- package/middleware.js +0 -14
package/internal.d.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import type { ArcjetDecision, ArcjetOptions as CoreOptions, ArcjetRule, Primitive, Product, ExtraProps, CharacteristicProps } from "arcjet";
|
|
2
|
-
import { type ProxyService } from "@arcjet/ip";
|
|
3
|
-
export * from "arcjet";
|
|
4
|
-
type Simplify<T> = {
|
|
5
|
-
[KeyType in keyof T]: T[KeyType];
|
|
6
|
-
} & {};
|
|
7
|
-
declare const emptyObjectSymbol: unique symbol;
|
|
8
|
-
type PlainObject = {
|
|
9
|
-
[key: string]: unknown;
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* Dynamically generate whether zero or one `properties` object must or can be passed.
|
|
13
|
-
*/
|
|
14
|
-
type MaybeProperties<T> = {
|
|
15
|
-
[P in keyof T]?: T[P];
|
|
16
|
-
} extends T ? T extends {
|
|
17
|
-
[emptyObjectSymbol]?: never;
|
|
18
|
-
} ? [
|
|
19
|
-
] : [
|
|
20
|
-
properties?: T
|
|
21
|
-
] : [
|
|
22
|
-
properties: T
|
|
23
|
-
];
|
|
24
|
-
/**
|
|
25
|
-
* Configuration for {@linkcode createRemoteClient}.
|
|
26
|
-
*/
|
|
27
|
-
export type RemoteClientOptions = {
|
|
28
|
-
/**
|
|
29
|
-
* Base URI for HTTP requests to Decide API (optional).
|
|
30
|
-
*
|
|
31
|
-
* Defaults to the environment variable `ARCJET_BASE_URL` (if that value
|
|
32
|
-
* is known and allowed) and the standard production API otherwise.
|
|
33
|
-
*/
|
|
34
|
-
baseUrl?: string;
|
|
35
|
-
/**
|
|
36
|
-
* Timeout in milliseconds for the Decide API (optional).
|
|
37
|
-
*
|
|
38
|
-
* Defaults to `500` in production and `1000` in development.
|
|
39
|
-
*/
|
|
40
|
-
timeout?: number;
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Create a remote client.
|
|
44
|
-
*
|
|
45
|
-
* @param options
|
|
46
|
-
* Configuration (optional).
|
|
47
|
-
* @returns
|
|
48
|
-
* Client.
|
|
49
|
-
*/
|
|
50
|
-
export declare function createRemoteClient(options?: RemoteClientOptions): import("@arcjet/protocol/client.js").Client;
|
|
51
|
-
/**
|
|
52
|
-
* Configuration for the Astro integration of Arcjet.
|
|
53
|
-
*
|
|
54
|
-
* @template Rules
|
|
55
|
-
* List of rules.
|
|
56
|
-
* @template Characteristics
|
|
57
|
-
* Characteristics to track a user by.
|
|
58
|
-
*/
|
|
59
|
-
export type ArcjetOptions<Rules extends [...Array<Primitive | Product>], Characteristics extends readonly string[]> = Simplify<CoreOptions<Rules, Characteristics> & {
|
|
60
|
-
/**
|
|
61
|
-
* IP addresses and CIDR ranges of trusted load balancers and proxies
|
|
62
|
-
* (optional, example: `["100.100.100.100", "100.100.100.0/24"]`).
|
|
63
|
-
*
|
|
64
|
-
* Proxy services such as {@linkcode cloudflare} can also be included to read
|
|
65
|
-
* the real client IP from a service-specific header when the request comes
|
|
66
|
-
* from that service.
|
|
67
|
-
*/
|
|
68
|
-
proxies?: Array<string | ProxyService>;
|
|
69
|
-
}>;
|
|
70
|
-
/**
|
|
71
|
-
* Instance of the Astro integration of Arcjet.
|
|
72
|
-
*
|
|
73
|
-
* Primarily has a `protect()` method to make a decision about how a request
|
|
74
|
-
* should be handled.
|
|
75
|
-
*
|
|
76
|
-
* @template Props
|
|
77
|
-
* Configuration.
|
|
78
|
-
*/
|
|
79
|
-
export interface ArcjetAstro<Props extends PlainObject> {
|
|
80
|
-
/**
|
|
81
|
-
* Make a decision about how to handle a request.
|
|
82
|
-
*
|
|
83
|
-
* This will analyze the request locally where possible and otherwise call
|
|
84
|
-
* the Arcjet decision API.
|
|
85
|
-
*
|
|
86
|
-
* @param ctx
|
|
87
|
-
* Additional context for this function call.
|
|
88
|
-
* @param request
|
|
89
|
-
* Details about the {@linkcode ArcjetRequest} that Arcjet needs to make a
|
|
90
|
-
* decision.
|
|
91
|
-
* @returns
|
|
92
|
-
* Promise that resolves to an {@linkcode ArcjetDecision} indicating
|
|
93
|
-
* Arcjet’s decision about the request.
|
|
94
|
-
*/
|
|
95
|
-
protect(request: Request, ...props: MaybeProperties<Props>): Promise<ArcjetDecision>;
|
|
96
|
-
/**
|
|
97
|
-
* Augment the client with another rule.
|
|
98
|
-
*
|
|
99
|
-
* Useful for varying rules based on criteria in your handler such as
|
|
100
|
-
* different rate limit for logged in users.
|
|
101
|
-
*
|
|
102
|
-
* @template Rule
|
|
103
|
-
* Type of rule.
|
|
104
|
-
* @param rule
|
|
105
|
-
* Rule to add to Arcjet.
|
|
106
|
-
* @returns
|
|
107
|
-
* Arcjet instance augmented with the given rule.
|
|
108
|
-
*/
|
|
109
|
-
withRule<Rule extends ArcjetRule>(rule: Array<Rule>): ArcjetAstro<Props & (Rule extends ArcjetRule<infer P> ? P : {})>;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Create a new Astro integration of Arcjet.
|
|
113
|
-
*
|
|
114
|
-
* @template Rules
|
|
115
|
-
* List of rules.
|
|
116
|
-
* @template Characteristics
|
|
117
|
-
* Characteristics to track a user by.
|
|
118
|
-
* @param options
|
|
119
|
-
* Configuration.
|
|
120
|
-
* @returns
|
|
121
|
-
* Astro integration of Arcjet.
|
|
122
|
-
*/
|
|
123
|
-
export declare function createArcjetClient<const Rules extends (Primitive | Product)[], const Characteristics extends readonly string[]>(options: ArcjetOptions<Rules, Characteristics>): ArcjetAstro<ExtraProps<Rules> & CharacteristicProps<Characteristics>>;
|
package/internal.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import core__default from 'arcjet';
|
|
2
|
-
export * from 'arcjet';
|
|
3
|
-
import { readBodyWeb } from '@arcjet/body';
|
|
4
|
-
import { parseProxies, findIp } from '@arcjet/ip';
|
|
5
|
-
import { ArcjetHeaders } from '@arcjet/headers';
|
|
6
|
-
import { logLevel, isDevelopment, baseUrl, platform } from '@arcjet/env';
|
|
7
|
-
import { Logger } from '@arcjet/logger';
|
|
8
|
-
import { createClient } from '@arcjet/protocol/client.js';
|
|
9
|
-
import { createTransport } from '@arcjet/transport';
|
|
10
|
-
import { VERCEL, RENDER, FLY_APP_NAME, FIREBASE_CONFIG, ARCJET_LOG_LEVEL, ARCJET_KEY, ARCJET_ENV, ARCJET_BASE_URL } from 'astro:env/server';
|
|
11
|
-
|
|
12
|
-
let warnedForAutomaticBodyRead = false;
|
|
13
|
-
// We use a middleware to store the IP address on a `Request` with this symbol.
|
|
14
|
-
// This is due to Astro inconsistently using `Symbol.for("astro.clientAddress")`
|
|
15
|
-
// to store the client address and not exporting it from their module.
|
|
16
|
-
const ipSymbol = Symbol.for("arcjet.ip");
|
|
17
|
-
const env = {
|
|
18
|
-
ARCJET_BASE_URL,
|
|
19
|
-
ARCJET_ENV,
|
|
20
|
-
ARCJET_KEY,
|
|
21
|
-
ARCJET_LOG_LEVEL,
|
|
22
|
-
FIREBASE_CONFIG,
|
|
23
|
-
FLY_APP_NAME,
|
|
24
|
-
// `MODE` is only set on `import.meta.env`.
|
|
25
|
-
MODE: import.meta.env.MODE,
|
|
26
|
-
RENDER,
|
|
27
|
-
VERCEL,
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Create a remote client.
|
|
31
|
-
*
|
|
32
|
-
* @param options
|
|
33
|
-
* Configuration (optional).
|
|
34
|
-
* @returns
|
|
35
|
-
* Client.
|
|
36
|
-
*/
|
|
37
|
-
function createRemoteClient(options) {
|
|
38
|
-
const url = options?.baseUrl ?? baseUrl(env);
|
|
39
|
-
const timeout = options?.timeout ?? (isDevelopment(env) ? 1000 : 500);
|
|
40
|
-
// Transport is the HTTP client that the client uses to make requests.
|
|
41
|
-
const transport = createTransport(url);
|
|
42
|
-
const sdkStack = "ASTRO";
|
|
43
|
-
const sdkVersion = "1.6.1";
|
|
44
|
-
return createClient({
|
|
45
|
-
transport,
|
|
46
|
-
baseUrl: url,
|
|
47
|
-
timeout,
|
|
48
|
-
sdkStack,
|
|
49
|
-
sdkVersion,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Create a new Astro integration of Arcjet.
|
|
54
|
-
*
|
|
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.
|
|
63
|
-
*/
|
|
64
|
-
function createArcjetClient(options) {
|
|
65
|
-
const client = options.client ?? createRemoteClient();
|
|
66
|
-
const log = options.log
|
|
67
|
-
? options.log
|
|
68
|
-
: new Logger({
|
|
69
|
-
level: logLevel(env),
|
|
70
|
-
});
|
|
71
|
-
const proxies = Array.isArray(options.proxies)
|
|
72
|
-
? parseProxies(options.proxies)
|
|
73
|
-
: undefined;
|
|
74
|
-
if (isDevelopment(process.env)) {
|
|
75
|
-
log.warn("Arcjet will use 127.0.0.1 when missing public IP address in development mode");
|
|
76
|
-
}
|
|
77
|
-
function toArcjetRequest(request, props) {
|
|
78
|
-
const clientAddress = Reflect.get(request, ipSymbol);
|
|
79
|
-
if (!clientAddress) {
|
|
80
|
-
throw new Error("`protect()` cannot be used in prerendered pages");
|
|
81
|
-
}
|
|
82
|
-
const cookies = request.headers.get("cookie") ?? "";
|
|
83
|
-
// We construct an ArcjetHeaders to normalize over Headers
|
|
84
|
-
const headers = new ArcjetHeaders(request.headers);
|
|
85
|
-
const url = new URL(request.url);
|
|
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 });
|
|
91
|
-
if (ip === "") {
|
|
92
|
-
// If the `ip` is empty but we're in development mode, we default the IP
|
|
93
|
-
// so the request doesn't fail.
|
|
94
|
-
if (isDevelopment(env)) {
|
|
95
|
-
ip = "127.0.0.1";
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
log.warn(`Client IP address is missing. If this is a dev environment set the ARCJET_ENV env var to "development"`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return {
|
|
102
|
-
...props,
|
|
103
|
-
ip,
|
|
104
|
-
method: request.method,
|
|
105
|
-
protocol: url.protocol,
|
|
106
|
-
host: url.host,
|
|
107
|
-
path: url.pathname,
|
|
108
|
-
headers,
|
|
109
|
-
cookies,
|
|
110
|
-
query: url.search,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function withClient(aj) {
|
|
114
|
-
const client = {
|
|
115
|
-
withRule(rule) {
|
|
116
|
-
const client = aj.withRule(rule);
|
|
117
|
-
return withClient(client);
|
|
118
|
-
},
|
|
119
|
-
async protect(request, props) {
|
|
120
|
-
// Cast of `{}` because here we switch from `undefined` to `Properties`.
|
|
121
|
-
const req = toArcjetRequest(request, props || {});
|
|
122
|
-
const getBody = async () => {
|
|
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);
|
|
128
|
-
}
|
|
129
|
-
// HEAD and GET requests do not have a body.
|
|
130
|
-
if (!clonedRequest.body) {
|
|
131
|
-
throw new Error("Cannot read body: body is missing");
|
|
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 });
|
|
138
|
-
};
|
|
139
|
-
return aj.protect({ getBody }, req);
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
return Object.freeze(client);
|
|
143
|
-
}
|
|
144
|
-
const aj = core__default({ ...options, client, log });
|
|
145
|
-
return withClient(aj);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export { createArcjetClient, createRemoteClient };
|
package/middleware.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const onRequest: import("astro").MiddlewareHandler;
|
package/middleware.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineMiddleware } from 'astro/middleware';
|
|
2
|
-
|
|
3
|
-
// We use a middleware to store the IP address on a `Request` with this symbol.
|
|
4
|
-
// This is due to Astro inconsistently using `Symbol.for("astro.clientAddress")`
|
|
5
|
-
// to store the client address and not exporting it from their module.
|
|
6
|
-
const ipSymbol = Symbol.for("arcjet.ip");
|
|
7
|
-
const onRequest = defineMiddleware((ctx, next) => {
|
|
8
|
-
if (!ctx.isPrerendered) {
|
|
9
|
-
Reflect.set(ctx.request, ipSymbol, ctx.clientAddress);
|
|
10
|
-
}
|
|
11
|
-
return next();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
export { onRequest };
|