@unkey/api 0.15.0 → 0.17.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/dist/index.d.mts +146 -206
- package/dist/index.d.ts +146 -206
- package/dist/index.js +49 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -5
package/dist/index.d.mts
CHANGED
|
@@ -248,6 +248,14 @@ interface paths {
|
|
|
248
248
|
meta?: {
|
|
249
249
|
[key: string]: unknown;
|
|
250
250
|
};
|
|
251
|
+
/**
|
|
252
|
+
* @description A list of roles that this key should have. New roles will be created if they don't exist yet.
|
|
253
|
+
* @example [
|
|
254
|
+
* "admin",
|
|
255
|
+
* "finance"
|
|
256
|
+
* ]
|
|
257
|
+
*/
|
|
258
|
+
roles?: string[];
|
|
251
259
|
/**
|
|
252
260
|
* @description You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again.
|
|
253
261
|
* @example 1623869797161
|
|
@@ -297,6 +305,12 @@ interface paths {
|
|
|
297
305
|
/** @description Determines the speed at which tokens are refilled, in milliseconds. */
|
|
298
306
|
refillInterval: number;
|
|
299
307
|
};
|
|
308
|
+
/**
|
|
309
|
+
* @description Sets if key is enabled or disabled. Disabled keys are not valid.
|
|
310
|
+
* @default true
|
|
311
|
+
* @example false
|
|
312
|
+
*/
|
|
313
|
+
enabled?: boolean;
|
|
300
314
|
};
|
|
301
315
|
};
|
|
302
316
|
};
|
|
@@ -367,107 +381,14 @@ interface paths {
|
|
|
367
381
|
post: {
|
|
368
382
|
requestBody: {
|
|
369
383
|
content: {
|
|
370
|
-
"application/json":
|
|
371
|
-
/**
|
|
372
|
-
* @description The id of the api where the key belongs to. This is optional for now but will be required soon.
|
|
373
|
-
* The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail.
|
|
374
|
-
* @example api_1234
|
|
375
|
-
*/
|
|
376
|
-
apiId?: string;
|
|
377
|
-
/**
|
|
378
|
-
* @description The key to verify
|
|
379
|
-
* @example sk_1234
|
|
380
|
-
*/
|
|
381
|
-
key: string;
|
|
382
|
-
};
|
|
384
|
+
"application/json": components["schemas"]["V1KeysVerifyKeyRequest"];
|
|
383
385
|
};
|
|
384
386
|
};
|
|
385
387
|
responses: {
|
|
386
388
|
/** @description The verification result */
|
|
387
389
|
200: {
|
|
388
390
|
content: {
|
|
389
|
-
"application/json":
|
|
390
|
-
/**
|
|
391
|
-
* @description The id of the key
|
|
392
|
-
* @example key_1234
|
|
393
|
-
*/
|
|
394
|
-
keyId?: string;
|
|
395
|
-
/**
|
|
396
|
-
* @description Whether the key is valid or not.
|
|
397
|
-
* A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted.
|
|
398
|
-
* @example true
|
|
399
|
-
*/
|
|
400
|
-
valid: boolean;
|
|
401
|
-
/**
|
|
402
|
-
* @description The name of the key, give keys a name to easily identifiy their purpose
|
|
403
|
-
* @example Customer X
|
|
404
|
-
*/
|
|
405
|
-
name?: string;
|
|
406
|
-
/**
|
|
407
|
-
* @description The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.
|
|
408
|
-
* @example user_123
|
|
409
|
-
*/
|
|
410
|
-
ownerId?: string;
|
|
411
|
-
/**
|
|
412
|
-
* @description Any additional metadata you want to store with the key
|
|
413
|
-
* @example {
|
|
414
|
-
* "roles": [
|
|
415
|
-
* "admin",
|
|
416
|
-
* "user"
|
|
417
|
-
* ],
|
|
418
|
-
* "stripeCustomerId": "cus_1234"
|
|
419
|
-
* }
|
|
420
|
-
*/
|
|
421
|
-
meta?: {
|
|
422
|
-
[key: string]: unknown;
|
|
423
|
-
};
|
|
424
|
-
/**
|
|
425
|
-
* @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
|
|
426
|
-
* @example 123
|
|
427
|
-
*/
|
|
428
|
-
expires?: number;
|
|
429
|
-
/**
|
|
430
|
-
* @description The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit.
|
|
431
|
-
* @example {
|
|
432
|
-
* "limit": 10,
|
|
433
|
-
* "remaining": 9,
|
|
434
|
-
* "reset": 3600000
|
|
435
|
-
* }
|
|
436
|
-
*/
|
|
437
|
-
ratelimit?: {
|
|
438
|
-
/**
|
|
439
|
-
* @description Maximum number of requests that can be made inside a window
|
|
440
|
-
* @example 10
|
|
441
|
-
*/
|
|
442
|
-
limit: number;
|
|
443
|
-
/**
|
|
444
|
-
* @description Remaining requests after this verification
|
|
445
|
-
* @example 9
|
|
446
|
-
*/
|
|
447
|
-
remaining: number;
|
|
448
|
-
/**
|
|
449
|
-
* @description Unix timestamp in milliseconds when the ratelimit will reset
|
|
450
|
-
* @example 3600000
|
|
451
|
-
*/
|
|
452
|
-
reset: number;
|
|
453
|
-
};
|
|
454
|
-
/**
|
|
455
|
-
* @description The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit.
|
|
456
|
-
* @example 1000
|
|
457
|
-
*/
|
|
458
|
-
remaining?: number;
|
|
459
|
-
/**
|
|
460
|
-
* @description If the key is invalid this field will be set to the reason why it is invalid.
|
|
461
|
-
* Possible values are:
|
|
462
|
-
* - NOT_FOUND: the key does not exist or has expired
|
|
463
|
-
* - FORBIDDEN: the key is not allowed to access the api
|
|
464
|
-
* - USAGE_EXCEEDED: the key has exceeded its request limit
|
|
465
|
-
* - RATE_LIMITED: the key has been ratelimited,
|
|
466
|
-
*
|
|
467
|
-
* @enum {string}
|
|
468
|
-
*/
|
|
469
|
-
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED";
|
|
470
|
-
};
|
|
391
|
+
"application/json": components["schemas"]["V1KeysVerifyKeyResponse"];
|
|
471
392
|
};
|
|
472
393
|
};
|
|
473
394
|
/** @description The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). */
|
|
@@ -596,6 +517,11 @@ interface paths {
|
|
|
596
517
|
/** @description The amount of verifications to refill for each occurrence is determined individually for each key. */
|
|
597
518
|
amount: number;
|
|
598
519
|
}) | null;
|
|
520
|
+
/**
|
|
521
|
+
* @description Set if key is enabled or disabled. If disabled, the key cannot be used to verify.
|
|
522
|
+
* @example true
|
|
523
|
+
*/
|
|
524
|
+
enabled?: boolean;
|
|
599
525
|
};
|
|
600
526
|
};
|
|
601
527
|
};
|
|
@@ -733,92 +659,6 @@ interface paths {
|
|
|
733
659
|
};
|
|
734
660
|
};
|
|
735
661
|
"/v1/keys.getVerifications": {
|
|
736
|
-
get: {
|
|
737
|
-
parameters: {
|
|
738
|
-
query?: {
|
|
739
|
-
keyId?: string;
|
|
740
|
-
ownerId?: string;
|
|
741
|
-
start?: number;
|
|
742
|
-
end?: number;
|
|
743
|
-
granularity?: "day";
|
|
744
|
-
};
|
|
745
|
-
};
|
|
746
|
-
responses: {
|
|
747
|
-
/** @description The configuration for a single key */
|
|
748
|
-
200: {
|
|
749
|
-
content: {
|
|
750
|
-
"application/json": {
|
|
751
|
-
verifications: {
|
|
752
|
-
/**
|
|
753
|
-
* @description The timestamp of the usage data
|
|
754
|
-
* @example 1620000000000
|
|
755
|
-
*/
|
|
756
|
-
time: number;
|
|
757
|
-
/**
|
|
758
|
-
* @description The number of successful requests
|
|
759
|
-
* @example 100
|
|
760
|
-
*/
|
|
761
|
-
success: number;
|
|
762
|
-
/**
|
|
763
|
-
* @description The number of requests that were rate limited
|
|
764
|
-
* @example 10
|
|
765
|
-
*/
|
|
766
|
-
rateLimited: number;
|
|
767
|
-
/**
|
|
768
|
-
* @description The number of requests that exceeded the usage limit
|
|
769
|
-
* @example 0
|
|
770
|
-
*/
|
|
771
|
-
usageExceeded: number;
|
|
772
|
-
}[];
|
|
773
|
-
};
|
|
774
|
-
};
|
|
775
|
-
};
|
|
776
|
-
/** @description The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). */
|
|
777
|
-
400: {
|
|
778
|
-
content: {
|
|
779
|
-
"application/json": components["schemas"]["ErrBadRequest"];
|
|
780
|
-
};
|
|
781
|
-
};
|
|
782
|
-
/** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */
|
|
783
|
-
401: {
|
|
784
|
-
content: {
|
|
785
|
-
"application/json": components["schemas"]["ErrUnauthorized"];
|
|
786
|
-
};
|
|
787
|
-
};
|
|
788
|
-
/** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */
|
|
789
|
-
403: {
|
|
790
|
-
content: {
|
|
791
|
-
"application/json": components["schemas"]["ErrForbidden"];
|
|
792
|
-
};
|
|
793
|
-
};
|
|
794
|
-
/** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */
|
|
795
|
-
404: {
|
|
796
|
-
content: {
|
|
797
|
-
"application/json": components["schemas"]["ErrNotFound"];
|
|
798
|
-
};
|
|
799
|
-
};
|
|
800
|
-
/** @description This response is sent when a request conflicts with the current state of the server. */
|
|
801
|
-
409: {
|
|
802
|
-
content: {
|
|
803
|
-
"application/json": components["schemas"]["ErrConflict"];
|
|
804
|
-
};
|
|
805
|
-
};
|
|
806
|
-
/** @description The user has sent too many requests in a given amount of time ("rate limiting") */
|
|
807
|
-
429: {
|
|
808
|
-
content: {
|
|
809
|
-
"application/json": components["schemas"]["ErrTooManyRequests"];
|
|
810
|
-
};
|
|
811
|
-
};
|
|
812
|
-
/** @description The server has encountered a situation it does not know how to handle. */
|
|
813
|
-
500: {
|
|
814
|
-
content: {
|
|
815
|
-
"application/json": components["schemas"]["ErrInternalServerError"];
|
|
816
|
-
};
|
|
817
|
-
};
|
|
818
|
-
};
|
|
819
|
-
};
|
|
820
|
-
};
|
|
821
|
-
"/vx/keys.getVerifications": {
|
|
822
662
|
get: {
|
|
823
663
|
parameters: {
|
|
824
664
|
query?: {
|
|
@@ -1189,9 +1029,6 @@ interface paths {
|
|
|
1189
1029
|
"/v1/keys/{keyId}": {
|
|
1190
1030
|
put: {
|
|
1191
1031
|
parameters: {
|
|
1192
|
-
header: {
|
|
1193
|
-
authorization: string;
|
|
1194
|
-
};
|
|
1195
1032
|
path: {
|
|
1196
1033
|
keyId: string;
|
|
1197
1034
|
};
|
|
@@ -1311,11 +1148,6 @@ interface paths {
|
|
|
1311
1148
|
};
|
|
1312
1149
|
"/v1/keys/:keyId": {
|
|
1313
1150
|
get: {
|
|
1314
|
-
parameters: {
|
|
1315
|
-
header: {
|
|
1316
|
-
authorization: string;
|
|
1317
|
-
};
|
|
1318
|
-
};
|
|
1319
1151
|
responses: {
|
|
1320
1152
|
/** @description The configuration for a single key */
|
|
1321
1153
|
200: {
|
|
@@ -1368,11 +1200,6 @@ interface paths {
|
|
|
1368
1200
|
};
|
|
1369
1201
|
};
|
|
1370
1202
|
delete: {
|
|
1371
|
-
parameters: {
|
|
1372
|
-
header: {
|
|
1373
|
-
authorization: string;
|
|
1374
|
-
};
|
|
1375
|
-
};
|
|
1376
1203
|
responses: {
|
|
1377
1204
|
/** @description The key was successfully revoked, it may take up to 30s for this to take effect in all regions */
|
|
1378
1205
|
200: {
|
|
@@ -1427,11 +1254,6 @@ interface paths {
|
|
|
1427
1254
|
};
|
|
1428
1255
|
"/v1/keys": {
|
|
1429
1256
|
post: {
|
|
1430
|
-
parameters: {
|
|
1431
|
-
header: {
|
|
1432
|
-
authorization: string;
|
|
1433
|
-
};
|
|
1434
|
-
};
|
|
1435
1257
|
requestBody: {
|
|
1436
1258
|
content: {
|
|
1437
1259
|
"application/json": {
|
|
@@ -1687,7 +1509,7 @@ interface paths {
|
|
|
1687
1509
|
* @example NOT_FOUND
|
|
1688
1510
|
* @enum {string}
|
|
1689
1511
|
*/
|
|
1690
|
-
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED";
|
|
1512
|
+
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | "UNAUTHORIZED" | "DISABLED";
|
|
1691
1513
|
};
|
|
1692
1514
|
};
|
|
1693
1515
|
};
|
|
@@ -1883,9 +1705,6 @@ interface paths {
|
|
|
1883
1705
|
};
|
|
1884
1706
|
delete: {
|
|
1885
1707
|
parameters: {
|
|
1886
|
-
header: {
|
|
1887
|
-
authorization: string;
|
|
1888
|
-
};
|
|
1889
1708
|
path: {
|
|
1890
1709
|
apiId: string;
|
|
1891
1710
|
};
|
|
@@ -2280,6 +2099,117 @@ interface components {
|
|
|
2280
2099
|
/** @description Determines the speed at which tokens are refilled, in milliseconds. */
|
|
2281
2100
|
refillInterval: number;
|
|
2282
2101
|
};
|
|
2102
|
+
/**
|
|
2103
|
+
* @description All roles this key belongs to
|
|
2104
|
+
* @example [
|
|
2105
|
+
* "admin",
|
|
2106
|
+
* "finance"
|
|
2107
|
+
* ]
|
|
2108
|
+
*/
|
|
2109
|
+
roles?: string[];
|
|
2110
|
+
/**
|
|
2111
|
+
* @description Sets if key is enabled or disabled. Disabled keys are not valid.
|
|
2112
|
+
* @example true
|
|
2113
|
+
*/
|
|
2114
|
+
enabled?: boolean;
|
|
2115
|
+
};
|
|
2116
|
+
V1KeysVerifyKeyResponse: {
|
|
2117
|
+
/**
|
|
2118
|
+
* @description The id of the key
|
|
2119
|
+
* @example key_1234
|
|
2120
|
+
*/
|
|
2121
|
+
keyId?: string;
|
|
2122
|
+
/**
|
|
2123
|
+
* @description Whether the key is valid or not.
|
|
2124
|
+
* A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted.
|
|
2125
|
+
* @example true
|
|
2126
|
+
*/
|
|
2127
|
+
valid: boolean;
|
|
2128
|
+
/**
|
|
2129
|
+
* @description The name of the key, give keys a name to easily identifiy their purpose
|
|
2130
|
+
* @example Customer X
|
|
2131
|
+
*/
|
|
2132
|
+
name?: string;
|
|
2133
|
+
/**
|
|
2134
|
+
* @description The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.
|
|
2135
|
+
* @example user_123
|
|
2136
|
+
*/
|
|
2137
|
+
ownerId?: string;
|
|
2138
|
+
/**
|
|
2139
|
+
* @description Any additional metadata you want to store with the key
|
|
2140
|
+
* @example {
|
|
2141
|
+
* "roles": [
|
|
2142
|
+
* "admin",
|
|
2143
|
+
* "user"
|
|
2144
|
+
* ],
|
|
2145
|
+
* "stripeCustomerId": "cus_1234"
|
|
2146
|
+
* }
|
|
2147
|
+
*/
|
|
2148
|
+
meta?: {
|
|
2149
|
+
[key: string]: unknown;
|
|
2150
|
+
};
|
|
2151
|
+
/**
|
|
2152
|
+
* @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
|
|
2153
|
+
* @example 123
|
|
2154
|
+
*/
|
|
2155
|
+
expires?: number;
|
|
2156
|
+
/**
|
|
2157
|
+
* @description The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit.
|
|
2158
|
+
* @example {
|
|
2159
|
+
* "limit": 10,
|
|
2160
|
+
* "remaining": 9,
|
|
2161
|
+
* "reset": 3600000
|
|
2162
|
+
* }
|
|
2163
|
+
*/
|
|
2164
|
+
ratelimit?: {
|
|
2165
|
+
/**
|
|
2166
|
+
* @description Maximum number of requests that can be made inside a window
|
|
2167
|
+
* @example 10
|
|
2168
|
+
*/
|
|
2169
|
+
limit: number;
|
|
2170
|
+
/**
|
|
2171
|
+
* @description Remaining requests after this verification
|
|
2172
|
+
* @example 9
|
|
2173
|
+
*/
|
|
2174
|
+
remaining: number;
|
|
2175
|
+
/**
|
|
2176
|
+
* @description Unix timestamp in milliseconds when the ratelimit will reset
|
|
2177
|
+
* @example 3600000
|
|
2178
|
+
*/
|
|
2179
|
+
reset: number;
|
|
2180
|
+
};
|
|
2181
|
+
/**
|
|
2182
|
+
* @description The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit.
|
|
2183
|
+
* @example 1000
|
|
2184
|
+
*/
|
|
2185
|
+
remaining?: number;
|
|
2186
|
+
/**
|
|
2187
|
+
* @description If the key is invalid this field will be set to the reason why it is invalid.
|
|
2188
|
+
* Possible values are:
|
|
2189
|
+
* - NOT_FOUND: the key does not exist or has expired
|
|
2190
|
+
* - FORBIDDEN: the key is not allowed to access the api
|
|
2191
|
+
* - USAGE_EXCEEDED: the key has exceeded its request limit
|
|
2192
|
+
* - RATE_LIMITED: the key has been ratelimited
|
|
2193
|
+
* - UNAUTHORIZED: the key is not authorized
|
|
2194
|
+
* - DISABLED: the key is disabled
|
|
2195
|
+
* @enum {string}
|
|
2196
|
+
*/
|
|
2197
|
+
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | "UNAUTHORIZED" | "DISABLED";
|
|
2198
|
+
/** @description Sets the key to be enabled or disabled. Disabled keys will not verify. */
|
|
2199
|
+
enabled?: boolean;
|
|
2200
|
+
};
|
|
2201
|
+
V1KeysVerifyKeyRequest: {
|
|
2202
|
+
/**
|
|
2203
|
+
* @description The id of the api where the key belongs to. This is optional for now but will be required soon.
|
|
2204
|
+
* The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail.
|
|
2205
|
+
* @example api_1234
|
|
2206
|
+
*/
|
|
2207
|
+
apiId?: string;
|
|
2208
|
+
/**
|
|
2209
|
+
* @description The key to verify
|
|
2210
|
+
* @example sk_1234
|
|
2211
|
+
*/
|
|
2212
|
+
key: string;
|
|
2283
2213
|
};
|
|
2284
2214
|
};
|
|
2285
2215
|
responses: never;
|
|
@@ -2314,6 +2244,14 @@ type UnkeyOptions = ({
|
|
|
2314
2244
|
* @default https://api.unkey.dev
|
|
2315
2245
|
*/
|
|
2316
2246
|
baseUrl?: string;
|
|
2247
|
+
/**
|
|
2248
|
+
*
|
|
2249
|
+
* By default telemetry data is enabled, and sends:
|
|
2250
|
+
* runtime (Node.js / Edge)
|
|
2251
|
+
* platform (Node.js / Vercel / AWS)
|
|
2252
|
+
* SDK version
|
|
2253
|
+
*/
|
|
2254
|
+
disableTelemetry?: boolean;
|
|
2317
2255
|
/**
|
|
2318
2256
|
* Retry on network errors
|
|
2319
2257
|
*/
|
|
@@ -2344,7 +2282,7 @@ type UnkeyOptions = ({
|
|
|
2344
2282
|
*
|
|
2345
2283
|
* You can leave this blank unless you are building a wrapper around this SDK.
|
|
2346
2284
|
*/
|
|
2347
|
-
wrapperSdkVersion?:
|
|
2285
|
+
wrapperSdkVersion?: string;
|
|
2348
2286
|
};
|
|
2349
2287
|
type Result<R> = {
|
|
2350
2288
|
result: R;
|
|
@@ -2357,12 +2295,13 @@ declare class Unkey {
|
|
|
2357
2295
|
readonly baseUrl: string;
|
|
2358
2296
|
private readonly rootKey;
|
|
2359
2297
|
private readonly cache?;
|
|
2360
|
-
private readonly
|
|
2298
|
+
private readonly telemetry?;
|
|
2361
2299
|
readonly retry: {
|
|
2362
2300
|
attempts: number;
|
|
2363
2301
|
backoff: (retryCount: number) => number;
|
|
2364
2302
|
};
|
|
2365
2303
|
constructor(opts: UnkeyOptions);
|
|
2304
|
+
private getHeaders;
|
|
2366
2305
|
private fetch;
|
|
2367
2306
|
get keys(): {
|
|
2368
2307
|
create: (req: paths["/v1/keys.createKey"]["post"]["requestBody"]["content"]["application/json"]) => Promise<Result<paths["/v1/keys.createKey"]["post"]["responses"]["200"]["content"]["application/json"]>>;
|
|
@@ -2429,7 +2368,8 @@ declare function verifyKey(req: string | {
|
|
|
2429
2368
|
reset: number;
|
|
2430
2369
|
} | undefined;
|
|
2431
2370
|
remaining?: number | undefined;
|
|
2432
|
-
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | undefined;
|
|
2371
|
+
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | "UNAUTHORIZED" | "DISABLED" | undefined;
|
|
2372
|
+
enabled?: boolean | undefined;
|
|
2433
2373
|
};
|
|
2434
2374
|
error?: undefined;
|
|
2435
2375
|
}>;
|
package/dist/index.d.ts
CHANGED
|
@@ -248,6 +248,14 @@ interface paths {
|
|
|
248
248
|
meta?: {
|
|
249
249
|
[key: string]: unknown;
|
|
250
250
|
};
|
|
251
|
+
/**
|
|
252
|
+
* @description A list of roles that this key should have. New roles will be created if they don't exist yet.
|
|
253
|
+
* @example [
|
|
254
|
+
* "admin",
|
|
255
|
+
* "finance"
|
|
256
|
+
* ]
|
|
257
|
+
*/
|
|
258
|
+
roles?: string[];
|
|
251
259
|
/**
|
|
252
260
|
* @description You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again.
|
|
253
261
|
* @example 1623869797161
|
|
@@ -297,6 +305,12 @@ interface paths {
|
|
|
297
305
|
/** @description Determines the speed at which tokens are refilled, in milliseconds. */
|
|
298
306
|
refillInterval: number;
|
|
299
307
|
};
|
|
308
|
+
/**
|
|
309
|
+
* @description Sets if key is enabled or disabled. Disabled keys are not valid.
|
|
310
|
+
* @default true
|
|
311
|
+
* @example false
|
|
312
|
+
*/
|
|
313
|
+
enabled?: boolean;
|
|
300
314
|
};
|
|
301
315
|
};
|
|
302
316
|
};
|
|
@@ -367,107 +381,14 @@ interface paths {
|
|
|
367
381
|
post: {
|
|
368
382
|
requestBody: {
|
|
369
383
|
content: {
|
|
370
|
-
"application/json":
|
|
371
|
-
/**
|
|
372
|
-
* @description The id of the api where the key belongs to. This is optional for now but will be required soon.
|
|
373
|
-
* The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail.
|
|
374
|
-
* @example api_1234
|
|
375
|
-
*/
|
|
376
|
-
apiId?: string;
|
|
377
|
-
/**
|
|
378
|
-
* @description The key to verify
|
|
379
|
-
* @example sk_1234
|
|
380
|
-
*/
|
|
381
|
-
key: string;
|
|
382
|
-
};
|
|
384
|
+
"application/json": components["schemas"]["V1KeysVerifyKeyRequest"];
|
|
383
385
|
};
|
|
384
386
|
};
|
|
385
387
|
responses: {
|
|
386
388
|
/** @description The verification result */
|
|
387
389
|
200: {
|
|
388
390
|
content: {
|
|
389
|
-
"application/json":
|
|
390
|
-
/**
|
|
391
|
-
* @description The id of the key
|
|
392
|
-
* @example key_1234
|
|
393
|
-
*/
|
|
394
|
-
keyId?: string;
|
|
395
|
-
/**
|
|
396
|
-
* @description Whether the key is valid or not.
|
|
397
|
-
* A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted.
|
|
398
|
-
* @example true
|
|
399
|
-
*/
|
|
400
|
-
valid: boolean;
|
|
401
|
-
/**
|
|
402
|
-
* @description The name of the key, give keys a name to easily identifiy their purpose
|
|
403
|
-
* @example Customer X
|
|
404
|
-
*/
|
|
405
|
-
name?: string;
|
|
406
|
-
/**
|
|
407
|
-
* @description The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.
|
|
408
|
-
* @example user_123
|
|
409
|
-
*/
|
|
410
|
-
ownerId?: string;
|
|
411
|
-
/**
|
|
412
|
-
* @description Any additional metadata you want to store with the key
|
|
413
|
-
* @example {
|
|
414
|
-
* "roles": [
|
|
415
|
-
* "admin",
|
|
416
|
-
* "user"
|
|
417
|
-
* ],
|
|
418
|
-
* "stripeCustomerId": "cus_1234"
|
|
419
|
-
* }
|
|
420
|
-
*/
|
|
421
|
-
meta?: {
|
|
422
|
-
[key: string]: unknown;
|
|
423
|
-
};
|
|
424
|
-
/**
|
|
425
|
-
* @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
|
|
426
|
-
* @example 123
|
|
427
|
-
*/
|
|
428
|
-
expires?: number;
|
|
429
|
-
/**
|
|
430
|
-
* @description The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit.
|
|
431
|
-
* @example {
|
|
432
|
-
* "limit": 10,
|
|
433
|
-
* "remaining": 9,
|
|
434
|
-
* "reset": 3600000
|
|
435
|
-
* }
|
|
436
|
-
*/
|
|
437
|
-
ratelimit?: {
|
|
438
|
-
/**
|
|
439
|
-
* @description Maximum number of requests that can be made inside a window
|
|
440
|
-
* @example 10
|
|
441
|
-
*/
|
|
442
|
-
limit: number;
|
|
443
|
-
/**
|
|
444
|
-
* @description Remaining requests after this verification
|
|
445
|
-
* @example 9
|
|
446
|
-
*/
|
|
447
|
-
remaining: number;
|
|
448
|
-
/**
|
|
449
|
-
* @description Unix timestamp in milliseconds when the ratelimit will reset
|
|
450
|
-
* @example 3600000
|
|
451
|
-
*/
|
|
452
|
-
reset: number;
|
|
453
|
-
};
|
|
454
|
-
/**
|
|
455
|
-
* @description The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit.
|
|
456
|
-
* @example 1000
|
|
457
|
-
*/
|
|
458
|
-
remaining?: number;
|
|
459
|
-
/**
|
|
460
|
-
* @description If the key is invalid this field will be set to the reason why it is invalid.
|
|
461
|
-
* Possible values are:
|
|
462
|
-
* - NOT_FOUND: the key does not exist or has expired
|
|
463
|
-
* - FORBIDDEN: the key is not allowed to access the api
|
|
464
|
-
* - USAGE_EXCEEDED: the key has exceeded its request limit
|
|
465
|
-
* - RATE_LIMITED: the key has been ratelimited,
|
|
466
|
-
*
|
|
467
|
-
* @enum {string}
|
|
468
|
-
*/
|
|
469
|
-
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED";
|
|
470
|
-
};
|
|
391
|
+
"application/json": components["schemas"]["V1KeysVerifyKeyResponse"];
|
|
471
392
|
};
|
|
472
393
|
};
|
|
473
394
|
/** @description The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). */
|
|
@@ -596,6 +517,11 @@ interface paths {
|
|
|
596
517
|
/** @description The amount of verifications to refill for each occurrence is determined individually for each key. */
|
|
597
518
|
amount: number;
|
|
598
519
|
}) | null;
|
|
520
|
+
/**
|
|
521
|
+
* @description Set if key is enabled or disabled. If disabled, the key cannot be used to verify.
|
|
522
|
+
* @example true
|
|
523
|
+
*/
|
|
524
|
+
enabled?: boolean;
|
|
599
525
|
};
|
|
600
526
|
};
|
|
601
527
|
};
|
|
@@ -733,92 +659,6 @@ interface paths {
|
|
|
733
659
|
};
|
|
734
660
|
};
|
|
735
661
|
"/v1/keys.getVerifications": {
|
|
736
|
-
get: {
|
|
737
|
-
parameters: {
|
|
738
|
-
query?: {
|
|
739
|
-
keyId?: string;
|
|
740
|
-
ownerId?: string;
|
|
741
|
-
start?: number;
|
|
742
|
-
end?: number;
|
|
743
|
-
granularity?: "day";
|
|
744
|
-
};
|
|
745
|
-
};
|
|
746
|
-
responses: {
|
|
747
|
-
/** @description The configuration for a single key */
|
|
748
|
-
200: {
|
|
749
|
-
content: {
|
|
750
|
-
"application/json": {
|
|
751
|
-
verifications: {
|
|
752
|
-
/**
|
|
753
|
-
* @description The timestamp of the usage data
|
|
754
|
-
* @example 1620000000000
|
|
755
|
-
*/
|
|
756
|
-
time: number;
|
|
757
|
-
/**
|
|
758
|
-
* @description The number of successful requests
|
|
759
|
-
* @example 100
|
|
760
|
-
*/
|
|
761
|
-
success: number;
|
|
762
|
-
/**
|
|
763
|
-
* @description The number of requests that were rate limited
|
|
764
|
-
* @example 10
|
|
765
|
-
*/
|
|
766
|
-
rateLimited: number;
|
|
767
|
-
/**
|
|
768
|
-
* @description The number of requests that exceeded the usage limit
|
|
769
|
-
* @example 0
|
|
770
|
-
*/
|
|
771
|
-
usageExceeded: number;
|
|
772
|
-
}[];
|
|
773
|
-
};
|
|
774
|
-
};
|
|
775
|
-
};
|
|
776
|
-
/** @description The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). */
|
|
777
|
-
400: {
|
|
778
|
-
content: {
|
|
779
|
-
"application/json": components["schemas"]["ErrBadRequest"];
|
|
780
|
-
};
|
|
781
|
-
};
|
|
782
|
-
/** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */
|
|
783
|
-
401: {
|
|
784
|
-
content: {
|
|
785
|
-
"application/json": components["schemas"]["ErrUnauthorized"];
|
|
786
|
-
};
|
|
787
|
-
};
|
|
788
|
-
/** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */
|
|
789
|
-
403: {
|
|
790
|
-
content: {
|
|
791
|
-
"application/json": components["schemas"]["ErrForbidden"];
|
|
792
|
-
};
|
|
793
|
-
};
|
|
794
|
-
/** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */
|
|
795
|
-
404: {
|
|
796
|
-
content: {
|
|
797
|
-
"application/json": components["schemas"]["ErrNotFound"];
|
|
798
|
-
};
|
|
799
|
-
};
|
|
800
|
-
/** @description This response is sent when a request conflicts with the current state of the server. */
|
|
801
|
-
409: {
|
|
802
|
-
content: {
|
|
803
|
-
"application/json": components["schemas"]["ErrConflict"];
|
|
804
|
-
};
|
|
805
|
-
};
|
|
806
|
-
/** @description The user has sent too many requests in a given amount of time ("rate limiting") */
|
|
807
|
-
429: {
|
|
808
|
-
content: {
|
|
809
|
-
"application/json": components["schemas"]["ErrTooManyRequests"];
|
|
810
|
-
};
|
|
811
|
-
};
|
|
812
|
-
/** @description The server has encountered a situation it does not know how to handle. */
|
|
813
|
-
500: {
|
|
814
|
-
content: {
|
|
815
|
-
"application/json": components["schemas"]["ErrInternalServerError"];
|
|
816
|
-
};
|
|
817
|
-
};
|
|
818
|
-
};
|
|
819
|
-
};
|
|
820
|
-
};
|
|
821
|
-
"/vx/keys.getVerifications": {
|
|
822
662
|
get: {
|
|
823
663
|
parameters: {
|
|
824
664
|
query?: {
|
|
@@ -1189,9 +1029,6 @@ interface paths {
|
|
|
1189
1029
|
"/v1/keys/{keyId}": {
|
|
1190
1030
|
put: {
|
|
1191
1031
|
parameters: {
|
|
1192
|
-
header: {
|
|
1193
|
-
authorization: string;
|
|
1194
|
-
};
|
|
1195
1032
|
path: {
|
|
1196
1033
|
keyId: string;
|
|
1197
1034
|
};
|
|
@@ -1311,11 +1148,6 @@ interface paths {
|
|
|
1311
1148
|
};
|
|
1312
1149
|
"/v1/keys/:keyId": {
|
|
1313
1150
|
get: {
|
|
1314
|
-
parameters: {
|
|
1315
|
-
header: {
|
|
1316
|
-
authorization: string;
|
|
1317
|
-
};
|
|
1318
|
-
};
|
|
1319
1151
|
responses: {
|
|
1320
1152
|
/** @description The configuration for a single key */
|
|
1321
1153
|
200: {
|
|
@@ -1368,11 +1200,6 @@ interface paths {
|
|
|
1368
1200
|
};
|
|
1369
1201
|
};
|
|
1370
1202
|
delete: {
|
|
1371
|
-
parameters: {
|
|
1372
|
-
header: {
|
|
1373
|
-
authorization: string;
|
|
1374
|
-
};
|
|
1375
|
-
};
|
|
1376
1203
|
responses: {
|
|
1377
1204
|
/** @description The key was successfully revoked, it may take up to 30s for this to take effect in all regions */
|
|
1378
1205
|
200: {
|
|
@@ -1427,11 +1254,6 @@ interface paths {
|
|
|
1427
1254
|
};
|
|
1428
1255
|
"/v1/keys": {
|
|
1429
1256
|
post: {
|
|
1430
|
-
parameters: {
|
|
1431
|
-
header: {
|
|
1432
|
-
authorization: string;
|
|
1433
|
-
};
|
|
1434
|
-
};
|
|
1435
1257
|
requestBody: {
|
|
1436
1258
|
content: {
|
|
1437
1259
|
"application/json": {
|
|
@@ -1687,7 +1509,7 @@ interface paths {
|
|
|
1687
1509
|
* @example NOT_FOUND
|
|
1688
1510
|
* @enum {string}
|
|
1689
1511
|
*/
|
|
1690
|
-
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED";
|
|
1512
|
+
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | "UNAUTHORIZED" | "DISABLED";
|
|
1691
1513
|
};
|
|
1692
1514
|
};
|
|
1693
1515
|
};
|
|
@@ -1883,9 +1705,6 @@ interface paths {
|
|
|
1883
1705
|
};
|
|
1884
1706
|
delete: {
|
|
1885
1707
|
parameters: {
|
|
1886
|
-
header: {
|
|
1887
|
-
authorization: string;
|
|
1888
|
-
};
|
|
1889
1708
|
path: {
|
|
1890
1709
|
apiId: string;
|
|
1891
1710
|
};
|
|
@@ -2280,6 +2099,117 @@ interface components {
|
|
|
2280
2099
|
/** @description Determines the speed at which tokens are refilled, in milliseconds. */
|
|
2281
2100
|
refillInterval: number;
|
|
2282
2101
|
};
|
|
2102
|
+
/**
|
|
2103
|
+
* @description All roles this key belongs to
|
|
2104
|
+
* @example [
|
|
2105
|
+
* "admin",
|
|
2106
|
+
* "finance"
|
|
2107
|
+
* ]
|
|
2108
|
+
*/
|
|
2109
|
+
roles?: string[];
|
|
2110
|
+
/**
|
|
2111
|
+
* @description Sets if key is enabled or disabled. Disabled keys are not valid.
|
|
2112
|
+
* @example true
|
|
2113
|
+
*/
|
|
2114
|
+
enabled?: boolean;
|
|
2115
|
+
};
|
|
2116
|
+
V1KeysVerifyKeyResponse: {
|
|
2117
|
+
/**
|
|
2118
|
+
* @description The id of the key
|
|
2119
|
+
* @example key_1234
|
|
2120
|
+
*/
|
|
2121
|
+
keyId?: string;
|
|
2122
|
+
/**
|
|
2123
|
+
* @description Whether the key is valid or not.
|
|
2124
|
+
* A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted.
|
|
2125
|
+
* @example true
|
|
2126
|
+
*/
|
|
2127
|
+
valid: boolean;
|
|
2128
|
+
/**
|
|
2129
|
+
* @description The name of the key, give keys a name to easily identifiy their purpose
|
|
2130
|
+
* @example Customer X
|
|
2131
|
+
*/
|
|
2132
|
+
name?: string;
|
|
2133
|
+
/**
|
|
2134
|
+
* @description The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API.
|
|
2135
|
+
* @example user_123
|
|
2136
|
+
*/
|
|
2137
|
+
ownerId?: string;
|
|
2138
|
+
/**
|
|
2139
|
+
* @description Any additional metadata you want to store with the key
|
|
2140
|
+
* @example {
|
|
2141
|
+
* "roles": [
|
|
2142
|
+
* "admin",
|
|
2143
|
+
* "user"
|
|
2144
|
+
* ],
|
|
2145
|
+
* "stripeCustomerId": "cus_1234"
|
|
2146
|
+
* }
|
|
2147
|
+
*/
|
|
2148
|
+
meta?: {
|
|
2149
|
+
[key: string]: unknown;
|
|
2150
|
+
};
|
|
2151
|
+
/**
|
|
2152
|
+
* @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
|
|
2153
|
+
* @example 123
|
|
2154
|
+
*/
|
|
2155
|
+
expires?: number;
|
|
2156
|
+
/**
|
|
2157
|
+
* @description The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit.
|
|
2158
|
+
* @example {
|
|
2159
|
+
* "limit": 10,
|
|
2160
|
+
* "remaining": 9,
|
|
2161
|
+
* "reset": 3600000
|
|
2162
|
+
* }
|
|
2163
|
+
*/
|
|
2164
|
+
ratelimit?: {
|
|
2165
|
+
/**
|
|
2166
|
+
* @description Maximum number of requests that can be made inside a window
|
|
2167
|
+
* @example 10
|
|
2168
|
+
*/
|
|
2169
|
+
limit: number;
|
|
2170
|
+
/**
|
|
2171
|
+
* @description Remaining requests after this verification
|
|
2172
|
+
* @example 9
|
|
2173
|
+
*/
|
|
2174
|
+
remaining: number;
|
|
2175
|
+
/**
|
|
2176
|
+
* @description Unix timestamp in milliseconds when the ratelimit will reset
|
|
2177
|
+
* @example 3600000
|
|
2178
|
+
*/
|
|
2179
|
+
reset: number;
|
|
2180
|
+
};
|
|
2181
|
+
/**
|
|
2182
|
+
* @description The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit.
|
|
2183
|
+
* @example 1000
|
|
2184
|
+
*/
|
|
2185
|
+
remaining?: number;
|
|
2186
|
+
/**
|
|
2187
|
+
* @description If the key is invalid this field will be set to the reason why it is invalid.
|
|
2188
|
+
* Possible values are:
|
|
2189
|
+
* - NOT_FOUND: the key does not exist or has expired
|
|
2190
|
+
* - FORBIDDEN: the key is not allowed to access the api
|
|
2191
|
+
* - USAGE_EXCEEDED: the key has exceeded its request limit
|
|
2192
|
+
* - RATE_LIMITED: the key has been ratelimited
|
|
2193
|
+
* - UNAUTHORIZED: the key is not authorized
|
|
2194
|
+
* - DISABLED: the key is disabled
|
|
2195
|
+
* @enum {string}
|
|
2196
|
+
*/
|
|
2197
|
+
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | "UNAUTHORIZED" | "DISABLED";
|
|
2198
|
+
/** @description Sets the key to be enabled or disabled. Disabled keys will not verify. */
|
|
2199
|
+
enabled?: boolean;
|
|
2200
|
+
};
|
|
2201
|
+
V1KeysVerifyKeyRequest: {
|
|
2202
|
+
/**
|
|
2203
|
+
* @description The id of the api where the key belongs to. This is optional for now but will be required soon.
|
|
2204
|
+
* The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail.
|
|
2205
|
+
* @example api_1234
|
|
2206
|
+
*/
|
|
2207
|
+
apiId?: string;
|
|
2208
|
+
/**
|
|
2209
|
+
* @description The key to verify
|
|
2210
|
+
* @example sk_1234
|
|
2211
|
+
*/
|
|
2212
|
+
key: string;
|
|
2283
2213
|
};
|
|
2284
2214
|
};
|
|
2285
2215
|
responses: never;
|
|
@@ -2314,6 +2244,14 @@ type UnkeyOptions = ({
|
|
|
2314
2244
|
* @default https://api.unkey.dev
|
|
2315
2245
|
*/
|
|
2316
2246
|
baseUrl?: string;
|
|
2247
|
+
/**
|
|
2248
|
+
*
|
|
2249
|
+
* By default telemetry data is enabled, and sends:
|
|
2250
|
+
* runtime (Node.js / Edge)
|
|
2251
|
+
* platform (Node.js / Vercel / AWS)
|
|
2252
|
+
* SDK version
|
|
2253
|
+
*/
|
|
2254
|
+
disableTelemetry?: boolean;
|
|
2317
2255
|
/**
|
|
2318
2256
|
* Retry on network errors
|
|
2319
2257
|
*/
|
|
@@ -2344,7 +2282,7 @@ type UnkeyOptions = ({
|
|
|
2344
2282
|
*
|
|
2345
2283
|
* You can leave this blank unless you are building a wrapper around this SDK.
|
|
2346
2284
|
*/
|
|
2347
|
-
wrapperSdkVersion?:
|
|
2285
|
+
wrapperSdkVersion?: string;
|
|
2348
2286
|
};
|
|
2349
2287
|
type Result<R> = {
|
|
2350
2288
|
result: R;
|
|
@@ -2357,12 +2295,13 @@ declare class Unkey {
|
|
|
2357
2295
|
readonly baseUrl: string;
|
|
2358
2296
|
private readonly rootKey;
|
|
2359
2297
|
private readonly cache?;
|
|
2360
|
-
private readonly
|
|
2298
|
+
private readonly telemetry?;
|
|
2361
2299
|
readonly retry: {
|
|
2362
2300
|
attempts: number;
|
|
2363
2301
|
backoff: (retryCount: number) => number;
|
|
2364
2302
|
};
|
|
2365
2303
|
constructor(opts: UnkeyOptions);
|
|
2304
|
+
private getHeaders;
|
|
2366
2305
|
private fetch;
|
|
2367
2306
|
get keys(): {
|
|
2368
2307
|
create: (req: paths["/v1/keys.createKey"]["post"]["requestBody"]["content"]["application/json"]) => Promise<Result<paths["/v1/keys.createKey"]["post"]["responses"]["200"]["content"]["application/json"]>>;
|
|
@@ -2429,7 +2368,8 @@ declare function verifyKey(req: string | {
|
|
|
2429
2368
|
reset: number;
|
|
2430
2369
|
} | undefined;
|
|
2431
2370
|
remaining?: number | undefined;
|
|
2432
|
-
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | undefined;
|
|
2371
|
+
code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | "UNAUTHORIZED" | "DISABLED" | undefined;
|
|
2372
|
+
enabled?: boolean | undefined;
|
|
2433
2373
|
};
|
|
2434
2374
|
error?: undefined;
|
|
2435
2375
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -26,21 +26,45 @@ __export(src_exports, {
|
|
|
26
26
|
module.exports = __toCommonJS(src_exports);
|
|
27
27
|
|
|
28
28
|
// package.json
|
|
29
|
-
var version = "0.
|
|
29
|
+
var version = "0.17.0";
|
|
30
|
+
|
|
31
|
+
// src/telemetry.ts
|
|
32
|
+
function getTelemetry(opts) {
|
|
33
|
+
let platform;
|
|
34
|
+
let runtime;
|
|
35
|
+
const sdkVersions = [`@unkey/api@${version}`];
|
|
36
|
+
try {
|
|
37
|
+
if (typeof process !== "undefined") {
|
|
38
|
+
if (process.env.UNKEY_DISABLE_TELEMETRY) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
platform = process.env.VERCEL ? "vercel" : process.env.AWS_REGION ? "aws" : void 0;
|
|
42
|
+
if (typeof EdgeRuntime !== "undefined") {
|
|
43
|
+
runtime = "edge-light";
|
|
44
|
+
} else {
|
|
45
|
+
runtime = `node@${process.version}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (opts.wrapperSdkVersion) {
|
|
49
|
+
sdkVersions.push(opts.wrapperSdkVersion);
|
|
50
|
+
}
|
|
51
|
+
} catch (_error) {
|
|
52
|
+
}
|
|
53
|
+
return { platform, runtime, sdkVersions };
|
|
54
|
+
}
|
|
30
55
|
|
|
31
56
|
// src/client.ts
|
|
32
57
|
var Unkey = class {
|
|
33
58
|
baseUrl;
|
|
34
59
|
rootKey;
|
|
35
60
|
cache;
|
|
36
|
-
|
|
61
|
+
telemetry;
|
|
37
62
|
retry;
|
|
38
63
|
constructor(opts) {
|
|
39
64
|
this.baseUrl = opts.baseUrl ?? "https://api.unkey.dev";
|
|
40
65
|
this.rootKey = opts.rootKey ?? opts.token;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.sdkVersions.push(opts.wrapperSdkVersion);
|
|
66
|
+
if (!opts.disableTelemetry) {
|
|
67
|
+
this.telemetry = getTelemetry(opts);
|
|
44
68
|
}
|
|
45
69
|
this.cache = opts.cache;
|
|
46
70
|
if (!this.rootKey) {
|
|
@@ -53,6 +77,22 @@ var Unkey = class {
|
|
|
53
77
|
backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10))
|
|
54
78
|
};
|
|
55
79
|
}
|
|
80
|
+
getHeaders() {
|
|
81
|
+
const headers = {
|
|
82
|
+
"Content-Type": "application/json",
|
|
83
|
+
Authorization: `Bearer ${this.rootKey}`
|
|
84
|
+
};
|
|
85
|
+
if (this.telemetry?.sdkVersions) {
|
|
86
|
+
headers["Unkey-Telemetry-SDK"] = this.telemetry.sdkVersions.join(",");
|
|
87
|
+
}
|
|
88
|
+
if (this.telemetry?.platform) {
|
|
89
|
+
headers["Unkey-Telemetry-Platform"] = this.telemetry.platform;
|
|
90
|
+
}
|
|
91
|
+
if (this.telemetry?.runtime) {
|
|
92
|
+
headers["Unkey-Telemetry-Runtime"] = this.telemetry.runtime;
|
|
93
|
+
}
|
|
94
|
+
return headers;
|
|
95
|
+
}
|
|
56
96
|
async fetch(req) {
|
|
57
97
|
let res = null;
|
|
58
98
|
let err = null;
|
|
@@ -60,16 +100,15 @@ var Unkey = class {
|
|
|
60
100
|
const url = new URL(`${this.baseUrl}/${req.path.join("/")}`);
|
|
61
101
|
if (req.query) {
|
|
62
102
|
for (const [k, v] of Object.entries(req.query)) {
|
|
103
|
+
if (v === null) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
63
106
|
url.searchParams.set(k, v.toString());
|
|
64
107
|
}
|
|
65
108
|
}
|
|
66
109
|
res = await fetch(url, {
|
|
67
110
|
method: req.method,
|
|
68
|
-
headers:
|
|
69
|
-
"Content-Type": "application/json",
|
|
70
|
-
Authorization: `Bearer ${this.rootKey}`,
|
|
71
|
-
"Unkey-SDK": this.sdkVersions.join(",")
|
|
72
|
-
},
|
|
111
|
+
headers: this.getHeaders(),
|
|
73
112
|
cache: this.cache,
|
|
74
113
|
body: JSON.stringify(req.body)
|
|
75
114
|
}).catch((e) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../package.json","../src/client.ts","../src/verify.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./verify\";\nexport * from \"./errors\";\n","{\n \"name\": \"@unkey/api\",\n \"version\": \"0.15.0\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"keywords\": [\n \"unkey\",\n \"client\",\n \"api\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/unkeyed/unkey/issues\"\n },\n \"homepage\": \"https://github.com/unkeyed/unkey#readme\",\n \"files\": [\n \"./dist/**\"\n ],\n \"author\": \"Andreas Thomas <andreas@chronark.com>\",\n \"scripts\": {\n \"test\": \"bun test\",\n \"test:coverage\": \"bun test --coverage\",\n \"generate\": \"openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts\",\n \"build\": \"pnpm generate && tsup\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.8.7\",\n \"@unkey/tsconfig\": \"workspace:^\",\n \"openapi-typescript\": \"^6.7.2\",\n \"tsup\": \"^7.2.0\",\n \"tsx\": \"^3.14.0\",\n \"typescript\": \"^5.2.2\"\n }\n}\n","import { version } from \"../package.json\";\nimport { ErrorResponse } from \"./errors\";\nimport type { paths } from \"./openapi\";\nexport type UnkeyOptions = (\n | {\n token?: never;\n\n /**\n * The root key from unkey.dev.\n *\n * You can create/manage your root keys here:\n * https://unkey.dev/app/settings/root-keys\n */\n rootKey: string;\n }\n | {\n /**\n * The workspace key from unkey.dev\n *\n * @deprecated Use `rootKey`\n */\n token: string;\n rootKey?: never;\n }\n) & {\n /**\n * @default https://api.unkey.dev\n */\n baseUrl?: string;\n\n /**\n * Retry on network errors\n */\n retry?: {\n /**\n * How many attempts should be made\n * The maximum number of requests will be `attempts + 1`\n * `0` means no retries\n *\n * @default 5\n */\n attempts?: number;\n /**\n * Return how many milliseconds to wait until the next attempt is made\n *\n * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),`\n */\n backoff?: (retryCount: number) => number;\n };\n /**\n * Customize the `fetch` cache behaviour\n */\n cache?: RequestCache;\n\n /**\n * The version of the SDK instantiating this client.\n *\n * This is used for internal metrics and is not covered by semver, and may change at any time.\n *\n * You can leave this blank unless you are building a wrapper around this SDK.\n */\n wrapperSdkVersion?: `v${string}`;\n};\n\ntype ApiRequest = {\n path: string[];\n} & (\n | {\n method: \"GET\";\n body?: never;\n query?: Record<string, string | number | boolean>;\n }\n | {\n method: \"POST\";\n body?: unknown;\n query?: never;\n }\n);\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: ErrorResponse[\"error\"];\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n private readonly sdkVersions: `v${string}`[] = [];\n\n public readonly retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n constructor(opts: UnkeyOptions) {\n this.baseUrl = opts.baseUrl ?? \"https://api.unkey.dev\";\n this.rootKey = opts.rootKey ?? opts.token;\n this.sdkVersions.push(`v${version}`);\n if (opts.wrapperSdkVersion) {\n this.sdkVersions.push(opts.wrapperSdkVersion);\n }\n\n this.cache = opts.cache;\n /**\n * Even though typescript should prevent this, some people still pass undefined or empty strings\n */\n if (!this.rootKey) {\n throw new Error(\n \"Unkey root key must be set, maybe you passed in `undefined` or an empty string?\",\n );\n }\n\n this.retry = {\n attempts: opts.retry?.attempts ?? 5,\n backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)),\n };\n }\n\n private async fetch<TResult>(req: ApiRequest): Promise<Result<TResult>> {\n let res: Response | null = null;\n let err: Error | null = null;\n for (let i = 0; i <= this.retry.attempts; i++) {\n const url = new URL(`${this.baseUrl}/${req.path.join(\"/\")}`);\n if (req.query) {\n for (const [k, v] of Object.entries(req.query)) {\n url.searchParams.set(k, v.toString());\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n \"Unkey-SDK\": this.sdkVersions.join(\",\"),\n },\n cache: this.cache,\n body: JSON.stringify(req.body),\n }).catch((e: Error) => {\n err = e;\n return null; // set `res` to `null`\n });\n if (res?.ok) {\n return { result: (await res.json()) as TResult };\n }\n const backoff = this.retry.backoff(i);\n console.debug(\n \"attempt %d of %d to reach %s failed, retrying in %d ms: %s\",\n i + 1,\n this.retry.attempts + 1,\n url,\n backoff,\n // @ts-ignore I don't understand why `err` is `never`\n err?.message,\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: (await res.json()) as ErrorResponse[\"error\"] };\n }\n\n return {\n error: {\n // @ts-ignore\n code: \"FETCH_ERROR\",\n // @ts-ignore I don't understand why `err` is `never`\n message: err?.message ?? \"No response\",\n docs: \"https://developer.mozilla.org/en-US/docs/Web/API/fetch\",\n requestId: \"N/A\",\n },\n };\n }\n\n public get keys() {\n return {\n create: async (\n req: paths[\"/v1/keys.createKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.createKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.createKey\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (\n req: paths[\"/v1/keys.updateKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateKey\"],\n method: \"POST\",\n body: req,\n });\n },\n verify: async (\n req: paths[\"/v1/keys.verifyKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.verifyKey\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/keys.deleteKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.deleteKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.deleteKey\"],\n method: \"POST\",\n body: req,\n });\n },\n updateRemaining: async (\n req: paths[\"/v1/keys.updateRemaining\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateRemaining\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateRemaining\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/keys.getKey\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/keys.getKey\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getKey\"],\n method: \"GET\",\n query: req,\n });\n },\n getVerifications: async (\n req: paths[\"/v1/keys.getVerifications\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.getVerifications\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getVerifications\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (\n req: paths[\"/v1/apis.createApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.createApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/apis.deleteApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.deleteApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.deleteApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/apis.getApi\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.getApi\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.getApi\"],\n method: \"GET\",\n query: req,\n });\n },\n listKeys: async (\n req: paths[\"/v1/apis.listKeys\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.listKeys\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.listKeys\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n}\n","import { Unkey } from \"./client\";\n\n/**\n * Verify a key\n *\n * @example\n * ```ts\n * const { result, error } = await verifyKey(\"key_123\")\n * if (error){\n * // handle potential network or bad request error\n * // a link to our docs will be in the `error.docs` field\n * console.error(error.message)\n * return\n * }\n * if (!result.valid) {\n * // do not grant access\n * return\n * }\n *\n * // process request\n * console.log(result)\n * ```\n */\nexport function verifyKey(req: string | { key: string; apiId: string }) {\n // yes this is empty to make typescript happy but we don't need a token for verifying keys\n // it's not the cleanest but it works for now :)\n const unkey = new Unkey({ rootKey: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../package.json","../src/telemetry.ts","../src/client.ts","../src/verify.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./verify\";\nexport * from \"./errors\";\n","{\n \"name\": \"@unkey/api\",\n \"version\": \"0.17.0\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"keywords\": [\n \"unkey\",\n \"client\",\n \"api\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/unkeyed/unkey/issues\"\n },\n \"homepage\": \"https://github.com/unkeyed/unkey#readme\",\n \"files\": [\n \"./dist/**\"\n ],\n \"author\": \"Andreas Thomas <andreas@chronark.com>\",\n \"scripts\": {\n \"generate\": \"openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts\",\n \"build\": \"pnpm generate && tsup\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.11.5\",\n \"@unkey/tsconfig\": \"workspace:^\",\n \"openapi-typescript\": \"^6.7.2\",\n \"tsup\": \"^7.2.0\",\n \"typescript\": \"^5.2.2\"\n }\n}\n","import { version } from \"../package.json\";\nimport { UnkeyOptions } from \"./client\";\n\nexport type Telemetry = {\n /**\n * Unkey-Telemetry-Sdk\n * @example @unkey/api@v1.1.1\n */\n sdkVersions: string[];\n /**\n * Unkey-Telemetry-Platform\n * @example cloudflare\n */\n platform?: string;\n /**\n * Unkey-Telemetry-Runtime\n * @example node@v18\n */\n runtime?: string;\n};\n\nexport function getTelemetry(opts: UnkeyOptions): Telemetry | null {\n let platform: string | undefined;\n let runtime: string | undefined;\n const sdkVersions = [`@unkey/api@${version}`];\n\n try {\n if (typeof process !== \"undefined\") {\n if (process.env.UNKEY_DISABLE_TELEMETRY) {\n return null;\n }\n platform = process.env.VERCEL ? \"vercel\" : process.env.AWS_REGION ? \"aws\" : undefined;\n\n // @ts-ignore\n if (typeof EdgeRuntime !== \"undefined\") {\n runtime = \"edge-light\";\n } else {\n runtime = `node@${process.version}`;\n }\n }\n\n if (opts.wrapperSdkVersion) {\n sdkVersions.push(opts.wrapperSdkVersion);\n }\n } catch (_error) {}\n\n return { platform, runtime, sdkVersions };\n}\n","import { ErrorResponse } from \"./errors\";\nimport type { paths } from \"./openapi\";\n\nimport { type Telemetry, getTelemetry } from \"./telemetry\";\n\nexport type UnkeyOptions = (\n | {\n token?: never;\n\n /**\n * The root key from unkey.dev.\n *\n * You can create/manage your root keys here:\n * https://unkey.dev/app/settings/root-keys\n */\n rootKey: string;\n }\n | {\n /**\n * The workspace key from unkey.dev\n *\n * @deprecated Use `rootKey`\n */\n token: string;\n rootKey?: never;\n }\n) & {\n /**\n * @default https://api.unkey.dev\n */\n baseUrl?: string;\n\n /**\n *\n * By default telemetry data is enabled, and sends:\n * runtime (Node.js / Edge)\n * platform (Node.js / Vercel / AWS)\n * SDK version\n */\n disableTelemetry?: boolean;\n\n /**\n * Retry on network errors\n */\n retry?: {\n /**\n * How many attempts should be made\n * The maximum number of requests will be `attempts + 1`\n * `0` means no retries\n *\n * @default 5\n */\n attempts?: number;\n /**\n * Return how many milliseconds to wait until the next attempt is made\n *\n * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),`\n */\n backoff?: (retryCount: number) => number;\n };\n /**\n * Customize the `fetch` cache behaviour\n */\n cache?: RequestCache;\n\n /**\n * The version of the SDK instantiating this client.\n *\n * This is used for internal metrics and is not covered by semver, and may change at any time.\n *\n * You can leave this blank unless you are building a wrapper around this SDK.\n */\n wrapperSdkVersion?: string;\n};\n\ntype ApiRequest = {\n path: string[];\n} & (\n | {\n method: \"GET\";\n body?: never;\n query?: Record<string, string | number | boolean | null>;\n }\n | {\n method: \"POST\";\n body?: unknown;\n query?: never;\n }\n);\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: ErrorResponse[\"error\"];\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n private readonly telemetry?: Telemetry | null;\n\n public readonly retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n constructor(opts: UnkeyOptions) {\n this.baseUrl = opts.baseUrl ?? \"https://api.unkey.dev\";\n this.rootKey = opts.rootKey ?? opts.token;\n if (!opts.disableTelemetry) {\n this.telemetry = getTelemetry(opts);\n }\n\n this.cache = opts.cache;\n /**\n * Even though typescript should prevent this, some people still pass undefined or empty strings\n */\n if (!this.rootKey) {\n throw new Error(\n \"Unkey root key must be set, maybe you passed in `undefined` or an empty string?\",\n );\n }\n\n this.retry = {\n attempts: opts.retry?.attempts ?? 5,\n backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)),\n };\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n };\n if (this.telemetry?.sdkVersions) {\n headers[\"Unkey-Telemetry-SDK\"] = this.telemetry.sdkVersions.join(\",\");\n }\n if (this.telemetry?.platform) {\n headers[\"Unkey-Telemetry-Platform\"] = this.telemetry.platform;\n }\n if (this.telemetry?.runtime) {\n headers[\"Unkey-Telemetry-Runtime\"] = this.telemetry.runtime;\n }\n return headers;\n }\n\n private async fetch<TResult>(req: ApiRequest): Promise<Result<TResult>> {\n let res: Response | null = null;\n let err: Error | null = null;\n for (let i = 0; i <= this.retry.attempts; i++) {\n const url = new URL(`${this.baseUrl}/${req.path.join(\"/\")}`);\n if (req.query) {\n for (const [k, v] of Object.entries(req.query)) {\n if (v === null) {\n continue;\n }\n url.searchParams.set(k, v.toString());\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: this.getHeaders(),\n cache: this.cache,\n body: JSON.stringify(req.body),\n }).catch((e: Error) => {\n err = e;\n return null; // set `res` to `null`\n });\n if (res?.ok) {\n return { result: (await res.json()) as TResult };\n }\n const backoff = this.retry.backoff(i);\n console.debug(\n \"attempt %d of %d to reach %s failed, retrying in %d ms: %s\",\n i + 1,\n this.retry.attempts + 1,\n url,\n backoff,\n // @ts-ignore I don't understand why `err` is `never`\n err?.message,\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: (await res.json()) as ErrorResponse[\"error\"] };\n }\n\n return {\n error: {\n // @ts-ignore\n code: \"FETCH_ERROR\",\n // @ts-ignore I don't understand why `err` is `never`\n message: err?.message ?? \"No response\",\n docs: \"https://developer.mozilla.org/en-US/docs/Web/API/fetch\",\n requestId: \"N/A\",\n },\n };\n }\n\n public get keys() {\n return {\n create: async (\n req: paths[\"/v1/keys.createKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.createKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.createKey\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (\n req: paths[\"/v1/keys.updateKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateKey\"],\n method: \"POST\",\n body: req,\n });\n },\n verify: async (\n req: paths[\"/v1/keys.verifyKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.verifyKey\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/keys.deleteKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.deleteKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.deleteKey\"],\n method: \"POST\",\n body: req,\n });\n },\n updateRemaining: async (\n req: paths[\"/v1/keys.updateRemaining\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateRemaining\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateRemaining\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/keys.getKey\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/keys.getKey\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getKey\"],\n method: \"GET\",\n query: req,\n });\n },\n getVerifications: async (\n req: paths[\"/v1/keys.getVerifications\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.getVerifications\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getVerifications\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (\n req: paths[\"/v1/apis.createApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.createApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/apis.deleteApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.deleteApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.deleteApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/apis.getApi\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.getApi\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.getApi\"],\n method: \"GET\",\n query: req,\n });\n },\n listKeys: async (\n req: paths[\"/v1/apis.listKeys\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.listKeys\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.listKeys\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n}\n","import { Unkey } from \"./client\";\n\n/**\n * Verify a key\n *\n * @example\n * ```ts\n * const { result, error } = await verifyKey(\"key_123\")\n * if (error){\n * // handle potential network or bad request error\n * // a link to our docs will be in the `error.docs` field\n * console.error(error.message)\n * return\n * }\n * if (!result.valid) {\n * // do not grant access\n * return\n * }\n *\n * // process request\n * console.log(result)\n * ```\n */\nexport function verifyKey(req: string | { key: string; apiId: string }) {\n // yes this is empty to make typescript happy but we don't need a token for verifying keys\n // it's not the cleanest but it works for now :)\n const unkey = new Unkey({ rootKey: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,43 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.
|
|
2
|
+
var version = "0.17.0";
|
|
3
|
+
|
|
4
|
+
// src/telemetry.ts
|
|
5
|
+
function getTelemetry(opts) {
|
|
6
|
+
let platform;
|
|
7
|
+
let runtime;
|
|
8
|
+
const sdkVersions = [`@unkey/api@${version}`];
|
|
9
|
+
try {
|
|
10
|
+
if (typeof process !== "undefined") {
|
|
11
|
+
if (process.env.UNKEY_DISABLE_TELEMETRY) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
platform = process.env.VERCEL ? "vercel" : process.env.AWS_REGION ? "aws" : void 0;
|
|
15
|
+
if (typeof EdgeRuntime !== "undefined") {
|
|
16
|
+
runtime = "edge-light";
|
|
17
|
+
} else {
|
|
18
|
+
runtime = `node@${process.version}`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (opts.wrapperSdkVersion) {
|
|
22
|
+
sdkVersions.push(opts.wrapperSdkVersion);
|
|
23
|
+
}
|
|
24
|
+
} catch (_error) {
|
|
25
|
+
}
|
|
26
|
+
return { platform, runtime, sdkVersions };
|
|
27
|
+
}
|
|
3
28
|
|
|
4
29
|
// src/client.ts
|
|
5
30
|
var Unkey = class {
|
|
6
31
|
baseUrl;
|
|
7
32
|
rootKey;
|
|
8
33
|
cache;
|
|
9
|
-
|
|
34
|
+
telemetry;
|
|
10
35
|
retry;
|
|
11
36
|
constructor(opts) {
|
|
12
37
|
this.baseUrl = opts.baseUrl ?? "https://api.unkey.dev";
|
|
13
38
|
this.rootKey = opts.rootKey ?? opts.token;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this.sdkVersions.push(opts.wrapperSdkVersion);
|
|
39
|
+
if (!opts.disableTelemetry) {
|
|
40
|
+
this.telemetry = getTelemetry(opts);
|
|
17
41
|
}
|
|
18
42
|
this.cache = opts.cache;
|
|
19
43
|
if (!this.rootKey) {
|
|
@@ -26,6 +50,22 @@ var Unkey = class {
|
|
|
26
50
|
backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10))
|
|
27
51
|
};
|
|
28
52
|
}
|
|
53
|
+
getHeaders() {
|
|
54
|
+
const headers = {
|
|
55
|
+
"Content-Type": "application/json",
|
|
56
|
+
Authorization: `Bearer ${this.rootKey}`
|
|
57
|
+
};
|
|
58
|
+
if (this.telemetry?.sdkVersions) {
|
|
59
|
+
headers["Unkey-Telemetry-SDK"] = this.telemetry.sdkVersions.join(",");
|
|
60
|
+
}
|
|
61
|
+
if (this.telemetry?.platform) {
|
|
62
|
+
headers["Unkey-Telemetry-Platform"] = this.telemetry.platform;
|
|
63
|
+
}
|
|
64
|
+
if (this.telemetry?.runtime) {
|
|
65
|
+
headers["Unkey-Telemetry-Runtime"] = this.telemetry.runtime;
|
|
66
|
+
}
|
|
67
|
+
return headers;
|
|
68
|
+
}
|
|
29
69
|
async fetch(req) {
|
|
30
70
|
let res = null;
|
|
31
71
|
let err = null;
|
|
@@ -33,16 +73,15 @@ var Unkey = class {
|
|
|
33
73
|
const url = new URL(`${this.baseUrl}/${req.path.join("/")}`);
|
|
34
74
|
if (req.query) {
|
|
35
75
|
for (const [k, v] of Object.entries(req.query)) {
|
|
76
|
+
if (v === null) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
36
79
|
url.searchParams.set(k, v.toString());
|
|
37
80
|
}
|
|
38
81
|
}
|
|
39
82
|
res = await fetch(url, {
|
|
40
83
|
method: req.method,
|
|
41
|
-
headers:
|
|
42
|
-
"Content-Type": "application/json",
|
|
43
|
-
Authorization: `Bearer ${this.rootKey}`,
|
|
44
|
-
"Unkey-SDK": this.sdkVersions.join(",")
|
|
45
|
-
},
|
|
84
|
+
headers: this.getHeaders(),
|
|
46
85
|
cache: this.cache,
|
|
47
86
|
body: JSON.stringify(req.body)
|
|
48
87
|
}).catch((e) => {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/client.ts","../src/verify.ts"],"sourcesContent":["{\n \"name\": \"@unkey/api\",\n \"version\": \"0.15.0\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"keywords\": [\n \"unkey\",\n \"client\",\n \"api\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/unkeyed/unkey/issues\"\n },\n \"homepage\": \"https://github.com/unkeyed/unkey#readme\",\n \"files\": [\n \"./dist/**\"\n ],\n \"author\": \"Andreas Thomas <andreas@chronark.com>\",\n \"scripts\": {\n \"test\": \"bun test\",\n \"test:coverage\": \"bun test --coverage\",\n \"generate\": \"openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts\",\n \"build\": \"pnpm generate && tsup\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.8.7\",\n \"@unkey/tsconfig\": \"workspace:^\",\n \"openapi-typescript\": \"^6.7.2\",\n \"tsup\": \"^7.2.0\",\n \"tsx\": \"^3.14.0\",\n \"typescript\": \"^5.2.2\"\n }\n}\n","import { version } from \"../package.json\";\nimport { ErrorResponse } from \"./errors\";\nimport type { paths } from \"./openapi\";\nexport type UnkeyOptions = (\n | {\n token?: never;\n\n /**\n * The root key from unkey.dev.\n *\n * You can create/manage your root keys here:\n * https://unkey.dev/app/settings/root-keys\n */\n rootKey: string;\n }\n | {\n /**\n * The workspace key from unkey.dev\n *\n * @deprecated Use `rootKey`\n */\n token: string;\n rootKey?: never;\n }\n) & {\n /**\n * @default https://api.unkey.dev\n */\n baseUrl?: string;\n\n /**\n * Retry on network errors\n */\n retry?: {\n /**\n * How many attempts should be made\n * The maximum number of requests will be `attempts + 1`\n * `0` means no retries\n *\n * @default 5\n */\n attempts?: number;\n /**\n * Return how many milliseconds to wait until the next attempt is made\n *\n * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),`\n */\n backoff?: (retryCount: number) => number;\n };\n /**\n * Customize the `fetch` cache behaviour\n */\n cache?: RequestCache;\n\n /**\n * The version of the SDK instantiating this client.\n *\n * This is used for internal metrics and is not covered by semver, and may change at any time.\n *\n * You can leave this blank unless you are building a wrapper around this SDK.\n */\n wrapperSdkVersion?: `v${string}`;\n};\n\ntype ApiRequest = {\n path: string[];\n} & (\n | {\n method: \"GET\";\n body?: never;\n query?: Record<string, string | number | boolean>;\n }\n | {\n method: \"POST\";\n body?: unknown;\n query?: never;\n }\n);\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: ErrorResponse[\"error\"];\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n private readonly sdkVersions: `v${string}`[] = [];\n\n public readonly retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n constructor(opts: UnkeyOptions) {\n this.baseUrl = opts.baseUrl ?? \"https://api.unkey.dev\";\n this.rootKey = opts.rootKey ?? opts.token;\n this.sdkVersions.push(`v${version}`);\n if (opts.wrapperSdkVersion) {\n this.sdkVersions.push(opts.wrapperSdkVersion);\n }\n\n this.cache = opts.cache;\n /**\n * Even though typescript should prevent this, some people still pass undefined or empty strings\n */\n if (!this.rootKey) {\n throw new Error(\n \"Unkey root key must be set, maybe you passed in `undefined` or an empty string?\",\n );\n }\n\n this.retry = {\n attempts: opts.retry?.attempts ?? 5,\n backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)),\n };\n }\n\n private async fetch<TResult>(req: ApiRequest): Promise<Result<TResult>> {\n let res: Response | null = null;\n let err: Error | null = null;\n for (let i = 0; i <= this.retry.attempts; i++) {\n const url = new URL(`${this.baseUrl}/${req.path.join(\"/\")}`);\n if (req.query) {\n for (const [k, v] of Object.entries(req.query)) {\n url.searchParams.set(k, v.toString());\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n \"Unkey-SDK\": this.sdkVersions.join(\",\"),\n },\n cache: this.cache,\n body: JSON.stringify(req.body),\n }).catch((e: Error) => {\n err = e;\n return null; // set `res` to `null`\n });\n if (res?.ok) {\n return { result: (await res.json()) as TResult };\n }\n const backoff = this.retry.backoff(i);\n console.debug(\n \"attempt %d of %d to reach %s failed, retrying in %d ms: %s\",\n i + 1,\n this.retry.attempts + 1,\n url,\n backoff,\n // @ts-ignore I don't understand why `err` is `never`\n err?.message,\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: (await res.json()) as ErrorResponse[\"error\"] };\n }\n\n return {\n error: {\n // @ts-ignore\n code: \"FETCH_ERROR\",\n // @ts-ignore I don't understand why `err` is `never`\n message: err?.message ?? \"No response\",\n docs: \"https://developer.mozilla.org/en-US/docs/Web/API/fetch\",\n requestId: \"N/A\",\n },\n };\n }\n\n public get keys() {\n return {\n create: async (\n req: paths[\"/v1/keys.createKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.createKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.createKey\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (\n req: paths[\"/v1/keys.updateKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateKey\"],\n method: \"POST\",\n body: req,\n });\n },\n verify: async (\n req: paths[\"/v1/keys.verifyKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.verifyKey\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/keys.deleteKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.deleteKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.deleteKey\"],\n method: \"POST\",\n body: req,\n });\n },\n updateRemaining: async (\n req: paths[\"/v1/keys.updateRemaining\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateRemaining\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateRemaining\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/keys.getKey\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/keys.getKey\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getKey\"],\n method: \"GET\",\n query: req,\n });\n },\n getVerifications: async (\n req: paths[\"/v1/keys.getVerifications\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.getVerifications\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getVerifications\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (\n req: paths[\"/v1/apis.createApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.createApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/apis.deleteApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.deleteApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.deleteApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/apis.getApi\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.getApi\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.getApi\"],\n method: \"GET\",\n query: req,\n });\n },\n listKeys: async (\n req: paths[\"/v1/apis.listKeys\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.listKeys\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.listKeys\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n}\n","import { Unkey } from \"./client\";\n\n/**\n * Verify a key\n *\n * @example\n * ```ts\n * const { result, error } = await verifyKey(\"key_123\")\n * if (error){\n * // handle potential network or bad request error\n * // a link to our docs will be in the `error.docs` field\n * console.error(error.message)\n * return\n * }\n * if (!result.valid) {\n * // do not grant access\n * return\n * }\n *\n * // process request\n * console.log(result)\n * ```\n */\nexport function verifyKey(req: string | { key: string; apiId: string }) {\n // yes this is empty to make typescript happy but we don't need a token for verifying keys\n // it's not the cleanest but it works for now :)\n const unkey = new Unkey({ rootKey: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/telemetry.ts","../src/client.ts","../src/verify.ts"],"sourcesContent":["{\n \"name\": \"@unkey/api\",\n \"version\": \"0.17.0\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"keywords\": [\n \"unkey\",\n \"client\",\n \"api\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/unkeyed/unkey/issues\"\n },\n \"homepage\": \"https://github.com/unkeyed/unkey#readme\",\n \"files\": [\n \"./dist/**\"\n ],\n \"author\": \"Andreas Thomas <andreas@chronark.com>\",\n \"scripts\": {\n \"generate\": \"openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts\",\n \"build\": \"pnpm generate && tsup\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.11.5\",\n \"@unkey/tsconfig\": \"workspace:^\",\n \"openapi-typescript\": \"^6.7.2\",\n \"tsup\": \"^7.2.0\",\n \"typescript\": \"^5.2.2\"\n }\n}\n","import { version } from \"../package.json\";\nimport { UnkeyOptions } from \"./client\";\n\nexport type Telemetry = {\n /**\n * Unkey-Telemetry-Sdk\n * @example @unkey/api@v1.1.1\n */\n sdkVersions: string[];\n /**\n * Unkey-Telemetry-Platform\n * @example cloudflare\n */\n platform?: string;\n /**\n * Unkey-Telemetry-Runtime\n * @example node@v18\n */\n runtime?: string;\n};\n\nexport function getTelemetry(opts: UnkeyOptions): Telemetry | null {\n let platform: string | undefined;\n let runtime: string | undefined;\n const sdkVersions = [`@unkey/api@${version}`];\n\n try {\n if (typeof process !== \"undefined\") {\n if (process.env.UNKEY_DISABLE_TELEMETRY) {\n return null;\n }\n platform = process.env.VERCEL ? \"vercel\" : process.env.AWS_REGION ? \"aws\" : undefined;\n\n // @ts-ignore\n if (typeof EdgeRuntime !== \"undefined\") {\n runtime = \"edge-light\";\n } else {\n runtime = `node@${process.version}`;\n }\n }\n\n if (opts.wrapperSdkVersion) {\n sdkVersions.push(opts.wrapperSdkVersion);\n }\n } catch (_error) {}\n\n return { platform, runtime, sdkVersions };\n}\n","import { ErrorResponse } from \"./errors\";\nimport type { paths } from \"./openapi\";\n\nimport { type Telemetry, getTelemetry } from \"./telemetry\";\n\nexport type UnkeyOptions = (\n | {\n token?: never;\n\n /**\n * The root key from unkey.dev.\n *\n * You can create/manage your root keys here:\n * https://unkey.dev/app/settings/root-keys\n */\n rootKey: string;\n }\n | {\n /**\n * The workspace key from unkey.dev\n *\n * @deprecated Use `rootKey`\n */\n token: string;\n rootKey?: never;\n }\n) & {\n /**\n * @default https://api.unkey.dev\n */\n baseUrl?: string;\n\n /**\n *\n * By default telemetry data is enabled, and sends:\n * runtime (Node.js / Edge)\n * platform (Node.js / Vercel / AWS)\n * SDK version\n */\n disableTelemetry?: boolean;\n\n /**\n * Retry on network errors\n */\n retry?: {\n /**\n * How many attempts should be made\n * The maximum number of requests will be `attempts + 1`\n * `0` means no retries\n *\n * @default 5\n */\n attempts?: number;\n /**\n * Return how many milliseconds to wait until the next attempt is made\n *\n * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),`\n */\n backoff?: (retryCount: number) => number;\n };\n /**\n * Customize the `fetch` cache behaviour\n */\n cache?: RequestCache;\n\n /**\n * The version of the SDK instantiating this client.\n *\n * This is used for internal metrics and is not covered by semver, and may change at any time.\n *\n * You can leave this blank unless you are building a wrapper around this SDK.\n */\n wrapperSdkVersion?: string;\n};\n\ntype ApiRequest = {\n path: string[];\n} & (\n | {\n method: \"GET\";\n body?: never;\n query?: Record<string, string | number | boolean | null>;\n }\n | {\n method: \"POST\";\n body?: unknown;\n query?: never;\n }\n);\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: ErrorResponse[\"error\"];\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n private readonly telemetry?: Telemetry | null;\n\n public readonly retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n constructor(opts: UnkeyOptions) {\n this.baseUrl = opts.baseUrl ?? \"https://api.unkey.dev\";\n this.rootKey = opts.rootKey ?? opts.token;\n if (!opts.disableTelemetry) {\n this.telemetry = getTelemetry(opts);\n }\n\n this.cache = opts.cache;\n /**\n * Even though typescript should prevent this, some people still pass undefined or empty strings\n */\n if (!this.rootKey) {\n throw new Error(\n \"Unkey root key must be set, maybe you passed in `undefined` or an empty string?\",\n );\n }\n\n this.retry = {\n attempts: opts.retry?.attempts ?? 5,\n backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)),\n };\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n };\n if (this.telemetry?.sdkVersions) {\n headers[\"Unkey-Telemetry-SDK\"] = this.telemetry.sdkVersions.join(\",\");\n }\n if (this.telemetry?.platform) {\n headers[\"Unkey-Telemetry-Platform\"] = this.telemetry.platform;\n }\n if (this.telemetry?.runtime) {\n headers[\"Unkey-Telemetry-Runtime\"] = this.telemetry.runtime;\n }\n return headers;\n }\n\n private async fetch<TResult>(req: ApiRequest): Promise<Result<TResult>> {\n let res: Response | null = null;\n let err: Error | null = null;\n for (let i = 0; i <= this.retry.attempts; i++) {\n const url = new URL(`${this.baseUrl}/${req.path.join(\"/\")}`);\n if (req.query) {\n for (const [k, v] of Object.entries(req.query)) {\n if (v === null) {\n continue;\n }\n url.searchParams.set(k, v.toString());\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: this.getHeaders(),\n cache: this.cache,\n body: JSON.stringify(req.body),\n }).catch((e: Error) => {\n err = e;\n return null; // set `res` to `null`\n });\n if (res?.ok) {\n return { result: (await res.json()) as TResult };\n }\n const backoff = this.retry.backoff(i);\n console.debug(\n \"attempt %d of %d to reach %s failed, retrying in %d ms: %s\",\n i + 1,\n this.retry.attempts + 1,\n url,\n backoff,\n // @ts-ignore I don't understand why `err` is `never`\n err?.message,\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: (await res.json()) as ErrorResponse[\"error\"] };\n }\n\n return {\n error: {\n // @ts-ignore\n code: \"FETCH_ERROR\",\n // @ts-ignore I don't understand why `err` is `never`\n message: err?.message ?? \"No response\",\n docs: \"https://developer.mozilla.org/en-US/docs/Web/API/fetch\",\n requestId: \"N/A\",\n },\n };\n }\n\n public get keys() {\n return {\n create: async (\n req: paths[\"/v1/keys.createKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.createKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.createKey\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (\n req: paths[\"/v1/keys.updateKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateKey\"],\n method: \"POST\",\n body: req,\n });\n },\n verify: async (\n req: paths[\"/v1/keys.verifyKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.verifyKey\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/keys.deleteKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.deleteKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.deleteKey\"],\n method: \"POST\",\n body: req,\n });\n },\n updateRemaining: async (\n req: paths[\"/v1/keys.updateRemaining\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateRemaining\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateRemaining\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/keys.getKey\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/keys.getKey\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getKey\"],\n method: \"GET\",\n query: req,\n });\n },\n getVerifications: async (\n req: paths[\"/v1/keys.getVerifications\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.getVerifications\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getVerifications\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (\n req: paths[\"/v1/apis.createApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.createApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/apis.deleteApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.deleteApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.deleteApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/apis.getApi\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.getApi\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.getApi\"],\n method: \"GET\",\n query: req,\n });\n },\n listKeys: async (\n req: paths[\"/v1/apis.listKeys\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.listKeys\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.listKeys\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n}\n","import { Unkey } from \"./client\";\n\n/**\n * Verify a key\n *\n * @example\n * ```ts\n * const { result, error } = await verifyKey(\"key_123\")\n * if (error){\n * // handle potential network or bad request error\n * // a link to our docs will be in the `error.docs` field\n * console.error(error.message)\n * return\n * }\n * if (!result.valid) {\n * // do not grant access\n * return\n * }\n *\n * // process request\n * console.log(result)\n * ```\n */\nexport function verifyKey(req: string | { key: string; apiId: string }) {\n // yes this is empty to make typescript happy but we don't need a token for verifying keys\n // it's not the cleanest but it works for now :)\n const unkey = new Unkey({ rootKey: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unkey/api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,16 +22,13 @@
|
|
|
22
22
|
],
|
|
23
23
|
"author": "Andreas Thomas <andreas@chronark.com>",
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@types/node": "^20.
|
|
25
|
+
"@types/node": "^20.11.5",
|
|
26
26
|
"openapi-typescript": "^6.7.2",
|
|
27
27
|
"tsup": "^7.2.0",
|
|
28
|
-
"tsx": "^3.14.0",
|
|
29
28
|
"typescript": "^5.2.2",
|
|
30
29
|
"@unkey/tsconfig": "^0.0.0"
|
|
31
30
|
},
|
|
32
31
|
"scripts": {
|
|
33
|
-
"test": "bun test",
|
|
34
|
-
"test:coverage": "bun test --coverage",
|
|
35
32
|
"generate": "openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts",
|
|
36
33
|
"build": "pnpm generate && tsup"
|
|
37
34
|
}
|