@arcjet/node 1.0.0-beta.16 → 1.0.0-beta.18

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.
Files changed (3) hide show
  1. package/index.d.ts +25 -15
  2. package/index.js +25 -59
  3. package/package.json +13 -13
package/index.d.ts CHANGED
@@ -4,12 +4,22 @@ type Simplify<T> = {
4
4
  [KeyType in keyof T]: T[KeyType];
5
5
  } & {};
6
6
  declare const emptyObjectSymbol: unique symbol;
7
- type WithoutCustomProps = {
8
- [emptyObjectSymbol]?: never;
9
- };
10
7
  type PlainObject = {
11
8
  [key: string]: unknown;
12
9
  };
10
+ /**
11
+ * Dynamically generate whether zero or one `properties` object must or can be passed.
12
+ */
13
+ type MaybeProperties<T> = {
14
+ [P in keyof T]?: T[P];
15
+ } extends T ? T extends {
16
+ [emptyObjectSymbol]?: never;
17
+ } ? [
18
+ ] : [
19
+ properties?: T
20
+ ] : [
21
+ properties: T
22
+ ];
13
23
  /**
14
24
  * Configuration for {@linkcode createRemoteClient}.
15
25
  */
@@ -47,30 +57,30 @@ export interface ArcjetNodeRequest {
47
57
  /**
48
58
  * Headers of the request.
49
59
  */
50
- headers?: Record<string, string | string[] | undefined>;
60
+ headers?: Record<string, string | string[] | undefined> | undefined;
51
61
  /**
52
62
  * `net.Socket` object associated with the connection.
53
63
  *
54
64
  * See <https://nodejs.org/api/http.html#messagesocket>.
55
65
  */
56
66
  socket?: Partial<{
57
- remoteAddress: string;
67
+ remoteAddress?: string | undefined;
58
68
  encrypted: boolean;
59
- }>;
69
+ }> | undefined;
60
70
  /**
61
71
  * HTTP method of the request.
62
72
  */
63
- method?: string;
73
+ method?: string | undefined;
64
74
  /**
65
75
  * HTTP version sent by the client.
66
76
  *
67
77
  * See <https://nodejs.org/api/http.html#messagehttpversion>.
68
78
  */
69
- httpVersion?: string;
79
+ httpVersion?: string | undefined;
70
80
  /**
71
81
  * URL.
72
82
  */
73
- url?: string;
83
+ url?: string | undefined;
74
84
  /**
75
85
  * Request body.
76
86
  */
@@ -82,7 +92,7 @@ export interface ArcjetNodeRequest {
82
92
  *
83
93
  * See <https://nodejs.org/api/events.html#emitteroneventname-listener>.
84
94
  */
85
- on?: EventHandlerLike;
95
+ on?: EventHandlerLike | undefined;
86
96
  /**
87
97
  * Remove event handlers.
88
98
  *
@@ -90,7 +100,7 @@ export interface ArcjetNodeRequest {
90
100
  *
91
101
  * See <https://nodejs.org/api/events.html#emitterremovelistenereventname-listener>.
92
102
  */
93
- removeListener?: EventHandlerLike;
103
+ removeListener?: EventHandlerLike | undefined;
94
104
  /**
95
105
  * Whether the readable stream is readable.
96
106
  *
@@ -98,7 +108,7 @@ export interface ArcjetNodeRequest {
98
108
  *
99
109
  * See <https://nodejs.org/api/stream.html#readablereadable>.
100
110
  */
101
- readable?: boolean;
111
+ readable?: boolean | undefined;
102
112
  }
103
113
  /**
104
114
  * Configuration for the Node.js integration of Arcjet.
@@ -140,7 +150,7 @@ export interface ArcjetNode<Props extends PlainObject> {
140
150
  * Promise that resolves to an {@linkcode ArcjetDecision} indicating
141
151
  * Arcjet’s decision about the request.
142
152
  */
