diff --git a/arcjet/index.ts b/arcjet/index.ts index 301beb228..7c81d5165 100644 --- a/arcjet/index.ts +++ b/arcjet/index.ts @@ -4,6 +4,7 @@ import type { ArcjetBotRule, ArcjetRule, ArcjetLocalRule, + ArcjetMode, ArcjetRequestDetails, ArcjetTokenBucketRateLimitRule, ArcjetFixedWindowRateLimitRule, @@ -14,16 +15,15 @@ import type { ArcjetIdentifiedEntity, ArcjetWellKnownBot, ArcjetBotCategory, + ArcjetEmailType, + ArcjetSensitiveInfoType, } from "@arcjet/protocol"; import { ArcjetBotReason, ArcjetEmailReason, - ArcjetEmailType, ArcjetErrorReason, - ArcjetMode, ArcjetReason, ArcjetRuleResult, - ArcjetSensitiveInfoType, ArcjetSensitiveInfoReason, ArcjetDecision, ArcjetDenyDecision, diff --git a/arcjet/test/arcjet.test.ts b/arcjet/test/arcjet.test.ts index 733fbd2ec..a421c82f9 100644 --- a/arcjet/test/arcjet.test.ts +++ b/arcjet/test/arcjet.test.ts @@ -3,11 +3,9 @@ import { expect } from "expect"; import type { ArcjetRule, ArcjetLocalRule, Primitive, Arcjet } from "../index"; import arcjet, { - ArcjetMode, detectBot, validateEmail, protectSignup, - ArcjetEmailType, ArcjetAllowDecision, ArcjetDenyDecision, ArcjetErrorDecision, @@ -481,10 +479,6 @@ describe("Primitive > detectBot", () => { }); test("denies curl", async () => { - const options = { - mode: ArcjetMode.LIVE, - allow: [], - }; const context = { key: "test-key", fingerprint: "test-fingerprint", @@ -507,7 +501,10 @@ describe("Primitive > detectBot", () => { }, }; - const [rule] = detectBot(options); + const [rule] = detectBot({ + mode: "LIVE", + allow: [], + }); expect(rule.type).toEqual("BOT"); assertIsLocalRule(rule); const result = await rule.protect(context, details); @@ -560,7 +557,7 @@ describe("Primitive > detectBot", () => { }; const [rule] = detectBot({ - mode: ArcjetMode.LIVE, + mode: "LIVE", deny: ["CURL"], }); expect(rule.type).toEqual("BOT"); @@ -613,7 +610,7 @@ describe("Primitive > detectBot", () => { }; const [rule] = detectBot({ - mode: ArcjetMode.LIVE, + mode: "LIVE", allow: ["CURL"], }); expect(rule.type).toEqual("BOT"); @@ -1302,17 +1299,9 @@ describe("Primitive > validateEmail", () => { }); test("allows specifying EmailTypes to deny", async () => { - const options = { - deny: [ - ArcjetEmailType.DISPOSABLE, - ArcjetEmailType.FREE, - ArcjetEmailType.NO_GRAVATAR, - ArcjetEmailType.NO_MX_RECORDS, - ArcjetEmailType.INVALID, - ], - }; - - const [rule] = validateEmail(options); + const [rule] = validateEmail({ + deny: ["DISPOSABLE", "FREE", "NO_GRAVATAR", "NO_MX_RECORDS", "INVALID"], + }); expect(rule.type).toEqual("EMAIL"); expect(rule).toHaveProperty("deny", [ "DISPOSABLE", @@ -1324,17 +1313,9 @@ describe("Primitive > validateEmail", () => { }); test("allows specifying EmailTypes to block and maps these to deny", async () => { - const options = { - block: [ - ArcjetEmailType.DISPOSABLE, - ArcjetEmailType.FREE, - ArcjetEmailType.NO_GRAVATAR, - ArcjetEmailType.NO_MX_RECORDS, - ArcjetEmailType.INVALID, - ], - }; - - const [rule] = validateEmail(options); + const [rule] = validateEmail({ + block: ["DISPOSABLE", "FREE", "NO_GRAVATAR", "NO_MX_RECORDS", "INVALID"], + }); expect(rule.type).toEqual("EMAIL"); expect(rule).toHaveProperty("deny", [ "DISPOSABLE", @@ -1346,17 +1327,9 @@ describe("Primitive > validateEmail", () => { }); test("allows specifying EmailTypes to allow", async () => { - const options = { - allow: [ - ArcjetEmailType.DISPOSABLE, - ArcjetEmailType.FREE, - ArcjetEmailType.NO_GRAVATAR, - ArcjetEmailType.NO_MX_RECORDS, - ArcjetEmailType.INVALID, - ], - }; - - const [rule] = validateEmail(options); + const [rule] = validateEmail({ + allow: ["DISPOSABLE", "FREE", "NO_GRAVATAR", "NO_MX_RECORDS", "INVALID"], + }); expect(rule.type).toEqual("EMAIL"); expect(rule).toHaveProperty("allow", [ "DISPOSABLE", @@ -2404,18 +2377,18 @@ describe("Products > protectSignup", () => { test("allows configuration of rateLimit, bot, and email", () => { const rules = protectSignup({ rateLimit: { - mode: ArcjetMode.DRY_RUN, + mode: "DRY_RUN", characteristics: ["ip.src"], interval: 60 /* minutes */ * 60 /* seconds */, max: 1, }, bots: { - mode: ArcjetMode.DRY_RUN, + mode: "DRY_RUN", allow: [], }, email: { allow: [], - mode: ArcjetMode.LIVE, + mode: "LIVE", }, }); expect(rules.length).toEqual(3); @@ -2425,7 +2398,7 @@ describe("Products > protectSignup", () => { describe("SDK", () => { function testRuleLocalAllowed() { return { - mode: ArcjetMode.LIVE, + mode: "LIVE", type: "TEST_RULE_LOCAL_ALLOWED", priority: 1, validate: mock.fn(), @@ -2438,11 +2411,11 @@ describe("SDK", () => { reason: new ArcjetTestReason(), }), ), - }; + } as const; } function testRuleLocalDenied() { return { - mode: ArcjetMode.LIVE, + mode: "LIVE", type: "TEST_RULE_LOCAL_DENIED", priority: 1, validate: mock.fn(), @@ -2455,16 +2428,16 @@ describe("SDK", () => { reason: new ArcjetTestReason(), }), ), - }; + } as const; } function testRuleLocalIncorrect() { return { - mode: ArcjetMode.LIVE, + mode: "LIVE", type: "TEST_RULE_LOCAL_INCORRECT", priority: 1, validate: mock.fn(), protect: mock.fn(async () => undefined), - }; + } as const; } function testRuleRemote(): ArcjetRule { @@ -2485,7 +2458,7 @@ describe("SDK", () => { function testRuleInvalidType(): ArcjetRule { return { - mode: ArcjetMode.LIVE, + mode: "LIVE", type: "TEST_RULE_INVALID_TYPE", priority: 1, }; @@ -2493,19 +2466,19 @@ describe("SDK", () => { function testRuleLocalThrow() { return { - mode: ArcjetMode.LIVE, + mode: "LIVE", type: "TEST_RULE_LOCAL_THROW", priority: 1, validate: mock.fn(), protect: mock.fn(async () => { throw new Error("Local rule protect failed"); }), - }; + } as const; } function testRuleLocalDryRun() { return { - mode: ArcjetMode.DRY_RUN, + mode: "DRY_RUN", type: "TEST_RULE_LOCAL_DRY_RUN", priority: 1, validate: mock.fn(), @@ -2517,7 +2490,7 @@ describe("SDK", () => { reason: new ArcjetTestReason(), }); }), - }; + } as const; } function testRuleProps(): Primitive<{ abc: number }> { @@ -3688,7 +3661,7 @@ describe("SDK", () => { function testRuleLocalThrowString(): ArcjetLocalRule { return { - mode: ArcjetMode.LIVE, + mode: "LIVE", type: "TEST_RULE_LOCAL_THROW_STRING", priority: 1, validate: mock.fn(), @@ -3745,7 +3718,7 @@ describe("SDK", () => { function testRuleLocalThrowNull(): ArcjetLocalRule { return { - mode: ArcjetMode.LIVE, + mode: "LIVE", type: "TEST_RULE_LOCAL_THROW_NULL", priority: 1, validate: mock.fn(), diff --git a/protocol/client.ts b/protocol/client.ts index 13728079a..0dee26134 100644 --- a/protocol/client.ts +++ b/protocol/client.ts @@ -10,8 +10,9 @@ import type { ArcjetContext, ArcjetRequestDetails, ArcjetRule, + ArcjetStack, } from "./index.js"; -import { ArcjetDecision, ArcjetStack } from "./index.js"; +import { ArcjetDecision } from "./index.js"; import { DecideService } from "./proto/decide/v1alpha1/decide_connect.js"; import { DecideRequest, diff --git a/protocol/convert.ts b/protocol/convert.ts index 47d922815..3e25e578a 100644 --- a/protocol/convert.ts +++ b/protocol/convert.ts @@ -3,7 +3,12 @@ import type { ArcjetRule, ArcjetRateLimitRule, ArcjetBotRule, + ArcjetConclusion, ArcjetEmailRule, + ArcjetEmailType, + ArcjetMode, + ArcjetRuleState, + ArcjetStack, ArcjetTokenBucketRateLimitRule, ArcjetFixedWindowRateLimitRule, ArcjetSlidingWindowRateLimitRule, @@ -22,13 +27,8 @@ import { ArcjetRateLimitReason, ArcjetRuleResult, ArcjetShieldReason, - ArcjetConclusion, ArcjetDecision, - ArcjetEmailType, - ArcjetMode, ArcjetReason, - ArcjetRuleState, - ArcjetStack, ArcjetIpDetails, ArcjetSensitiveInfoReason, } from "./index.js"; diff --git a/protocol/index.ts b/protocol/index.ts index 01d9b432b..e441a87eb 100644 --- a/protocol/index.ts +++ b/protocol/index.ts @@ -9,12 +9,15 @@ export { categories as botCategories } from "./well-known-bots.js"; type RequiredProps = Required> & Omit; -type ArcjetEnum = { readonly [Key in T]: T }; - export type ArcjetMode = "LIVE" | "DRY_RUN"; -/** @deprecated use equivalent string union type instead */ -export const ArcjetMode: ArcjetEnum = Object.freeze({ +export const ArcjetMode = Object.freeze({ + /** + * @deprecated Use the string `"LIVE"` instead. + **/ LIVE: "LIVE", + /** + * @deprecated Use the string `"DRY_RUN"` instead. + **/ DRY_RUN: "DRY_RUN", }); @@ -22,13 +25,20 @@ export type ArcjetRateLimitAlgorithm = | "TOKEN_BUCKET" | "FIXED_WINDOW" | "SLIDING_WINDOW"; -/** @deprecated use equivalent string union type instead */ -export const ArcjetRateLimitAlgorithm: ArcjetEnum = - Object.freeze({ - TOKEN_BUCKET: "TOKEN_BUCKET", - FIXED_WINDOW: "FIXED_WINDOW", - SLIDING_WINDOW: "SLIDING_WINDOW", - }); +export const ArcjetRateLimitAlgorithm = Object.freeze({ + /** + * @deprecated Use the string `"TOKEN_BUCKET"` instead. + **/ + TOKEN_BUCKET: "TOKEN_BUCKET", + /** + * @deprecated Use the string `"FIXED_WINDOW"` instead. + **/ + FIXED_WINDOW: "FIXED_WINDOW", + /** + * @deprecated Use the string `"SLIDING_WINDOW"` instead. + **/ + SLIDING_WINDOW: "SLIDING_WINDOW", +}); export type ArcjetEmailType = | "DISPOSABLE" @@ -36,14 +46,28 @@ export type ArcjetEmailType = | "NO_MX_RECORDS" | "NO_GRAVATAR" | "INVALID"; -/** @deprecated use equivalent string union type instead */ -export const ArcjetEmailType: ArcjetEnum = { +export const ArcjetEmailType = Object.freeze({ + /** + * @deprecated Use the string `"DISPOSABLE"` instead. + **/ DISPOSABLE: "DISPOSABLE", + /** + * @deprecated Use the string `"FREE"` instead. + **/ FREE: "FREE", + /** + * @deprecated Use the string `"NO_MX_RECORDS"` instead. + **/ NO_MX_RECORDS: "NO_MX_RECORDS", + /** + * @deprecated Use the string `"NO_GRAVATAR"` instead. + **/ NO_GRAVATAR: "NO_GRAVATAR", + /** + * @deprecated Use the string `"INVALID"` instead. + **/ INVALID: "INVALID", -}; +}); export type ArcjetIdentifiedEntity = { start: number; @@ -59,32 +83,74 @@ export type ArcjetStack = | "DENO" | "NESTJS" | "REMIX"; -/** @deprecated use equivalent string union type instead */ -export const ArcjetStack: ArcjetEnum = { +export const ArcjetStack = Object.freeze({ + /** + * @deprecated Use the string `"NODEJS"` instead. + **/ NODEJS: "NODEJS", + /** + * @deprecated Use the string `"NEXTJS"` instead. + **/ NEXTJS: "NEXTJS", + /** + * @deprecated Use the string `"BUN"` instead. + **/ BUN: "BUN", + /** + * @deprecated Use the string `"SVELTEKIT"` instead. + **/ SVELTEKIT: "SVELTEKIT", + /** + * @deprecated Use the string `"DENO"` instead. + **/ DENO: "DENO", + /** + * @deprecated Use the string `"NESTJS"` instead. + **/ NESTJS: "NESTJS", + /** + * @deprecated Use the string `"REMIX"` instead. + **/ REMIX: "REMIX", -}; +}); export type ArcjetRuleState = "RUN" | "NOT_RUN" | "CACHED" | "DRY_RUN"; -/** @deprecated use equivalent string union type instead */ -export const ArcjetRuleState: ArcjetEnum = Object.freeze({ +export const ArcjetRuleState = Object.freeze({ + /** + * @deprecated Use the string `"RUN"` instead. + **/ RUN: "RUN", + /** + * @deprecated Use the string `"NOT_RUN"` instead. + **/ NOT_RUN: "NOT_RUN", + /** + * @deprecated Use the string `"CACHED"` instead. + **/ CACHED: "CACHED", + /** + * @deprecated Use the string `"DRY_RUN"` instead. + **/ DRY_RUN: "DRY_RUN", }); export type ArcjetConclusion = "ALLOW" | "DENY" | "CHALLENGE" | "ERROR"; -/** @deprecated use equivalent string union type instead */ -export const ArcjetConclusion: ArcjetEnum = Object.freeze({ +export const ArcjetConclusion = Object.freeze({ + /** + * @deprecated Use the string `"ALLOW"` instead. + **/ ALLOW: "ALLOW", + /** + * @deprecated Use the string `"DENY"` instead. + **/ DENY: "DENY", + /** + * @deprecated Use the string `"CHALLENGE"` instead. + **/ CHALLENGE: "CHALLENGE", + /** + * @deprecated Use the string `"ERROR"` instead. + **/ ERROR: "ERROR", }); @@ -93,18 +159,34 @@ export type ArcjetSensitiveInfoType = | "PHONE_NUMBER" | "IP_ADDRESS" | "CREDIT_CARD_NUMBER"; -/** @deprecated use equivalent string union type instead */ -export const ArcjetSensitiveInfoType: ArcjetEnum = { +export const ArcjetSensitiveInfoType = Object.freeze({ + /** + * @deprecated Use the string `"EMAIL"` instead. + **/ EMAIL: "EMAIL", + /** + * @deprecated Use the string `"PHONE_NUMBER"` instead. + **/ PHONE_NUMBER: "PHONE_NUMBER", + /** + * @deprecated Use the string `"IP_ADDRESS"` instead. + **/ IP_ADDRESS: "IP_ADDRESS", + /** + * @deprecated Use the string `"CREDIT_CARD_NUMBER"` instead. + **/ CREDIT_CARD_NUMBER: "CREDIT_CARD_NUMBER", -}; +}); export type ArcjetRuleType = "LOCAL" | "REMOTE"; -/** @deprecated use equivalent string union type instead */ -export const ArcjetRuleType: ArcjetEnum = Object.freeze({ +export const ArcjetRuleType = Object.freeze({ + /** + * @deprecated Use the string `"LOCAL"` instead. + **/ LOCAL: "LOCAL", + /** + * @deprecated Use the string `"REMOTE"` instead. + **/ REMOTE: "REMOTE", }); diff --git a/protocol/test/client.test.ts b/protocol/test/client.test.ts index 603b59b23..be04a5883 100644 --- a/protocol/test/client.test.ts +++ b/protocol/test/client.test.ts @@ -15,11 +15,10 @@ import { RuleState, SDKStack, } from "../proto/decide/v1alpha1/decide_pb.js"; -import type { ArcjetRule } from "../index.js"; +import type { ArcjetConclusion, ArcjetRule } from "../index.js"; import { ArcjetAllowDecision, ArcjetChallengeDecision, - ArcjetConclusion, ArcjetDecision, ArcjetDenyDecision, ArcjetErrorDecision,