@@ -12,11 +12,30 @@ export class Api {
12
12
private _any : string [ ] = [ ]
13
13
private _all : string [ ] = [ ]
14
14
15
+ /**
16
+ * Number of seconds per second
17
+ */
15
18
public readonly SECOND = 1
16
- public readonly MINUTE = this . SECOND * 60
17
- public readonly HOUR = this . MINUTE * 60
18
- public readonly DAY = this . HOUR * 24
19
- public readonly WEEK = this . DAY * 7
19
+
20
+ /**
21
+ * Number of seconds per minute
22
+ */
23
+ public readonly MINUTE = 60
24
+
25
+ /**
26
+ * Number of seconds per hour
27
+ */
28
+ public readonly HOUR = 3_600
29
+
30
+ /**
31
+ * Number of seconds per day
32
+ */
33
+ public readonly DAY = 86_400
34
+
35
+ /**
36
+ * Number of seconds per week
37
+ */
38
+ public readonly WEEK = 604_800
20
39
21
40
constructor (
22
41
private readonly event : RequestEvent ,
@@ -25,16 +44,32 @@ export class Api {
25
44
public readonly info : KeyInfo | null ,
26
45
) { }
27
46
47
+ /**
48
+ * Allow anonymous requests without any API key
49
+ */
28
50
anonymous ( ) {
29
51
this . _anon = true
30
52
return this
31
53
}
32
54
55
+ /**
56
+ * Set the token bucket name to use for rate limiting.
57
+ * Each named token bucket maintains a separate rate-limit.
58
+ * Without a name, a single rate limit will apply across all calls.
59
+ *
60
+ * @param {string } name - the name of the token bucket
61
+ */
33
62
name ( name : string ) {
34
63
this . _name = name
35
64
return this
36
65
}
37
66
67
+ /**
68
+ * Set the token cost to use when rate-limiting.
69
+ * This is the number of tokens consumed when called.
70
+ *
71
+ * @param {number } cost - the number of tokens to consume
72
+ */
38
73
cost ( cost : number ) {
39
74
if ( cost < 1 ) {
40
75
error ( 500 , 'API cost must be at least 1' )
@@ -43,21 +78,57 @@ export class Api {
43
78
return this
44
79
}
45
80
81
+ /**
82
+ * Requires that the API Key has the given permission.
83
+ *
84
+ * @param {string } permission - the permission
85
+ */
46
86
has ( permission : string ) {
47
87
this . _has = permission
48
88
return this
49
89
}
50
90
91
+ /**
92
+ * Requires that the API Key has _any_ of the specified permissions.
93
+ * This allows you to check for single or all permissions, such as
94
+ * `read:my-project` and `read:*` (for all projects)
95
+ *
96
+ * @param {string[] } permissions - the permissions
97
+ */
51
98
any ( permissions : string [ ] ) {
52
99
this . _any = permissions
53
100
return this
54
101
}
55
102
103
+ /**
104
+ * Requires that the API Key has _all_ of the specified permissions.
105
+ * This allows you to check that the caller has permissions on a hierarchy
106
+ * of entities.
107
+ *
108
+ * @param {string[] } permissions - the permissions
109
+ */
56
110
all ( permissions : string [ ] ) {
57
111
this . _all = permissions
58
112
return this
59
113
}
60
114
115
+ /**
116
+ * Verify the call is allowed and is within the rate limit supplied.
117
+ * Rate-limiting http headers are added to the response whether the
118
+ * request is limited or not.
119
+ *
120
+ * If the request should be denied an error will be thrown and handled
121
+ * by SvelteKit otherwise you can continue with generating the response.
122
+ *
123
+ * @param {Object } refill - the token bucket refill parameters
124
+ * @param {number } refill.rate - the refill rate in tokens per second
125
+ * @param {number } refill.size - the size / capacity of the token bucket
126
+ * @throws {HttpError } Will throw a 401 error if the request doesn't include an api key and the call is not set to be anonymous
127
+ * @throws {HttpError } Will throw a 403 error if the provided api key is invalid
128
+ * @throws {HttpError } Will throw a 403 error if the provided api key has expired
129
+ * @throws {HttpError } Will throw a 403 error if the provided api key lacks the required permissions
130
+ * @throws {HttpError } Will throw a 429 error if the rate-limit is hit
131
+ */
61
132
async limit ( refill : Refill ) {
62
133
if ( refill . rate <= 0 ) throw `refill rate must be greater than 0`
63
134
if ( refill . size < 1 ) throw `refill size must be at least 1`
@@ -67,7 +138,7 @@ export class Api {
67
138
68
139
const { key, info } = this
69
140
70
- // if not anonymouse , key must be provided
141
+ // if not anonymous , key must be provided
71
142
if ( ! this . _anon && ! key ) {
72
143
error ( 401 , 'Missing API Key' )
73
144
}
0 commit comments