143
- protect(request: ArcjetNodeRequest, ...props: Props extends WithoutCustomProps ? [] : [Props]): Promise<ArcjetDecision>;
153
+ protect(request: ArcjetNodeRequest, ...props: MaybeProperties<Props>): Promise<ArcjetDecision>;
144
154
  /**
145
155
  * Augment the client with another rule.
146
156
  *
@@ -154,7 +164,7 @@ export interface ArcjetNode<Props extends PlainObject> {
154
164
  * @returns
155
165
  * Arcjet instance augmented with the given rule.
156
166
  */
157
- withRule<Rule extends Primitive | Product>(rule: Rule): ArcjetNode<Simplify<Props & ExtraProps<Rule>>>;
167
+ withRule<ChildProperties extends PlainObject>(rule: Primitive<ChildProperties> | Product<ChildProperties>): ArcjetNode<Props & ChildProperties>;
158
168
  }
159
169
  /**
160
170
  * Create a new Node.js integration of Arcjet.
@@ -174,4 +184,4 @@ export interface ArcjetNode<Props extends PlainObject> {
174
184
  * @returns
175
185
  * Node.js integration of Arcjet.
176
186
  */
177
- export default function arcjet<const Rules extends (Primitive | Product)[], const Characteristics extends readonly string[]>(options: ArcjetOptions<Rules, Characteristics>): ArcjetNode<Simplify<ExtraProps<Rules> & CharacteristicProps<Characteristics>>>;
187
+ export default function arcjet<const Rules extends (Primitive | Product)[], const Characteristics extends readonly string[]>(options: ArcjetOptions<Rules, Characteristics>): ArcjetNode<ExtraProps<Rules> & CharacteristicProps<Characteristics>>;
package/index.js CHANGED
@@ -41,20 +41,7 @@ const env = {
41
41
  return process.env.FIREBASE_CONFIG;
42
42
  },
43
43
  };
