@unkey/api 0.16.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 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
@@ -373,110 +381,14 @@ interface paths {
373
381
  post: {
374
382
  requestBody: {
375
383
  content: {
376
- "application/json": {
377
- /**
378
- * @description The id of the api where the key belongs to. This is optional for now but will be required soon.
379
- * The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail.
380
- * @example api_1234
381
- */
382
- apiId?: string;
383
- /**
384
- * @description The key to verify
385
- * @example sk_1234
386
- */
387
- key: string;
388
- };
384
+ "application/json": components["schemas"]["V1KeysVerifyKeyRequest"];
389
385
  };
390
386
  };
391
387
  responses: {
392
388
  /** @description The verification result */
393
389
  200: {
394
390
  content: {
395
- "application/json": {
396
- /**
397
- * @description The id of the key
398
- * @example key_1234
399
- */
400
- keyId?: string;
401
- /**
402
- * @description Whether the key is valid or not.
403
- * 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.
404
- * @example true
405
- */
406
- valid: boolean;
407
- /**
408
- * @description The name of the key, give keys a name to easily identifiy their purpose
409
- * @example Customer X
410
- */
411
- name?: string;
412
- /**
413
- * @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.
414
- * @example user_123
415
- */
416
- ownerId?: string;
417
- /**
418
- * @description Any additional metadata you want to store with the key
419
- * @example {
420
- * "roles": [
421
- * "admin",
422
- * "user"
423
- * ],
424
- * "stripeCustomerId": "cus_1234"
425
- * }
426
- */
427
- meta?: {
428
- [key: string]: unknown;
429
- };
430
- /**
431
- * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
432
- * @example 123
433
- */
434
- expires?: number;
435
- /**
436
- * @description The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit.
437
- * @example {
438
- * "limit": 10,
439
- * "remaining": 9,
440
- * "reset": 3600000
441
- * }
442
- */
443
- ratelimit?: {
444
- /**
445
- * @description Maximum number of requests that can be made inside a window
446
- * @example 10
447
- */
448
- limit: number;
449
- /**
450
- * @description Remaining requests after this verification
451
- * @example 9
452
- */
453
- remaining: number;
454
- /**
455
- * @description Unix timestamp in milliseconds when the ratelimit will reset
456
- * @example 3600000
457
- */
458
- reset: number;
459
- };
460
- /**
461
- * @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.
462
- * @example 1000
463
- */
464
- remaining?: number;
465
- /**
466
- * @description If the key is invalid this field will be set to the reason why it is invalid.
467
- * Possible values are:
468
- * - NOT_FOUND: the key does not exist or has expired
469
- * - FORBIDDEN: the key is not allowed to access the api
470
- * - USAGE_EXCEEDED: the key has exceeded its request limit
471
- * - RATE_LIMITED: the key has been ratelimited
472
- * - UNAUTHORIZED: the key is not authorized
473
- * - DISABLED: the key is disabled
474
- * @enum {string}
475
- */
476
- code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | "UNAUTHORIZED" | "DISABLED";
477
- /** @description Sets the key to be enabled or disabled. Disabled keys will not verify. */
478
- enabled?: boolean;
479
- };
391
+ "application/json": components["schemas"]["V1KeysVerifyKeyResponse"];
480
392
  };
481
393
  };
482
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). */
@@ -832,92 +744,6 @@ interface paths {
832
744
  };
833
745
  };
834
746
  };
