ecwt 0.2.1-beta.1 → 0.2.1-beta.3

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/bun.lockb ADDED
Binary file
package/dist/main.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -43,7 +44,6 @@ var import_snowflake = require("@kirick/snowflake");
43
44
  var import_cbor_x = require("cbor-x");
44
45
  var import_evilcrypt = require("evilcrypt");
45
46
  var import_lru_cache = require("lru-cache");
46
- var import_redis = require("redis");
47
47
 
48
48
  // src/utils/time.js
49
49
  function toSeconds(value) {
@@ -78,21 +78,21 @@ var Ecwt = class {
78
78
  ts_expired;
79
79
  /**
80
80
  * Data stored in token.
81
- * @type {{ [key: string]: any }}
81
+ * @type {D}
82
82
  * @readonly
83
83
  */
84
84
  data;
85
85
  /** @type {EcwtFactory} */
86
86
  #ecwtFactory;
87
- /** @type {number} */
87
+ /** @type {number | null} */
88
88
  #ttl_initial;
89
89
  /**
90
90
  * @param {EcwtFactory} ecwtFactory -
91
91
  * @param {object} options -
92
92
  * @param {string} options.token String representation of token.
93
93
  * @param {Snowflake} options.snowflake -
94
- * @param {number?} options.ttl_initial Time to live in seconds at the moment of token creation.
95
- * @param {object} options.data Data stored in token.
94
+ * @param {number | null} options.ttl_initial Time to live in seconds at the moment of token creation.
95
+ * @param {D} options.data Data stored in token.
96
96
  */
97
97
  constructor(ecwtFactory, {
98
98
  token,
@@ -150,7 +150,9 @@ var InvalidPackageInstanceError = class extends TypeError {
150
150
  * @param {string} package_name -
151
151
  */
152
152
  constructor(property, class_name, package_name) {
153
- super(`Value ${property} must be an instance of ${class_name} from package "${package_name}". That error is probably caused by two separate installations of "${package_name}". Please, make sure that "${package_name}" in your project is matches "peerDependencies" of "ecwt" package.`);
153
+ super(
154
+ `Value ${property} must be an instance of ${class_name} from package "${package_name}". That error is probably caused by two separate installations of "${package_name}". Please, make sure that "${package_name}" in your project is matches "peerDependencies" of "ecwt" package.`
155
+ );
154
156
  }
155
157
  };
156
158
  var EcwtParseError = class extends Error {
@@ -177,16 +179,6 @@ var EcwtRevokedError = class extends EcwtInvalidError {
177
179
 
178
180
  // src/factory.js
179
181
  var REDIS_PREFIX = "@ecwt:";
180
- function getAllKeysList(value) {
181
- const keys = [];
182
- for (const key in value) {
183
- keys.push(key);
184
- }
185
- return keys.sort().join(",");
186
- }
187
- var redisClient = (0, import_redis.createClient)();
188
- var redis_client_constructor_name = redisClient.constructor.name;
189
- var redis_client_keys = getAllKeysList(redisClient);
190
182
  var EcwtFactory = class {
191
183
  #redisClient;
192
184
  #lruCache;
@@ -197,9 +189,8 @@ var EcwtFactory = class {
197
189
  /** @type {CborEncoder | null} */
198
190
  #cborEncoder = null;
199
191
  /**
200
- *
201
192
  * @param {object} param0 -
202
- * @param {import('redis').RedisClientType} [param0.redisClient] RedisClient instance. If not provided, tokens will not be revoked and cannot be checked for revocation.
193
+ * @param {import('redis').RedisClientType<import('redis').RedisModules, import('redis').RedisFunctions, import('redis').RedisScripts>} [param0.redisClient] RedisClient instance. If not provided, tokens will not be revoked and cannot be checked for revocation.
203
194
  * @param {LRUCache<string, CacheValue>} [param0.lruCache] LRUCache instance. If not provided, tokens will be decrypted every time they are verified.
204
195
  * @param {SnowflakeFactory} param0.snowflakeFactory SnowflakeFactory instance.
205
196
  * @param {object} param0.options -
@@ -209,7 +200,7 @@ var EcwtFactory = class {
209
200
  * @param {Record<string, number>} [param0.options.senml_key_map] Payload object keys mapped for their SenML keys.
210
201
  */
211
202
  constructor({
212
- redisClient: redisClient2,
203
+ redisClient,
213
204
  lruCache,
214
205
  snowflakeFactory,
215
206
  options: {
@@ -219,14 +210,7 @@ var EcwtFactory = class {
219
210
  senml_key_map
220
211
  }
221
212
  }) {
222
- if (redisClient2 !== void 0 && (redisClient2.constructor.name !== redis_client_constructor_name || getAllKeysList(redisClient2) !== redis_client_keys)) {
223
- throw new InvalidPackageInstanceError(
224
- "redisClient",
225
- "Commander extends RedisClient",
226
- "redis"
227
- );
228
- }
229
- this.#redisClient = redisClient2;
213
+ this.#redisClient = redisClient;
230
214
  if (lruCache !== void 0 && lruCache instanceof import_lru_cache.LRUCache !== true) {
231
215
  throw new InvalidPackageInstanceError(
232
216
  "lruCache",
@@ -255,7 +239,7 @@ var EcwtFactory = class {
255
239
  /**
256
240
  * Creates new token.
257
241
  * @async
258
- * @param {object} data Data to be stored in token.
242
+ * @param {D} data Data to be stored in token.
259
243
  * @param {object} [options] -
260
244
  * @param {number | null} [options.ttl] Time to live in seconds. By default, token will never expire.
261
245
  * @returns {Promise<Ecwt>} -
@@ -308,7 +292,7 @@ var EcwtFactory = class {
308
292
  this.#lruCache?.set(
309
293
  token,
310
294
  cache_value,
311
- {
295
+ cache_value.ttl_initial === null ? void 0 : {
312
296
  ttl: cache_value.ttl_initial * 1e3
313
297
  }
314
298
  );
@@ -341,9 +325,7 @@ var EcwtFactory = class {
341
325
  throw new EcwtParseError();
342
326
  }
343
327
  const payload = this.#cborEncoder ? this.#cborEncoder.decode(token_raw) : (0, import_cbor_x.decode)(token_raw);
344
- const [
345
- snowflake_buffer
346
- ] = payload;
328
+ const [snowflake_buffer] = payload;
347
329
  [
348
330
  ,
349
331
  ttl_initial,
@@ -440,7 +422,7 @@ var EcwtFactory = class {
440
422
  ttl_initial
441
423
  }) {
442
424
  if (this.#redisClient) {
443
- ttl_initial = ttl_initial ?? Number.MAX_SAFE_INTEGER;
425
+ ttl_initial ??= Number.MAX_SAFE_INTEGER;
444
426
  const ts_ms_expired = ts_ms_created + ttl_initial * 1e3;
445
427
  if (ts_ms_expired > Date.now()) {
446
428
  await this.#redisClient.MULTI().addCommand([
@@ -1,8 +1,10 @@
1
- export class EcwtFactory {
1
+ /**
2
+ * @template {Record<string, any>} [D=Record<string, any>]
3
+ */
4
+ export class EcwtFactory<D extends Record<string, any> = Record<string, any>> {
2
5
  /**
3
- *
4
6
  * @param {object} param0 -
5
- * @param {import('redis').RedisClientType} [param0.redisClient] RedisClient instance. If not provided, tokens will not be revoked and cannot be checked for revocation.
7
+ * @param {import('redis').RedisClientType<import('redis').RedisModules, import('redis').RedisFunctions, import('redis').RedisScripts>} [param0.redisClient] RedisClient instance. If not provided, tokens will not be revoked and cannot be checked for revocation.
6
8
  * @param {LRUCache<string, CacheValue>} [param0.lruCache] LRUCache instance. If not provided, tokens will be decrypted every time they are verified.
7
9
  * @param {SnowflakeFactory} param0.snowflakeFactory SnowflakeFactory instance.
8
10
  * @param {object} param0.options -
@@ -12,27 +14,27 @@ export class EcwtFactory {
12
14
  * @param {Record<string, number>} [param0.options.senml_key_map] Payload object keys mapped for their SenML keys.
13
15
  */
14
16
  constructor({ redisClient, lruCache, snowflakeFactory, options: { namespace, key, validator, senml_key_map, }, }: {
15
- redisClient?: import("redis").RedisClientType;
16
- lruCache?: LRUCache<string, CacheValue>;
17
+ redisClient?: import("redis").RedisClientType<import("redis").RedisModules, import("redis").RedisFunctions, import("redis").RedisScripts> | undefined;
18
+ lruCache?: LRUCache<string, CacheValue, any> | undefined;
17
19
  snowflakeFactory: SnowflakeFactory;
18
20
  options: {
19
- namespace?: string;
21
+ namespace?: string | undefined;
20
22
  key: Buffer;
21
- validator?: (value: any) => any;
22
- senml_key_map?: Record<string, number>;
23
+ validator?: ((value: any) => any) | undefined;
24
+ senml_key_map?: Record<string, number> | undefined;
23
25
  };
24
26
  });
25
27
  /**
26
28
  * Creates new token.
27
29
  * @async
28
- * @param {object} data Data to be stored in token.
30
+ * @param {D} data Data to be stored in token.
29
31
  * @param {object} [options] -
30
32
  * @param {number | null} [options.ttl] Time to live in seconds. By default, token will never expire.
31
33
  * @returns {Promise<Ecwt>} -
32
34
  */
33
- create(data: object, { ttl, }?: {
34
- ttl?: number | null;
35
- }): Promise<Ecwt>;
35
+ create(data: D, { ttl, }?: {
36
+ ttl?: number | null | undefined;
37
+ } | undefined): Promise<Ecwt>;
36
38
  /**
37
39
  * Parses token.
38
40
  * @async
@@ -84,7 +86,7 @@ export type CacheValue = {
84
86
  /**
85
87
  * -
86
88
  */
87
- ttl_initial: number;
89
+ ttl_initial: number | null;
88
90
  /**
89
91
  * -
90
92
  */
@@ -2,20 +2,23 @@
2
2
  * @typedef {import('@kirick/snowflake').Snowflake} Snowflake
3
3
  * @typedef {import('./factory.js').EcwtFactory} EcwtFactory
4
4
  */
5
- export class Ecwt {
5
+ /**
6
+ * @template {Record<string, any>} [D=Record<string, any>]
7
+ */
8
+ export class Ecwt<D extends Record<string, any> = Record<string, any>> {
6
9
  /**
7
10
  * @param {EcwtFactory} ecwtFactory -
8
11
  * @param {object} options -
9
12
  * @param {string} options.token String representation of token.
10
13
  * @param {Snowflake} options.snowflake -
11
- * @param {number?} options.ttl_initial Time to live in seconds at the moment of token creation.
12
- * @param {object} options.data Data stored in token.
14
+ * @param {number | null} options.ttl_initial Time to live in seconds at the moment of token creation.
15
+ * @param {D} options.data Data stored in token.
13
16
  */
14
17
  constructor(ecwtFactory: EcwtFactory, { token, snowflake, ttl_initial, data, }: {
15
18
  token: string;
16
19
  snowflake: Snowflake;
17
20
  ttl_initial: number | null;
18
- data: object;
21
+ data: D;
19
22
  });
20
23
  /**
21
24
  * Token string representation.
@@ -43,12 +46,10 @@ export class Ecwt {
43
46
  readonly ts_expired: number | null;
44
47
  /**
45
48
  * Data stored in token.
46
- * @type {{ [key: string]: any }}
49
+ * @type {D}
47
50
  * @readonly
48
51
  */
49
- readonly data: {
50
- [key: string]: any;
51
- };
52
+ readonly data: D;
52
53
  /**
53
54
  * Actual time to live in seconds.
54
55
  * @returns {number | null} -
@@ -23,7 +23,7 @@ export class EcwtInvalidError extends Error {
23
23
  * @param {Ecwt} ecwt -
24
24
  */
25
25
  constructor(ecwt: Ecwt);
26
- ecwt: import("../token.js").Ecwt;
26
+ ecwt: import("../token.js").Ecwt<Record<string, any>>;
27
27
  }
28
28
  /**
29
29
  * Error thrown when parsed Ecwt is expired.
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "ecwt",
3
- "version": "0.2.1-beta.1",
3
+ "version": "0.2.1-beta.3",
4
4
  "description": "Encrypted CBOR-encoded Web Token",
5
5
  "type": "module",
6
6
  "main": "src/main.js",
7
- "types": "types/main.d.ts",
7
+ "types": "dist/types/main.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
10
  "import": "./src/main.js",
@@ -25,28 +25,21 @@
25
25
  "redis": "^4"
26
26
  },
27
27
  "devDependencies": {
28
- "@babel/eslint-parser": "7.21.8",
28
+ "@kirick/eslint-config": "^0.1.11",
29
29
  "@types/node": "^20.14.9",
30
- "eslint": "8.41.0",
31
- "eslint-config-xo": "0.43.1",
32
- "eslint-plugin-import": "2.27.5",
33
- "eslint-plugin-jsdoc": "46.5.0",
34
- "eslint-plugin-node": "11.1.0",
35
- "eslint-plugin-promise": "6.1.1",
36
- "eslint-plugin-unicorn": "47.0.0",
30
+ "eslint": "9.8.0",
37
31
  "valibot": "^0.33",
38
32
  "vitest": "^1.6"
39
33
  },
40
34
  "scripts": {
41
- "test": "export REDIS_PORT=16274 ; bun run redis:up && npm run test:vitest && bun test --coverage ; bun run redis:down",
42
- "test:vitest": "vitest run --no-file-parallelism",
43
35
  "build": "bun run build:types && bun run build:cjs",
44
36
  "build:cjs": "bunx esbuild --bundle --platform=node --format=cjs --packages=external --outfile=dist/main.cjs src/main.js",
45
- "build:types": "bunx tsc --skipLibCheck --declaration --emitDeclarationOnly --outDir types",
37
+ "build:types": "bunx tsc --skipLibCheck --declaration --emitDeclarationOnly --outDir dist/types",
46
38
  "lint": "eslint . && bunx tsc --skipLibCheck --noemit",
47
39
  "publish:npm": "bun run build && bun run lint && bun run test && npm publish",
48
- "redis:up": "docker ps | grep test-ecwt >/dev/null || docker run --rm -d -p $REDIS_PORT:6379 --name test-ecwt redis:7-alpine",
49
- "redis:down": "docker stop test-ecwt || true"
40
+ "redis:up": "docker ps | grep test-redis >/dev/null || docker run --rm -d -p $REDIS_PORT:6379 --name test-redis redis:7-alpine",
41
+ "test": "export REDIS_PORT=16379 ; bun run redis:up && npm run test:vitest && bun test --coverage",
42
+ "test:vitest": "vitest run --no-file-parallelism"
50
43
  },
51
44
  "repository": {
52
45
  "type": "git",
package/src/factory.js CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @typedef {object} CacheValue
7
7
  * @property {Snowflake} snowflake -
8
- * @property {number} ttl_initial -
8
+ * @property {number | null} ttl_initial -
9
9
  * @property {Record<string, any>} data -
10
10
  */
11
11
 
@@ -13,12 +13,13 @@ import { SnowflakeFactory } from '@kirick/snowflake';
13
13
  import {
14
14
  Encoder as CborEncoder,
15
15
  encode as cborEncode,
16
- decode as cborDecode } from 'cbor-x';
16
+ decode as cborDecode,
17
+ } from 'cbor-x';
17
18
  import {
18
19
  decrypt as evilcryptDecrypt,
19
- v2 as evilcryptV2 } from 'evilcrypt';
20
+ v2 as evilcryptV2,
21
+ } from 'evilcrypt';
20
22
  import { LRUCache } from 'lru-cache';
21
- import { createClient } from 'redis';
22
23
  import { Ecwt } from './token.js';
23
24
  import { base62 } from './utils/base62.js';
24
25
  import {
@@ -26,43 +27,27 @@ import {
26
27
  EcwtInvalidError,
27
28
  EcwtExpiredError,
28
29
  EcwtRevokedError,
29
- EcwtParseError } from './utils/errors.js';
30
+ EcwtParseError,
31
+ } from './utils/errors.js';
30
32
 
31
33
  const REDIS_PREFIX = '@ecwt:';
32
34
 
33
35
  /**
34
- * @param {object} value -
35
- * @returns {string} -
36
+ * @template {Record<string, any>} [D=Record<string, any>]
36
37
  */
37
- function getAllKeysList(value) {
38
- const keys = [];
39
- // eslint-disable-next-line guard-for-in
40
- for (const key in value) {
41
- keys.push(key);
42
- }
43
- return keys.sort().join(',');
44
- }
45
-
46
- const redisClient = createClient();
47
- const redis_client_constructor_name = redisClient.constructor.name;
48
- const redis_client_keys = getAllKeysList(redisClient);
49
-
50
38
  export class EcwtFactory {
51
39
  #redisClient;
52
40
  #lruCache;
53
41
  #snowflakeFactory;
54
-
55
42
  #redis_key_revoked;
56
43
  #encryption_key;
57
-
58
44
  #validator;
59
45
  /** @type {CborEncoder | null} */
60
46
  #cborEncoder = null;
61
47
 
62
48
  /**
63
- *
64
49
  * @param {object} param0 -
65
- * @param {import('redis').RedisClientType} [param0.redisClient] RedisClient instance. If not provided, tokens will not be revoked and cannot be checked for revocation.
50
+ * @param {import('redis').RedisClientType<import('redis').RedisModules, import('redis').RedisFunctions, import('redis').RedisScripts>} [param0.redisClient] RedisClient instance. If not provided, tokens will not be revoked and cannot be checked for revocation.
66
51
  * @param {LRUCache<string, CacheValue>} [param0.lruCache] LRUCache instance. If not provided, tokens will be decrypted every time they are verified.
67
52
  * @param {SnowflakeFactory} param0.snowflakeFactory SnowflakeFactory instance.
68
53
  * @param {object} param0.options -
@@ -82,19 +67,6 @@ export class EcwtFactory {
82
67
  senml_key_map,
83
68
  },
84
69
  }) {
85
- if (
86
- redisClient !== undefined
87
- && (
88
- redisClient.constructor.name !== redis_client_constructor_name
89
- || getAllKeysList(redisClient) !== redis_client_keys
90
- )
91
- ) {
92
- throw new InvalidPackageInstanceError(
93
- 'redisClient',
94
- 'Commander extends RedisClient',
95
- 'redis',
96
- );
97
- }
98
70
  this.#redisClient = redisClient;
99
71
 
100
72
  if (
@@ -107,6 +79,7 @@ export class EcwtFactory {
107
79
  'lru-cache',
108
80
  );
109
81
  }
82
+
110
83
  this.#lruCache = lruCache;
111
84
 
112
85
  if (snowflakeFactory instanceof SnowflakeFactory !== true) {
@@ -116,6 +89,7 @@ export class EcwtFactory {
116
89
  '@kirick/snowflake',
117
90
  );
118
91
  }
92
+
119
93
  this.#snowflakeFactory = snowflakeFactory;
120
94
 
121
95
  this.#redis_key_revoked = `${REDIS_PREFIX}${namespace}:revoked`;
@@ -134,7 +108,7 @@ export class EcwtFactory {
134
108
  /**
135
109
  * Creates new token.
136
110
  * @async
137
- * @param {object} data Data to be stored in token.
111
+ * @param {D} data Data to be stored in token.
138
112
  * @param {object} [options] -
139
113
  * @param {number | null} [options.ttl] Time to live in seconds. By default, token will never expire.
140
114
  * @returns {Promise<Ecwt>} -
@@ -204,9 +178,11 @@ export class EcwtFactory {
204
178
  this.#lruCache?.set(
205
179
  token,
206
180
  cache_value,
207
- {
208
- ttl: cache_value.ttl_initial * 1000,
209
- },
181
+ cache_value.ttl_initial === null
182
+ ? undefined
183
+ : {
184
+ ttl: cache_value.ttl_initial * 1000,
185
+ },
210
186
  );
211
187
  }
212
188
 
@@ -247,9 +223,7 @@ export class EcwtFactory {
247
223
  ? this.#cborEncoder.decode(token_raw)
248
224
  : cborDecode(token_raw);
249
225
 
250
- const [
251
- snowflake_buffer,
252
- ] = payload;
226
+ const [ snowflake_buffer ] = payload;
253
227
  [
254
228
  ,
255
229
  ttl_initial,
@@ -369,7 +343,7 @@ export class EcwtFactory {
369
343
  ttl_initial,
370
344
  }) {
371
345
  if (this.#redisClient) {
372
- ttl_initial = ttl_initial ?? Number.MAX_SAFE_INTEGER;
346
+ ttl_initial ??= Number.MAX_SAFE_INTEGER;
373
347
 
374
348
  const ts_ms_expired = ts_ms_created + (ttl_initial * 1000);
375
349
  if (ts_ms_expired > Date.now()) {
package/src/token.js CHANGED
@@ -6,6 +6,9 @@ import { toSeconds } from './utils/time.js';
6
6
  * @typedef {import('./factory.js').EcwtFactory} EcwtFactory
7
7
  */
8
8
 
9
+ /**
10
+ * @template {Record<string, any>} [D=Record<string, any>]
11
+ */
9
12
  export class Ecwt {
10
13
  /**
11
14
  * Token string representation.
@@ -33,14 +36,13 @@ export class Ecwt {
33
36
  ts_expired;
34
37
  /**
35
38
  * Data stored in token.
36
- * @type {{ [key: string]: any }}
39
+ * @type {D}
37
40
  * @readonly
38
41
  */
39
42
  data;
40
-
41
43
  /** @type {EcwtFactory} */
42
44
  #ecwtFactory;
43
- /** @type {number} */
45
+ /** @type {number | null} */
44
46
  #ttl_initial;
45
47
 
46
48
  /**
@@ -48,8 +50,8 @@ export class Ecwt {
48
50
  * @param {object} options -
49
51
  * @param {string} options.token String representation of token.
50
52
  * @param {Snowflake} options.snowflake -
51
- * @param {number?} options.ttl_initial Time to live in seconds at the moment of token creation.
52
- * @param {object} options.data Data stored in token.
53
+ * @param {number | null} options.ttl_initial Time to live in seconds at the moment of token creation.
54
+ * @param {D} options.data Data stored in token.
53
55
  */
54
56
  constructor(
55
57
  ecwtFactory,
@@ -10,7 +10,11 @@ export class InvalidPackageInstanceError extends TypeError {
10
10
  * @param {string} package_name -
11
11
  */
12
12
  constructor(property, class_name, package_name) {
13
- super(`Value ${property} must be an instance of ${class_name} from package "${package_name}". That error is probably caused by two separate installations of "${package_name}". Please, make sure that "${package_name}" in your project is matches "peerDependencies" of "ecwt" package.`);
13
+ super(
14
+ `Value ${property} must be an instance of ${class_name} from package "${package_name}".`
15
+ + ` That error is probably caused by two separate installations of "${package_name}".`
16
+ + ` Please, make sure that "${package_name}" in your project is matches "peerDependencies" of "ecwt" package.`,
17
+ );
14
18
  }
15
19
  }
16
20
 
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "esnext",
4
- "module": "esnext",
5
- "noImplicitAny": true,
6
- "checkJs": true,
7
- "allowJs": true,
8
- "moduleResolution": "node",
9
- "allowSyntheticDefaultImports": true
10
- },
11
- "include": [
12
- "src/**/*"
13
- ],
14
- "exclude": [
15
- "node_modules/",
16
- "dist/",
17
- "**/*.test.js"
18
- ]
19
- }
File without changes
File without changes
File without changes