44
- // TODO: Deduplicate with other packages
45
- function errorMessage(err) {
46
- if (err) {
47
- if (typeof err === "string") {
48
- return err;
49
- }
50
- if (typeof err === "object" &&
51
- "message" in err &&
52
- typeof err.message === "string") {
53
- return err.message;
54
- }
55
- }
56
- return "Unknown problem";
57
- }
44
+ let warnedForAutomaticBodyRead = false;
58
45
  /**
59
46
  * Create a remote client.
60
47
  *
@@ -69,7 +56,7 @@ function createRemoteClient(options) {
69
56
  // Transport is the HTTP client that the client uses to make requests.
70
57
  const transport = createTransport(url);
71
58
  const sdkStack = "NODEJS";
72
- const sdkVersion = "1.0.0-beta.16";
59
+ const sdkVersion = "1.0.0-beta.18";
73
60
  return createClient({
74
61
  transport,
75
62
  baseUrl: url,
@@ -186,62 +173,41 @@ function arcjet(options) {
186
173
  };
187
174
  }
188
175
  function withClient(aj) {
189
- return Object.freeze({
176
+ const client = {
190
177
  withRule(rule) {
191
178
  const client = aj.withRule(rule);
192
179
  return withClient(client);
193
180
  },
194
- async protect(request, ...[props]) {
195
- // TODO(#220): The generic manipulations get really mad here, so we cast
196
- // Further investigation makes it seem like it has something to do with
197
- // the definition of `props` in the signature but it's hard to track down
198
- const req = toArcjetRequest(request, props ?? {});
181
+ async protect(request, props) {
182
+ // Cast of `{}` because here we switch from `undefined` to `Properties`.
183
+ const req = toArcjetRequest(request, props || {});
199
184
  const getBody = async () => {
200
- try {
201
- // If request.body is present then the body was likely read by a package like express' `body-parser`.
202
- // If it's not present then we attempt to read the bytes from the IncomingMessage ourselves.
203
- if (typeof request.body === "string") {
204
- return request.body;
185
+ // Read the stream if the body is not present.
186
+ if (request.body === null || request.body === undefined) {
187
+ let expectedLength;
188
+ // TODO: This shouldn't need to build headers again but the type
189
+ // for `req` above is overly relaxed
190
+ const headers = new ArcjetHeaders(request.headers);
191
+ const expectedLengthStr = headers.get("content-length");
192
+ if (typeof expectedLengthStr === "string") {
193
+ expectedLength = parseInt(expectedLengthStr, 10);
205
194
  }
206
- else if (typeof request.body !== "undefined" &&
207
- // BigInt cannot be serialized with JSON.stringify
208
- typeof request.body !== "bigint") {
209
- return JSON.stringify(request.body);
195
+ if (!warnedForAutomaticBodyRead) {
196
+ warnedForAutomaticBodyRead = true;
197
+ log.warn("Automatically reading the request body is deprecated; please pass an explicit `sensitiveInfoValue` field. See <https://docs.arcjet.com/upgrading/sdk-migration>.");
210
198
  }
211
- if (typeof request.on === "function" &&
212
- typeof request.removeListener === "function") {
213
- let expectedLength;
214
- // TODO: This shouldn't need to build headers again but the type
215
- // for `req` above is overly relaxed
216
- const headers = new ArcjetHeaders(request.headers);
217
- const expectedLengthStr = headers.get("content-length");
218
- if (typeof expectedLengthStr === "string") {
219
- try {
220
- expectedLength = parseInt(expectedLengthStr, 10);
221
- }
222
- catch {
223
- // If the expected length couldn't be parsed we'll just not set one.
224
- }
225
- }
226
- // Awaited to throw if it rejects and we'll just return undefined
227
- const body = await readBody(request, {
228
- // We will process 1mb bodies
229
- limit: 1048576,
230
- expectedLength,
231
- });
232
- return body;
233
- }
234
- log.warn("no body available");
235
- return;
199
+ return readBody(request, { expectedLength });
236
200
  }
237
- catch (e) {
238
- log.error("failed to get request body: %s", errorMessage(e));
239
- return;
201
+ // A package like `body-parser` was used to read the stream.
202
+ if (typeof request.body === "string") {
203
+ return request.body;
240
204
  }
205
+ return JSON.stringify(request.body);
241
206
  };
242
207
  return aj.protect({ getBody }, req);
243
208
  },
244
- });
209
+ };
210
+ return Object.freeze(client);
245
211
  }
246
212
  const aj = core__default({ ...options, client, log });
247
213
  return withClient(aj);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcjet/node",
3
- "version": "1.0.0-beta.16",
3
+ "version": "1.0.0-beta.18",
4
4
  "description": "Arcjet SDK for Node.js",
5
5
  "keywords": [
6
6
  "analyze",
@@ -50,20 +50,20 @@
50
50
  "test": "npm run build && npm run lint && npm run test-coverage"
51
51
  },
52
52
  "dependencies": {
53
- "@arcjet/env": "1.0.0-beta.16",
54
- "@arcjet/headers": "1.0.0-beta.16",
55
- "@arcjet/ip": "1.0.0-beta.16",
56
- "@arcjet/logger": "1.0.0-beta.16",
57
- "@arcjet/protocol": "1.0.0-beta.16",
58
- "@arcjet/transport": "1.0.0-beta.16",
59
- "@arcjet/body": "1.0.0-beta.16",
60
- "arcjet": "1.0.0-beta.16"
53
+ "@arcjet/env": "1.0.0-beta.18",
54
+ "@arcjet/headers": "1.0.0-beta.18",
55
+ "@arcjet/ip": "1.0.0-beta.18",
56
+ "@arcjet/logger": "1.0.0-beta.18",
57
+ "@arcjet/protocol": "1.0.0-beta.18",
58
+ "@arcjet/transport": "1.0.0-beta.18",
59
+ "@arcjet/body": "1.0.0-beta.18",
60
+ "arcjet": "1.0.0-beta.18"
61
61
  },
62
62
  "devDependencies": {
63
- "@arcjet/eslint-config": "1.0.0-beta.16",
64
- "@arcjet/rollup-config": "1.0.0-beta.16",
65
- "@types/node": "25.0.3",
66
- "@rollup/wasm-node": "4.54.0",
63
+ "@arcjet/eslint-config": "1.0.0-beta.18",
64
+ "@arcjet/rollup-config": "1.0.0-beta.18",
65
+ "@types/node": "25.0.8",
66
+ "@rollup/wasm-node": "4.55.1",
67
67
  "eslint": "9.39.2",
68
68
  "typescript": "5.9.3"
69
69
  },