835
- "/vx/keys.getVerifications": {
836
- get: {
837
- parameters: {
838
- query?: {
839
- keyId?: string;
840
- ownerId?: string;
841
- start?: number | null;
842
- end?: number | null;
843
- granularity?: "day";
844
- };
845
- };
846
- responses: {
847
- /** @description The configuration for a single key */
848
- 200: {
849
- content: {
850
- "application/json": {
851
- verifications: {
852
- /**
853
- * @description The timestamp of the usage data
854
- * @example 1620000000000
855
- */
856
- time: number;
857
- /**
858
- * @description The number of successful requests
859
- * @example 100
860
- */
861
- success: number;
862
- /**
863
- * @description The number of requests that were rate limited
864
- * @example 10
865
- */
866
- rateLimited: number;
867
- /**
868
- * @description The number of requests that exceeded the usage limit
869
- * @example 0
870
- */
871
- usageExceeded: number;
872
- }[];
873
- };
874
- };
875
- };
876
- /** @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). */
877
- 400: {
878
- content: {
879
- "application/json": components["schemas"]["ErrBadRequest"];
880
- };
881
- };
882
- /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */
883
- 401: {
884
- content: {
885
- "application/json": components["schemas"]["ErrUnauthorized"];
886
- };
887
- };
888
- /** @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. */
889
- 403: {
890
- content: {
891
- "application/json": components["schemas"]["ErrForbidden"];
892
- };
893
- };
894
- /** @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. */
895
- 404: {
896
- content: {
897
- "application/json": components["schemas"]["ErrNotFound"];
898
- };
899
- };
900
- /** @description This response is sent when a request conflicts with the current state of the server. */
901
- 409: {
902
- content: {
903
- "application/json": components["schemas"]["ErrConflict"];
904
- };
905
- };
906
- /** @description The user has sent too many requests in a given amount of time ("rate limiting") */
907
- 429: {
908
- content: {
909
- "application/json": components["schemas"]["ErrTooManyRequests"];
910
- };
911
- };
912
- /** @description The server has encountered a situation it does not know how to handle. */
913
- 500: {
914
- content: {
915
- "application/json": components["schemas"]["ErrInternalServerError"];
916
- };
917
- };
918
- };
919
- };
920
- };
921
747
  "/v1/apis.getApi": {
922
748
  get: {
923
749
  parameters: {
@@ -1203,9 +1029,6 @@ interface paths {
1203
1029
  "/v1/keys/{keyId}": {
1204
1030
  put: {
1205
1031
  parameters: {
1206
- header: {
1207
- authorization: string;
1208
- };
1209
1032
  path: {
1210
1033
  keyId: string;
1211
1034
  };
@@ -1325,11 +1148,6 @@ interface paths {
1325
1148
  };
1326
1149
  "/v1/keys/:keyId": {
1327
1150
  get: {
1328
- parameters: {
1329
- header: {
1330
- authorization: string;
1331
- };
1332
- };
1333
1151
  responses: {
1334
1152
  /** @description The configuration for a single key */
1335
1153
  200: {
@@ -1382,11 +1200,6 @@ interface paths {
1382
1200
  };
1383
1201
  };
1384
1202
  delete: {
1385
- parameters: {
1386
- header: {
1387
- authorization: string;
1388
- };
1389
- };
1390
1203
  responses: {
1391
1204
  /** @description The key was successfully revoked, it may take up to 30s for this to take effect in all regions */
1392
1205
  200: {
@@ -1441,11 +1254,6 @@ interface paths {
1441
1254
  };
1442
1255
  "/v1/keys": {
1443
1256
  post: {
1444
- parameters: {
1445
- header: {
1446
- authorization: string;
1447
- };
1448
- };
1449
1257
  requestBody: {
1450
1258
  content: {
1451
1259
  "application/json": {
@@ -1897,9 +1705,6 @@ interface paths {
1897
1705
  };
1898
1706
  delete: {
1899
1707
  parameters: {
1900
- header: {
1901
- authorization: string;
1902
- };
1903
1708
  path: {
1904
1709
  apiId: string;
1905
1710
  };
@@ -2294,12 +2099,118 @@ interface components {
2294
2099
  /** @description Determines the speed at which tokens are refilled, in milliseconds. */
2295
2100
  refillInterval: number;
2296
2101
  };
2102
+ /**
2103
+ * @description All roles this key belongs to
2104
+ * @example [
2105
+ * "admin",
2106
+ * "finance"
2107
+ * ]
2108
+ */
2109
+ roles?: string[];
2297
2110
  /**
2298
2111
  * @description Sets if key is enabled or disabled. Disabled keys are not valid.
2299
2112
  * @example true
2300
2113
  */
2301
2114
  enabled?: boolean;
2302
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;
2213
+ };
2303
2214
  };
2304
2215
  responses: never;
2305
2216
  parameters: {
@@ -2333,6 +2244,14 @@ type UnkeyOptions = ({
2333
2244
  * @default https://api.unkey.dev
2334
2245
  */
2335
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;
2336
2255
  /**
2337
2256
  * Retry on network errors
2338
2257
  */
@@ -2363,7 +2282,7 @@ type UnkeyOptions = ({
2363
2282
  *
2364
2283
  * You can leave this blank unless you are building a wrapper around this SDK.
2365
2284
  */
2366
- wrapperSdkVersion?: `v${string}`;
2285
+ wrapperSdkVersion?: string;
2367
2286
  };
2368
2287
  type Result<R> = {
2369
2288
  result: R;
@@ -2376,12 +2295,13 @@ declare class Unkey {
2376
2295
  readonly baseUrl: string;
2377
2296
  private readonly rootKey;
2378
2297
  private readonly cache?;
2379
- private readonly sdkVersions;
2298
+ private readonly telemetry?;
2380
2299
  readonly retry: {
2381
2300
  attempts: number;
2382
2301
  backoff: (retryCount: number) => number;
2383
2302
  };
2384
2303
  constructor(opts: UnkeyOptions);
2304
+ private getHeaders;
2385
2305
  private fetch;
2386
2306
  get keys(): {
2387
2307
  create: (req: paths["/v1/keys.createKey"]["post"]["requestBody"]["content"]["application/json"]) => Promise<Result<paths["/v1/keys.createKey"]["post"]["responses"]["200"]["content"]["application/json"]>>;
@@ -2454,4 +2374,4 @@ declare function verifyKey(req: string | {
2454
2374
  error?: undefined;
2455
2375
  }>;
2456
2376
 
2457
- export { type ErrorResponse, Unkey, type UnkeyOptions, verifyKey };
2377
+ export { ErrorResponse, Unkey, UnkeyOptions, verifyKey };
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
@@ -373,110 +381,14 @@ interface paths {
373
381
  post: {
374
382
  requestBody: {
375
383
  content: {
376
- "application/json": {
377
- /**
378
- * @description The id of the api where the key belongs to. This is optional for now but will be required soon.
379
- * The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail.
380
- * @example api_1234
381
- */
382
- apiId?: string;
383
- /**
384
- * @description The key to verify
385
- * @example sk_1234
386
- */
387
- key: string;
388
- };
384
+ "application/json": components["schemas"]["V1KeysVerifyKeyRequest"];
389
385
  };
390
386
  };
391
387
  responses: {
392
388
  /** @description The verification result */
393
389
  200: {
394
390
  content: {
395
- "application/json": {
396
- /**
397
- * @description The id of the key
398
- * @example key_1234
399
- */
400
- keyId?: string;
401
- /**
402
- * @description Whether the key is valid or not.
403
- * 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.
404
- * @example true
405
- */
406
- valid: boolean;
407
- /**
408
- * @description The name of the key, give keys a name to easily identifiy their purpose
409
- * @example Customer X
410
- */
411
- name?: string;
412
- /**
413
- * @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.
414
- * @example user_123
415
- */
416
- ownerId?: string;
417
- /**
418
- * @description Any additional metadata you want to store with the key
419
- * @example {
420
- * "roles": [
421
- * "admin",
422
- * "user"
423
- * ],
424
- * "stripeCustomerId": "cus_1234"
425
- * }
426
- */
427
- meta?: {
428
- [key: string]: unknown;
429
- };
430
- /**
431
- * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
432
- * @example 123
433
- */
434
- expires?: number;
435
- /**
436
- * @description The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit.
437
- * @example {
438
- * "limit": 10,
439
- * "remaining": 9,
440
- * "reset": 3600000
441
- * }
442
- */
443
- ratelimit?: {
444
- /**
445
- * @description Maximum number of requests that can be made inside a window
446
- * @example 10
447
- */
448
- limit: number;
449
- /**
450
- * @description Remaining requests after this verification
451
- * @example 9
452
- */
453
- remaining: number;
454
- /**
455
- * @description Unix timestamp in milliseconds when the ratelimit will reset
456
- * @example 3600000
457
- */
458
- reset: number;
459
- };
460
- /**
461
- * @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.
462
- * @example 1000
463
- */
464
- remaining?: number;
465
- /**
466
- * @description If the key is invalid this field will be set to the reason why it is invalid.
467
- * Possible values are:
468
- * - NOT_FOUND: the key does not exist or has expired
469
- * - FORBIDDEN: the key is not allowed to access the api
470
- * - USAGE_EXCEEDED: the key has exceeded its request limit
471
- * - RATE_LIMITED: the key has been ratelimited
472
- * - UNAUTHORIZED: the key is not authorized
473
- * - DISABLED: the key is disabled
474
- * @enum {string}
475
- */
476
- code?: "NOT_FOUND" | "FORBIDDEN" | "USAGE_EXCEEDED" | "RATE_LIMITED" | "UNAUTHORIZED" | "DISABLED";
477
- /** @description Sets the key to be enabled or disabled. Disabled keys will not verify. */
478
- enabled?: boolean;
479
- };
391
+ "application/json": components["schemas"]["V1KeysVerifyKeyResponse"];
480
392
  };
481
393
  };
482
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). */
@@ -832,92 +744,6 @@ interface paths {
832
744
  };
833
745
  };
834
746
  };
835
- "/vx/keys.getVerifications": {
836
- get: {
837
- parameters: {
838
- query?: {
839
- keyId?: string;
840
- ownerId?: string;
841
- start?: number | null;
842
- end?: number | null;
843
- granularity?: "day";
844
- };
845
- };
846
- responses: {
847
- /** @description The configuration for a single key */
848
- 200: {
849
- content: {
850
- "application/json": {
851
- verifications: {
852
- /**
853
- * @description The timestamp of the usage data
854
- * @example 1620000000000
855
- */
856
- time: number;
857
- /**
858
- * @description The number of successful requests
859
- * @example 100
860
- */
861
- success: number;
862
- /**
863
- * @description The number of requests that were rate limited
864
- * @example 10
865
- */
866
- rateLimited: number;
867
- /**
868
- * @description The number of requests that exceeded the usage limit
869
- * @example 0
870
- */
871
- usageExceeded: number;
872
- }[];
873
- };
874
- };
875
- };
876
- /** @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). */
877
- 400: {
878
- content: {
879
- "application/json": components["schemas"]["ErrBadRequest"];
880
- };
881
- };
882
- /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */
883
- 401: {
884
- content: {
885
- "application/json": components["schemas"]["ErrUnauthorized"];
886
- };
887
- };
888
- /** @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. */
889
- 403: {
890
- content: {
891
- "application/json": components["schemas"]["ErrForbidden"];
892
- };
893
- };
894
- /** @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. */
895
- 404: {
896
- content: {
897
- "application/json": components["schemas"]["ErrNotFound"];
898
- };
899
- };
900
- /** @description This response is sent when a request conflicts with the current state of the server. */
901
- 409: {
902
- content: {
903
- "application/json": components["schemas"]["ErrConflict"];
904
- };
905
- };
906
- /** @description The user has sent too many requests in a given amount of time ("rate limiting") */
907
- 429: {
908
- content: {
909
- "application/json": components["schemas"]["ErrTooManyRequests"];
910
- };
911
- };
912
- /** @description The server has encountered a situation it does not know how to handle. */
913
- 500: {
914
- content: {
915
- "application/json": components["schemas"]["ErrInternalServerError"];
916
- };
917
- };
918
- };
919
- };
920
- };
921
747
  "/v1/apis.getApi": {
922
748
  get: {
923
749
  parameters: {
@@ -1203,9 +1029,6 @@ interface paths {
1203
1029
  "/v1/keys/{keyId}": {
1204
1030
  put: {
1205
1031
  parameters: {
1206
- header: {
1207
- authorization: string;
1208
- };
1209
1032
  path: {
1210
1033
  keyId: string;
1211
1034
  };
@@ -1325,11 +1148,6 @@ interface paths {
1325
1148
  };
1326
1149
  "/v1/keys/:keyId": {
1327
1150
  get: {
1328
- parameters: {
1329
- header: {
1330
- authorization: string;
1331
- };
1332
- };
1333
1151
  responses: {
1334
1152
  /** @description The configuration for a single key */
1335
1153
  200: {
@@ -1382,11 +1200,6 @@ interface paths {
1382
1200
  };
1383
1201
  };
1384
1202
  delete: {
1385
- parameters: {
1386
- header: {
1387
- authorization: string;
1388
- };
1389
- };
1390
1203
  responses: {
1391
1204
  /** @description The key was successfully revoked, it may take up to 30s for this to take effect in all regions */
1392
1205
  200: {
@@ -1441,11 +1254,6 @@ interface paths {
1441
1254
  };
1442
1255
  "/v1/keys": {
1443
1256
  post: {
1444
- parameters: {
1445
- header: {
1446
- authorization: string;
1447
- };
1448
- };
1449
1257
  requestBody: {
1450
1258
  content: {
1451
1259
  "application/json": {
@@ -1897,9 +1705,6 @@ interface paths {
1897
1705
  };
1898
1706
  delete: {
1899
1707
  parameters: {
1900
- header: {
1901
- authorization: string;
1902
- };
1903
1708
  path: {
1904
1709
  apiId: string;
1905
1710
  };
@@ -2294,12 +2099,118 @@ interface components {
2294
2099
  /** @description Determines the speed at which tokens are refilled, in milliseconds. */
2295
2100
  refillInterval: number;
2296
2101
  };
2102
+ /**
2103
+ * @description All roles this key belongs to
2104
+ * @example [
2105
+ * "admin",
2106
+ * "finance"
2107
+ * ]
2108
+ */
2109
+ roles?: string[];
2297
2110
  /**
2298
2111
  * @description Sets if key is enabled or disabled. Disabled keys are not valid.
2299
2112
  * @example true
2300
2113
  */
2301
2114
  enabled?: boolean;
2302
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;
2213
+ };
2303
2214
  };
2304
2215
  responses: never;
2305
2216
  parameters: {
@@ -2333,6 +2244,14 @@ type UnkeyOptions = ({
2333
2244
  * @default https://api.unkey.dev
2334
2245
  */
2335
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;
2336
2255
  /**
2337
2256
  * Retry on network errors
2338
2257
  */
@@ -2363,7 +2282,7 @@ type UnkeyOptions = ({
2363
2282
  *
2364
2283
  * You can leave this blank unless you are building a wrapper around this SDK.
2365
2284
  */
2366
- wrapperSdkVersion?: `v${string}`;
2285
+ wrapperSdkVersion?: string;
2367
2286
  };
2368
2287
  type Result<R> = {
2369
2288
  result: R;
@@ -2376,12 +2295,13 @@ declare class Unkey {
2376
2295
  readonly baseUrl: string;
2377
2296
  private readonly rootKey;
2378
2297
  private readonly cache?;
2379
- private readonly sdkVersions;
2298
+ private readonly telemetry?;
2380
2299
  readonly retry: {
2381
2300
  attempts: number;
2382
2301
  backoff: (retryCount: number) => number;
2383
2302
  };
2384
2303
  constructor(opts: UnkeyOptions);
2304
+ private getHeaders;
2385
2305
  private fetch;
2386
2306
  get keys(): {
2387
2307
  create: (req: paths["/v1/keys.createKey"]["post"]["requestBody"]["content"]["application/json"]) => Promise<Result<paths["/v1/keys.createKey"]["post"]["responses"]["200"]["content"]["application/json"]>>;
@@ -2454,4 +2374,4 @@ declare function verifyKey(req: string | {
2454
2374
  error?: undefined;
2455
2375
  }>;
2456
2376
 
2457
- export { type ErrorResponse, Unkey, type UnkeyOptions, verifyKey };
2377
+ export { ErrorResponse, Unkey, UnkeyOptions, verifyKey };
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.16.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
- sdkVersions = [];
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
- this.sdkVersions.push(`v${version}`);
42
- if (opts.wrapperSdkVersion) {
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;
@@ -68,11 +108,7 @@ var Unkey = class {
68
108
  }
69
109
  res = await fetch(url, {
70
110
  method: req.method,
71
- headers: {
72
- "Content-Type": "application/json",
73
- Authorization: `Bearer ${this.rootKey}`,
74
- "Unkey-SDK": this.sdkVersions.join(",")
75
- },
111
+ headers: this.getHeaders(),
76
112
  cache: this.cache,
77
113
  body: JSON.stringify(req.body)
78
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.16.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 | 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 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 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: {\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.16.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
- sdkVersions = [];
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
- this.sdkVersions.push(`v${version}`);
15
- if (opts.wrapperSdkVersion) {
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;
@@ -41,11 +81,7 @@ var Unkey = class {
41
81
  }
42
82
  res = await fetch(url, {
43
83
  method: req.method,
44
- headers: {
45
- "Content-Type": "application/json",
46
- Authorization: `Bearer ${this.rootKey}`,
47
- "Unkey-SDK": this.sdkVersions.join(",")
48
- },
84
+ headers: this.getHeaders(),
49
85
  cache: this.cache,
50
86
  body: JSON.stringify(req.body)
51
87
  }).catch((e) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/client.ts","../src/verify.ts"],"sourcesContent":["{\n \"name\": \"@unkey/api\",\n \"version\": \"0.16.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 | 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 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 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: {\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.16.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.8.7",
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
  }