dynamodb-refresh-token-provider 0.2.6 → 0.3.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/README.md CHANGED
@@ -1,17 +1,19 @@
1
1
  # DynamoDB Refresh Token Provider
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/dynamodb-refresh-token-provider.svg)](https://www.npmjs.com/package/dynamodb-refresh-token-provider)
4
- [![License](https://img.shields.io/npm/l/dynamodb-refresh-token-provider.svg)](https://github.com/gammarers-aws-sdk-extensions/athena-query-result-collector/blob/main/LICENSE)
5
- [![build](https://github.com/gammarers-aws-sdk-extensions/athena-query-result-collector/actions/workflows/build.yml/badge.svg)](https://github.com/gammarers-aws-sdk-extensions/athena-query-result-collector/actions/workflows/build.yml)
4
+ [![License](https://img.shields.io/npm/l/dynamodb-refresh-token-provider.svg)](https://github.com/gammarers-aws-sdk-modules/dynamodb-refresh-token-provider/blob/main/LICENSE)
5
+ [![build](https://github.com/gammarers-aws-sdk-modules/dynamodb-refresh-token-provider/actions/workflows/build.yml/badge.svg)](https://github.com/gammarers-aws-sdk-modules/dynamodb-refresh-token-provider/actions/workflows/build.yml)
6
6
 
7
7
  TypeScript library that stores **opaque refresh tokens** in **Amazon DynamoDB** using AWS SDK for JavaScript v3. Tokens are persisted under a hash of the plaintext value; **issue**, **rotate** (with reuse detection via a transactional write), and **revoke** (idempotent) are supported.
8
8
 
9
9
  ## Features
10
10
 
11
11
  - **`RefreshTokenStore` interface** — swap implementations while keeping the same API.
12
- - **`DynamodbRefreshTokenProvider`** — single-table design with partition key `pk` (string), strongly consistent reads by default.
13
- - **Rotation safety** — marks the old row as rotated and inserts the successor in one DynamoDB transaction; detects reuse and conflicting updates.
14
- - **Structured errors** — `RefreshTokenInvalidError`, `RefreshTokenExpiredError`, `RefreshTokenRevokedError`, `RefreshTokenReusedError`, and related types for `instanceof` handling.
12
+ - **`DynamodbRefreshTokenProvider`** — single-table design with string partition key `pk` and strongly consistent reads by default.
13
+ - **DynamoDB TTL** — writes `ttl` (Unix seconds) on `Put` and `TransactWriteItems` so expired and rotated rows can be removed automatically when table TTL is enabled.
14
+ - **Logical expiration** — `expiresAt` drives validation; `ttl` is for storage cleanup only.
15
+ - **Rotation safety** — marks the old row as rotated and inserts the successor in one transaction; detects reuse and conflicting updates.
16
+ - **Structured errors** — `RefreshTokenError`, `RefreshTokenInvalidError`, `RefreshTokenExpiredError`, `RefreshTokenRevokedError`, `RefreshTokenReusedError`, and `RefreshTokenRotateFailedError` for `instanceof` handling.
15
17
  - **Utilities** — `sha256hex` and `randomtoken` for hashing and token generation aligned with the store.
16
18
 
17
19
  ## Installation
@@ -26,13 +28,15 @@ yarn add dynamodb-refresh-token-provider
26
28
 
27
29
  ## Usage
28
30
 
29
- Create a store with your table name, AWS region, and optional `StoreOptions`. Ensure your DynamoDB table has a **string partition key** named `pk` (same attribute name the library uses for items).
31
+ Create a store with your table name, AWS region, and optional `StoreOptions`. Your DynamoDB table needs a **string partition key** named `pk`, and **TTL enabled** on attribute `ttl` (see [DynamoDB TTL](#dynamodb-ttl)).
30
32
 
31
33
  ```typescript
32
34
  import {
33
35
  DynamodbRefreshTokenProvider,
36
+ RefreshTokenExpiredError,
34
37
  RefreshTokenInvalidError,
35
38
  RefreshTokenReusedError,
39
+ RefreshTokenRevokedError,
36
40
  } from 'dynamodb-refresh-token-provider';
37
41
 
38
42
  const store = new DynamodbRefreshTokenProvider('your-refresh-token-table', 'us-east-1', {
@@ -46,19 +50,25 @@ const issued = await store.issue({
46
50
  sessionId: 'session-456',
47
51
  });
48
52
  // issued.refreshToken — send to the client (plaintext)
49
- // issued.refreshTokenExpiresAt — Unix seconds
53
+ // issued.refreshTokenExpiresAt — Unix seconds (same as expiresAt / ttl on the item)
50
54
 
51
- // Rotate: exchange current token for a new one
55
+ // Rotate: exchange the current token for a new one
52
56
  try {
53
57
  const rotated = await store.rotate({ refreshToken: issued.refreshToken });
54
58
  // rotated.refreshToken, rotated.refreshTokenExpiresAt, rotated.subjectId, rotated.sessionId
55
59
  } catch (e) {
56
60
  if (e instanceof RefreshTokenReusedError) {
57
- // token was already rotated or transaction lost the race
61
+ // already rotated or lost a transactional race
58
62
  }
59
63
  if (e instanceof RefreshTokenInvalidError) {
60
64
  // unknown or malformed token
61
65
  }
66
+ if (e instanceof RefreshTokenExpiredError) {
67
+ // past expiresAt
68
+ }
69
+ if (e instanceof RefreshTokenRevokedError) {
70
+ // revokedAt is set
71
+ }
62
72
  throw e;
63
73
  }
64
74
 
@@ -66,23 +76,51 @@ try {
66
76
  await store.revoke({ refreshToken: issued.refreshToken });
67
77
  ```
68
78
 
79
+ ### DynamoDB TTL
80
+
81
+ Each item includes:
82
+
83
+ | Attribute | Purpose |
84
+ |-----------|---------|
85
+ | `expiresAt` | Logical expiration (Unix seconds); used by the library for validation. |
86
+ | `ttl` | DynamoDB TTL attribute (Unix seconds); enable table TTL on this name for automatic deletion. |
87
+
88
+ On **issue**, both are set to the same value. On **rotate**, the successor `Put` sets both to the new expiration; the previous row’s `ttl` is updated to its existing `expiresAt`. **Revoke** does not change `ttl` (the value from issue/rotate still applies).
89
+
90
+ Enable TTL on your table once (per table/region). The TTL attribute name must be **`ttl`**.
91
+
92
+ **AWS CLI**
93
+
94
+ ```bash
95
+ aws dynamodb update-time-to-live \
96
+ --table-name your-refresh-token-table \
97
+ --time-to-live-specification "Enabled=true, AttributeName=ttl"
98
+ ```
99
+
100
+ **AWS Console**
101
+
102
+ 1. Open the table → **Additional settings** → **Time to Live (TTL)**.
103
+ 2. Turn TTL on and set the attribute name to **`ttl`**.
104
+
105
+ DynamoDB deletes items asynchronously, typically within 48 hours after `ttl` is in the past.
106
+
69
107
  ## Options
70
108
 
71
109
  Constructor: `new DynamodbRefreshTokenProvider(tableName, region, options?)`.
72
110
 
73
111
  | Option | Type | Default | Description |
74
112
  |--------|------|---------|-------------|
75
- | `ttlDays` | `number` | `60` | Lifetime of issued/rotated tokens in days (added to `now` in seconds). |
76
- | `pkPrefix` | `string` | `'rt#'` | Prefix for the partition key; full `pk` is `prefix` + SHA-256 hex of the plaintext token. |
113
+ | `ttlDays` | `number` | `60` | Token lifetime in days; added to `now` when computing `expiresAt` and `ttl` (Unix seconds). |
114
+ | `pkPrefix` | `string` | `'rt#'` | Partition key prefix; full `pk` is `prefix` + SHA-256 hex of the plaintext token. |
77
115
  | `consistentRead` | `boolean` | `true` | Use strongly consistent reads on `GetItem` when loading a token row. |
78
116
  | `endpoint` | `string` | (none) | Custom DynamoDB API endpoint (e.g. LocalStack or DynamoDB Local). |
79
117
 
80
- Method parameters also accept an optional `now?: Date` on `issue`, `rotate`, and `revoke` for testing or clock injection.
118
+ `issue`, `rotate`, and `revoke` accept an optional `now?: Date` for testing or clock injection.
81
119
 
82
120
  ## Requirements
83
121
 
84
122
  - **Node.js** 20.0.0 or later.
85
- - A **DynamoDB table** with a string partition key attribute **`pk`**.
123
+ - A **DynamoDB table** with a string partition key **`pk`** and **TTL enabled** on attribute **`ttl`** (see [DynamoDB TTL](#dynamodb-ttl)).
86
124
  - **AWS credentials** and permissions for `PutItem`, `GetItem`, `UpdateItem`, and `TransactWriteItems` on that table (and the configured `endpoint` if used).
87
125
 
88
126
  ## License
package/lib/index.d.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  /**
2
- * Public API: refresh token store types, DynamoDB-backed implementation, errors, and crypto helpers.
2
+ * Public API: refresh token store types, DynamoDB-backed implementation, structured errors, and crypto helpers.
3
+ *
4
+ * Enable DynamoDB TTL on attribute `ttl` when using {@link DynamodbRefreshTokenProvider}.
3
5
  */
4
6
  export type { RefreshTokenStore, IssueParams, IssueResult, RotateParams, RotateResult, RevokeParams, StoreOptions, TokenRecord, EpochSec, } from './types/index';
7
+ /** DynamoDB-backed {@link RefreshTokenStore} with rotation reuse detection. */
5
8
  export { DynamodbRefreshTokenProvider } from './stores/dynamodb';
9
+ /** Structured errors for `instanceof` handling in auth flows. */
6
10
  export { RefreshTokenError, RefreshTokenExpiredError, RefreshTokenInvalidError, RefreshTokenReusedError, RefreshTokenRevokedError, RefreshTokenRotateFailedError, } from './stores/refresh-token-errors';
11
+ /** SHA-256 hex hashing and cryptographically secure token generation. */
7
12
  export { sha256hex, randomtoken } from './utils/hash';
package/lib/index.js CHANGED
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.randomtoken = exports.sha256hex = exports.RefreshTokenRotateFailedError = exports.RefreshTokenRevokedError = exports.RefreshTokenReusedError = exports.RefreshTokenInvalidError = exports.RefreshTokenExpiredError = exports.RefreshTokenError = exports.DynamodbRefreshTokenProvider = void 0;
4
+ /** DynamoDB-backed {@link RefreshTokenStore} with rotation reuse detection. */
4
5
  var dynamodb_1 = require("./stores/dynamodb");
5
6
  Object.defineProperty(exports, "DynamodbRefreshTokenProvider", { enumerable: true, get: function () { return dynamodb_1.DynamodbRefreshTokenProvider; } });
7
+ /** Structured errors for `instanceof` handling in auth flows. */
6
8
  var refresh_token_errors_1 = require("./stores/refresh-token-errors");
7
9
  Object.defineProperty(exports, "RefreshTokenError", { enumerable: true, get: function () { return refresh_token_errors_1.RefreshTokenError; } });
8
10
  Object.defineProperty(exports, "RefreshTokenExpiredError", { enumerable: true, get: function () { return refresh_token_errors_1.RefreshTokenExpiredError; } });
@@ -10,7 +12,8 @@ Object.defineProperty(exports, "RefreshTokenInvalidError", { enumerable: true, g
10
12
  Object.defineProperty(exports, "RefreshTokenReusedError", { enumerable: true, get: function () { return refresh_token_errors_1.RefreshTokenReusedError; } });
11
13
  Object.defineProperty(exports, "RefreshTokenRevokedError", { enumerable: true, get: function () { return refresh_token_errors_1.RefreshTokenRevokedError; } });
12
14
  Object.defineProperty(exports, "RefreshTokenRotateFailedError", { enumerable: true, get: function () { return refresh_token_errors_1.RefreshTokenRotateFailedError; } });
15
+ /** SHA-256 hex hashing and cryptographically secure token generation. */
13
16
  var hash_1 = require("./utils/hash");
14
17
  Object.defineProperty(exports, "sha256hex", { enumerable: true, get: function () { return hash_1.sha256hex; } });
15
18
  Object.defineProperty(exports, "randomtoken", { enumerable: true, get: function () { return hash_1.randomtoken; } });
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBZUEsOENBQWlFO0FBQXhELHdIQUFBLDRCQUE0QixPQUFBO0FBQ3JDLHNFQU91QztBQU5yQyx5SEFBQSxpQkFBaUIsT0FBQTtBQUNqQixnSUFBQSx3QkFBd0IsT0FBQTtBQUN4QixnSUFBQSx3QkFBd0IsT0FBQTtBQUN4QiwrSEFBQSx1QkFBdUIsT0FBQTtBQUN2QixnSUFBQSx3QkFBd0IsT0FBQTtBQUN4QixxSUFBQSw2QkFBNkIsT0FBQTtBQUUvQixxQ0FBc0Q7QUFBN0MsaUdBQUEsU0FBUyxPQUFBO0FBQUUsbUdBQUEsV0FBVyxPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQdWJsaWMgQVBJOiByZWZyZXNoIHRva2VuIHN0b3JlIHR5cGVzLCBEeW5hbW9EQi1iYWNrZWQgaW1wbGVtZW50YXRpb24sIGVycm9ycywgYW5kIGNyeXB0byBoZWxwZXJzLlxuICovXG5leHBvcnQgdHlwZSB7XG4gIFJlZnJlc2hUb2tlblN0b3JlLFxuICBJc3N1ZVBhcmFtcyxcbiAgSXNzdWVSZXN1bHQsXG4gIFJvdGF0ZVBhcmFtcyxcbiAgUm90YXRlUmVzdWx0LFxuICBSZXZva2VQYXJhbXMsXG4gIFN0b3JlT3B0aW9ucyxcbiAgVG9rZW5SZWNvcmQsXG4gIEVwb2NoU2VjLFxufSBmcm9tICcuL3R5cGVzL2luZGV4JztcblxuZXhwb3J0IHsgRHluYW1vZGJSZWZyZXNoVG9rZW5Qcm92aWRlciB9IGZyb20gJy4vc3RvcmVzL2R5bmFtb2RiJztcbmV4cG9ydCB7XG4gIFJlZnJlc2hUb2tlbkVycm9yLFxuICBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3IsXG4gIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IsXG4gIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUm90YXRlRmFpbGVkRXJyb3IsXG59IGZyb20gJy4vc3RvcmVzL3JlZnJlc2gtdG9rZW4tZXJyb3JzJztcbmV4cG9ydCB7IHNoYTI1NmhleCwgcmFuZG9tdG9rZW4gfSBmcm9tICcuL3V0aWxzL2hhc2gnO1xuIl19
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBaUJBLCtFQUErRTtBQUMvRSw4Q0FBaUU7QUFBeEQsd0hBQUEsNEJBQTRCLE9BQUE7QUFFckMsaUVBQWlFO0FBQ2pFLHNFQU91QztBQU5yQyx5SEFBQSxpQkFBaUIsT0FBQTtBQUNqQixnSUFBQSx3QkFBd0IsT0FBQTtBQUN4QixnSUFBQSx3QkFBd0IsT0FBQTtBQUN4QiwrSEFBQSx1QkFBdUIsT0FBQTtBQUN2QixnSUFBQSx3QkFBd0IsT0FBQTtBQUN4QixxSUFBQSw2QkFBNkIsT0FBQTtBQUcvQix5RUFBeUU7QUFDekUscUNBQXNEO0FBQTdDLGlHQUFBLFNBQVMsT0FBQTtBQUFFLG1HQUFBLFdBQVcsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUHVibGljIEFQSTogcmVmcmVzaCB0b2tlbiBzdG9yZSB0eXBlcywgRHluYW1vREItYmFja2VkIGltcGxlbWVudGF0aW9uLCBzdHJ1Y3R1cmVkIGVycm9ycywgYW5kIGNyeXB0byBoZWxwZXJzLlxuICpcbiAqIEVuYWJsZSBEeW5hbW9EQiBUVEwgb24gYXR0cmlidXRlIGB0dGxgIHdoZW4gdXNpbmcge0BsaW5rIER5bmFtb2RiUmVmcmVzaFRva2VuUHJvdmlkZXJ9LlxuICovXG5leHBvcnQgdHlwZSB7XG4gIFJlZnJlc2hUb2tlblN0b3JlLFxuICBJc3N1ZVBhcmFtcyxcbiAgSXNzdWVSZXN1bHQsXG4gIFJvdGF0ZVBhcmFtcyxcbiAgUm90YXRlUmVzdWx0LFxuICBSZXZva2VQYXJhbXMsXG4gIFN0b3JlT3B0aW9ucyxcbiAgVG9rZW5SZWNvcmQsXG4gIEVwb2NoU2VjLFxufSBmcm9tICcuL3R5cGVzL2luZGV4JztcblxuLyoqIER5bmFtb0RCLWJhY2tlZCB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmV9IHdpdGggcm90YXRpb24gcmV1c2UgZGV0ZWN0aW9uLiAqL1xuZXhwb3J0IHsgRHluYW1vZGJSZWZyZXNoVG9rZW5Qcm92aWRlciB9IGZyb20gJy4vc3RvcmVzL2R5bmFtb2RiJztcblxuLyoqIFN0cnVjdHVyZWQgZXJyb3JzIGZvciBgaW5zdGFuY2VvZmAgaGFuZGxpbmcgaW4gYXV0aCBmbG93cy4gKi9cbmV4cG9ydCB7XG4gIFJlZnJlc2hUb2tlbkVycm9yLFxuICBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3IsXG4gIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IsXG4gIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUm90YXRlRmFpbGVkRXJyb3IsXG59IGZyb20gJy4vc3RvcmVzL3JlZnJlc2gtdG9rZW4tZXJyb3JzJztcblxuLyoqIFNIQS0yNTYgaGV4IGhhc2hpbmcgYW5kIGNyeXB0b2dyYXBoaWNhbGx5IHNlY3VyZSB0b2tlbiBnZW5lcmF0aW9uLiAqL1xuZXhwb3J0IHsgc2hhMjU2aGV4LCByYW5kb210b2tlbiB9IGZyb20gJy4vdXRpbHMvaGFzaCc7XG4iXX0=
@@ -2,9 +2,12 @@ import type { RefreshTokenStore, StoreOptions, TokenRecord, IssueParams, RotateP
2
2
  /** Re-exported types for consumers that import the DynamoDB store module. */
3
3
  export { RefreshTokenStore, StoreOptions, TokenRecord, IssueParams, RotateParams, RevokeParams, IssueResult, RotateResult };
4
4
  /**
5
- * {@link RefreshTokenStore} implementation using a single DynamoDB table.
5
+ * {@link RefreshTokenStore} implementation backed by a single DynamoDB table.
6
6
  *
7
- * This class owns the DynamoDB client; callers supply `tableName`, `region`, and optional {@link StoreOptions}.
7
+ * Items use partition key `pk`, logical expiration `expiresAt`, and DynamoDB TTL attribute `ttl`
8
+ * (Unix seconds). Enable table TTL on attribute `ttl` so expired and rotated rows are removed
9
+ * asynchronously. This class owns the DynamoDB client; callers supply `tableName`, `region`, and
10
+ * optional {@link StoreOptions}.
8
11
  */
9
12
  export declare class DynamodbRefreshTokenProvider implements RefreshTokenStore {
10
13
  private readonly tableName;
@@ -17,11 +20,11 @@ export declare class DynamodbRefreshTokenProvider implements RefreshTokenStore {
17
20
  /**
18
21
  * @param tableName - DynamoDB table name for refresh token items.
19
22
  * @param region - AWS region for the DynamoDB client.
20
- * @param options - TTL, PK prefix, consistent reads, or custom endpoint.
23
+ * @param options - Token lifetime, PK prefix, consistent reads, or custom endpoint.
21
24
  */
22
25
  constructor(tableName: string, region: string, options?: StoreOptions | undefined);
23
26
  /**
24
- * Inserts a new token record. Fails the put if the partition key already exists.
27
+ * Inserts a new token record with `expiresAt` and matching `ttl`. Fails the put if `pk` already exists.
25
28
  *
26
29
  * @param params - Subject, session, and optional clock (`now`).
27
30
  * @returns Plaintext refresh token and expiration as Unix seconds.
@@ -30,6 +33,9 @@ export declare class DynamodbRefreshTokenProvider implements RefreshTokenStore {
30
33
  /**
31
34
  * Marks the current token as rotated and creates the successor row in one transaction.
32
35
  *
36
+ * Updates the previous row’s `ttl` to its `expiresAt` and sets `ttl` on the new Put to the
37
+ * successor’s expiration so DynamoDB can delete both when appropriate.
38
+ *
33
39
  * @param params - Client refresh token and optional clock (`now`).
34
40
  * @returns Subject, session, new plaintext token, and new expiration.
35
41
  * @throws {@link RefreshTokenInvalidError} When the token format is invalid or no row exists.
@@ -41,24 +47,50 @@ export declare class DynamodbRefreshTokenProvider implements RefreshTokenStore {
41
47
  /**
42
48
  * Sets `revokedAt` on the token row. Missing items succeed (idempotent revoke).
43
49
  *
50
+ * Does not update `ttl`; existing `ttl` from issue/rotate still applies for DynamoDB cleanup.
51
+ *
44
52
  * @param params - Refresh token and optional clock (`now`).
45
53
  * @returns `true` after a successful update or no-op when the item is absent.
46
54
  * @throws {@link RefreshTokenInvalidError} When the token string format is invalid.
47
55
  */
48
56
  revoke: (params: RevokeParams) => Promise<true>;
49
- /** Returns the cached client, creating it on first use. */
57
+ /**
58
+ * Returns the cached {@link DynamoDBDocumentClient}, creating it on first use.
59
+ *
60
+ * @returns Document client configured for `region` and optional `endpoint`.
61
+ */
50
62
  private getddb;
51
- /** Loads a token row by partition key, or `null` if absent. */
63
+ /**
64
+ * Loads a token row by partition key.
65
+ *
66
+ * @param pk - Full partition key (`prefix` + hash).
67
+ * @returns Parsed {@link TokenRecord}, or `null` if the item does not exist.
68
+ */
52
69
  private getTokenRecord;
53
- /** Effective PK prefix from options or {@link DEFAULT_PRIMARY_KEY_PREFIX}. */
70
+ /**
71
+ * Effective partition key prefix from {@link StoreOptions} or {@link DEFAULT_PRIMARY_KEY_PREFIX}.
72
+ *
73
+ * @returns Prefix string (e.g. `rt#`).
74
+ */
54
75
  private getPrimaryKeyPrefix;
55
- /** Full partition key: prefix + SHA-256 hex of the raw token. */
76
+ /**
77
+ * Builds the full partition key for a token hash.
78
+ *
79
+ * @param hash - SHA-256 hex digest of the plaintext token.
80
+ * @returns `prefix` + `hash`.
81
+ */
56
82
  private getPrimaryKey;
57
- /** Expiration timestamp: `nowSec` plus TTL from options (default 60 days). */
83
+ /**
84
+ * Computes logical expiration (`expiresAt` / `ttl`) as `nowSec` plus {@link StoreOptions.ttlDays}.
85
+ *
86
+ * @param nowSec - Current time as Unix seconds.
87
+ * @returns Expiration timestamp in Unix seconds (default lifetime: 60 days).
88
+ */
58
89
  private makeExpiresAt;
59
90
  /**
60
- * Ensures the token is non-empty and matches the expected base64url length for `tokenBytes` (32 bytes → URL-safe base64 length).
91
+ * Ensures the token is non-empty and matches the expected base64url length for `tokenBytes`.
61
92
  *
93
+ * @param token - Plaintext refresh token from the client.
62
94
  * @throws {@link RefreshTokenInvalidError} When validation fails.
63
95
  */
64
96
  private validateRefreshToken;
@@ -9,15 +9,18 @@ const time_1 = require("../utils/time");
9
9
  /** Default partition key prefix for refresh token items. */
10
10
  const DEFAULT_PRIMARY_KEY_PREFIX = 'rt#';
11
11
  /**
12
- * {@link RefreshTokenStore} implementation using a single DynamoDB table.
12
+ * {@link RefreshTokenStore} implementation backed by a single DynamoDB table.
13
13
  *
14
- * This class owns the DynamoDB client; callers supply `tableName`, `region`, and optional {@link StoreOptions}.
14
+ * Items use partition key `pk`, logical expiration `expiresAt`, and DynamoDB TTL attribute `ttl`
15
+ * (Unix seconds). Enable table TTL on attribute `ttl` so expired and rotated rows are removed
16
+ * asynchronously. This class owns the DynamoDB client; callers supply `tableName`, `region`, and
17
+ * optional {@link StoreOptions}.
15
18
  */
16
19
  class DynamodbRefreshTokenProvider {
17
20
  /**
18
21
  * @param tableName - DynamoDB table name for refresh token items.
19
22
  * @param region - AWS region for the DynamoDB client.
20
- * @param options - TTL, PK prefix, consistent reads, or custom endpoint.
23
+ * @param options - Token lifetime, PK prefix, consistent reads, or custom endpoint.
21
24
  */
22
25
  constructor(tableName, region, options) {
23
26
  this.tableName = tableName;
@@ -28,7 +31,7 @@ class DynamodbRefreshTokenProvider {
28
31
  /** Random byte length for generated refresh tokens (default 32 → 256-bit). */
29
32
  this.tokenBytes = 32;
30
33
  /**
31
- * Inserts a new token record. Fails the put if the partition key already exists.
34
+ * Inserts a new token record with `expiresAt` and matching `ttl`. Fails the put if `pk` already exists.
32
35
  *
33
36
  * @param params - Subject, session, and optional clock (`now`).
34
37
  * @returns Plaintext refresh token and expiration as Unix seconds.
@@ -49,6 +52,7 @@ class DynamodbRefreshTokenProvider {
49
52
  sessionId: params.sessionId,
50
53
  createdAt: nowSec,
51
54
  expiresAt,
55
+ ttl: expiresAt,
52
56
  },
53
57
  ConditionExpression: 'attribute_not_exists(pk)',
54
58
  }));
@@ -60,6 +64,9 @@ class DynamodbRefreshTokenProvider {
60
64
  /**
61
65
  * Marks the current token as rotated and creates the successor row in one transaction.
62
66
  *
67
+ * Updates the previous row’s `ttl` to its `expiresAt` and sets `ttl` on the new Put to the
68
+ * successor’s expiration so DynamoDB can delete both when appropriate.
69
+ *
63
70
  * @param params - Client refresh token and optional clock (`now`).
64
71
  * @returns Subject, session, new plaintext token, and new expiration.
65
72
  * @throws {@link RefreshTokenInvalidError} When the token format is invalid or no row exists.
@@ -99,11 +106,15 @@ class DynamodbRefreshTokenProvider {
99
106
  Update: {
100
107
  TableName: this.tableName,
101
108
  Key: { pk: currentPk },
102
- UpdateExpression: 'SET rotatedAt = :now, replacedByPk = :nextPk',
109
+ UpdateExpression: 'SET rotatedAt = :now, replacedByPk = :nextPk, #ttl = :ttl',
103
110
  ConditionExpression: 'attribute_exists(pk) AND attribute_not_exists(rotatedAt) AND attribute_not_exists(revokedAt)',
111
+ ExpressionAttributeNames: {
112
+ '#ttl': 'ttl',
113
+ },
104
114
  ExpressionAttributeValues: {
105
115
  ':now': nowSec,
106
116
  ':nextPk': nextPk,
117
+ ':ttl': current.expiresAt,
107
118
  },
108
119
  },
109
120
  },
@@ -116,6 +127,7 @@ class DynamodbRefreshTokenProvider {
116
127
  sessionId: current.sessionId,
117
128
  createdAt: nowSec,
118
129
  expiresAt: nextRefreshTokenExpiresAt,
130
+ ttl: nextRefreshTokenExpiresAt,
119
131
  },
120
132
  ConditionExpression: 'attribute_not_exists(pk)',
121
133
  },
@@ -140,6 +152,8 @@ class DynamodbRefreshTokenProvider {
140
152
  /**
141
153
  * Sets `revokedAt` on the token row. Missing items succeed (idempotent revoke).
142
154
  *
155
+ * Does not update `ttl`; existing `ttl` from issue/rotate still applies for DynamoDB cleanup.
156
+ *
143
157
  * @param params - Refresh token and optional clock (`now`).
144
158
  * @returns `true` after a successful update or no-op when the item is absent.
145
159
  * @throws {@link RefreshTokenInvalidError} When the token string format is invalid.
@@ -172,7 +186,11 @@ class DynamodbRefreshTokenProvider {
172
186
  }
173
187
  return true;
174
188
  };
175
- /** Returns the cached client, creating it on first use. */
189
+ /**
190
+ * Returns the cached {@link DynamoDBDocumentClient}, creating it on first use.
191
+ *
192
+ * @returns Document client configured for `region` and optional `endpoint`.
193
+ */
176
194
  this.getddb = () => {
177
195
  if (!this.ddb) {
178
196
  const client = new client_dynamodb_1.DynamoDBClient({
@@ -188,7 +206,12 @@ class DynamodbRefreshTokenProvider {
188
206
  }
189
207
  return this.ddb;
190
208
  };
191
- /** Loads a token row by partition key, or `null` if absent. */
209
+ /**
210
+ * Loads a token row by partition key.
211
+ *
212
+ * @param pk - Full partition key (`prefix` + hash).
213
+ * @returns Parsed {@link TokenRecord}, or `null` if the item does not exist.
214
+ */
192
215
  this.getTokenRecord = async (pk) => {
193
216
  const ddb = this.getddb();
194
217
  const res = await ddb.send(new lib_dynamodb_1.GetCommand({
@@ -198,22 +221,37 @@ class DynamodbRefreshTokenProvider {
198
221
  }));
199
222
  return res.Item ?? null;
200
223
  };
201
- /** Effective PK prefix from options or {@link DEFAULT_PRIMARY_KEY_PREFIX}. */
224
+ /**
225
+ * Effective partition key prefix from {@link StoreOptions} or {@link DEFAULT_PRIMARY_KEY_PREFIX}.
226
+ *
227
+ * @returns Prefix string (e.g. `rt#`).
228
+ */
202
229
  this.getPrimaryKeyPrefix = () => {
203
230
  return `${this.options?.pkPrefix ?? DEFAULT_PRIMARY_KEY_PREFIX}`;
204
231
  };
205
- /** Full partition key: prefix + SHA-256 hex of the raw token. */
232
+ /**
233
+ * Builds the full partition key for a token hash.
234
+ *
235
+ * @param hash - SHA-256 hex digest of the plaintext token.
236
+ * @returns `prefix` + `hash`.
237
+ */
206
238
  this.getPrimaryKey = (hash) => {
207
239
  return `${this.getPrimaryKeyPrefix()}${hash}`;
208
240
  };
209
- /** Expiration timestamp: `nowSec` plus TTL from options (default 60 days). */
241
+ /**
242
+ * Computes logical expiration (`expiresAt` / `ttl`) as `nowSec` plus {@link StoreOptions.ttlDays}.
243
+ *
244
+ * @param nowSec - Current time as Unix seconds.
245
+ * @returns Expiration timestamp in Unix seconds (default lifetime: 60 days).
246
+ */
210
247
  this.makeExpiresAt = (nowSec) => {
211
248
  return nowSec + (this.options?.ttlDays ?? 60) * 24 * 60 * 60;
212
249
  };
213
250
  }
214
251
  /**
215
- * Ensures the token is non-empty and matches the expected base64url length for `tokenBytes` (32 bytes → URL-safe base64 length).
252
+ * Ensures the token is non-empty and matches the expected base64url length for `tokenBytes`.
216
253
  *
254
+ * @param token - Plaintext refresh token from the client.
217
255
  * @throws {@link RefreshTokenInvalidError} When validation fails.
218
256
  */
219
257
  validateRefreshToken(token) {
@@ -223,4 +261,4 @@ class DynamodbRefreshTokenProvider {
223
261
  }
224
262
  }
225
263
  exports.DynamodbRefreshTokenProvider = DynamodbRefreshTokenProvider;
226
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1vZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmVzL2R5bmFtb2RiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDhEQUEwRDtBQUMxRCx3REFBNEg7QUFFNUgsaUVBS2dDO0FBRWhDLHdDQUF1RDtBQUN2RCx3Q0FBeUM7QUFLekMsNERBQTREO0FBQzVELE1BQU0sMEJBQTBCLEdBQUcsS0FBSyxDQUFDO0FBRXpDOzs7O0dBSUc7QUFDSCxNQUFhLDRCQUE0QjtJQU92Qzs7OztPQUlHO0lBQ0gsWUFDbUIsU0FBaUIsRUFDakIsTUFBYyxFQUNkLE9BQXNCO1FBRnRCLGNBQVMsR0FBVCxTQUFTLENBQVE7UUFDakIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQWU7UUFkekMscURBQXFEO1FBQzdDLFFBQUcsR0FBa0MsSUFBSSxDQUFDO1FBRWxELDhFQUE4RTtRQUM3RCxlQUFVLEdBQUcsRUFBRSxDQUFDO1FBYWpDOzs7OztXQUtHO1FBQ0ksVUFBSyxHQUFHLEtBQUssRUFBRSxNQUFtQixFQUF3QixFQUFFO1lBQ2pFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUUxQixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7WUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBQSxlQUFRLEVBQUMsR0FBRyxDQUFDLENBQUM7WUFDN0IsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUU3QyxNQUFNLFlBQVksR0FBRyxJQUFBLGtCQUFXLEVBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2xELE1BQU0sSUFBSSxHQUFHLElBQUEsZ0JBQVMsRUFBQyxZQUFZLENBQUMsQ0FBQztZQUNyQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUks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QyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2xFLE1BQU0sSUFBSSwrQ0FBd0IsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7SUFDSCxDQUFDO0NBRUY7QUFqUEQsb0VBaVBDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHluYW1vREJDbGllbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtZHluYW1vZGInO1xuaW1wb3J0IHsgRHluYW1vREJEb2N1bWVudENsaWVudCwgR2V0Q29tbWFuZCwgUHV0Q29tbWFuZCwgVXBkYXRlQ29tbWFuZCwgVHJhbnNhY3RXcml0ZUNvbW1hbmQgfSBmcm9tICdAYXdzLXNkay9saWItZHluYW1vZGInO1xuXG5pbXBvcnQge1xuICBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3IsXG4gIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IsXG4gIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcixcbn0gZnJvbSAnLi9yZWZyZXNoLXRva2VuLWVycm9ycyc7XG5pbXBvcnQgdHlwZSB7IFJlZnJlc2hUb2tlblN0b3JlLCBTdG9yZU9wdGlvbnMsIFRva2VuUmVjb3JkLCBJc3N1ZVBhcmFtcywgUm90YXRlUGFyYW1zLCBSZXZva2VQYXJhbXMsIElzc3VlUmVzdWx0LCBSb3RhdGVSZXN1bHQgfSBmcm9tICcuLi90eXBlcy9pbmRleCc7XG5pbXBvcnQgeyByYW5kb210b2tlbiwgc2hhMjU2aGV4IH0gZnJvbSAnLi4vdXRpbHMvaGFzaCc7XG5pbXBvcnQgeyBlcG9jaHNlYyB9IGZyb20gJy4uL3V0aWxzL3RpbWUnO1xuXG4vKiogUmUtZXhwb3J0ZWQgdHlwZXMgZm9yIGNvbnN1bWVycyB0aGF0IGltcG9ydCB0aGUgRHluYW1vREIgc3RvcmUgbW9kdWxlLiAqL1xuZXhwb3J0IHsgUmVmcmVzaFRva2VuU3RvcmUsIFN0b3JlT3B0aW9ucywgVG9rZW5SZWNvcmQsIElzc3VlUGFyYW1zLCBSb3RhdGVQYXJhbXMsIFJldm9rZVBhcmFtcywgSXNzdWVSZXN1bHQsIFJvdGF0ZVJlc3VsdCB9O1xuXG4vKiogRGVmYXVsdCBwYXJ0aXRpb24ga2V5IHByZWZpeCBmb3IgcmVmcmVzaCB0b2tlbiBpdGVtcy4gKi9cbmNvbnN0IERFRkFVTFRfUFJJTUFSWV9LRVlfUFJFRklYID0gJ3J0Iyc7XG5cbi8qKlxuICoge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlfSBpbXBsZW1lbnRhdGlvbiB1c2luZyBhIHNpbmdsZSBEeW5hbW9EQiB0YWJsZS5cbiAqXG4gKiBUaGlzIGNsYXNzIG93bnMgdGhlIER5bmFtb0RCIGNsaWVudDsgY2FsbGVycyBzdXBwbHkgYHRhYmxlTmFtZWAsIGByZWdpb25gLCBhbmQgb3B0aW9uYWwge0BsaW5rIFN0b3JlT3B0aW9uc30uXG4gKi9cbmV4cG9ydCBjbGFzcyBEeW5hbW9kYlJlZnJlc2hUb2tlblByb3ZpZGVyIGltcGxlbWVudHMgUmVmcmVzaFRva2VuU3RvcmUge1xuICAvKiogTGF6aWx5IGluaXRpYWxpemVkIGFuZCBjYWNoZWQgZG9jdW1lbnQgY2xpZW50LiAqL1xuICBwcml2YXRlIGRkYjogRHluYW1vREJEb2N1bWVudENsaWVudCB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBSYW5kb20gYnl0ZSBsZW5ndGggZm9yIGdlbmVyYXRlZCByZWZyZXNoIHRva2VucyAoZGVmYXVsdCAzMiDihpIgMjU2LWJpdCkuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdG9rZW5CeXRlcyA9IDMyO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gdGFibGVOYW1lIC0gRHluYW1vREIgdGFibGUgbmFtZSBmb3IgcmVmcmVzaCB0b2tlbiBpdGVtcy5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIEFXUyByZWdpb24gZm9yIHRoZSBEeW5hbW9EQiBjbGllbnQuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gVFRMLCBQSyBwcmVmaXgsIGNvbnNpc3RlbnQgcmVhZHMsIG9yIGN1c3RvbSBlbmRwb2ludC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSByZWdpb246IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM/OiBTdG9yZU9wdGlvbnMsXG4gICkge31cblxuICAvKipcbiAgICogSW5zZXJ0cyBhIG5ldyB0b2tlbiByZWNvcmQuIEZhaWxzIHRoZSBwdXQgaWYgdGhlIHBhcnRpdGlvbiBrZXkgYWxyZWFkeSBleGlzdHMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTdWJqZWN0LCBzZXNzaW9uLCBhbmQgb3B0aW9uYWwgY2xvY2sgKGBub3dgKS5cbiAgICogQHJldHVybnMgUGxhaW50ZXh0IHJlZnJlc2ggdG9rZW4gYW5kIGV4cGlyYXRpb24gYXMgVW5peCBzZWNvbmRzLlxuICAgKi9cbiAgcHVibGljIGlzc3VlID0gYXN5bmMgKHBhcmFtczogSXNzdWVQYXJhbXMpOiBQcm9taXNlPElzc3VlUmVzdWx0PiA9PiB7XG4gICAgY29uc3QgZGRiID0gdGhpcy5nZXRkZGIoKTtcblxuICAgIGNvbnN0IG5vdyA9IHBhcmFtcy5ub3cgPz8gbmV3IERhdGUoKTtcbiAgICBjb25zdCBub3dTZWMgPSBlcG9jaHNlYyhub3cpO1xuICAgIGNvbnN0IGV4cGlyZXNBdCA9IHRoaXMubWFrZUV4cGlyZXNBdChub3dTZWMpO1xuXG4gICAgY29uc3QgcmVmcmVzaFRva2VuID0gcmFuZG9tdG9rZW4odGhpcy50b2tlbkJ5dGVzKTtcbiAgICBjb25zdCBoYXNoID0gc2hhMjU2aGV4KHJlZnJlc2hUb2tlbik7XG4gICAgY29uc3QgcGsgPSB0aGlzLmdldFByaW1hcnlLZXkoaGFzaCk7XG5cbiAgICBhd2FpdCBkZGIuc2VuZChcbiAgICAgIG5ldyBQdXRDb21tYW5kKHtcbiAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgSXRlbToge1xuICAgICAgICAgIHBrLFxuICAgICAgICAgIHN1YmplY3RJZDogcGFyYW1zLnN1YmplY3RJZCxcbiAgICAgICAgICBzZXNzaW9uSWQ6IHBhcmFtcy5zZXNzaW9uSWQsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3dTZWMsXG4gICAgICAgICAgZXhwaXJlc0F0LFxuICAgICAgICB9LFxuICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiAnYXR0cmlidXRlX25vdF9leGlzdHMocGspJyxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVmcmVzaFRva2VuLFxuICAgICAgcmVmcmVzaFRva2VuRXhwaXJlc0F0OiBleHBpcmVzQXQsXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogTWFya3MgdGhlIGN1cnJlbnQgdG9rZW4gYXMgcm90YXRlZCBhbmQgY3JlYXRlcyB0aGUgc3VjY2Vzc29yIHJvdyBpbiBvbmUgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBDbGllbnQgcmVmcmVzaCB0b2tlbiBhbmQgb3B0aW9uYWwgY2xvY2sgKGBub3dgKS5cbiAgICogQHJldHVybnMgU3ViamVjdCwgc2Vzc2lvbiwgbmV3IHBsYWludGV4dCB0b2tlbiwgYW5kIG5ldyBleHBpcmF0aW9uLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3J9IFdoZW4gdGhlIHRva2VuIGZvcm1hdCBpcyBpbnZhbGlkIG9yIG5vIHJvdyBleGlzdHMuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkV4cGlyZWRFcnJvcn0gV2hlbiBgZXhwaXJlc0F0YCBpcyBub3QgYWZ0ZXIgYG5vd2AuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gcm93IGhhcyBgcmV2b2tlZEF0YCBzZXQuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlblJldXNlZEVycm9yfSBXaGVuIHRoZSB0b2tlbiB3YXMgYWxyZWFkeSByb3RhdGVkIG9yIHRoZSB0cmFuc2FjdGlvbiBpbmRpY2F0ZXMgcmV1c2UuXG4gICAqL1xuICBwdWJsaWMgcm90YXRlID0gYXN5bmMgKHBhcmFtczogUm90YXRlUGFyYW1zKTogUHJvbWlzZTxSb3RhdGVSZXN1bHQ+ID0+IHtcbiAgICAvLyB2YWxpZGF0ZSByZWZyZXNoIHRva2VuXG4gICAgdGhpcy52YWxpZGF0ZVJlZnJlc2hUb2tlbihwYXJhbXMucmVmcmVzaFRva2VuKTtcblxuICAgIGNvbnN0IGRkYiA9IHRoaXMuZ2V0ZGRiKCk7XG5cbiAgICBjb25zdCBub3cgPSBwYXJhbXMubm93ID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgbm93U2VjID0gZXBvY2hzZWMobm93KTtcblxuICAgIGNvbnN0IGN1cnJlbnRIYXNoID0gc2hhMjU2aGV4KHBhcmFtcy5yZWZyZXNoVG9rZW4pO1xuICAgIGNvbnN0IGN1cnJlbnRQayA9IHRoaXMuZ2V0UHJpbWFyeUtleShjdXJyZW50SGFzaCk7XG5cbiAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgdGhpcy5nZXRUb2tlblJlY29yZChjdXJyZW50UGspO1xuICAgIGlmICghY3VycmVudCkge1xuICAgICAgdGhyb3cgbmV3IFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcigpO1xuICAgIH1cbiAgICBpZiAoY3VycmVudC5leHBpcmVzQXQgPD0gbm93U2VjKSB7XG4gICAgICB0aHJvdyBuZXcgUmVmcmVzaFRva2VuRXhwaXJlZEVycm9yKCk7XG4gICAgfVxuICAgIGlmIChjdXJyZW50LnJldm9rZWRBdCkge1xuICAgICAgdGhyb3cgbmV3IFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcigpO1xuICAgIH1cbiAgICBpZiAoY3VycmVudC5yb3RhdGVkQXQpIHtcbiAgICAgIHRocm93IG5ldyBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcigpO1xuICAgIH1cblxuICAgIGNvbnN0IG5leHRSZWZyZXNoVG9rZW5FeHBpcmVzQXQgPSB0aGlzLm1ha2VFeHBpcmVzQXQobm93U2VjKTtcbiAgICBjb25zdCBuZXh0UmVmcmVzaFRva2VuID0gcmFuZG9tdG9rZW4odGhpcy50b2tlbkJ5dGVzKTtcbiAgICBjb25zdCBuZXh0SGFzaCA9IHNoYTI1NmhleChuZXh0UmVmcmVzaFRva2VuKTtcbiAgICBjb25zdCBuZXh0UGsgPSB0aGlzLmdldFByaW1hcnlLZXkobmV4dEhhc2gpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGRkYi5zZW5kKG5ldyBUcmFuc2FjdFdyaXRlQ29tbWFuZCh7XG4gICAgICAgIFRyYW5zYWN0SXRlbXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBVcGRhdGU6IHtcbiAgICAgICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICAgICAgS2V5OiB7IHBrOiBjdXJyZW50UGsgfSxcbiAgICAgICAgICAgICAgVXBkYXRlRXhwcmVzc2lvbjogJ1NFVCByb3RhdGVkQXQgPSA6bm93LCByZXBsYWNlZEJ5UGsgPSA6bmV4dFBrJyxcbiAgICAgICAgICAgICAgQ29uZGl0aW9uRXhwcmVzc2lvbjogJ2F0dHJpYnV0ZV9leGlzdHMocGspIEFORCBhdHRyaWJ1dGVfbm90X2V4aXN0cyhyb3RhdGVkQXQpIEFORCBhdHRyaWJ1dGVfbm90X2V4aXN0cyhyZXZva2VkQXQpJyxcbiAgICAgICAgICAgICAgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczoge1xuICAgICAgICAgICAgICAgICc6bm93Jzogbm93U2VjLFxuICAgICAgICAgICAgICAgICc6bmV4dFBrJzogbmV4dFBrLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFB1dDoge1xuICAgICAgICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICAgICAgICBJdGVtOiB7XG4gICAgICAgICAgICAgICAgcGs6IG5leHRQayxcbiAgICAgICAgICAgICAgICBzdWJqZWN0SWQ6IGN1cnJlbnQuc3ViamVjdElkLFxuICAgICAgICAgICAgICAgIHNlc3Npb25JZDogY3VycmVudC5zZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0OiBub3dTZWMsXG4gICAgICAgICAgICAgICAgZXhwaXJlc0F0OiBuZXh0UmVmcmVzaFRva2VuRXhwaXJlc0F0LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiAnYXR0cmlidXRlX25vdF9leGlzdHMocGspJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pKTtcblxuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5uYW1lID09PSAnVHJhbnNhY3Rpb25DYW5jZWxlZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgLy8gVHJlYXQgY29uZGl0aW9uYWwgdHJhbnNhY3Rpb24gZmFpbHVyZSBhcyB0b2tlbiByZXVzZS5cbiAgICAgICAgdGhyb3cgbmV3IFJlZnJlc2hUb2tlblJldXNlZEVycm9yKCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3ViamVjdElkOiBjdXJyZW50LnN1YmplY3RJZCxcbiAgICAgIHNlc3Npb25JZDogY3VycmVudC5zZXNzaW9uSWQsXG4gICAgICByZWZyZXNoVG9rZW46IG5leHRSZWZyZXNoVG9rZW4sXG4gICAgICByZWZyZXNoVG9rZW5FeHBpcmVzQXQ6IG5leHRSZWZyZXNoVG9rZW5FeHBpcmVzQXQsXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogU2V0cyBgcmV2b2tlZEF0YCBvbiB0aGUgdG9rZW4gcm93LiBNaXNzaW5nIGl0ZW1zIHN1Y2NlZWQgKGlkZW1wb3RlbnQgcmV2b2tlKS5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFJlZnJlc2ggdG9rZW4gYW5kIG9wdGlvbmFsIGNsb2NrIChgbm93YCkuXG4gICAqIEByZXR1cm5zIGB0cnVlYCBhZnRlciBhIHN1Y2Nlc3NmdWwgdXBkYXRlIG9yIG5vLW9wIHdoZW4gdGhlIGl0ZW0gaXMgYWJzZW50LlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3J9IFdoZW4gdGhlIHRva2VuIHN0cmluZyBmb3JtYXQgaXMgaW52YWxpZC5cbiAgICovXG4gIHB1YmxpYyByZXZva2UgPSBhc3luYyAocGFyYW1zOiBSZXZva2VQYXJhbXMpOiBQcm9taXNlPHRydWU+ID0+IHtcbiAgICAvLyB2YWxpZGF0ZSByZWZyZXNoIHRva2VuXG4gICAgdGhpcy52YWxpZGF0ZVJlZnJlc2hUb2tlbihwYXJhbXMucmVmcmVzaFRva2VuKTtcblxuICAgIGNvbnN0IGRkYiA9IHRoaXMuZ2V0ZGRiKCk7XG5cbiAgICBjb25zdCBub3cgPSBwYXJhbXMubm93ID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgbm93U2VjID0gZXBvY2hzZWMobm93KTtcblxuICAgIGNvbnN0IGhhc2ggPSBzaGEyNTZoZXgocGFyYW1zLnJlZnJlc2hUb2tlbik7XG4gICAgY29uc3QgcGsgPSB0aGlzLmdldFByaW1hcnlLZXkoaGFzaCk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZGRiLnNlbmQoXG4gICAgICAgIG5ldyBVcGRhdGVDb21tYW5kKHtcbiAgICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICAgIEtleTogeyBwayB9LFxuICAgICAgICAgIFVwZGF0ZUV4cHJlc3Npb246ICdTRVQgcmV2b2tlZEF0ID0gOm5vdycsXG4gICAgICAgICAgQ29uZGl0aW9uRXhwcmVzc2lvbjogJ2F0dHJpYnV0ZV9leGlzdHMocGspJyxcbiAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICAnOm5vdyc6IG5vd1NlYyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIE1pc3NpbmcgaXRlbTogdHJlYXQgYXMgc3VjY2VzcyAoaWRlbXBvdGVudCByZXZva2UpLlxuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubmFtZSA9PT0gJ0NvbmRpdGlvbmFsQ2hlY2tGYWlsZWRFeGNlcHRpb24nKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8qKiBSZXR1cm5zIHRoZSBjYWNoZWQgY2xpZW50LCBjcmVhdGluZyBpdCBvbiBmaXJzdCB1c2UuICovXG4gIHByaXZhdGUgZ2V0ZGRiID0gKCk6IER5bmFtb0RCRG9jdW1lbnRDbGllbnQgPT4ge1xuICAgIGlmICghdGhpcy5kZGIpIHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IG5ldyBEeW5hbW9EQkNsaWVudCh7XG4gICAgICAgIHJlZ2lvbjogdGhpcy5yZWdpb24sXG4gICAgICAgIGVuZHBvaW50OiAoKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnM/LmVuZHBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmVuZHBvaW50O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYGh0dHBzOi8vZHluYW1vZGIuJHt0aGlzLnJlZ2lvbn0uYW1hem9uYXdzLmNvbWA7XG4gICAgICAgIH0pKCksXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZGRiID0gRHluYW1vREJEb2N1bWVudENsaWVudC5mcm9tKGNsaWVudCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRkYjtcbiAgfTtcblxuICAvKiogTG9hZHMgYSB0b2tlbiByb3cgYnkgcGFydGl0aW9uIGtleSwgb3IgYG51bGxgIGlmIGFic2VudC4gKi9cbiAgcHJpdmF0ZSBnZXRUb2tlblJlY29yZCA9IGFzeW5jIChwazogc3RyaW5nKTogUHJvbWlzZTxUb2tlblJlY29yZCB8IG51bGw+ID0+IHtcbiAgICBjb25zdCBkZGIgPSB0aGlzLmdldGRkYigpO1xuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgZGRiLnNlbmQoXG4gICAgICBuZXcgR2V0Q29tbWFuZCh7XG4gICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgIEtleTogeyBwayB9LFxuICAgICAgICBDb25zaXN0ZW50UmVhZDogdGhpcy5vcHRpb25zPy5jb25zaXN0ZW50UmVhZCA/PyB0cnVlLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gKHJlcy5JdGVtIGFzIFRva2VuUmVjb3JkKSA/PyBudWxsO1xuICB9O1xuXG4gIC8qKiBFZmZlY3RpdmUgUEsgcHJlZml4IGZyb20gb3B0aW9ucyBvciB7QGxpbmsgREVGQVVMVF9QUklNQVJZX0tFWV9QUkVGSVh9LiAqL1xuICBwcml2YXRlIGdldFByaW1hcnlLZXlQcmVmaXggPSAoKTogc3RyaW5nID0+IHtcbiAgICByZXR1cm4gYCR7dGhpcy5vcHRpb25zPy5wa1ByZWZpeCA/PyBERUZBVUxUX1BSSU1BUllfS0VZX1BSRUZJWH1gO1xuICB9O1xuXG4gIC8qKiBGdWxsIHBhcnRpdGlvbiBrZXk6IHByZWZpeCArIFNIQS0yNTYgaGV4IG9mIHRoZSByYXcgdG9rZW4uICovXG4gIHByaXZhdGUgZ2V0UHJpbWFyeUtleSA9IChoYXNoOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgIHJldHVybiBgJHt0aGlzLmdldFByaW1hcnlLZXlQcmVmaXgoKX0ke2hhc2h9YDtcbiAgfTtcblxuICAvKiogRXhwaXJhdGlvbiB0aW1lc3RhbXA6IGBub3dTZWNgIHBsdXMgVFRMIGZyb20gb3B0aW9ucyAoZGVmYXVsdCA2MCBkYXlzKS4gKi9cbiAgcHJpdmF0ZSBtYWtlRXhwaXJlc0F0ID0gKG5vd1NlYzogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gbm93U2VjICsgKHRoaXMub3B0aW9ucz8udHRsRGF5cyA/PyA2MCkgKiAyNCAqIDYwICogNjA7XG4gIH07XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhlIHRva2VuIGlzIG5vbi1lbXB0eSBhbmQgbWF0Y2hlcyB0aGUgZXhwZWN0ZWQgYmFzZTY0dXJsIGxlbmd0aCBmb3IgYHRva2VuQnl0ZXNgICgzMiBieXRlcyDihpIgVVJMLXNhZmUgYmFzZTY0IGxlbmd0aCkuXG4gICAqXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcn0gV2hlbiB2YWxpZGF0aW9uIGZhaWxzLlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVJlZnJlc2hUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0b2tlbiB8fCB0b2tlbi5sZW5ndGggIT09IE1hdGguY2VpbCh0aGlzLnRva2VuQnl0ZXMgKiA4IC8gNikpIHtcbiAgICAgIHRocm93IG5ldyBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3IoKTtcbiAgICB9XG4gIH1cblxufVxuIl19
264
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1vZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmVzL2R5bmFtb2RiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDhEQUEwRDtBQUMxRCx3REFBNEg7QUFFNUgsaUVBS2dDO0FBRWhDLHdDQUF1RDtBQUN2RCx3Q0FBeUM7QUFLekMsNERBQTREO0FBQzVELE1BQU0sMEJBQTBCLEdBQUcsS0FBSyxDQUFDO0FBRXpDOzs7Ozs7O0dBT0c7QUFDSCxNQUFhLDRCQUE0QjtJQU92Qzs7OztPQUlHO0lBQ0gsWUFDbUIsU0FBaUIsRUFDakIsTUFBYyxFQUNkLE9BQXNCO1FBRnRCLGNBQVMsR0FBVCxTQUFTLENBQVE7UUFDakIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQWU7UUFkekMscURBQXFEO1FBQzdDLFFBQUcsR0FBa0MsSUFBSSxDQUFDO1FBRWxELDhFQUE4RTtRQUM3RCxlQUFVLEdBQUcsRUFBRSxDQUFDO1FBYWpDOzs7OztXQUtHO1FBQ0ksVUFBSyxHQUFHLEtBQUssRUFBRSxNQUFtQixFQUF3QixFQUFFO1lBQ2pFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUUxQixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7WUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBQSxlQUFRLEVBQUMsR0FBRyxDQUFDLENBQUM7WUFDN0IsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUU3QyxNQUFNLFlBQVksR0FBRyxJQUFBLGtCQUFXLEVBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2xELE1BQU0sSUFBSSxHQUFHLElBQUEsZ0JBQVMsRUFBQyxZQUFZLENBQUMsQ0FBQztZQUNyQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElB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RSxDQUFDO1FBQy9ELENBQUMsQ0FBQztJQXRQQyxDQUFDO0lBd1BKOzs7OztPQUtHO0lBQ0ssb0JBQW9CLENBQUMsS0FBYTtRQUN4QyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2xFLE1BQU0sSUFBSSwrQ0FBd0IsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7SUFDSCxDQUFDO0NBRUY7QUFwUkQsb0VBb1JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHluYW1vREJDbGllbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtZHluYW1vZGInO1xuaW1wb3J0IHsgRHluYW1vREJEb2N1bWVudENsaWVudCwgR2V0Q29tbWFuZCwgUHV0Q29tbWFuZCwgVXBkYXRlQ29tbWFuZCwgVHJhbnNhY3RXcml0ZUNvbW1hbmQgfSBmcm9tICdAYXdzLXNkay9saWItZHluYW1vZGInO1xuXG5pbXBvcnQge1xuICBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3IsXG4gIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcixcbiAgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IsXG4gIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcixcbn0gZnJvbSAnLi9yZWZyZXNoLXRva2VuLWVycm9ycyc7XG5pbXBvcnQgdHlwZSB7IFJlZnJlc2hUb2tlblN0b3JlLCBTdG9yZU9wdGlvbnMsIFRva2VuUmVjb3JkLCBJc3N1ZVBhcmFtcywgUm90YXRlUGFyYW1zLCBSZXZva2VQYXJhbXMsIElzc3VlUmVzdWx0LCBSb3RhdGVSZXN1bHQgfSBmcm9tICcuLi90eXBlcy9pbmRleCc7XG5pbXBvcnQgeyByYW5kb210b2tlbiwgc2hhMjU2aGV4IH0gZnJvbSAnLi4vdXRpbHMvaGFzaCc7XG5pbXBvcnQgeyBlcG9jaHNlYyB9IGZyb20gJy4uL3V0aWxzL3RpbWUnO1xuXG4vKiogUmUtZXhwb3J0ZWQgdHlwZXMgZm9yIGNvbnN1bWVycyB0aGF0IGltcG9ydCB0aGUgRHluYW1vREIgc3RvcmUgbW9kdWxlLiAqL1xuZXhwb3J0IHsgUmVmcmVzaFRva2VuU3RvcmUsIFN0b3JlT3B0aW9ucywgVG9rZW5SZWNvcmQsIElzc3VlUGFyYW1zLCBSb3RhdGVQYXJhbXMsIFJldm9rZVBhcmFtcywgSXNzdWVSZXN1bHQsIFJvdGF0ZVJlc3VsdCB9O1xuXG4vKiogRGVmYXVsdCBwYXJ0aXRpb24ga2V5IHByZWZpeCBmb3IgcmVmcmVzaCB0b2tlbiBpdGVtcy4gKi9cbmNvbnN0IERFRkFVTFRfUFJJTUFSWV9LRVlfUFJFRklYID0gJ3J0Iyc7XG5cbi8qKlxuICoge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlfSBpbXBsZW1lbnRhdGlvbiBiYWNrZWQgYnkgYSBzaW5nbGUgRHluYW1vREIgdGFibGUuXG4gKlxuICogSXRlbXMgdXNlIHBhcnRpdGlvbiBrZXkgYHBrYCwgbG9naWNhbCBleHBpcmF0aW9uIGBleHBpcmVzQXRgLCBhbmQgRHluYW1vREIgVFRMIGF0dHJpYnV0ZSBgdHRsYFxuICogKFVuaXggc2Vjb25kcykuIEVuYWJsZSB0YWJsZSBUVEwgb24gYXR0cmlidXRlIGB0dGxgIHNvIGV4cGlyZWQgYW5kIHJvdGF0ZWQgcm93cyBhcmUgcmVtb3ZlZFxuICogYXN5bmNocm9ub3VzbHkuIFRoaXMgY2xhc3Mgb3ducyB0aGUgRHluYW1vREIgY2xpZW50OyBjYWxsZXJzIHN1cHBseSBgdGFibGVOYW1lYCwgYHJlZ2lvbmAsIGFuZFxuICogb3B0aW9uYWwge0BsaW5rIFN0b3JlT3B0aW9uc30uXG4gKi9cbmV4cG9ydCBjbGFzcyBEeW5hbW9kYlJlZnJlc2hUb2tlblByb3ZpZGVyIGltcGxlbWVudHMgUmVmcmVzaFRva2VuU3RvcmUge1xuICAvKiogTGF6aWx5IGluaXRpYWxpemVkIGFuZCBjYWNoZWQgZG9jdW1lbnQgY2xpZW50LiAqL1xuICBwcml2YXRlIGRkYjogRHluYW1vREJEb2N1bWVudENsaWVudCB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBSYW5kb20gYnl0ZSBsZW5ndGggZm9yIGdlbmVyYXRlZCByZWZyZXNoIHRva2VucyAoZGVmYXVsdCAzMiDihpIgMjU2LWJpdCkuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdG9rZW5CeXRlcyA9IDMyO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gdGFibGVOYW1lIC0gRHluYW1vREIgdGFibGUgbmFtZSBmb3IgcmVmcmVzaCB0b2tlbiBpdGVtcy5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIEFXUyByZWdpb24gZm9yIHRoZSBEeW5hbW9EQiBjbGllbnQuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gVG9rZW4gbGlmZXRpbWUsIFBLIHByZWZpeCwgY29uc2lzdGVudCByZWFkcywgb3IgY3VzdG9tIGVuZHBvaW50LlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvbjogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9ucz86IFN0b3JlT3B0aW9ucyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBJbnNlcnRzIGEgbmV3IHRva2VuIHJlY29yZCB3aXRoIGBleHBpcmVzQXRgIGFuZCBtYXRjaGluZyBgdHRsYC4gRmFpbHMgdGhlIHB1dCBpZiBgcGtgIGFscmVhZHkgZXhpc3RzLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU3ViamVjdCwgc2Vzc2lvbiwgYW5kIG9wdGlvbmFsIGNsb2NrIChgbm93YCkuXG4gICAqIEByZXR1cm5zIFBsYWludGV4dCByZWZyZXNoIHRva2VuIGFuZCBleHBpcmF0aW9uIGFzIFVuaXggc2Vjb25kcy5cbiAgICovXG4gIHB1YmxpYyBpc3N1ZSA9IGFzeW5jIChwYXJhbXM6IElzc3VlUGFyYW1zKTogUHJvbWlzZTxJc3N1ZVJlc3VsdD4gPT4ge1xuICAgIGNvbnN0IGRkYiA9IHRoaXMuZ2V0ZGRiKCk7XG5cbiAgICBjb25zdCBub3cgPSBwYXJhbXMubm93ID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgbm93U2VjID0gZXBvY2hzZWMobm93KTtcbiAgICBjb25zdCBleHBpcmVzQXQgPSB0aGlzLm1ha2VFeHBpcmVzQXQobm93U2VjKTtcblxuICAgIGNvbnN0IHJlZnJlc2hUb2tlbiA9IHJhbmRvbXRva2VuKHRoaXMudG9rZW5CeXRlcyk7XG4gICAgY29uc3QgaGFzaCA9IHNoYTI1NmhleChyZWZyZXNoVG9rZW4pO1xuICAgIGNvbnN0IHBrID0gdGhpcy5nZXRQcmltYXJ5S2V5KGhhc2gpO1xuXG4gICAgYXdhaXQgZGRiLnNlbmQoXG4gICAgICBuZXcgUHV0Q29tbWFuZCh7XG4gICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgIEl0ZW06IHtcbiAgICAgICAgICBwayxcbiAgICAgICAgICBzdWJqZWN0SWQ6IHBhcmFtcy5zdWJqZWN0SWQsXG4gICAgICAgICAgc2Vzc2lvbklkOiBwYXJhbXMuc2Vzc2lvbklkLFxuICAgICAgICAgIGNyZWF0ZWRBdDogbm93U2VjLFxuICAgICAgICAgIGV4cGlyZXNBdCxcbiAgICAgICAgICB0dGw6IGV4cGlyZXNBdCxcbiAgICAgICAgfSxcbiAgICAgICAgQ29uZGl0aW9uRXhwcmVzc2lvbjogJ2F0dHJpYnV0ZV9ub3RfZXhpc3RzKHBrKScsXG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlZnJlc2hUb2tlbixcbiAgICAgIHJlZnJlc2hUb2tlbkV4cGlyZXNBdDogZXhwaXJlc0F0LFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIE1hcmtzIHRoZSBjdXJyZW50IHRva2VuIGFzIHJvdGF0ZWQgYW5kIGNyZWF0ZXMgdGhlIHN1Y2Nlc3NvciByb3cgaW4gb25lIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBVcGRhdGVzIHRoZSBwcmV2aW91cyByb3figJlzIGB0dGxgIHRvIGl0cyBgZXhwaXJlc0F0YCBhbmQgc2V0cyBgdHRsYCBvbiB0aGUgbmV3IFB1dCB0byB0aGVcbiAgICogc3VjY2Vzc29y4oCZcyBleHBpcmF0aW9uIHNvIER5bmFtb0RCIGNhbiBkZWxldGUgYm90aCB3aGVuIGFwcHJvcHJpYXRlLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gQ2xpZW50IHJlZnJlc2ggdG9rZW4gYW5kIG9wdGlvbmFsIGNsb2NrIChgbm93YCkuXG4gICAqIEByZXR1cm5zIFN1YmplY3QsIHNlc3Npb24sIG5ldyBwbGFpbnRleHQgdG9rZW4sIGFuZCBuZXcgZXhwaXJhdGlvbi5cbiAgICogQHRocm93cyB7QGxpbmsgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yfSBXaGVuIHRoZSB0b2tlbiBmb3JtYXQgaXMgaW52YWxpZCBvciBubyByb3cgZXhpc3RzLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3J9IFdoZW4gYGV4cGlyZXNBdGAgaXMgbm90IGFmdGVyIGBub3dgLlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXZva2VkRXJyb3J9IFdoZW4gdGhlIHRva2VuIHJvdyBoYXMgYHJldm9rZWRBdGAgc2V0LlxuICAgKiBAdGhyb3dzIHtAbGluayBSZWZyZXNoVG9rZW5SZXVzZWRFcnJvcn0gV2hlbiB0aGUgdG9rZW4gd2FzIGFscmVhZHkgcm90YXRlZCBvciB0aGUgdHJhbnNhY3Rpb24gaW5kaWNhdGVzIHJldXNlLlxuICAgKi9cbiAgcHVibGljIHJvdGF0ZSA9IGFzeW5jIChwYXJhbXM6IFJvdGF0ZVBhcmFtcyk6IFByb21pc2U8Um90YXRlUmVzdWx0PiA9PiB7XG4gICAgLy8gdmFsaWRhdGUgcmVmcmVzaCB0b2tlblxuICAgIHRoaXMudmFsaWRhdGVSZWZyZXNoVG9rZW4ocGFyYW1zLnJlZnJlc2hUb2tlbik7XG5cbiAgICBjb25zdCBkZGIgPSB0aGlzLmdldGRkYigpO1xuXG4gICAgY29uc3Qgbm93ID0gcGFyYW1zLm5vdyA/PyBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IG5vd1NlYyA9IGVwb2Noc2VjKG5vdyk7XG5cbiAgICBjb25zdCBjdXJyZW50SGFzaCA9IHNoYTI1NmhleChwYXJhbXMucmVmcmVzaFRva2VuKTtcbiAgICBjb25zdCBjdXJyZW50UGsgPSB0aGlzLmdldFByaW1hcnlLZXkoY3VycmVudEhhc2gpO1xuXG4gICAgY29uc3QgY3VycmVudCA9IGF3YWl0IHRoaXMuZ2V0VG9rZW5SZWNvcmQoY3VycmVudFBrKTtcbiAgICBpZiAoIWN1cnJlbnQpIHtcbiAgICAgIHRocm93IG5ldyBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3IoKTtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnQuZXhwaXJlc0F0IDw9IG5vd1NlYykge1xuICAgICAgdGhyb3cgbmV3IFJlZnJlc2hUb2tlbkV4cGlyZWRFcnJvcigpO1xuICAgIH1cbiAgICBpZiAoY3VycmVudC5yZXZva2VkQXQpIHtcbiAgICAgIHRocm93IG5ldyBSZWZyZXNoVG9rZW5SZXZva2VkRXJyb3IoKTtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnQucm90YXRlZEF0KSB7XG4gICAgICB0aHJvdyBuZXcgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IoKTtcbiAgICB9XG5cbiAgICBjb25zdCBuZXh0UmVmcmVzaFRva2VuRXhwaXJlc0F0ID0gdGhpcy5tYWtlRXhwaXJlc0F0KG5vd1NlYyk7XG4gICAgY29uc3QgbmV4dFJlZnJlc2hUb2tlbiA9IHJhbmRvbXRva2VuKHRoaXMudG9rZW5CeXRlcyk7XG4gICAgY29uc3QgbmV4dEhhc2ggPSBzaGEyNTZoZXgobmV4dFJlZnJlc2hUb2tlbik7XG4gICAgY29uc3QgbmV4dFBrID0gdGhpcy5nZXRQcmltYXJ5S2V5KG5leHRIYXNoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBkZGIuc2VuZChuZXcgVHJhbnNhY3RXcml0ZUNvbW1hbmQoe1xuICAgICAgICBUcmFuc2FjdEl0ZW1zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgVXBkYXRlOiB7XG4gICAgICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgICAgIEtleTogeyBwazogY3VycmVudFBrIH0sXG4gICAgICAgICAgICAgIFVwZGF0ZUV4cHJlc3Npb246ICdTRVQgcm90YXRlZEF0ID0gOm5vdywgcmVwbGFjZWRCeVBrID0gOm5leHRQaywgI3R0bCA9IDp0dGwnLFxuICAgICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiAnYXR0cmlidXRlX2V4aXN0cyhwaykgQU5EIGF0dHJpYnV0ZV9ub3RfZXhpc3RzKHJvdGF0ZWRBdCkgQU5EIGF0dHJpYnV0ZV9ub3RfZXhpc3RzKHJldm9rZWRBdCknLFxuICAgICAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlTmFtZXM6IHtcbiAgICAgICAgICAgICAgICAnI3R0bCc6ICd0dGwnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICAgICAgJzpub3cnOiBub3dTZWMsXG4gICAgICAgICAgICAgICAgJzpuZXh0UGsnOiBuZXh0UGssXG4gICAgICAgICAgICAgICAgJzp0dGwnOiBjdXJyZW50LmV4cGlyZXNBdCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBQdXQ6IHtcbiAgICAgICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICAgICAgSXRlbToge1xuICAgICAgICAgICAgICAgIHBrOiBuZXh0UGssXG4gICAgICAgICAgICAgICAgc3ViamVjdElkOiBjdXJyZW50LnN1YmplY3RJZCxcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IGN1cnJlbnQuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgIGNyZWF0ZWRBdDogbm93U2VjLFxuICAgICAgICAgICAgICAgIGV4cGlyZXNBdDogbmV4dFJlZnJlc2hUb2tlbkV4cGlyZXNBdCxcbiAgICAgICAgICAgICAgICB0dGw6IG5leHRSZWZyZXNoVG9rZW5FeHBpcmVzQXQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIENvbmRpdGlvbkV4cHJlc3Npb246ICdhdHRyaWJ1dGVfbm90X2V4aXN0cyhwayknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSkpO1xuXG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdUcmFuc2FjdGlvbkNhbmNlbGVkRXhjZXB0aW9uJykge1xuICAgICAgICAvLyBUcmVhdCBjb25kaXRpb25hbCB0cmFuc2FjdGlvbiBmYWlsdXJlIGFzIHRva2VuIHJldXNlLlxuICAgICAgICB0aHJvdyBuZXcgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBzdWJqZWN0SWQ6IGN1cnJlbnQuc3ViamVjdElkLFxuICAgICAgc2Vzc2lvbklkOiBjdXJyZW50LnNlc3Npb25JZCxcbiAgICAgIHJlZnJlc2hUb2tlbjogbmV4dFJlZnJlc2hUb2tlbixcbiAgICAgIHJlZnJlc2hUb2tlbkV4cGlyZXNBdDogbmV4dFJlZnJlc2hUb2tlbkV4cGlyZXNBdCxcbiAgICB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiBTZXRzIGByZXZva2VkQXRgIG9uIHRoZSB0b2tlbiByb3cuIE1pc3NpbmcgaXRlbXMgc3VjY2VlZCAoaWRlbXBvdGVudCByZXZva2UpLlxuICAgKlxuICAgKiBEb2VzIG5vdCB1cGRhdGUgYHR0bGA7IGV4aXN0aW5nIGB0dGxgIGZyb20gaXNzdWUvcm90YXRlIHN0aWxsIGFwcGxpZXMgZm9yIER5bmFtb0RCIGNsZWFudXAuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBSZWZyZXNoIHRva2VuIGFuZCBvcHRpb25hbCBjbG9jayAoYG5vd2ApLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgYWZ0ZXIgYSBzdWNjZXNzZnVsIHVwZGF0ZSBvciBuby1vcCB3aGVuIHRoZSBpdGVtIGlzIGFic2VudC5cbiAgICogQHRocm93cyB7QGxpbmsgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yfSBXaGVuIHRoZSB0b2tlbiBzdHJpbmcgZm9ybWF0IGlzIGludmFsaWQuXG4gICAqL1xuICBwdWJsaWMgcmV2b2tlID0gYXN5bmMgKHBhcmFtczogUmV2b2tlUGFyYW1zKTogUHJvbWlzZTx0cnVlPiA9PiB7XG4gICAgLy8gdmFsaWRhdGUgcmVmcmVzaCB0b2tlblxuICAgIHRoaXMudmFsaWRhdGVSZWZyZXNoVG9rZW4ocGFyYW1zLnJlZnJlc2hUb2tlbik7XG5cbiAgICBjb25zdCBkZGIgPSB0aGlzLmdldGRkYigpO1xuXG4gICAgY29uc3Qgbm93ID0gcGFyYW1zLm5vdyA/PyBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IG5vd1NlYyA9IGVwb2Noc2VjKG5vdyk7XG5cbiAgICBjb25zdCBoYXNoID0gc2hhMjU2aGV4KHBhcmFtcy5yZWZyZXNoVG9rZW4pO1xuICAgIGNvbnN0IHBrID0gdGhpcy5nZXRQcmltYXJ5S2V5KGhhc2gpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGRkYi5zZW5kKFxuICAgICAgICBuZXcgVXBkYXRlQ29tbWFuZCh7XG4gICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICBLZXk6IHsgcGsgfSxcbiAgICAgICAgICBVcGRhdGVFeHByZXNzaW9uOiAnU0VUIHJldm9rZWRBdCA9IDpub3cnLFxuICAgICAgICAgIENvbmRpdGlvbkV4cHJlc3Npb246ICdhdHRyaWJ1dGVfZXhpc3RzKHBrKScsXG4gICAgICAgICAgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczoge1xuICAgICAgICAgICAgJzpub3cnOiBub3dTZWMsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvLyBNaXNzaW5nIGl0ZW06IHRyZWF0IGFzIHN1Y2Nlc3MgKGlkZW1wb3RlbnQgcmV2b2tlKS5cbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm5hbWUgPT09ICdDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY2FjaGVkIHtAbGluayBEeW5hbW9EQkRvY3VtZW50Q2xpZW50fSwgY3JlYXRpbmcgaXQgb24gZmlyc3QgdXNlLlxuICAgKlxuICAgKiBAcmV0dXJucyBEb2N1bWVudCBjbGllbnQgY29uZmlndXJlZCBmb3IgYHJlZ2lvbmAgYW5kIG9wdGlvbmFsIGBlbmRwb2ludGAuXG4gICAqL1xuICBwcml2YXRlIGdldGRkYiA9ICgpOiBEeW5hbW9EQkRvY3VtZW50Q2xpZW50ID0+IHtcbiAgICBpZiAoIXRoaXMuZGRiKSB7XG4gICAgICBjb25zdCBjbGllbnQgPSBuZXcgRHluYW1vREJDbGllbnQoe1xuICAgICAgICByZWdpb246IHRoaXMucmVnaW9uLFxuICAgICAgICBlbmRwb2ludDogKCgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5vcHRpb25zPy5lbmRwb2ludCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5lbmRwb2ludDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGBodHRwczovL2R5bmFtb2RiLiR7dGhpcy5yZWdpb259LmFtYXpvbmF3cy5jb21gO1xuICAgICAgICB9KSgpLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmRkYiA9IER5bmFtb0RCRG9jdW1lbnRDbGllbnQuZnJvbShjbGllbnQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5kZGI7XG4gIH07XG5cbiAgLyoqXG4gICAqIExvYWRzIGEgdG9rZW4gcm93IGJ5IHBhcnRpdGlvbiBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSBwayAtIEZ1bGwgcGFydGl0aW9uIGtleSAoYHByZWZpeGAgKyBoYXNoKS5cbiAgICogQHJldHVybnMgUGFyc2VkIHtAbGluayBUb2tlblJlY29yZH0sIG9yIGBudWxsYCBpZiB0aGUgaXRlbSBkb2VzIG5vdCBleGlzdC5cbiAgICovXG4gIHByaXZhdGUgZ2V0VG9rZW5SZWNvcmQgPSBhc3luYyAocGs6IHN0cmluZyk6IFByb21pc2U8VG9rZW5SZWNvcmQgfCBudWxsPiA9PiB7XG4gICAgY29uc3QgZGRiID0gdGhpcy5nZXRkZGIoKTtcblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGRkYi5zZW5kKFxuICAgICAgbmV3IEdldENvbW1hbmQoe1xuICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICBLZXk6IHsgcGsgfSxcbiAgICAgICAgQ29uc2lzdGVudFJlYWQ6IHRoaXMub3B0aW9ucz8uY29uc2lzdGVudFJlYWQgPz8gdHJ1ZSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIChyZXMuSXRlbSBhcyBUb2tlblJlY29yZCkgPz8gbnVsbDtcbiAgfTtcblxuICAvKipcbiAgICogRWZmZWN0aXZlIHBhcnRpdGlvbiBrZXkgcHJlZml4IGZyb20ge0BsaW5rIFN0b3JlT3B0aW9uc30gb3Ige0BsaW5rIERFRkFVTFRfUFJJTUFSWV9LRVlfUFJFRklYfS5cbiAgICpcbiAgICogQHJldHVybnMgUHJlZml4IHN0cmluZyAoZS5nLiBgcnQjYCkuXG4gICAqL1xuICBwcml2YXRlIGdldFByaW1hcnlLZXlQcmVmaXggPSAoKTogc3RyaW5nID0+IHtcbiAgICByZXR1cm4gYCR7dGhpcy5vcHRpb25zPy5wa1ByZWZpeCA/PyBERUZBVUxUX1BSSU1BUllfS0VZX1BSRUZJWH1gO1xuICB9O1xuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIGZ1bGwgcGFydGl0aW9uIGtleSBmb3IgYSB0b2tlbiBoYXNoLlxuICAgKlxuICAgKiBAcGFyYW0gaGFzaCAtIFNIQS0yNTYgaGV4IGRpZ2VzdCBvZiB0aGUgcGxhaW50ZXh0IHRva2VuLlxuICAgKiBAcmV0dXJucyBgcHJlZml4YCArIGBoYXNoYC5cbiAgICovXG4gIHByaXZhdGUgZ2V0UHJpbWFyeUtleSA9IChoYXNoOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgIHJldHVybiBgJHt0aGlzLmdldFByaW1hcnlLZXlQcmVmaXgoKX0ke2hhc2h9YDtcbiAgfTtcblxuICAvKipcbiAgICogQ29tcHV0ZXMgbG9naWNhbCBleHBpcmF0aW9uIChgZXhwaXJlc0F0YCAvIGB0dGxgKSBhcyBgbm93U2VjYCBwbHVzIHtAbGluayBTdG9yZU9wdGlvbnMudHRsRGF5c30uXG4gICAqXG4gICAqIEBwYXJhbSBub3dTZWMgLSBDdXJyZW50IHRpbWUgYXMgVW5peCBzZWNvbmRzLlxuICAgKiBAcmV0dXJucyBFeHBpcmF0aW9uIHRpbWVzdGFtcCBpbiBVbml4IHNlY29uZHMgKGRlZmF1bHQgbGlmZXRpbWU6IDYwIGRheXMpLlxuICAgKi9cbiAgcHJpdmF0ZSBtYWtlRXhwaXJlc0F0ID0gKG5vd1NlYzogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gbm93U2VjICsgKHRoaXMub3B0aW9ucz8udHRsRGF5cyA/PyA2MCkgKiAyNCAqIDYwICogNjA7XG4gIH07XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhlIHRva2VuIGlzIG5vbi1lbXB0eSBhbmQgbWF0Y2hlcyB0aGUgZXhwZWN0ZWQgYmFzZTY0dXJsIGxlbmd0aCBmb3IgYHRva2VuQnl0ZXNgLlxuICAgKlxuICAgKiBAcGFyYW0gdG9rZW4gLSBQbGFpbnRleHQgcmVmcmVzaCB0b2tlbiBmcm9tIHRoZSBjbGllbnQuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkludmFsaWRFcnJvcn0gV2hlbiB2YWxpZGF0aW9uIGZhaWxzLlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVJlZnJlc2hUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0b2tlbiB8fCB0b2tlbi5sZW5ndGggIT09IE1hdGguY2VpbCh0aGlzLnRva2VuQnl0ZXMgKiA4IC8gNikpIHtcbiAgICAgIHRocm93IG5ldyBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3IoKTtcbiAgICB9XG4gIH1cblxufVxuIl19
@@ -3,35 +3,53 @@
3
3
  * Use `instanceof` on concrete classes or this base for handling.
4
4
  */
5
5
  export declare abstract class RefreshTokenError extends Error {
6
+ /**
7
+ * @param message - Human-readable error description.
8
+ */
6
9
  protected constructor(message: string);
7
10
  }
8
11
  /**
9
12
  * Thrown when the refresh token is missing, malformed, or not recognized.
10
13
  */
11
14
  export declare class RefreshTokenInvalidError extends RefreshTokenError {
15
+ /**
16
+ * @param message - Human-readable error description.
17
+ */
12
18
  constructor(message?: string);
13
19
  }
14
20
  /**
15
- * Thrown when the refresh token has passed its expiration time.
21
+ * Thrown when the refresh token has passed its logical expiration (`expiresAt`).
16
22
  */
17
23
  export declare class RefreshTokenExpiredError extends RefreshTokenError {
24
+ /**
25
+ * @param message - Human-readable error description.
26
+ */
18
27
  constructor(message?: string);
19
28
  }
20
29
  /**
21
30
  * Thrown when the refresh token has been explicitly revoked.
22
31
  */
23
32
  export declare class RefreshTokenRevokedError extends RefreshTokenError {
33
+ /**
34
+ * @param message - Human-readable error description.
35
+ */
24
36
  constructor(message?: string);
25
37
  }
26
38
  /**
27
39
  * Thrown when a refresh token is presented after it has already been rotated (reuse detection).
28
40
  */
29
41
  export declare class RefreshTokenReusedError extends RefreshTokenError {
42
+ /**
43
+ * @param message - Human-readable error description.
44
+ */
30
45
  constructor(message?: string);
31
46
  }
32
47
  /**
33
48
  * Thrown when rotation fails for a reason other than reuse (e.g. transient store failure).
34
49
  */
35
50
  export declare class RefreshTokenRotateFailedError extends RefreshTokenError {
51
+ /**
52
+ * @param message - Human-readable error description.
53
+ */
36
54
  constructor(message?: string);
37
55
  }
@@ -6,6 +6,9 @@ exports.RefreshTokenRotateFailedError = exports.RefreshTokenReusedError = export
6
6
  * Use `instanceof` on concrete classes or this base for handling.
7
7
  */
8
8
  class RefreshTokenError extends Error {
9
+ /**
10
+ * @param message - Human-readable error description.
11
+ */
9
12
  constructor(message) {
10
13
  super(message);
11
14
  this.name = new.target.name;
@@ -16,15 +19,21 @@ exports.RefreshTokenError = RefreshTokenError;
16
19
  * Thrown when the refresh token is missing, malformed, or not recognized.
17
20
  */
18
21
  class RefreshTokenInvalidError extends RefreshTokenError {
22
+ /**
23
+ * @param message - Human-readable error description.
24
+ */
19
25
  constructor(message = 'The refresh token is missing, malformed, or not recognized.') {
20
26
  super(message);
21
27
  }
22
28
  }
23
29
  exports.RefreshTokenInvalidError = RefreshTokenInvalidError;
24
30
  /**
25
- * Thrown when the refresh token has passed its expiration time.
31
+ * Thrown when the refresh token has passed its logical expiration (`expiresAt`).
26
32
  */
27
33
  class RefreshTokenExpiredError extends RefreshTokenError {
34
+ /**
35
+ * @param message - Human-readable error description.
36
+ */
28
37
  constructor(message = 'The refresh token has expired. Please sign in again.') {
29
38
  super(message);
30
39
  }
@@ -34,6 +43,9 @@ exports.RefreshTokenExpiredError = RefreshTokenExpiredError;
34
43
  * Thrown when the refresh token has been explicitly revoked.
35
44
  */
36
45
  class RefreshTokenRevokedError extends RefreshTokenError {
46
+ /**
47
+ * @param message - Human-readable error description.
48
+ */
37
49
  constructor(message = 'The refresh token has been revoked.') {
38
50
  super(message);
39
51
  }
@@ -43,6 +55,9 @@ exports.RefreshTokenRevokedError = RefreshTokenRevokedError;
43
55
  * Thrown when a refresh token is presented after it has already been rotated (reuse detection).
44
56
  */
45
57
  class RefreshTokenReusedError extends RefreshTokenError {
58
+ /**
59
+ * @param message - Human-readable error description.
60
+ */
46
61
  constructor(message = 'This refresh token has already been rotated and cannot be used again.') {
47
62
  super(message);
48
63
  }
@@ -52,9 +67,12 @@ exports.RefreshTokenReusedError = RefreshTokenReusedError;
52
67
  * Thrown when rotation fails for a reason other than reuse (e.g. transient store failure).
53
68
  */
54
69
  class RefreshTokenRotateFailedError extends RefreshTokenError {
70
+ /**
71
+ * @param message - Human-readable error description.
72
+ */
55
73
  constructor(message = 'The refresh token could not be rotated. Please try signing in again.') {
56
74
  super(message);
57
75
  }
58
76
  }
59
77
  exports.RefreshTokenRotateFailedError = RefreshTokenRotateFailedError;
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmcmVzaC10b2tlbi1lcnJvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmVzL3JlZnJlc2gtdG9rZW4tZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7R0FHRztBQUNILE1BQXNCLGlCQUFrQixTQUFRLEtBQUs7SUFDbkQsWUFBc0IsT0FBZTtRQUNuQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQzlCLENBQUM7Q0FDRjtBQUxELDhDQUtDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLHdCQUF5QixTQUFRLGlCQUFpQjtJQUM3RCxZQUNFLE9BQU8sR0FBRyw2REFBNkQ7UUFFdkUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQU5ELDREQU1DO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLHdCQUF5QixTQUFRLGlCQUFpQjtJQUM3RCxZQUFZLE9BQU8sR0FBRyxzREFBc0Q7UUFDMUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQUpELDREQUlDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLHdCQUF5QixTQUFRLGlCQUFpQjtJQUM3RCxZQUFZLE9BQU8sR0FBRyxxQ0FBcUM7UUFDekQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQUpELDREQUlDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLHVCQUF3QixTQUFRLGlCQUFpQjtJQUM1RCxZQUNFLE9BQU8sR0FBRyx1RUFBdUU7UUFFakYsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQU5ELDBEQU1DO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLDZCQUE4QixTQUFRLGlCQUFpQjtJQUNsRSxZQUNFLE9BQU8sR0FBRyxzRUFBc0U7UUFFaEYsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQU5ELHNFQU1DIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCYXNlIGNsYXNzIGZvciByZWZyZXNoIHRva2VuIHN0b3JlIGVycm9ycy5cbiAqIFVzZSBgaW5zdGFuY2VvZmAgb24gY29uY3JldGUgY2xhc3NlcyBvciB0aGlzIGJhc2UgZm9yIGhhbmRsaW5nLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUmVmcmVzaFRva2VuRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBuZXcudGFyZ2V0Lm5hbWU7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiB0aGUgcmVmcmVzaCB0b2tlbiBpcyBtaXNzaW5nLCBtYWxmb3JtZWQsIG9yIG5vdCByZWNvZ25pemVkLlxuICovXG5leHBvcnQgY2xhc3MgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yIGV4dGVuZHMgUmVmcmVzaFRva2VuRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlID0gJ1RoZSByZWZyZXNoIHRva2VuIGlzIG1pc3NpbmcsIG1hbGZvcm1lZCwgb3Igbm90IHJlY29nbml6ZWQuJyxcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiB0aGUgcmVmcmVzaCB0b2tlbiBoYXMgcGFzc2VkIGl0cyBleHBpcmF0aW9uIHRpbWUuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3IgZXh0ZW5kcyBSZWZyZXNoVG9rZW5FcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnVGhlIHJlZnJlc2ggdG9rZW4gaGFzIGV4cGlyZWQuIFBsZWFzZSBzaWduIGluIGFnYWluLicpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxufVxuXG4vKipcbiAqIFRocm93biB3aGVuIHRoZSByZWZyZXNoIHRva2VuIGhhcyBiZWVuIGV4cGxpY2l0bHkgcmV2b2tlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvciBleHRlbmRzIFJlZnJlc2hUb2tlbkVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdUaGUgcmVmcmVzaCB0b2tlbiBoYXMgYmVlbiByZXZva2VkLicpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxufVxuXG4vKipcbiAqIFRocm93biB3aGVuIGEgcmVmcmVzaCB0b2tlbiBpcyBwcmVzZW50ZWQgYWZ0ZXIgaXQgaGFzIGFscmVhZHkgYmVlbiByb3RhdGVkIChyZXVzZSBkZXRlY3Rpb24pLlxuICovXG5leHBvcnQgY2xhc3MgUmVmcmVzaFRva2VuUmV1c2VkRXJyb3IgZXh0ZW5kcyBSZWZyZXNoVG9rZW5FcnJvciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2UgPSAnVGhpcyByZWZyZXNoIHRva2VuIGhhcyBhbHJlYWR5IGJlZW4gcm90YXRlZCBhbmQgY2Fubm90IGJlIHVzZWQgYWdhaW4uJyxcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiByb3RhdGlvbiBmYWlscyBmb3IgYSByZWFzb24gb3RoZXIgdGhhbiByZXVzZSAoZS5nLiB0cmFuc2llbnQgc3RvcmUgZmFpbHVyZSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWZyZXNoVG9rZW5Sb3RhdGVGYWlsZWRFcnJvciBleHRlbmRzIFJlZnJlc2hUb2tlbkVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZSA9ICdUaGUgcmVmcmVzaCB0b2tlbiBjb3VsZCBub3QgYmUgcm90YXRlZC4gUGxlYXNlIHRyeSBzaWduaW5nIGluIGFnYWluLicsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG59XG4iXX0=
78
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmcmVzaC10b2tlbi1lcnJvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmVzL3JlZnJlc2gtdG9rZW4tZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7R0FHRztBQUNILE1BQXNCLGlCQUFrQixTQUFRLEtBQUs7SUFDbkQ7O09BRUc7SUFDSCxZQUFzQixPQUFlO1FBQ25DLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDOUIsQ0FBQztDQUNGO0FBUkQsOENBUUM7QUFFRDs7R0FFRztBQUNILE1BQWEsd0JBQXlCLFNBQVEsaUJBQWlCO0lBQzdEOztPQUVHO0lBQ0gsWUFDRSxPQUFPLEdBQUcsNkRBQTZEO1FBRXZFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQixDQUFDO0NBQ0Y7QUFURCw0REFTQztBQUVEOztHQUVHO0FBQ0gsTUFBYSx3QkFBeUIsU0FBUSxpQkFBaUI7SUFDN0Q7O09BRUc7SUFDSCxZQUFZLE9BQU8sR0FBRyxzREFBc0Q7UUFDMUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQVBELDREQU9DO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLHdCQUF5QixTQUFRLGlCQUFpQjtJQUM3RDs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLHFDQUFxQztRQUN6RCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakIsQ0FBQztDQUNGO0FBUEQsNERBT0M7QUFFRDs7R0FFRztBQUNILE1BQWEsdUJBQXdCLFNBQVEsaUJBQWlCO0lBQzVEOztPQUVHO0lBQ0gsWUFDRSxPQUFPLEdBQUcsdUVBQXVFO1FBRWpGLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQixDQUFDO0NBQ0Y7QUFURCwwREFTQztBQUVEOztHQUVHO0FBQ0gsTUFBYSw2QkFBOEIsU0FBUSxpQkFBaUI7SUFDbEU7O09BRUc7SUFDSCxZQUNFLE9BQU8sR0FBRyxzRUFBc0U7UUFFaEYsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQVRELHNFQVNDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCYXNlIGNsYXNzIGZvciByZWZyZXNoIHRva2VuIHN0b3JlIGVycm9ycy5cbiAqIFVzZSBgaW5zdGFuY2VvZmAgb24gY29uY3JldGUgY2xhc3NlcyBvciB0aGlzIGJhc2UgZm9yIGhhbmRsaW5nLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUmVmcmVzaFRva2VuRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIGVycm9yIGRlc2NyaXB0aW9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IG5ldy50YXJnZXQubmFtZTtcbiAgfVxufVxuXG4vKipcbiAqIFRocm93biB3aGVuIHRoZSByZWZyZXNoIHRva2VuIGlzIG1pc3NpbmcsIG1hbGZvcm1lZCwgb3Igbm90IHJlY29nbml6ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWZyZXNoVG9rZW5JbnZhbGlkRXJyb3IgZXh0ZW5kcyBSZWZyZXNoVG9rZW5FcnJvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIGVycm9yIGRlc2NyaXB0aW9uLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZSA9ICdUaGUgcmVmcmVzaCB0b2tlbiBpcyBtaXNzaW5nLCBtYWxmb3JtZWQsIG9yIG5vdCByZWNvZ25pemVkLicsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gdGhlIHJlZnJlc2ggdG9rZW4gaGFzIHBhc3NlZCBpdHMgbG9naWNhbCBleHBpcmF0aW9uIChgZXhwaXJlc0F0YCkuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWZyZXNoVG9rZW5FeHBpcmVkRXJyb3IgZXh0ZW5kcyBSZWZyZXNoVG9rZW5FcnJvciB7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIGVycm9yIGRlc2NyaXB0aW9uLlxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdUaGUgcmVmcmVzaCB0b2tlbiBoYXMgZXhwaXJlZC4gUGxlYXNlIHNpZ24gaW4gYWdhaW4uJykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gdGhlIHJlZnJlc2ggdG9rZW4gaGFzIGJlZW4gZXhwbGljaXRseSByZXZva2VkLlxuICovXG5leHBvcnQgY2xhc3MgUmVmcmVzaFRva2VuUmV2b2tlZEVycm9yIGV4dGVuZHMgUmVmcmVzaFRva2VuRXJyb3Ige1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSBlcnJvciBkZXNjcmlwdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnVGhlIHJlZnJlc2ggdG9rZW4gaGFzIGJlZW4gcmV2b2tlZC4nKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBhIHJlZnJlc2ggdG9rZW4gaXMgcHJlc2VudGVkIGFmdGVyIGl0IGhhcyBhbHJlYWR5IGJlZW4gcm90YXRlZCAocmV1c2UgZGV0ZWN0aW9uKS5cbiAqL1xuZXhwb3J0IGNsYXNzIFJlZnJlc2hUb2tlblJldXNlZEVycm9yIGV4dGVuZHMgUmVmcmVzaFRva2VuRXJyb3Ige1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSBlcnJvciBkZXNjcmlwdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2UgPSAnVGhpcyByZWZyZXNoIHRva2VuIGhhcyBhbHJlYWR5IGJlZW4gcm90YXRlZCBhbmQgY2Fubm90IGJlIHVzZWQgYWdhaW4uJyxcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiByb3RhdGlvbiBmYWlscyBmb3IgYSByZWFzb24gb3RoZXIgdGhhbiByZXVzZSAoZS5nLiB0cmFuc2llbnQgc3RvcmUgZmFpbHVyZSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWZyZXNoVG9rZW5Sb3RhdGVGYWlsZWRFcnJvciBleHRlbmRzIFJlZnJlc2hUb2tlbkVycm9yIHtcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgZXJyb3IgZGVzY3JpcHRpb24uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlID0gJ1RoZSByZWZyZXNoIHRva2VuIGNvdWxkIG5vdCBiZSByb3RhdGVkLiBQbGVhc2UgdHJ5IHNpZ25pbmcgaW4gYWdhaW4uJyxcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cbn1cbiJdfQ==
@@ -1,26 +1,33 @@
1
1
  /** Unix timestamp in whole seconds. */
2
2
  export type EpochSec = number;
3
+ /**
4
+ * Configuration for the DynamoDB refresh token provider constructor.
5
+ *
6
+ * Token lifetime (`ttlDays`) drives both logical expiration (`expiresAt`) and the
7
+ * DynamoDB TTL attribute (`ttl`) written on Put / Transact.
8
+ */
3
9
  export type StoreOptions = {
4
10
  /**
5
- * Refresh token time-to-live in days.
11
+ * Refresh token lifetime in days (added to `now` when computing `expiresAt` / `ttl`).
6
12
  * @defaultValue 60
7
13
  */
8
14
  ttlDays?: number;
9
15
  /**
10
- * Partition key prefix for DynamoDB items.
16
+ * Partition key prefix for DynamoDB items; full `pk` is `prefix` + SHA-256 hex of the token.
11
17
  * @defaultValue `'rt#'`
12
18
  */
13
19
  pkPrefix?: string;
14
20
  /**
15
- * Whether to use strongly consistent reads on GetItem.
21
+ * Whether to use strongly consistent reads on `GetItem`.
16
22
  * @defaultValue true
17
23
  */
18
24
  consistentRead?: boolean;
19
25
  /**
20
- * Custom DynamoDB API endpoint (e.g. for LocalStack or DynamoDB Local).
26
+ * Custom DynamoDB API endpoint (e.g. LocalStack or DynamoDB Local).
21
27
  */
22
28
  endpoint?: string;
23
29
  };
30
+ /** Parameters for {@link RefreshTokenStore.issue}. */
24
31
  export type IssueParams = {
25
32
  /** Subject (user) identifier to associate with the token. */
26
33
  subjectId: string;
@@ -29,41 +36,64 @@ export type IssueParams = {
29
36
  /** Clock override for tests; defaults to `new Date()`. */
30
37
  now?: Date;
31
38
  };
39
+ /** Result of {@link RefreshTokenStore.issue}. */
32
40
  export type IssueResult = {
33
- /** Opaque refresh token string (plaintext; store only a hash at rest). */
41
+ /** Opaque refresh token string (plaintext; only a hash is stored at rest). */
34
42
  refreshToken: string;
35
- /** Expiration time as Unix seconds. */
43
+ /** Logical expiration time as Unix seconds (same value written to `expiresAt` / `ttl`). */
36
44
  refreshTokenExpiresAt: EpochSec;
37
45
  };
46
+ /** Parameters for {@link RefreshTokenStore.rotate}. */
38
47
  export type RotateParams = {
39
48
  /** Current refresh token from the client. */
40
49
  refreshToken: string;
41
50
  /** Clock override for tests; defaults to `new Date()`. */
42
51
  now?: Date;
43
52
  };
53
+ /** Result of {@link RefreshTokenStore.rotate}. */
44
54
  export type RotateResult = {
55
+ /** Subject identifier from the rotated token row. */
45
56
  subjectId: string;
57
+ /** Session identifier from the rotated token row. */
46
58
  sessionId: string;
47
59
  /** New opaque refresh token after rotation. */
48
60
  refreshToken: string;
49
- /** Expiration time of the new token as Unix seconds. */
61
+ /** Logical expiration of the new token as Unix seconds. */
50
62
  refreshTokenExpiresAt: EpochSec;
51
63
  };
64
+ /** Parameters for {@link RefreshTokenStore.revoke}. */
52
65
  export type RevokeParams = {
53
66
  /** Refresh token to revoke. */
54
67
  refreshToken: string;
55
68
  /** Clock override for tests; defaults to `new Date()`. */
56
69
  now?: Date;
57
70
  };
58
- /** DynamoDB item shape for a stored refresh token (hash-keyed). */
71
+ /**
72
+ * DynamoDB item shape for a stored refresh token (hash-keyed by `pk`).
73
+ *
74
+ * `expiresAt` is used for application-level validation; `ttl` is the DynamoDB TTL
75
+ * attribute for asynchronous item deletion (enable TTL on the table for attribute `ttl`).
76
+ */
59
77
  export type TokenRecord = {
78
+ /** Partition key: prefix + SHA-256 hex of the plaintext token. */
60
79
  pk: string;
80
+ /** Subject (user) identifier. */
61
81
  subjectId: string;
82
+ /** Session identifier. */
62
83
  sessionId: string;
84
+ /** Row creation time as Unix seconds. */
63
85
  createdAt: EpochSec;
86
+ /** Logical expiration time as Unix seconds. */
64
87
  expiresAt: EpochSec;
88
+ /**
89
+ * DynamoDB TTL attribute (Unix seconds). Set on write; table TTL must target this attribute name.
90
+ */
91
+ ttl: EpochSec;
92
+ /** Time the token was rotated, if applicable. */
65
93
  rotatedAt?: EpochSec | null;
94
+ /** Partition key of the successor token after rotation. */
66
95
  replacedByPk?: string | null;
96
+ /** Time the token was revoked, if applicable. */
67
97
  revokedAt?: EpochSec | null;
68
98
  };
69
99
  /**
@@ -74,18 +104,26 @@ export interface RefreshTokenStore {
74
104
  * Creates a new refresh token row and returns the plaintext token.
75
105
  *
76
106
  * @param params - Subject, session, and optional clock.
107
+ * @returns Plaintext token and expiration as Unix seconds.
77
108
  */
78
109
  issue(params: IssueParams): Promise<IssueResult>;
79
110
  /**
80
111
  * Validates the current token, marks it rotated, inserts the successor row, and returns the new token.
81
112
  *
82
113
  * @param params - Current token and optional clock.
114
+ * @returns Subject, session, new token, and new expiration.
115
+ * @throws {@link RefreshTokenInvalidError} When the token is invalid or no row exists.
116
+ * @throws {@link RefreshTokenExpiredError} When `expiresAt` is not after `now`.
117
+ * @throws {@link RefreshTokenRevokedError} When the row has `revokedAt` set.
118
+ * @throws {@link RefreshTokenReusedError} When the token was already rotated or the transaction failed conditionally.
83
119
  */
84
120
  rotate(params: RotateParams): Promise<RotateResult>;
85
121
  /**
86
122
  * Sets `revokedAt` on the token row. Idempotent if the row does not exist.
87
123
  *
88
124
  * @param params - Token to revoke and optional clock.
125
+ * @returns `true` after a successful update or no-op when the item is absent.
126
+ * @throws {@link RefreshTokenInvalidError} When the token string format is invalid.
89
127
  */
90
128
  revoke(params: RevokeParams): Promise<true>;
91
129
  }
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBVbml4IHRpbWVzdGFtcCBpbiB3aG9sZSBzZWNvbmRzLiAqL1xuZXhwb3J0IHR5cGUgRXBvY2hTZWMgPSBudW1iZXI7XG5cbmV4cG9ydCB0eXBlIFN0b3JlT3B0aW9ucyA9IHtcbiAgLyoqXG4gICAqIFJlZnJlc2ggdG9rZW4gdGltZS10by1saXZlIGluIGRheXMuXG4gICAqIEBkZWZhdWx0VmFsdWUgNjBcbiAgICovXG4gIHR0bERheXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFBhcnRpdGlvbiBrZXkgcHJlZml4IGZvciBEeW5hbW9EQiBpdGVtcy5cbiAgICogQGRlZmF1bHRWYWx1ZSBgJ3J0IydgXG4gICAqL1xuICBwa1ByZWZpeD86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0byB1c2Ugc3Ryb25nbHkgY29uc2lzdGVudCByZWFkcyBvbiBHZXRJdGVtLlxuICAgKiBAZGVmYXVsdFZhbHVlIHRydWVcbiAgICovXG4gIGNvbnNpc3RlbnRSZWFkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ3VzdG9tIER5bmFtb0RCIEFQSSBlbmRwb2ludCAoZS5nLiBmb3IgTG9jYWxTdGFjayBvciBEeW5hbW9EQiBMb2NhbCkuXG4gICAqL1xuICBlbmRwb2ludD86IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIElzc3VlUGFyYW1zID0ge1xuICAvKiogU3ViamVjdCAodXNlcikgaWRlbnRpZmllciB0byBhc3NvY2lhdGUgd2l0aCB0aGUgdG9rZW4uICovXG4gIHN1YmplY3RJZDogc3RyaW5nO1xuICAvKiogU2Vzc2lvbiBpZGVudGlmaWVyIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSB0b2tlbi4gKi9cbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIC8qKiBDbG9jayBvdmVycmlkZSBmb3IgdGVzdHM7IGRlZmF1bHRzIHRvIGBuZXcgRGF0ZSgpYC4gKi9cbiAgbm93PzogRGF0ZTtcbn07XG5cbmV4cG9ydCB0eXBlIElzc3VlUmVzdWx0ID0ge1xuICAvKiogT3BhcXVlIHJlZnJlc2ggdG9rZW4gc3RyaW5nIChwbGFpbnRleHQ7IHN0b3JlIG9ubHkgYSBoYXNoIGF0IHJlc3QpLiAqL1xuICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgLyoqIEV4cGlyYXRpb24gdGltZSBhcyBVbml4IHNlY29uZHMuICovXG4gIHJlZnJlc2hUb2tlbkV4cGlyZXNBdDogRXBvY2hTZWM7XG59O1xuXG5leHBvcnQgdHlwZSBSb3RhdGVQYXJhbXMgPSB7XG4gIC8qKiBDdXJyZW50IHJlZnJlc2ggdG9rZW4gZnJvbSB0aGUgY2xpZW50LiAqL1xuICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgLyoqIENsb2NrIG92ZXJyaWRlIGZvciB0ZXN0czsgZGVmYXVsdHMgdG8gYG5ldyBEYXRlKClgLiAqL1xuICBub3c/OiBEYXRlO1xufTtcblxuZXhwb3J0IHR5cGUgUm90YXRlUmVzdWx0ID0ge1xuICBzdWJqZWN0SWQ6IHN0cmluZztcbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIC8qKiBOZXcgb3BhcXVlIHJlZnJlc2ggdG9rZW4gYWZ0ZXIgcm90YXRpb24uICovXG4gIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xuICAvKiogRXhwaXJhdGlvbiB0aW1lIG9mIHRoZSBuZXcgdG9rZW4gYXMgVW5peCBzZWNvbmRzLiAqL1xuICByZWZyZXNoVG9rZW5FeHBpcmVzQXQ6IEVwb2NoU2VjO1xufTtcblxuZXhwb3J0IHR5cGUgUmV2b2tlUGFyYW1zID0ge1xuICAvKiogUmVmcmVzaCB0b2tlbiB0byByZXZva2UuICovXG4gIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xuICAvKiogQ2xvY2sgb3ZlcnJpZGUgZm9yIHRlc3RzOyBkZWZhdWx0cyB0byBgbmV3IERhdGUoKWAuICovXG4gIG5vdz86IERhdGU7XG59O1xuXG4vKiogRHluYW1vREIgaXRlbSBzaGFwZSBmb3IgYSBzdG9yZWQgcmVmcmVzaCB0b2tlbiAoaGFzaC1rZXllZCkuICovXG5leHBvcnQgdHlwZSBUb2tlblJlY29yZCA9IHtcbiAgcGs6IHN0cmluZztcbiAgc3ViamVjdElkOiBzdHJpbmc7XG4gIHNlc3Npb25JZDogc3RyaW5nO1xuXG4gIGNyZWF0ZWRBdDogRXBvY2hTZWM7XG4gIGV4cGlyZXNBdDogRXBvY2hTZWM7XG5cbiAgcm90YXRlZEF0PzogRXBvY2hTZWMgfCBudWxsO1xuICByZXBsYWNlZEJ5UGs/OiBzdHJpbmcgfCBudWxsO1xuICByZXZva2VkQXQ/OiBFcG9jaFNlYyB8IG51bGw7XG59O1xuXG4vKipcbiAqIFBlcnNpc3RlbmNlIGFic3RyYWN0aW9uIGZvciBvcGFxdWUgcmVmcmVzaCB0b2tlbnM6IGlzc3VlLCByb3RhdGUsIGFuZCByZXZva2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVmcmVzaFRva2VuU3RvcmUge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyByZWZyZXNoIHRva2VuIHJvdyBhbmQgcmV0dXJucyB0aGUgcGxhaW50ZXh0IHRva2VuLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU3ViamVjdCwgc2Vzc2lvbiwgYW5kIG9wdGlvbmFsIGNsb2NrLlxuICAgKi9cbiAgaXNzdWUocGFyYW1zOiBJc3N1ZVBhcmFtcyk6IFByb21pc2U8SXNzdWVSZXN1bHQ+O1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhlIGN1cnJlbnQgdG9rZW4sIG1hcmtzIGl0IHJvdGF0ZWQsIGluc2VydHMgdGhlIHN1Y2Nlc3NvciByb3csIGFuZCByZXR1cm5zIHRoZSBuZXcgdG9rZW4uXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBDdXJyZW50IHRva2VuIGFuZCBvcHRpb25hbCBjbG9jay5cbiAgICovXG4gIHJvdGF0ZShwYXJhbXM6IFJvdGF0ZVBhcmFtcyk6IFByb21pc2U8Um90YXRlUmVzdWx0PjtcblxuICAvKipcbiAgICogU2V0cyBgcmV2b2tlZEF0YCBvbiB0aGUgdG9rZW4gcm93LiBJZGVtcG90ZW50IGlmIHRoZSByb3cgZG9lcyBub3QgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUb2tlbiB0byByZXZva2UgYW5kIG9wdGlvbmFsIGNsb2NrLlxuICAgKi9cbiAgcmV2b2tlKHBhcmFtczogUmV2b2tlUGFyYW1zKTogUHJvbWlzZTx0cnVlPjtcbn1cbiJdfQ==
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBVbml4IHRpbWVzdGFtcCBpbiB3aG9sZSBzZWNvbmRzLiAqL1xuZXhwb3J0IHR5cGUgRXBvY2hTZWMgPSBudW1iZXI7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIER5bmFtb0RCIHJlZnJlc2ggdG9rZW4gcHJvdmlkZXIgY29uc3RydWN0b3IuXG4gKlxuICogVG9rZW4gbGlmZXRpbWUgKGB0dGxEYXlzYCkgZHJpdmVzIGJvdGggbG9naWNhbCBleHBpcmF0aW9uIChgZXhwaXJlc0F0YCkgYW5kIHRoZVxuICogRHluYW1vREIgVFRMIGF0dHJpYnV0ZSAoYHR0bGApIHdyaXR0ZW4gb24gUHV0IC8gVHJhbnNhY3QuXG4gKi9cbmV4cG9ydCB0eXBlIFN0b3JlT3B0aW9ucyA9IHtcbiAgLyoqXG4gICAqIFJlZnJlc2ggdG9rZW4gbGlmZXRpbWUgaW4gZGF5cyAoYWRkZWQgdG8gYG5vd2Agd2hlbiBjb21wdXRpbmcgYGV4cGlyZXNBdGAgLyBgdHRsYCkuXG4gICAqIEBkZWZhdWx0VmFsdWUgNjBcbiAgICovXG4gIHR0bERheXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFBhcnRpdGlvbiBrZXkgcHJlZml4IGZvciBEeW5hbW9EQiBpdGVtczsgZnVsbCBgcGtgIGlzIGBwcmVmaXhgICsgU0hBLTI1NiBoZXggb2YgdGhlIHRva2VuLlxuICAgKiBAZGVmYXVsdFZhbHVlIGAncnQjJ2BcbiAgICovXG4gIHBrUHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHVzZSBzdHJvbmdseSBjb25zaXN0ZW50IHJlYWRzIG9uIGBHZXRJdGVtYC5cbiAgICogQGRlZmF1bHRWYWx1ZSB0cnVlXG4gICAqL1xuICBjb25zaXN0ZW50UmVhZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBEeW5hbW9EQiBBUEkgZW5kcG9pbnQgKGUuZy4gTG9jYWxTdGFjayBvciBEeW5hbW9EQiBMb2NhbCkuXG4gICAqL1xuICBlbmRwb2ludD86IHN0cmluZztcbn07XG5cbi8qKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUuaXNzdWV9LiAqL1xuZXhwb3J0IHR5cGUgSXNzdWVQYXJhbXMgPSB7XG4gIC8qKiBTdWJqZWN0ICh1c2VyKSBpZGVudGlmaWVyIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSB0b2tlbi4gKi9cbiAgc3ViamVjdElkOiBzdHJpbmc7XG4gIC8qKiBTZXNzaW9uIGlkZW50aWZpZXIgdG8gYXNzb2NpYXRlIHdpdGggdGhlIHRva2VuLiAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgLyoqIENsb2NrIG92ZXJyaWRlIGZvciB0ZXN0czsgZGVmYXVsdHMgdG8gYG5ldyBEYXRlKClgLiAqL1xuICBub3c/OiBEYXRlO1xufTtcblxuLyoqIFJlc3VsdCBvZiB7QGxpbmsgUmVmcmVzaFRva2VuU3RvcmUuaXNzdWV9LiAqL1xuZXhwb3J0IHR5cGUgSXNzdWVSZXN1bHQgPSB7XG4gIC8qKiBPcGFxdWUgcmVmcmVzaCB0b2tlbiBzdHJpbmcgKHBsYWludGV4dDsgb25seSBhIGhhc2ggaXMgc3RvcmVkIGF0IHJlc3QpLiAqL1xuICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgLyoqIExvZ2ljYWwgZXhwaXJhdGlvbiB0aW1lIGFzIFVuaXggc2Vjb25kcyAoc2FtZSB2YWx1ZSB3cml0dGVuIHRvIGBleHBpcmVzQXRgIC8gYHR0bGApLiAqL1xuICByZWZyZXNoVG9rZW5FeHBpcmVzQXQ6IEVwb2NoU2VjO1xufTtcblxuLyoqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBSZWZyZXNoVG9rZW5TdG9yZS5yb3RhdGV9LiAqL1xuZXhwb3J0IHR5cGUgUm90YXRlUGFyYW1zID0ge1xuICAvKiogQ3VycmVudCByZWZyZXNoIHRva2VuIGZyb20gdGhlIGNsaWVudC4gKi9cbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIC8qKiBDbG9jayBvdmVycmlkZSBmb3IgdGVzdHM7IGRlZmF1bHRzIHRvIGBuZXcgRGF0ZSgpYC4gKi9cbiAgbm93PzogRGF0ZTtcbn07XG5cbi8qKiBSZXN1bHQgb2Yge0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJvdGF0ZX0uICovXG5leHBvcnQgdHlwZSBSb3RhdGVSZXN1bHQgPSB7XG4gIC8qKiBTdWJqZWN0IGlkZW50aWZpZXIgZnJvbSB0aGUgcm90YXRlZCB0b2tlbiByb3cuICovXG4gIHN1YmplY3RJZDogc3RyaW5nO1xuICAvKiogU2Vzc2lvbiBpZGVudGlmaWVyIGZyb20gdGhlIHJvdGF0ZWQgdG9rZW4gcm93LiAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgLyoqIE5ldyBvcGFxdWUgcmVmcmVzaCB0b2tlbiBhZnRlciByb3RhdGlvbi4gKi9cbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIC8qKiBMb2dpY2FsIGV4cGlyYXRpb24gb2YgdGhlIG5ldyB0b2tlbiBhcyBVbml4IHNlY29uZHMuICovXG4gIHJlZnJlc2hUb2tlbkV4cGlyZXNBdDogRXBvY2hTZWM7XG59O1xuXG4vKiogUGFyYW1ldGVycyBmb3Ige0BsaW5rIFJlZnJlc2hUb2tlblN0b3JlLnJldm9rZX0uICovXG5leHBvcnQgdHlwZSBSZXZva2VQYXJhbXMgPSB7XG4gIC8qKiBSZWZyZXNoIHRva2VuIHRvIHJldm9rZS4gKi9cbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIC8qKiBDbG9jayBvdmVycmlkZSBmb3IgdGVzdHM7IGRlZmF1bHRzIHRvIGBuZXcgRGF0ZSgpYC4gKi9cbiAgbm93PzogRGF0ZTtcbn07XG5cbi8qKlxuICogRHluYW1vREIgaXRlbSBzaGFwZSBmb3IgYSBzdG9yZWQgcmVmcmVzaCB0b2tlbiAoaGFzaC1rZXllZCBieSBgcGtgKS5cbiAqXG4gKiBgZXhwaXJlc0F0YCBpcyB1c2VkIGZvciBhcHBsaWNhdGlvbi1sZXZlbCB2YWxpZGF0aW9uOyBgdHRsYCBpcyB0aGUgRHluYW1vREIgVFRMXG4gKiBhdHRyaWJ1dGUgZm9yIGFzeW5jaHJvbm91cyBpdGVtIGRlbGV0aW9uIChlbmFibGUgVFRMIG9uIHRoZSB0YWJsZSBmb3IgYXR0cmlidXRlIGB0dGxgKS5cbiAqL1xuZXhwb3J0IHR5cGUgVG9rZW5SZWNvcmQgPSB7XG4gIC8qKiBQYXJ0aXRpb24ga2V5OiBwcmVmaXggKyBTSEEtMjU2IGhleCBvZiB0aGUgcGxhaW50ZXh0IHRva2VuLiAqL1xuICBwazogc3RyaW5nO1xuICAvKiogU3ViamVjdCAodXNlcikgaWRlbnRpZmllci4gKi9cbiAgc3ViamVjdElkOiBzdHJpbmc7XG4gIC8qKiBTZXNzaW9uIGlkZW50aWZpZXIuICovXG4gIHNlc3Npb25JZDogc3RyaW5nO1xuICAvKiogUm93IGNyZWF0aW9uIHRpbWUgYXMgVW5peCBzZWNvbmRzLiAqL1xuICBjcmVhdGVkQXQ6IEVwb2NoU2VjO1xuICAvKiogTG9naWNhbCBleHBpcmF0aW9uIHRpbWUgYXMgVW5peCBzZWNvbmRzLiAqL1xuICBleHBpcmVzQXQ6IEVwb2NoU2VjO1xuICAvKipcbiAgICogRHluYW1vREIgVFRMIGF0dHJpYnV0ZSAoVW5peCBzZWNvbmRzKS4gU2V0IG9uIHdyaXRlOyB0YWJsZSBUVEwgbXVzdCB0YXJnZXQgdGhpcyBhdHRyaWJ1dGUgbmFtZS5cbiAgICovXG4gIHR0bDogRXBvY2hTZWM7XG4gIC8qKiBUaW1lIHRoZSB0b2tlbiB3YXMgcm90YXRlZCwgaWYgYXBwbGljYWJsZS4gKi9cbiAgcm90YXRlZEF0PzogRXBvY2hTZWMgfCBudWxsO1xuICAvKiogUGFydGl0aW9uIGtleSBvZiB0aGUgc3VjY2Vzc29yIHRva2VuIGFmdGVyIHJvdGF0aW9uLiAqL1xuICByZXBsYWNlZEJ5UGs/OiBzdHJpbmcgfCBudWxsO1xuICAvKiogVGltZSB0aGUgdG9rZW4gd2FzIHJldm9rZWQsIGlmIGFwcGxpY2FibGUuICovXG4gIHJldm9rZWRBdD86IEVwb2NoU2VjIHwgbnVsbDtcbn07XG5cbi8qKlxuICogUGVyc2lzdGVuY2UgYWJzdHJhY3Rpb24gZm9yIG9wYXF1ZSByZWZyZXNoIHRva2VuczogaXNzdWUsIHJvdGF0ZSwgYW5kIHJldm9rZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZWZyZXNoVG9rZW5TdG9yZSB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHJlZnJlc2ggdG9rZW4gcm93IGFuZCByZXR1cm5zIHRoZSBwbGFpbnRleHQgdG9rZW4uXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTdWJqZWN0LCBzZXNzaW9uLCBhbmQgb3B0aW9uYWwgY2xvY2suXG4gICAqIEByZXR1cm5zIFBsYWludGV4dCB0b2tlbiBhbmQgZXhwaXJhdGlvbiBhcyBVbml4IHNlY29uZHMuXG4gICAqL1xuICBpc3N1ZShwYXJhbXM6IElzc3VlUGFyYW1zKTogUHJvbWlzZTxJc3N1ZVJlc3VsdD47XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgY3VycmVudCB0b2tlbiwgbWFya3MgaXQgcm90YXRlZCwgaW5zZXJ0cyB0aGUgc3VjY2Vzc29yIHJvdywgYW5kIHJldHVybnMgdGhlIG5ldyB0b2tlbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIEN1cnJlbnQgdG9rZW4gYW5kIG9wdGlvbmFsIGNsb2NrLlxuICAgKiBAcmV0dXJucyBTdWJqZWN0LCBzZXNzaW9uLCBuZXcgdG9rZW4sIGFuZCBuZXcgZXhwaXJhdGlvbi5cbiAgICogQHRocm93cyB7QGxpbmsgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yfSBXaGVuIHRoZSB0b2tlbiBpcyBpbnZhbGlkIG9yIG5vIHJvdyBleGlzdHMuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlbkV4cGlyZWRFcnJvcn0gV2hlbiBgZXhwaXJlc0F0YCBpcyBub3QgYWZ0ZXIgYG5vd2AuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlblJldm9rZWRFcnJvcn0gV2hlbiB0aGUgcm93IGhhcyBgcmV2b2tlZEF0YCBzZXQuXG4gICAqIEB0aHJvd3Mge0BsaW5rIFJlZnJlc2hUb2tlblJldXNlZEVycm9yfSBXaGVuIHRoZSB0b2tlbiB3YXMgYWxyZWFkeSByb3RhdGVkIG9yIHRoZSB0cmFuc2FjdGlvbiBmYWlsZWQgY29uZGl0aW9uYWxseS5cbiAgICovXG4gIHJvdGF0ZShwYXJhbXM6IFJvdGF0ZVBhcmFtcyk6IFByb21pc2U8Um90YXRlUmVzdWx0PjtcblxuICAvKipcbiAgICogU2V0cyBgcmV2b2tlZEF0YCBvbiB0aGUgdG9rZW4gcm93LiBJZGVtcG90ZW50IGlmIHRoZSByb3cgZG9lcyBub3QgZXhpc3QuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUb2tlbiB0byByZXZva2UgYW5kIG9wdGlvbmFsIGNsb2NrLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgYWZ0ZXIgYSBzdWNjZXNzZnVsIHVwZGF0ZSBvciBuby1vcCB3aGVuIHRoZSBpdGVtIGlzIGFic2VudC5cbiAgICogQHRocm93cyB7QGxpbmsgUmVmcmVzaFRva2VuSW52YWxpZEVycm9yfSBXaGVuIHRoZSB0b2tlbiBzdHJpbmcgZm9ybWF0IGlzIGludmFsaWQuXG4gICAqL1xuICByZXZva2UocGFyYW1zOiBSZXZva2VQYXJhbXMpOiBQcm9taXNlPHRydWU+O1xufVxuIl19
package/package.json CHANGED
@@ -39,19 +39,18 @@
39
39
  "commit-and-tag-version": "^12",
40
40
  "constructs": "^10.0.0",
41
41
  "eslint": "^9",
42
- "eslint-import-resolver-typescript": "^4.4.4",
42
+ "eslint-import-resolver-typescript": "^4.4.5",
43
43
  "eslint-plugin-import": "^2.32.0",
44
44
  "jest": "^30.4.2",
45
45
  "jest-junit": "^17",
46
- "projen": "^0.99.65",
46
+ "projen": "^0.99.70",
47
47
  "ts-jest": "^29.4.11",
48
48
  "ts-node": "^10.9.2",
49
49
  "typescript": "5.9.x"
50
50
  },
51
51
  "dependencies": {
52
52
  "@aws-sdk/client-dynamodb": "^3.777.0",
53
- "@aws-sdk/lib-dynamodb": "^3.777.0",
54
- "@aws-sdk/util-dynamodb": "^3.777.0"
53
+ "@aws-sdk/lib-dynamodb": "^3.777.0"
55
54
  },
56
55
  "engines": {
57
56
  "node": ">= 20.0.0"
@@ -68,7 +67,7 @@
68
67
  "publishConfig": {
69
68
  "access": "public"
70
69
  },
71
- "version": "0.2.6",
70
+ "version": "0.3.0",
72
71
  "jest": {
73
72
  "coverageProvider": "v8",
74
73
  "testMatch": [