@decaf-ts/core 0.5.1 → 0.5.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.
Files changed (206) hide show
  1. package/LICENSE.md +21 -157
  2. package/README.md +652 -15
  3. package/dist/core.cjs +2111 -133
  4. package/dist/core.esm.cjs +2112 -134
  5. package/lib/esm/identity/decorators.d.ts +52 -7
  6. package/lib/esm/identity/decorators.js +58 -13
  7. package/lib/esm/identity/index.js +3 -3
  8. package/lib/esm/identity/utils.d.ts +19 -0
  9. package/lib/esm/identity/utils.js +22 -3
  10. package/lib/esm/index.d.ts +10 -3
  11. package/lib/esm/index.js +19 -12
  12. package/lib/esm/interfaces/ErrorParser.d.ts +12 -0
  13. package/lib/esm/interfaces/ErrorParser.js +1 -1
  14. package/lib/esm/interfaces/Executor.d.ts +13 -0
  15. package/lib/esm/interfaces/Executor.js +1 -1
  16. package/lib/esm/interfaces/Observable.d.ts +27 -0
  17. package/lib/esm/interfaces/Observable.js +1 -1
  18. package/lib/esm/interfaces/Observer.d.ts +12 -0
  19. package/lib/esm/interfaces/Observer.js +1 -1
  20. package/lib/esm/interfaces/Paginatable.d.ts +15 -0
  21. package/lib/esm/interfaces/Paginatable.js +1 -1
  22. package/lib/esm/interfaces/Queriable.d.ts +34 -9
  23. package/lib/esm/interfaces/Queriable.js +1 -1
  24. package/lib/esm/interfaces/RawExecutor.d.ts +14 -0
  25. package/lib/esm/interfaces/RawExecutor.js +1 -1
  26. package/lib/esm/interfaces/SequenceOptions.d.ts +52 -0
  27. package/lib/esm/interfaces/SequenceOptions.js +19 -1
  28. package/lib/esm/interfaces/index.js +8 -8
  29. package/lib/esm/model/BaseModel.d.ts +31 -0
  30. package/lib/esm/model/BaseModel.js +24 -1
  31. package/lib/esm/model/construction.d.ts +433 -0
  32. package/lib/esm/model/construction.js +444 -5
  33. package/lib/esm/model/decorators.d.ts +159 -29
  34. package/lib/esm/model/decorators.js +167 -37
  35. package/lib/esm/model/index.js +5 -5
  36. package/lib/esm/model/types.d.ts +9 -0
  37. package/lib/esm/model/types.js +1 -1
  38. package/lib/esm/persistence/Adapter.d.ts +358 -17
  39. package/lib/esm/persistence/Adapter.js +292 -24
  40. package/lib/esm/persistence/Dispatch.d.ts +114 -1
  41. package/lib/esm/persistence/Dispatch.js +104 -6
  42. package/lib/esm/persistence/ObserverHandler.d.ts +95 -0
  43. package/lib/esm/persistence/ObserverHandler.js +96 -1
  44. package/lib/esm/persistence/Sequence.d.ts +89 -0
  45. package/lib/esm/persistence/Sequence.js +71 -2
  46. package/lib/esm/persistence/constants.d.ts +22 -0
  47. package/lib/esm/persistence/constants.js +23 -1
  48. package/lib/esm/persistence/decorators.d.ts +10 -0
  49. package/lib/esm/persistence/decorators.js +13 -3
  50. package/lib/esm/persistence/errors.d.ts +23 -0
  51. package/lib/esm/persistence/errors.js +24 -1
  52. package/lib/esm/persistence/index.js +9 -9
  53. package/lib/esm/persistence/types.d.ts +18 -0
  54. package/lib/esm/persistence/types.js +1 -1
  55. package/lib/esm/query/Condition.d.ts +78 -31
  56. package/lib/esm/query/Condition.js +134 -55
  57. package/lib/esm/query/Paginator.d.ts +56 -0
  58. package/lib/esm/query/Paginator.js +58 -2
  59. package/lib/esm/query/Statement.d.ts +51 -0
  60. package/lib/esm/query/Statement.js +55 -4
  61. package/lib/esm/query/constants.d.ts +25 -0
  62. package/lib/esm/query/constants.js +26 -1
  63. package/lib/esm/query/errors.d.ts +14 -0
  64. package/lib/esm/query/errors.js +15 -1
  65. package/lib/esm/query/index.js +8 -8
  66. package/lib/esm/query/options.d.ts +21 -3
  67. package/lib/esm/query/options.js +1 -1
  68. package/lib/esm/query/selectors.d.ts +26 -0
  69. package/lib/esm/query/selectors.js +1 -1
  70. package/lib/esm/ram/RamAdapter.d.ts +311 -0
  71. package/lib/esm/ram/RamAdapter.js +319 -8
  72. package/lib/esm/ram/RamContext.d.ts +16 -1
  73. package/lib/esm/ram/RamContext.js +18 -3
  74. package/lib/esm/ram/RamPaginator.d.ts +43 -0
  75. package/lib/esm/ram/RamPaginator.js +55 -3
  76. package/lib/esm/ram/RamSequence.d.ts +61 -0
  77. package/lib/esm/ram/RamSequence.js +66 -5
  78. package/lib/esm/ram/RamStatement.d.ts +74 -0
  79. package/lib/esm/ram/RamStatement.js +78 -4
  80. package/lib/esm/ram/constants.d.ts +8 -0
  81. package/lib/esm/ram/constants.js +9 -1
  82. package/lib/esm/ram/handlers.d.ts +19 -0
  83. package/lib/esm/ram/handlers.js +21 -2
  84. package/lib/esm/ram/index.js +11 -11
  85. package/lib/esm/ram/model/RamSequence.d.ts +25 -0
  86. package/lib/esm/ram/model/RamSequence.js +21 -3
  87. package/lib/esm/ram/model/index.js +2 -2
  88. package/lib/esm/ram/types.d.ts +42 -0
  89. package/lib/esm/ram/types.js +1 -1
  90. package/lib/esm/repository/Repository.d.ts +363 -8
  91. package/lib/esm/repository/Repository.js +369 -24
  92. package/lib/esm/repository/constants.d.ts +25 -0
  93. package/lib/esm/repository/constants.js +26 -1
  94. package/lib/esm/repository/decorators.d.ts +27 -0
  95. package/lib/esm/repository/decorators.js +29 -2
  96. package/lib/esm/repository/errors.d.ts +12 -5
  97. package/lib/esm/repository/errors.js +13 -6
  98. package/lib/esm/repository/index.js +8 -8
  99. package/lib/esm/repository/injectables.d.ts +18 -0
  100. package/lib/esm/repository/injectables.js +23 -5
  101. package/lib/esm/repository/types.d.ts +15 -0
  102. package/lib/esm/repository/types.js +1 -1
  103. package/lib/esm/repository/utils.d.ts +11 -0
  104. package/lib/esm/repository/utils.js +15 -4
  105. package/lib/esm/utils/decorators.d.ts +8 -0
  106. package/lib/esm/utils/decorators.js +9 -1
  107. package/lib/esm/utils/errors.d.ts +46 -0
  108. package/lib/esm/utils/errors.js +47 -1
  109. package/lib/esm/utils/index.js +3 -3
  110. package/lib/identity/decorators.cjs +53 -8
  111. package/lib/identity/decorators.d.ts +52 -7
  112. package/lib/identity/utils.cjs +20 -1
  113. package/lib/identity/utils.d.ts +19 -0
  114. package/lib/index.cjs +11 -4
  115. package/lib/index.d.ts +10 -3
  116. package/lib/interfaces/ErrorParser.cjs +1 -1
  117. package/lib/interfaces/ErrorParser.d.ts +12 -0
  118. package/lib/interfaces/Executor.cjs +1 -1
  119. package/lib/interfaces/Executor.d.ts +13 -0
  120. package/lib/interfaces/Observable.cjs +1 -1
  121. package/lib/interfaces/Observable.d.ts +27 -0
  122. package/lib/interfaces/Observer.cjs +1 -1
  123. package/lib/interfaces/Observer.d.ts +12 -0
  124. package/lib/interfaces/Paginatable.cjs +1 -1
  125. package/lib/interfaces/Paginatable.d.ts +15 -0
  126. package/lib/interfaces/Queriable.cjs +1 -1
  127. package/lib/interfaces/Queriable.d.ts +34 -9
  128. package/lib/interfaces/RawExecutor.cjs +1 -1
  129. package/lib/interfaces/RawExecutor.d.ts +14 -0
  130. package/lib/interfaces/SequenceOptions.cjs +19 -1
  131. package/lib/interfaces/SequenceOptions.d.ts +52 -0
  132. package/lib/model/BaseModel.cjs +24 -1
  133. package/lib/model/BaseModel.d.ts +31 -0
  134. package/lib/model/construction.cjs +441 -2
  135. package/lib/model/construction.d.ts +433 -0
  136. package/lib/model/decorators.cjs +160 -30
  137. package/lib/model/decorators.d.ts +159 -29
  138. package/lib/model/types.cjs +1 -1
  139. package/lib/model/types.d.ts +9 -0
  140. package/lib/persistence/Adapter.cjs +287 -19
  141. package/lib/persistence/Adapter.d.ts +358 -17
  142. package/lib/persistence/Dispatch.cjs +102 -4
  143. package/lib/persistence/Dispatch.d.ts +114 -1
  144. package/lib/persistence/ObserverHandler.cjs +96 -1
  145. package/lib/persistence/ObserverHandler.d.ts +95 -0
  146. package/lib/persistence/Sequence.cjs +70 -1
  147. package/lib/persistence/Sequence.d.ts +89 -0
  148. package/lib/persistence/constants.cjs +23 -1
  149. package/lib/persistence/constants.d.ts +22 -0
  150. package/lib/persistence/decorators.cjs +11 -1
  151. package/lib/persistence/decorators.d.ts +10 -0
  152. package/lib/persistence/errors.cjs +24 -1
  153. package/lib/persistence/errors.d.ts +23 -0
  154. package/lib/persistence/types.cjs +1 -1
  155. package/lib/persistence/types.d.ts +18 -0
  156. package/lib/query/Condition.cjs +132 -53
  157. package/lib/query/Condition.d.ts +78 -31
  158. package/lib/query/Paginator.cjs +57 -1
  159. package/lib/query/Paginator.d.ts +56 -0
  160. package/lib/query/Statement.cjs +52 -1
  161. package/lib/query/Statement.d.ts +51 -0
  162. package/lib/query/constants.cjs +26 -1
  163. package/lib/query/constants.d.ts +25 -0
  164. package/lib/query/errors.cjs +15 -1
  165. package/lib/query/errors.d.ts +14 -0
  166. package/lib/query/options.cjs +1 -1
  167. package/lib/query/options.d.ts +21 -3
  168. package/lib/query/selectors.cjs +1 -1
  169. package/lib/query/selectors.d.ts +26 -0
  170. package/lib/ram/RamAdapter.cjs +312 -1
  171. package/lib/ram/RamAdapter.d.ts +311 -0
  172. package/lib/ram/RamContext.cjs +18 -3
  173. package/lib/ram/RamContext.d.ts +16 -1
  174. package/lib/ram/RamPaginator.cjs +54 -2
  175. package/lib/ram/RamPaginator.d.ts +43 -0
  176. package/lib/ram/RamSequence.cjs +63 -2
  177. package/lib/ram/RamSequence.d.ts +61 -0
  178. package/lib/ram/RamStatement.cjs +75 -1
  179. package/lib/ram/RamStatement.d.ts +74 -0
  180. package/lib/ram/constants.cjs +9 -1
  181. package/lib/ram/constants.d.ts +8 -0
  182. package/lib/ram/handlers.cjs +20 -1
  183. package/lib/ram/handlers.d.ts +19 -0
  184. package/lib/ram/model/RamSequence.cjs +19 -1
  185. package/lib/ram/model/RamSequence.d.ts +25 -0
  186. package/lib/ram/types.cjs +1 -1
  187. package/lib/ram/types.d.ts +42 -0
  188. package/lib/repository/Repository.cjs +360 -15
  189. package/lib/repository/Repository.d.ts +363 -8
  190. package/lib/repository/constants.cjs +26 -1
  191. package/lib/repository/constants.d.ts +25 -0
  192. package/lib/repository/decorators.cjs +28 -1
  193. package/lib/repository/decorators.d.ts +27 -0
  194. package/lib/repository/errors.cjs +13 -6
  195. package/lib/repository/errors.d.ts +12 -5
  196. package/lib/repository/injectables.cjs +19 -1
  197. package/lib/repository/injectables.d.ts +18 -0
  198. package/lib/repository/types.cjs +1 -1
  199. package/lib/repository/types.d.ts +15 -0
  200. package/lib/repository/utils.cjs +12 -1
  201. package/lib/repository/utils.d.ts +11 -0
  202. package/lib/utils/decorators.cjs +9 -1
  203. package/lib/utils/decorators.d.ts +8 -0
  204. package/lib/utils/errors.cjs +47 -1
  205. package/lib/utils/errors.d.ts +46 -0
  206. package/package.json +5 -5
@@ -13,19 +13,96 @@ import { Dispatch } from "./Dispatch";
13
13
  import { type EventIds, type ObserverFilter } from "./types";
14
14
  import { ObserverHandler } from "./ObserverHandler";
15
15
  /**
16
- * @summary Abstract Decaf-ts Persistence Adapter Class
17
- * @description Offers the base implementation for all Adapter Classes
18
- * and manages them various registered {@link Adapter}s
16
+ * @description Abstract base class for database adapters
17
+ * @summary Provides the foundation for all database adapters in the persistence layer. This class
18
+ * implements several interfaces to provide a consistent API for database operations, observer
19
+ * pattern support, and error handling. It manages adapter registration, CRUD operations, and
20
+ * observer notifications.
21
+ * @template Y - The underlying database driver type
22
+ * @template Q - The query object type used by the adapter
23
+ * @template F - The repository flags type
24
+ * @template C - The context type
25
+ * @param {Y} _native - The underlying database driver instance
26
+ * @param {string} flavour - The identifier for this adapter type
27
+ * @param {string} [_alias] - Optional alternative name for this adapter
28
+ * @class Adapter
29
+ * @example
30
+ * ```typescript
31
+ * // Implementing a concrete adapter
32
+ * class PostgresAdapter extends Adapter<pg.Client, pg.Query, PostgresFlags, PostgresContext> {
33
+ * constructor(client: pg.Client) {
34
+ * super(client, 'postgres');
35
+ * }
19
36
  *
20
- * @typedef Y the underlying persistence object type or the required config to set it up
21
- * @typedef Q The query object the adapter uses
37
+ * async initialize() {
38
+ * // Set up the adapter
39
+ * await this.native.connect();
40
+ * }
22
41
  *
23
- * @param {Y} native the underlying persistence object
24
- * @param {string} flavour the under witch the persistence adapter should be stored
42
+ * async create(tableName, id, model) {
43
+ * // Implementation for creating records
44
+ * const columns = Object.keys(model).join(', ');
45
+ * const values = Object.values(model);
46
+ * const placeholders = values.map((_, i) => `$${i+1}`).join(', ');
25
47
  *
26
- * @class Adapter
27
- * @implements RawExecutor
28
- * @implements Observable
48
+ * const query = `INSERT INTO ${tableName} (${columns}) VALUES (${placeholders}) RETURNING *`;
49
+ * const result = await this.native.query(query, values);
50
+ * return result.rows[0];
51
+ * }
52
+ *
53
+ * // Other required method implementations...
54
+ * }
55
+ *
56
+ * // Using the adapter
57
+ * const pgClient = new pg.Client(connectionString);
58
+ * const adapter = new PostgresAdapter(pgClient);
59
+ * await adapter.initialize();
60
+ *
61
+ * // Set as the default adapter
62
+ * Adapter.setCurrent('postgres');
63
+ *
64
+ * // Perform operations
65
+ * const user = await adapter.create('users', 1, { name: 'John', email: 'john@example.com' });
66
+ * ```
67
+ * @mermaid
68
+ * classDiagram
69
+ * class Adapter {
70
+ * +Y native
71
+ * +string flavour
72
+ * +string alias
73
+ * +create(tableName, id, model)
74
+ * +read(tableName, id)
75
+ * +update(tableName, id, model)
76
+ * +delete(tableName, id)
77
+ * +observe(observer, filter)
78
+ * +unObserve(observer)
79
+ * +static current
80
+ * +static get(flavour)
81
+ * +static setCurrent(flavour)
82
+ * }
83
+ *
84
+ * class RawExecutor {
85
+ * +raw(query)
86
+ * }
87
+ *
88
+ * class Observable {
89
+ * +observe(observer, filter)
90
+ * +unObserve(observer)
91
+ * +updateObservers(table, event, id)
92
+ * }
93
+ *
94
+ * class Observer {
95
+ * +refresh(table, event, id)
96
+ * }
97
+ *
98
+ * class ErrorParser {
99
+ * +parseError(err)
100
+ * }
101
+ *
102
+ * Adapter --|> RawExecutor
103
+ * Adapter --|> Observable
104
+ * Adapter --|> Observer
105
+ * Adapter --|> ErrorParser
29
106
  */
30
107
  export declare abstract class Adapter<Y, Q, F extends RepositoryFlags, C extends Context<F>> implements RawExecutor<Q>, Contextual<F, C>, Observable, Observer, ErrorParser {
31
108
  private readonly _native;
@@ -36,55 +113,319 @@ export declare abstract class Adapter<Y, Q, F extends RepositoryFlags, C extends
36
113
  private logger;
37
114
  protected dispatch?: Dispatch<Y>;
38
115
  protected readonly observerHandler?: ObserverHandler;
116
+ /**
117
+ * @description Logger accessor
118
+ * @summary Gets or initializes the logger for this adapter instance
119
+ * @return {Logger} The logger instance
120
+ */
39
121
  protected get log(): Logger;
122
+ /**
123
+ * @description Gets the native database driver
124
+ * @summary Provides access to the underlying database driver instance
125
+ * @return {Y} The native database driver
126
+ */
40
127
  get native(): Y;
128
+ /**
129
+ * @description Gets the adapter's alias or flavor name
130
+ * @summary Returns the alias if set, otherwise returns the flavor name
131
+ * @return {string} The adapter's identifier
132
+ */
41
133
  get alias(): string;
134
+ /**
135
+ * @description Gets the repository constructor for this adapter
136
+ * @summary Returns the constructor for creating repositories that work with this adapter
137
+ * @template M - The model type
138
+ * @return {Constructor<Repository<M, Q, Adapter<Y, Q, F, C>, F, C>>} The repository constructor
139
+ */
42
140
  repository<M extends Model>(): Constructor<Repository<M, Q, Adapter<Y, Q, F, C>, F, C>>;
141
+ /**
142
+ * @description Creates a new adapter instance
143
+ * @summary Initializes the adapter with the native driver and registers it in the adapter cache
144
+ */
43
145
  protected constructor(_native: Y, flavour: string, _alias?: string | undefined);
146
+ /**
147
+ * @description Creates a new statement builder for a model
148
+ * @summary Returns a statement builder that can be used to construct queries for a specific model
149
+ * @template M - The model type
150
+ * @return {Statement} A statement builder for the model
151
+ */
44
152
  abstract Statement<M extends Model>(): Statement<Q, M, any>;
153
+ /**
154
+ * @description Creates a new dispatch instance
155
+ * @summary Factory method that creates a dispatch instance for this adapter
156
+ * @return {Dispatch<Y>} A new dispatch instance
157
+ */
45
158
  protected Dispatch(): Dispatch<Y>;
159
+ /**
160
+ * @description Creates a new observer handler
161
+ * @summary Factory method that creates an observer handler for this adapter
162
+ * @return {ObserverHandler} A new observer handler instance
163
+ */
46
164
  protected ObserverHandler(): ObserverHandler;
165
+ /**
166
+ * @description Checks if an attribute name is reserved
167
+ * @summary Determines if a given attribute name is reserved and cannot be used as a column name
168
+ * @param {string} attr - The attribute name to check
169
+ * @return {boolean} True if the attribute is reserved, false otherwise
170
+ */
47
171
  protected isReserved(attr: string): boolean;
172
+ /**
173
+ * @description Parses a database error into a standardized error
174
+ * @summary Converts database-specific errors into standardized application errors
175
+ * @param {Error} err - The original database error
176
+ * @return {BaseError} A standardized error
177
+ */
48
178
  abstract parseError(err: Error): BaseError;
179
+ /**
180
+ * @description Initializes the adapter
181
+ * @summary Performs any necessary setup for the adapter, such as establishing connections
182
+ * @param {...any[]} args - Initialization arguments
183
+ * @return {Promise<void>} A promise that resolves when initialization is complete
184
+ */
49
185
  abstract initialize(...args: any[]): Promise<void>;
186
+ /**
187
+ * @description Creates a sequence generator
188
+ * @summary Factory method that creates a sequence generator for generating sequential values
189
+ * @param {SequenceOptions} options - Configuration options for the sequence
190
+ * @return {Promise<Sequence>} A promise that resolves to a new sequence instance
191
+ */
50
192
  abstract Sequence(options: SequenceOptions): Promise<Sequence>;
193
+ /**
194
+ * @description Creates repository flags for an operation
195
+ * @summary Generates a set of flags that describe a database operation, combining default flags with overrides
196
+ * @template F - The Repository Flags type
197
+ * @template M - The model type
198
+ * @param {OperationKeys} operation - The type of operation being performed
199
+ * @param {Constructor<M>} model - The model constructor
200
+ * @param {Partial<F>} flags - Custom flag overrides
201
+ * @param {...any[]} args - Additional arguments
202
+ * @return {F} The complete set of flags
203
+ */
51
204
  protected flags<M extends Model>(operation: OperationKeys, model: Constructor<M>, flags: Partial<F>, ...args: any[]): F;
52
- protected Context: Constructor<C>;
205
+ /**
206
+ * @description The context constructor for this adapter
207
+ * @summary Reference to the context class constructor used by this adapter
208
+ */
209
+ protected Context: {
210
+ new (): Context<F>;
211
+ factory: import("@decaf-ts/db-decorators").ContextFactory<any>;
212
+ childFrom<F_1 extends RepositoryFlags, C_1 extends Context<F_1>>(context: C_1, overrides?: Partial<F_1>): C_1;
213
+ from<M extends Model, F_1 extends RepositoryFlags, C_1 extends Context<F_1>>(operation: OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE, overrides: Partial<F_1>, model: Constructor<M>, ...args: any[]): Promise<C_1>;
214
+ args<M extends Model, C_1 extends Context<F_1>, F_1 extends RepositoryFlags>(operation: OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE, model: Constructor<M>, args: any[], contextual?: Contextual<F_1>, overrides?: Partial<F_1>): Promise<import("@decaf-ts/db-decorators").ContextArgs<F_1, C_1>>;
215
+ };
216
+ /**
217
+ * @description Creates a context for a database operation
218
+ * @summary Generates a context object that describes a database operation, used for tracking and auditing
219
+ * @template F - The Repository flags type
220
+ * @template M - The model type
221
+ * @param {OperationKeys.CREATE|OperationKeys.READ|OperationKeys.UPDATE|OperationKeys.DELETE} operation - The type of operation
222
+ * @param {Partial<F>} overrides - Custom flag overrides
223
+ * @param {Constructor<M>} model - The model constructor
224
+ * @param {...any[]} args - Additional arguments
225
+ * @return {Promise<C>} A promise that resolves to the context object
226
+ */
53
227
  context<M extends Model>(operation: OperationKeys.CREATE | OperationKeys.READ | OperationKeys.UPDATE | OperationKeys.DELETE, overrides: Partial<F>, model: Constructor<M>, ...args: any[]): Promise<C>;
228
+ /**
229
+ * @description Prepares a model for persistence
230
+ * @summary Converts a model instance into a format suitable for database storage,
231
+ * handling column mapping and separating transient properties
232
+ * @template M - The model type
233
+ * @param {M} model - The model instance to prepare
234
+ * @param pk - The primary key property name
235
+ * @return The prepared data
236
+ */
54
237
  prepare<M extends Model>(model: M, pk: keyof M): {
55
238
  record: Record<string, any>;
56
239
  id: string;
57
240
  transient?: Record<string, any>;
58
241
  };
242
+ /**
243
+ * @description Converts database data back into a model instance
244
+ * @summary Reconstructs a model instance from database data, handling column mapping
245
+ * and reattaching transient properties
246
+ * @template M - The model type
247
+ * @param obj - The database record
248
+ * @param {string|Constructor<M>} clazz - The model class or name
249
+ * @param pk - The primary key property name
250
+ * @param {string|number|bigint} id - The primary key value
251
+ * @param [transient] - Transient properties to reattach
252
+ * @return {M} The reconstructed model instance
253
+ */
59
254
  revert<M extends Model>(obj: Record<string, any>, clazz: string | Constructor<M>, pk: keyof M, id: string | number | bigint, transient?: Record<string, any>): M;
255
+ /**
256
+ * @description Creates a new record in the database
257
+ * @summary Inserts a new record with the given ID and data into the specified table
258
+ * @param {string} tableName - The name of the table to insert into
259
+ * @param {string|number} id - The identifier for the new record
260
+ * @param model - The data to insert
261
+ * @param {any[]} args - Additional arguments specific to the adapter implementation
262
+ * @return A promise that resolves to the created record
263
+ */
60
264
  abstract create(tableName: string, id: string | number, model: Record<string, any>, ...args: any[]): Promise<Record<string, any>>;
265
+ /**
266
+ * @description Creates multiple records in the database
267
+ * @summary Inserts multiple records with the given IDs and data into the specified table
268
+ * @param {string} tableName - The name of the table to insert into
269
+ * @param id - The identifiers for the new records
270
+ * @param model - The data to insert for each record
271
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
272
+ * @return A promise that resolves to an array of created records
273
+ */
61
274
  createAll(tableName: string, id: (string | number)[], model: Record<string, any>[], ...args: any[]): Promise<Record<string, any>[]>;
275
+ /**
276
+ * @description Retrieves a record from the database
277
+ * @summary Fetches a record with the given ID from the specified table
278
+ * @param {string} tableName - The name of the table to read from
279
+ * @param {string|number|bigint} id - The identifier of the record to retrieve
280
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
281
+ * @return A promise that resolves to the retrieved record
282
+ */
62
283
  abstract read(tableName: string, id: string | number | bigint, ...args: any[]): Promise<Record<string, any>>;
284
+ /**
285
+ * @description Retrieves multiple records from the database
286
+ * @summary Fetches multiple records with the given IDs from the specified table
287
+ * @param {string} tableName - The name of the table to read from
288
+ * @param id - The identifiers of the records to retrieve
289
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
290
+ * @return A promise that resolves to an array of retrieved records
291
+ */
63
292
  readAll(tableName: string, id: (string | number | bigint)[], ...args: any[]): Promise<Record<string, any>[]>;
293
+ /**
294
+ * @description Updates a record in the database
295
+ * @summary Modifies an existing record with the given ID in the specified table
296
+ * @param {string} tableName - The name of the table to update
297
+ * @param {string|number} id - The identifier of the record to update
298
+ * @param model - The new data for the record
299
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
300
+ * @return A promise that resolves to the updated record
301
+ */
64
302
  abstract update(tableName: string, id: string | number, model: Record<string, any>, ...args: any[]): Promise<Record<string, any>>;
303
+ /**
304
+ * @description Updates multiple records in the database
305
+ * @summary Modifies multiple existing records with the given IDs in the specified table
306
+ * @param {string} tableName - The name of the table to update
307
+ * @param {string[]|number[]} id - The identifiers of the records to update
308
+ * @param model - The new data for each record
309
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
310
+ * @return A promise that resolves to an array of updated records
311
+ */
65
312
  updateAll(tableName: string, id: string[] | number[], model: Record<string, any>[], ...args: any[]): Promise<Record<string, any>[]>;
313
+ /**
314
+ * @description Deletes a record from the database
315
+ * @summary Removes a record with the given ID from the specified table
316
+ * @param {string} tableName - The name of the table to delete from
317
+ * @param {string|number|bigint} id - The identifier of the record to delete
318
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
319
+ * @return A promise that resolves to the deleted record
320
+ */
66
321
  abstract delete(tableName: string, id: string | number | bigint, ...args: any[]): Promise<Record<string, any>>;
322
+ /**
323
+ * @description Deletes multiple records from the database
324
+ * @summary Removes multiple records with the given IDs from the specified table
325
+ * @param {string} tableName - The name of the table to delete from
326
+ * @param id - The identifiers of the records to delete
327
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
328
+ * @return A promise that resolves to an array of deleted records
329
+ */
67
330
  deleteAll(tableName: string, id: (string | number | bigint)[], ...args: any[]): Promise<Record<string, any>[]>;
331
+ /**
332
+ * @description Executes a raw query against the database
333
+ * @summary Allows executing database-specific queries directly
334
+ * @template Q - The raw query type
335
+ * @template R - The return type of the query
336
+ * @param {Q} rawInput - The query to execute
337
+ * @param {...any[]} args - Additional arguments specific to the adapter implementation
338
+ * @return {Promise<R>} A promise that resolves to the query result
339
+ */
68
340
  abstract raw<R>(rawInput: Q, ...args: any[]): Promise<R>;
69
341
  /**
70
- *
71
- * @see {Observable#observe}
342
+ * @description Registers an observer for database events
343
+ * @summary Adds an observer to be notified about database changes. The observer can optionally
344
+ * provide a filter function to receive only specific events.
345
+ * @param {Observer} observer - The observer to register
346
+ * @param {ObserverFilter} [filter] - Optional filter function to determine which events the observer receives
347
+ * @return {void}
72
348
  */
73
349
  observe(observer: Observer, filter?: ObserverFilter): void;
74
350
  /**
75
- * @summary Unregisters an {@link Observer}
76
- * @param {Observer} observer
77
- *
78
- * @see {Observable#unObserve}
351
+ * @description Unregisters an observer
352
+ * @summary Removes a previously registered observer so it no longer receives database event notifications
353
+ * @param {Observer} observer - The observer to unregister
354
+ * @return {void}
79
355
  */
80
356
  unObserve(observer: Observer): void;
357
+ /**
358
+ * @description Notifies all observers about a database event
359
+ * @summary Sends notifications to all registered observers about a change in the database,
360
+ * filtering based on each observer's filter function
361
+ * @param {string} table - The name of the table where the change occurred
362
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
363
+ * @param {EventIds} id - The identifier(s) of the affected record(s)
364
+ * @param {...any[]} args - Additional arguments to pass to the observers
365
+ * @return {Promise<void>} A promise that resolves when all observers have been notified
366
+ */
81
367
  updateObservers(table: string, event: OperationKeys | BulkCrudOperationKeys | string, id: EventIds, ...args: any[]): Promise<void>;
368
+ /**
369
+ * @description Refreshes data based on a database event
370
+ * @summary Implementation of the Observer interface method that delegates to updateObservers
371
+ * @param {string} table - The name of the table where the change occurred
372
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
373
+ * @param {EventIds} id - The identifier(s) of the affected record(s)
374
+ * @param {...any[]} args - Additional arguments related to the event
375
+ * @return {Promise<void>} A promise that resolves when the refresh is complete
376
+ */
82
377
  refresh(table: string, event: OperationKeys | BulkCrudOperationKeys | string, id: EventIds, ...args: any[]): Promise<void>;
378
+ /**
379
+ * @description Gets a string representation of the adapter
380
+ * @summary Returns a human-readable string identifying this adapter
381
+ * @return {string} A string representation of the adapter
382
+ */
83
383
  toString(): string;
384
+ /**
385
+ * @description Gets the adapter flavor associated with a model
386
+ * @summary Retrieves the adapter flavor that should be used for a specific model class
387
+ * @template M - The model type
388
+ * @param {Constructor<M>} model - The model constructor
389
+ * @return {string} The adapter flavor name
390
+ */
84
391
  static flavourOf<M extends Model>(model: Constructor<M>): string;
392
+ /**
393
+ * @description Gets the current default adapter
394
+ * @summary Retrieves the adapter that is currently set as the default for operations
395
+ * @return {Adapter<any, any, any, any>} The current adapter
396
+ */
85
397
  static get current(): Adapter<any, any, any, any>;
398
+ /**
399
+ * @description Gets an adapter by flavor
400
+ * @summary Retrieves a registered adapter by its flavor name
401
+ * @template Y - The database driver type
402
+ * @template Q - The query type
403
+ * @template C - The context type
404
+ * @template F - The repository flags type
405
+ * @param {string} flavour - The flavor name of the adapter to retrieve
406
+ * @return {Adapter<Y, Q, F, C> | undefined} The adapter instance or undefined if not found
407
+ */
86
408
  static get<Y, Q, C extends Context<F>, F extends RepositoryFlags>(flavour: any): Adapter<Y, Q, F, C> | undefined;
409
+ /**
410
+ * @description Sets the current default adapter
411
+ * @summary Changes which adapter is used as the default for operations
412
+ * @param {string} flavour - The flavor name of the adapter to set as current
413
+ * @return {void}
414
+ */
87
415
  static setCurrent(flavour: string): void;
416
+ /**
417
+ * @description Creates a metadata key
418
+ * @summary Generates a standardized metadata key for persistence-related metadata
419
+ * @param {string} key - The base key name
420
+ * @return {string} The formatted metadata key
421
+ */
88
422
  static key(key: string): string;
423
+ /**
424
+ * @description Gets all models associated with an adapter flavor
425
+ * @summary Retrieves all model constructors that are configured to use a specific adapter flavor
426
+ * @template M - The model type
427
+ * @param {string} flavour - The adapter flavor to find models for
428
+ * @return An array of model constructors
429
+ */
89
430
  static models<M extends Model>(flavour: string): ModelConstructor<any>[];
90
431
  }
@@ -5,14 +5,85 @@ const db_decorators_1 = require("@decaf-ts/db-decorators");
5
5
  const Adapter_1 = require("./Adapter.cjs");
6
6
  const errors_1 = require("./errors.cjs");
7
7
  const logging_1 = require("@decaf-ts/logging");
8
+ /**
9
+ * @description Dispatches database operation events to observers
10
+ * @summary The Dispatch class implements the Observable interface and is responsible for intercepting
11
+ * database operations from an Adapter and notifying observers when changes occur. It uses proxies to
12
+ * wrap the adapter's CRUD methods and automatically trigger observer updates after operations complete.
13
+ * @template Y - The native database driver type
14
+ * @param {void} - No constructor parameters
15
+ * @class Dispatch
16
+ * @example
17
+ * ```typescript
18
+ * // Creating and using a Dispatch instance
19
+ * const dispatch = new Dispatch<PostgresDriver>();
20
+ *
21
+ * // Connect it to an adapter
22
+ * const adapter = new PostgresAdapter(connection);
23
+ * dispatch.observe(adapter);
24
+ *
25
+ * // Now any CRUD operations on the adapter will automatically
26
+ * // trigger observer notifications
27
+ * await adapter.create('users', 123, userModel);
28
+ * // Observers will be notified about the creation
29
+ *
30
+ * // When done, you can disconnect
31
+ * dispatch.unObserve(adapter);
32
+ * ```
33
+ */
8
34
  class Dispatch {
35
+ /**
36
+ * @description Accessor for the logger
37
+ * @summary Gets or initializes the logger for this dispatch instance
38
+ * @return {Logger} The logger instance
39
+ */
9
40
  get log() {
10
41
  if (!this.logger)
11
42
  this.logger = logging_1.Logging.for(this).for(this.adapter);
12
43
  return this.logger;
13
44
  }
45
+ /**
46
+ * @description Creates a new Dispatch instance
47
+ * @summary Initializes a new Dispatch instance without any adapter
48
+ */
14
49
  constructor() { }
15
- initialize() {
50
+ /**
51
+ * @description Initializes the dispatch by proxying adapter methods
52
+ * @summary Sets up proxies on the adapter's CRUD methods to intercept operations and notify observers.
53
+ * This method is called automatically when an adapter is observed.
54
+ * @return {Promise<void>} A promise that resolves when initialization is complete
55
+ * @mermaid
56
+ * sequenceDiagram
57
+ * participant Dispatch
58
+ * participant Adapter
59
+ * participant Proxy
60
+ *
61
+ * Dispatch->>Dispatch: initialize()
62
+ * Dispatch->>Dispatch: Check if adapter exists
63
+ * alt No adapter
64
+ * Dispatch-->>Dispatch: Throw InternalError
65
+ * end
66
+ *
67
+ * loop For each CRUD method
68
+ * Dispatch->>Adapter: Check if method exists
69
+ * alt Method doesn't exist
70
+ * Dispatch-->>Dispatch: Throw InternalError
71
+ * end
72
+ *
73
+ * Dispatch->>Adapter: Get property descriptor
74
+ * loop While descriptor not found
75
+ * Dispatch->>Adapter: Check prototype chain
76
+ * end
77
+ *
78
+ * alt Descriptor not found or not writable
79
+ * Dispatch->>Dispatch: Log error and continue
80
+ * else Descriptor found and writable
81
+ * Dispatch->>Proxy: Create proxy for method
82
+ * Dispatch->>Adapter: Replace method with proxy
83
+ * end
84
+ * end
85
+ */
86
+ async initialize() {
16
87
  if (!this.adapter)
17
88
  throw new db_decorators_1.InternalError(`No adapter observed for dispatch`);
18
89
  const adapter = this.adapter;
@@ -64,20 +135,47 @@ class Dispatch {
64
135
  });
65
136
  });
66
137
  }
138
+ /**
139
+ * @description Closes the dispatch
140
+ * @summary Performs any necessary cleanup when the dispatch is no longer needed
141
+ * @return {Promise<void>} A promise that resolves when closing is complete
142
+ */
143
+ async close() {
144
+ // to nothing in this instance but may be required for closing connections
145
+ }
146
+ /**
147
+ * @description Starts observing an adapter
148
+ * @summary Connects this dispatch to an adapter to monitor its operations
149
+ * @param {Adapter<Y, any, any, any>} observer - The adapter to observe
150
+ * @return {void}
151
+ */
67
152
  observe(observer) {
68
153
  if (!(observer instanceof Adapter_1.Adapter))
69
154
  throw new errors_1.UnsupportedError("Only Adapters can be observed by dispatch");
70
155
  this.adapter = observer;
71
156
  this.native = observer.native;
72
157
  this.models = Adapter_1.Adapter.models(this.adapter.alias);
73
- this.initialize();
74
- this.log.verbose(`Dispatch initialized for ${this.adapter.alias} adapter`);
158
+ this.initialize().then(() => this.log.verbose(`Dispatch initialized for ${this.adapter.alias} adapter`));
75
159
  }
160
+ /**
161
+ * @description Stops observing an adapter
162
+ * @summary Disconnects this dispatch from an adapter
163
+ * @param {Observer} observer - The adapter to stop observing
164
+ * @return {void}
165
+ */
76
166
  unObserve(observer) {
77
167
  if (this.adapter !== observer)
78
168
  throw new errors_1.UnsupportedError("Only the adapter that was used to observe can be unobserved");
79
169
  this.adapter = undefined;
80
170
  }
171
+ /**
172
+ * @description Updates observers about a database event
173
+ * @summary Notifies observers about a change in the database
174
+ * @param {string} table - The name of the table where the change occurred
175
+ * @param {OperationKeys|BulkCrudOperationKeys|string} event - The type of operation that occurred
176
+ * @param {EventIds} id - The identifier(s) of the affected record(s)
177
+ * @return {Promise<void>} A promise that resolves when all observers have been notified
178
+ */
81
179
  async updateObservers(table, event, id) {
82
180
  if (!this.adapter)
83
181
  throw new db_decorators_1.InternalError(`No adapter observed for dispatch`);
@@ -90,4 +188,4 @@ class Dispatch {
90
188
  }
91
189
  }
92
190
  exports.Dispatch = Dispatch;
93
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGlzcGF0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGVyc2lzdGVuY2UvRGlzcGF0Y2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkRBSWlDO0FBR2pDLDJDQUFvQztBQUNwQyx5Q0FBNEM7QUFDNUMsK0NBQW9EO0FBR3BELE1BQWEsUUFBUTtJQU9uQixJQUFjLEdBQUc7UUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07WUFDZCxJQUFJLENBQUMsTUFBTSxHQUFHLGlCQUFPLENBQUMsR0FBRyxDQUFDLElBQVcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBYyxDQUFDLENBQUM7UUFDbEUsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxnQkFBZSxDQUFDO0lBRU4sVUFBVTtRQUNsQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFDZixNQUFNLElBQUksNkJBQWEsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1FBQzlELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFvQyxDQUFDO1FBRXhEO1lBQ0UsNkJBQWEsQ0FBQyxNQUFNO1lBQ3BCLDZCQUFhLENBQUMsTUFBTTtZQUNwQiw2QkFBYSxDQUFDLE1BQU07WUFDcEIscUNBQXFCLENBQUMsVUFBVTtZQUNoQyxxQ0FBcUIsQ0FBQyxVQUFVO1lBQ2hDLHFDQUFxQixDQUFDLFVBQVU7U0FFbkMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNuQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQkFDbEIsTUFBTSxJQUFJLDZCQUFhLENBQ3JCLFVBQVUsTUFBTSxpQkFBaUIsT0FBTyxDQUFDLEtBQUssdUNBQXVDLENBQ3RGLENBQUM7WUFFSixJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsd0JBQXdCLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2xFLElBQUksS0FBSyxHQUFR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LFFBQVE7WUFDM0IsTUFBTSxJQUFJLHlCQUFnQixDQUN4Qiw2REFBNkQsQ0FDOUQsQ0FBQztRQUNKLElBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDO0lBQzNCLENBQUM7SUFFRCxLQUFLLENBQUMsZUFBZSxDQUNuQixLQUFhLEVBQ2IsS0FBcUQsRUFDckQsRUFBWTtRQUVaLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUNmLE1BQU0sSUFBSSw2QkFBYSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSw2QkFBYSxDQUFDLCtCQUErQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzlELENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFqSEQsNEJBaUhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSW50ZXJuYWxFcnJvcixcbiAgT3BlcmF0aW9uS2V5cyxcbiAgQnVsa0NydWRPcGVyYXRpb25LZXlzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1vZGVsQ29uc3RydWN0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBPYnNlcnZlciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4vQWRhcHRlclwiO1xuaW1wb3J0IHsgVW5zdXBwb3J0ZWRFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBFdmVudElkcyB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBEaXNwYXRjaDxZPiBpbXBsZW1lbnRzIE9ic2VydmFibGUge1xuICBwcm90ZWN0ZWQgYWRhcHRlcj86IEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT47XG4gIHByb3RlY3RlZCBuYXRpdmU/OiBZO1xuICBwcm90ZWN0ZWQgbW9kZWxzITogTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+W107XG5cbiAgcHJpdmF0ZSBsb2dnZXIhOiBMb2dnZXI7XG5cbiAgcHJvdGVjdGVkIGdldCBsb2coKSB7XG4gICAgaWYgKCF0aGlzLmxvZ2dlcilcbiAgICAgIHRoaXMubG9nZ2VyID0gTG9nZ2luZy5mb3IodGhpcyBhcyBhbnkpLmZvcih0aGlzLmFkYXB0ZXIgYXMgYW55KTtcbiAgICByZXR1cm4gdGhpcy5sb2dnZXI7XG4gIH1cblxuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgcHJvdGVjdGVkIGluaXRpYWxpemUoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgTm8gYWRhcHRlciBvYnNlcnZlZCBmb3IgZGlzcGF0Y2hgKTtcbiAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5hZGFwdGVyIGFzIEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT47XG4gICAgKFxuICAgICAgW1xuICAgICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuQ1JFQVRFX0FMTCxcbiAgICAgICAgQnVsa0NydWRPcGVyYXRpb25LZXlzLlVQREFURV9BTEwsXG4gICAgICAgIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5ERUxFVEVfQUxMLFxuICAgICAgXSBhcyAoa2V5b2YgQWRhcHRlcjxZLCBhbnksIGFueSwgYW55PilbXVxuICAgICkuZm9yRWFjaCgobWV0aG9kKSA9PiB7XG4gICAgICBpZiAoIWFkYXB0ZXJbbWV0aG9kXSlcbiAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgYE1ldGhvZCAke21ldGhvZH0gbm90IGZvdW5kIGluICR7YWRhcHRlci5hbGlhc30gYWRhcHRlciB0byBiaW5kIE9ic2VydmFibGVzIERpc3BhdGNoYFxuICAgICAgICApO1xuXG4gICAgICBsZXQgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoYWRhcHRlciwgbWV0aG9kKTtcbiAgICAgIGxldCBwcm90bzogYW55ID0gYWRhcHRlcjtcbiAgICAgIHdoaWxlICghZGVzY3JpcHRvciAmJiBwcm90byAhPT0gT2JqZWN0LnByb3RvdHlwZSkge1xuICAgICAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG4gICAgICAgIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3RvLCBtZXRob2QpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWRlc2NyaXB0b3IgfHwgIWRlc2NyaXB0b3Iud3JpdGFibGUpIHtcbiAgICAgICAgdGhpcy5sb2cuZXJyb3IoXG4gICAgICAgICAgYENvdWxkIG5vdCBmaW5kIG1ldGhvZCAke21ldGhvZH0gdG8gYmluZCBPYnNlcnZhYmxlcyBEaXNwYXRjaGBcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gYnVsa1RvU2luZ2xlKG1ldGhvZDogc3RyaW5nKSB7XG4gICAgICAgIHN3aXRjaCAobWV0aG9kKSB7XG4gICAgICAgICAgY2FzZSBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuQ1JFQVRFX0FMTDpcbiAgICAgICAgICAgIHJldHVybiBPcGVyYXRpb25LZXlzLkNSRUFURTtcbiAgICAgICAgICBjYXNlIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5VUERBVEVfQUxMOlxuICAgICAgICAgICAgcmV0dXJuIE9wZXJhdGlvbktleXMuVVBEQVRFO1xuICAgICAgICAgIGNhc2UgQnVsa0NydWRPcGVyYXRpb25LZXlzLkRFTEVURV9BTEw6XG4gICAgICAgICAgICByZXR1cm4gT3BlcmF0aW9uS2V5cy5ERUxFVEU7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBtZXRob2Q7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgYmVjYXVzZSB0aGVyZSBhcmUgcmVhZCBvbmx5IHByb3BlcnRpZXNcbiAgICAgIGFkYXB0ZXJbbWV0aG9kXSA9IG5ldyBQcm94eShhZGFwdGVyW21ldGhvZF0sIHtcbiAgICAgICAgYXBwbHk6IGFzeW5jICh0YXJnZXQ6IGFueSwgdGhpc0FyZywgYXJnQXJyYXk6IGFueVtdKSA9PiB7XG4gICAgICAgICAgY29uc3QgW3RhYmxlTmFtZSwgaWRzXSA9IGFyZ0FycmF5O1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRhcmdldC5hcHBseSh0aGlzQXJnLCBhcmdBcnJheSk7XG4gICAgICAgICAgdGhpcy51cGRhdGVPYnNlcnZlcnModGFibGVOYW1lLCBidWxrVG9TaW5nbGUobWV0aG9kKSwgaWRzIGFzIEV2ZW50SWRzKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmxvZy52ZXJib3NlKFxuICAgICAgICAgICAgICAgIGBPYnNlcnZlciByZWZyZXNoIGRpc3BhdGNoZWQgYnkgJHttZXRob2R9IGZvciAke3RhYmxlTmFtZX1gXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGBwa3M6ICR7aWRzfWApO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZTogdW5rbm93bikgPT5cbiAgICAgICAgICAgICAgdGhpcy5sb2cuZXJyb3IoXG4gICAgICAgICAgICAgICAgYEZhaWxlZCB0byBkaXNwYXRjaCBvYnNlcnZlciByZWZyZXNoIGZvciAke21ldGhvZH0gb24gJHt0YWJsZU5hbWV9OiAke2V9YFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIG9ic2VydmUob2JzZXJ2ZXI6IEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT4pOiB2b2lkIHtcbiAgICBpZiAoIShvYnNlcnZlciBpbnN0YW5jZW9mIEFkYXB0ZXIpKVxuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXCJPbmx5IEFkYXB0ZXJzIGNhbiBiZSBvYnNlcnZlZCBieSBkaXNwYXRjaFwiKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSBvYnNlcnZlcjtcbiAgICB0aGlzLm5hdGl2ZSA9IG9ic2VydmVyLm5hdGl2ZTtcbiAgICB0aGlzLm1vZGVscyA9IEFkYXB0ZXIubW9kZWxzKHRoaXMuYWRhcHRlci5hbGlhcyk7XG4gICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgdGhpcy5sb2cudmVyYm9zZShgRGlzcGF0Y2ggaW5pdGlhbGl6ZWQgZm9yICR7dGhpcy5hZGFwdGVyLmFsaWFzfSBhZGFwdGVyYCk7XG4gIH1cblxuICB1bk9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWRhcHRlciAhPT0gb2JzZXJ2ZXIpXG4gICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFcnJvcihcbiAgICAgICAgXCJPbmx5IHRoZSBhZGFwdGVyIHRoYXQgd2FzIHVzZWQgdG8gb2JzZXJ2ZSBjYW4gYmUgdW5vYnNlcnZlZFwiXG4gICAgICApO1xuICAgIHRoaXMuYWRhcHRlciA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZU9ic2VydmVycyhcbiAgICB0YWJsZTogc3RyaW5nLFxuICAgIGV2ZW50OiBPcGVyYXRpb25LZXlzIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzIHwgc3RyaW5nLFxuICAgIGlkOiBFdmVudElkc1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuYWRhcHRlcilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBObyBhZGFwdGVyIG9ic2VydmVkIGZvciBkaXNwYXRjaGApO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmFkYXB0ZXIucmVmcmVzaCh0YWJsZSwgZXZlbnQsIGlkKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgRmFpbGVkIHRvIHJlZnJlc2ggZGlzcGF0Y2g6ICR7ZX1gKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
191
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGlzcGF0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGVyc2lzdGVuY2UvRGlzcGF0Y2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkRBSWlDO0FBR2pDLDJDQUFvQztBQUNwQyx5Q0FBNEM7QUFDNUMsK0NBQW9EO0FBR3BEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBQ0gsTUFBYSxRQUFRO0lBeUJuQjs7OztPQUlHO0lBQ0gsSUFBYyxHQUFHO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxpQkFBTyxDQUFDLEdBQUcsQ0FBQyxJQUFXLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQWMsQ0FBQyxDQUFDO1FBQ2xFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZ0JBQWUsQ0FBQztJQUVoQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FtQ0c7SUFDTyxLQUFLLENBQUMsVUFBVTtRQUN4QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFDZixNQUFNLElBQUksNkJBQWEsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO1FBQzlELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFvQyxDQUFDO1FBRXhEO1lBQ0UsNkJBQWEsQ0FBQyxNQUFNO1lBQ3BCLDZCQUFhLENBQUMsTUFBTTtZQUNwQiw2QkFBYSxDQUFDLE1BQU07WUFDcEIscUNBQXFCLENBQUMsVUFBVTtZQUNoQyxxQ0FBcUIsQ0FBQyxVQUFVO1lBQ2hDLHFDQUFxQixDQUFDLFVBQVU7U0FFbkMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNuQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQkFDbEIsTUFBTSxJQUFJLDZCQUFhLENBQ3JCLFVBQVUsTUFBTSxpQkFBaUIsT0FBTyxDQUFDLEtBQUssdUNBQXVDLENBQ3RGLENBQUM7WUFFSixJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsd0JBQXdCLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2xFLElBQUksS0FBSyxHQUFRLE9BQU8sQ0FBQztZQUN6QixPQUFPLENBQUMsVUFBVSxJQUFJLEtBQUssS0FBSyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2pELEtBQUssR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNyQyxVQUFVLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM5RCxDQUFDO1lBRUQsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1oseUJBQXlCLE1BQU0sK0JBQStCLENBQy9ELENBQUM7Z0JBQ0YsT0FBTztZQUNULENBQUM7WUFDRCxTQUFTLFlBQVksQ0FBQyxNQUFjO2dCQUNsQyxRQUFRLE1BQU0sRUFBRSxDQUFDO29CQUNmLEtBQUsscUNBQXFCLENBQUMsVUFBVTt3QkFDbkMsT0FBTyw2QkFBYSxDQUFDLE1BQU0sQ0FBQztvQkFDOUIsS0FBSyxxQ0FBcUIsQ0FBQyxVQUFVO3dCQUNuQyxPQUFPLDZCQUFhLENBQUMsTUFBTSxDQUFDO29CQUM5QixLQUFLLHFDQUFxQixDQUFDLFVBQVU7d0JBQ25DLE9BQU8sNkJBQWEsQ0FBQyxNQUFNLENBQUM7b0JBQzlCO3dCQUNFLE9BQU8sTUFBTSxDQUFDO2dCQUNsQixDQUFDO1lBQ0gsQ0FBQztZQUNELDBEQUEwRDtZQUMxRCxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUMzQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQVcsRUFBRSxPQUFPLEVBQUUsUUFBZSxFQUFFLEVBQUU7b0JBQ3JELE1BQU0sQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDO29CQUNsQyxNQUFNLE1BQU0sR0FBRyxNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO29CQUNyRCxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBZSxDQUFDO3lCQUNuRSxJQUFJLENBQUMsR0FBRyxFQUFFO3dCQUNULElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUNkLGtDQUFrQyxNQUFNLFFBQVEsU0FBUyxFQUFFLENBQzVELENBQUM7d0JBQ0YsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQyxDQUFDO29CQUNoQyxDQUFDLENBQUM7eUJBQ0QsS0FBSyxDQUFDLENBQUMsQ0FBVSxFQUFFLEVBQUUsQ0FDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osMkNBQTJDLE1BQU0sT0FBTyxTQUFTLEtBQUssQ0FBQyxFQUFFLENBQzFFLENBQ0YsQ0FBQztvQkFDSixPQUFPLE1BQU0sQ0FBQztnQkFDaEIsQ0FBQzthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsS0FBSztRQUNULDBFQUEwRTtJQUM1RSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxPQUFPLENBQUMsUUFBbUM7UUFDekMsSUFBSSxDQUFDLENBQUMsUUFBUSxZQUFZLGlCQUFPLENBQUM7WUFDaEMsTUFBTSxJQUFJLHlCQUFnQixDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFDMUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7UUFDeEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQzlCLElBQUksQ0FBQyxNQUFNLEdBQUcsaUJBQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUMxQixJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FDZCw0QkFBNEIsSUFBSSxDQUFDLE9BQVEsQ0FBQyxLQUFLLFVBQVUsQ0FDMUQsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsU0FBUyxDQUFDLFFBQWtCO1FBQzFCLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxRQUFRO1lBQzNCLE1BQU0sSUFBSSx5QkFBZ0IsQ0FDeEIsNkRBQTZELENBQzlELENBQUM7UUFDSixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztJQUMzQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxlQUFlLENBQ25CLEtBQWEsRUFDYixLQUFxRCxFQUNyRCxFQUFZO1FBRVosSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQ2YsTUFBTSxJQUFJLDZCQUFhLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLDZCQUFhLENBQUMsK0JBQStCLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDOUQsQ0FBQztJQUNILENBQUM7Q0FDRjtBQWhORCw0QkFnTkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBJbnRlcm5hbEVycm9yLFxuICBPcGVyYXRpb25LZXlzLFxuICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTW9kZWxDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE9ic2VydmFibGUsIE9ic2VydmVyIH0gZnJvbSBcIi4uL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi9BZGFwdGVyXCI7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBMb2dnZXIsIExvZ2dpbmcgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IEV2ZW50SWRzIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGlzcGF0Y2hlcyBkYXRhYmFzZSBvcGVyYXRpb24gZXZlbnRzIHRvIG9ic2VydmVyc1xuICogQHN1bW1hcnkgVGhlIERpc3BhdGNoIGNsYXNzIGltcGxlbWVudHMgdGhlIE9ic2VydmFibGUgaW50ZXJmYWNlIGFuZCBpcyByZXNwb25zaWJsZSBmb3IgaW50ZXJjZXB0aW5nXG4gKiBkYXRhYmFzZSBvcGVyYXRpb25zIGZyb20gYW4gQWRhcHRlciBhbmQgbm90aWZ5aW5nIG9ic2VydmVycyB3aGVuIGNoYW5nZXMgb2NjdXIuIEl0IHVzZXMgcHJveGllcyB0b1xuICogd3JhcCB0aGUgYWRhcHRlcidzIENSVUQgbWV0aG9kcyBhbmQgYXV0b21hdGljYWxseSB0cmlnZ2VyIG9ic2VydmVyIHVwZGF0ZXMgYWZ0ZXIgb3BlcmF0aW9ucyBjb21wbGV0ZS5cbiAqIEB0ZW1wbGF0ZSBZIC0gVGhlIG5hdGl2ZSBkYXRhYmFzZSBkcml2ZXIgdHlwZVxuICogQHBhcmFtIHt2b2lkfSAtIE5vIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnNcbiAqIEBjbGFzcyBEaXNwYXRjaFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0aW5nIGFuZCB1c2luZyBhIERpc3BhdGNoIGluc3RhbmNlXG4gKiBjb25zdCBkaXNwYXRjaCA9IG5ldyBEaXNwYXRjaDxQb3N0Z3Jlc0RyaXZlcj4oKTtcbiAqXG4gKiAvLyBDb25uZWN0IGl0IHRvIGFuIGFkYXB0ZXJcbiAqIGNvbnN0IGFkYXB0ZXIgPSBuZXcgUG9zdGdyZXNBZGFwdGVyKGNvbm5lY3Rpb24pO1xuICogZGlzcGF0Y2gub2JzZXJ2ZShhZGFwdGVyKTtcbiAqXG4gKiAvLyBOb3cgYW55IENSVUQgb3BlcmF0aW9ucyBvbiB0aGUgYWRhcHRlciB3aWxsIGF1dG9tYXRpY2FsbHlcbiAqIC8vIHRyaWdnZXIgb2JzZXJ2ZXIgbm90aWZpY2F0aW9uc1xuICogYXdhaXQgYWRhcHRlci5jcmVhdGUoJ3VzZXJzJywgMTIzLCB1c2VyTW9kZWwpO1xuICogLy8gT2JzZXJ2ZXJzIHdpbGwgYmUgbm90aWZpZWQgYWJvdXQgdGhlIGNyZWF0aW9uXG4gKlxuICogLy8gV2hlbiBkb25lLCB5b3UgY2FuIGRpc2Nvbm5lY3RcbiAqIGRpc3BhdGNoLnVuT2JzZXJ2ZShhZGFwdGVyKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgRGlzcGF0Y2g8WT4gaW1wbGVtZW50cyBPYnNlcnZhYmxlIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgYWRhcHRlciBiZWluZyBvYnNlcnZlZFxuICAgKiBAc3VtbWFyeSBSZWZlcmVuY2UgdG8gdGhlIGRhdGFiYXNlIGFkYXB0ZXIgd2hvc2Ugb3BlcmF0aW9ucyBhcmUgYmVpbmcgbW9uaXRvcmVkXG4gICAqL1xuICBwcm90ZWN0ZWQgYWRhcHRlcj86IEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgbmF0aXZlIGRhdGFiYXNlIGRyaXZlclxuICAgKiBAc3VtbWFyeSBSZWZlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgZGF0YWJhc2UgZHJpdmVyIGZyb20gdGhlIGFkYXB0ZXJcbiAgICovXG4gIHByb3RlY3RlZCBuYXRpdmU/OiBZO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGlzdCBvZiBtb2RlbCBjb25zdHJ1Y3RvcnNcbiAgICogQHN1bW1hcnkgQXJyYXkgb2YgbW9kZWwgY29uc3RydWN0b3JzIHRoYXQgYXJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgYWRhcHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIG1vZGVscyE6IE1vZGVsQ29uc3RydWN0b3I8YW55PltdO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9nZ2VyIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IExvZ2dlciBmb3IgcmVjb3JkaW5nIGRpc3BhdGNoIGFjdGl2aXRpZXNcbiAgICovXG4gIHByaXZhdGUgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQWNjZXNzb3IgZm9yIHRoZSBsb2dnZXJcbiAgICogQHN1bW1hcnkgR2V0cyBvciBpbml0aWFsaXplcyB0aGUgbG9nZ2VyIGZvciB0aGlzIGRpc3BhdGNoIGluc3RhbmNlXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gVGhlIGxvZ2dlciBpbnN0YW5jZVxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBsb2coKSB7XG4gICAgaWYgKCF0aGlzLmxvZ2dlcilcbiAgICAgIHRoaXMubG9nZ2VyID0gTG9nZ2luZy5mb3IodGhpcyBhcyBhbnkpLmZvcih0aGlzLmFkYXB0ZXIgYXMgYW55KTtcbiAgICByZXR1cm4gdGhpcy5sb2dnZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgRGlzcGF0Y2ggaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgRGlzcGF0Y2ggaW5zdGFuY2Ugd2l0aG91dCBhbnkgYWRhcHRlclxuICAgKi9cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSW5pdGlhbGl6ZXMgdGhlIGRpc3BhdGNoIGJ5IHByb3h5aW5nIGFkYXB0ZXIgbWV0aG9kc1xuICAgKiBAc3VtbWFyeSBTZXRzIHVwIHByb3hpZXMgb24gdGhlIGFkYXB0ZXIncyBDUlVEIG1ldGhvZHMgdG8gaW50ZXJjZXB0IG9wZXJhdGlvbnMgYW5kIG5vdGlmeSBvYnNlcnZlcnMuXG4gICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gYW4gYWRhcHRlciBpcyBvYnNlcnZlZC5cbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBpbml0aWFsaXphdGlvbiBpcyBjb21wbGV0ZVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBEaXNwYXRjaFxuICAgKiAgIHBhcnRpY2lwYW50IEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQcm94eVxuICAgKlxuICAgKiAgIERpc3BhdGNoLT4+RGlzcGF0Y2g6IGluaXRpYWxpemUoKVxuICAgKiAgIERpc3BhdGNoLT4+RGlzcGF0Y2g6IENoZWNrIGlmIGFkYXB0ZXIgZXhpc3RzXG4gICAqICAgYWx0IE5vIGFkYXB0ZXJcbiAgICogICAgIERpc3BhdGNoLS0+PkRpc3BhdGNoOiBUaHJvdyBJbnRlcm5hbEVycm9yXG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgbG9vcCBGb3IgZWFjaCBDUlVEIG1ldGhvZFxuICAgKiAgICAgRGlzcGF0Y2gtPj5BZGFwdGVyOiBDaGVjayBpZiBtZXRob2QgZXhpc3RzXG4gICAqICAgICBhbHQgTWV0aG9kIGRvZXNuJ3QgZXhpc3RcbiAgICogICAgICAgRGlzcGF0Y2gtLT4+RGlzcGF0Y2g6IFRocm93IEludGVybmFsRXJyb3JcbiAgICogICAgIGVuZFxuICAgKlxuICAgKiAgICAgRGlzcGF0Y2gtPj5BZGFwdGVyOiBHZXQgcHJvcGVydHkgZGVzY3JpcHRvclxuICAgKiAgICAgbG9vcCBXaGlsZSBkZXNjcmlwdG9yIG5vdCBmb3VuZFxuICAgKiAgICAgICBEaXNwYXRjaC0+PkFkYXB0ZXI6IENoZWNrIHByb3RvdHlwZSBjaGFpblxuICAgKiAgICAgZW5kXG4gICAqXG4gICAqICAgICBhbHQgRGVzY3JpcHRvciBub3QgZm91bmQgb3Igbm90IHdyaXRhYmxlXG4gICAqICAgICAgIERpc3BhdGNoLT4+RGlzcGF0Y2g6IExvZyBlcnJvciBhbmQgY29udGludWVcbiAgICogICAgIGVsc2UgRGVzY3JpcHRvciBmb3VuZCBhbmQgd3JpdGFibGVcbiAgICogICAgICAgRGlzcGF0Y2gtPj5Qcm94eTogQ3JlYXRlIHByb3h5IGZvciBtZXRob2RcbiAgICogICAgICAgRGlzcGF0Y2gtPj5BZGFwdGVyOiBSZXBsYWNlIG1ldGhvZCB3aXRoIHByb3h5XG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBpbml0aWFsaXplKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIGFkYXB0ZXIgb2JzZXJ2ZWQgZm9yIGRpc3BhdGNoYCk7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuYWRhcHRlciBhcyBBZGFwdGVyPFksIGFueSwgYW55LCBhbnk+O1xuICAgIChcbiAgICAgIFtcbiAgICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgICAgQnVsa0NydWRPcGVyYXRpb25LZXlzLkNSRUFURV9BTEwsXG4gICAgICAgIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5VUERBVEVfQUxMLFxuICAgICAgICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuREVMRVRFX0FMTCxcbiAgICAgIF0gYXMgKGtleW9mIEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT4pW11cbiAgICApLmZvckVhY2goKG1ldGhvZCkgPT4ge1xuICAgICAgaWYgKCFhZGFwdGVyW21ldGhvZF0pXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgIGBNZXRob2QgJHttZXRob2R9IG5vdCBmb3VuZCBpbiAke2FkYXB0ZXIuYWxpYXN9IGFkYXB0ZXIgdG8gYmluZCBPYnNlcnZhYmxlcyBEaXNwYXRjaGBcbiAgICAgICAgKTtcblxuICAgICAgbGV0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGFkYXB0ZXIsIG1ldGhvZCk7XG4gICAgICBsZXQgcHJvdG86IGFueSA9IGFkYXB0ZXI7XG4gICAgICB3aGlsZSAoIWRlc2NyaXB0b3IgJiYgcHJvdG8gIT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICAgICAgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuICAgICAgICBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm90bywgbWV0aG9kKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFkZXNjcmlwdG9yIHx8ICFkZXNjcmlwdG9yLndyaXRhYmxlKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yKFxuICAgICAgICAgIGBDb3VsZCBub3QgZmluZCBtZXRob2QgJHttZXRob2R9IHRvIGJpbmQgT2JzZXJ2YWJsZXMgRGlzcGF0Y2hgXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIGJ1bGtUb1NpbmdsZShtZXRob2Q6IHN0cmluZykge1xuICAgICAgICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgICAgICAgIGNhc2UgQnVsa0NydWRPcGVyYXRpb25LZXlzLkNSRUFURV9BTEw6XG4gICAgICAgICAgICByZXR1cm4gT3BlcmF0aW9uS2V5cy5DUkVBVEU7XG4gICAgICAgICAgY2FzZSBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuVVBEQVRFX0FMTDpcbiAgICAgICAgICAgIHJldHVybiBPcGVyYXRpb25LZXlzLlVQREFURTtcbiAgICAgICAgICBjYXNlIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5ERUxFVEVfQUxMOlxuICAgICAgICAgICAgcmV0dXJuIE9wZXJhdGlvbktleXMuREVMRVRFO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gbWV0aG9kO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGJlY2F1c2UgdGhlcmUgYXJlIHJlYWQgb25seSBwcm9wZXJ0aWVzXG4gICAgICBhZGFwdGVyW21ldGhvZF0gPSBuZXcgUHJveHkoYWRhcHRlclttZXRob2RdLCB7XG4gICAgICAgIGFwcGx5OiBhc3luYyAodGFyZ2V0OiBhbnksIHRoaXNBcmcsIGFyZ0FycmF5OiBhbnlbXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IFt0YWJsZU5hbWUsIGlkc10gPSBhcmdBcnJheTtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0YXJnZXQuYXBwbHkodGhpc0FyZywgYXJnQXJyYXkpO1xuICAgICAgICAgIHRoaXMudXBkYXRlT2JzZXJ2ZXJzKHRhYmxlTmFtZSwgYnVsa1RvU2luZ2xlKG1ldGhvZCksIGlkcyBhcyBFdmVudElkcylcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5sb2cudmVyYm9zZShcbiAgICAgICAgICAgICAgICBgT2JzZXJ2ZXIgcmVmcmVzaCBkaXNwYXRjaGVkIGJ5ICR7bWV0aG9kfSBmb3IgJHt0YWJsZU5hbWV9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgcGtzOiAke2lkc31gKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGU6IHVua25vd24pID0+XG4gICAgICAgICAgICAgIHRoaXMubG9nLmVycm9yKFxuICAgICAgICAgICAgICAgIGBGYWlsZWQgdG8gZGlzcGF0Y2ggb2JzZXJ2ZXIgcmVmcmVzaCBmb3IgJHttZXRob2R9IG9uICR7dGFibGVOYW1lfTogJHtlfWBcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENsb3NlcyB0aGUgZGlzcGF0Y2hcbiAgICogQHN1bW1hcnkgUGVyZm9ybXMgYW55IG5lY2Vzc2FyeSBjbGVhbnVwIHdoZW4gdGhlIGRpc3BhdGNoIGlzIG5vIGxvbmdlciBuZWVkZWRcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBjbG9zaW5nIGlzIGNvbXBsZXRlXG4gICAqL1xuICBhc3luYyBjbG9zZSgpIHtcbiAgICAvLyB0byBub3RoaW5nIGluIHRoaXMgaW5zdGFuY2UgYnV0IG1heSBiZSByZXF1aXJlZCBmb3IgY2xvc2luZyBjb25uZWN0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdGFydHMgb2JzZXJ2aW5nIGFuIGFkYXB0ZXJcbiAgICogQHN1bW1hcnkgQ29ubmVjdHMgdGhpcyBkaXNwYXRjaCB0byBhbiBhZGFwdGVyIHRvIG1vbml0b3IgaXRzIG9wZXJhdGlvbnNcbiAgICogQHBhcmFtIHtBZGFwdGVyPFksIGFueSwgYW55LCBhbnk+fSBvYnNlcnZlciAtIFRoZSBhZGFwdGVyIHRvIG9ic2VydmVcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIG9ic2VydmUob2JzZXJ2ZXI6IEFkYXB0ZXI8WSwgYW55LCBhbnksIGFueT4pOiB2b2lkIHtcbiAgICBpZiAoIShvYnNlcnZlciBpbnN0YW5jZW9mIEFkYXB0ZXIpKVxuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXCJPbmx5IEFkYXB0ZXJzIGNhbiBiZSBvYnNlcnZlZCBieSBkaXNwYXRjaFwiKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSBvYnNlcnZlcjtcbiAgICB0aGlzLm5hdGl2ZSA9IG9ic2VydmVyLm5hdGl2ZTtcbiAgICB0aGlzLm1vZGVscyA9IEFkYXB0ZXIubW9kZWxzKHRoaXMuYWRhcHRlci5hbGlhcyk7XG4gICAgdGhpcy5pbml0aWFsaXplKCkudGhlbigoKSA9PlxuICAgICAgdGhpcy5sb2cudmVyYm9zZShcbiAgICAgICAgYERpc3BhdGNoIGluaXRpYWxpemVkIGZvciAke3RoaXMuYWRhcHRlciEuYWxpYXN9IGFkYXB0ZXJgXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RvcHMgb2JzZXJ2aW5nIGFuIGFkYXB0ZXJcbiAgICogQHN1bW1hcnkgRGlzY29ubmVjdHMgdGhpcyBkaXNwYXRjaCBmcm9tIGFuIGFkYXB0ZXJcbiAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXIgLSBUaGUgYWRhcHRlciB0byBzdG9wIG9ic2VydmluZ1xuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgdW5PYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmFkYXB0ZXIgIT09IG9ic2VydmVyKVxuICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXG4gICAgICAgIFwiT25seSB0aGUgYWRhcHRlciB0aGF0IHdhcyB1c2VkIHRvIG9ic2VydmUgY2FuIGJlIHVub2JzZXJ2ZWRcIlxuICAgICAgKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgb2JzZXJ2ZXJzIGFib3V0IGEgZGF0YWJhc2UgZXZlbnRcbiAgICogQHN1bW1hcnkgTm90aWZpZXMgb2JzZXJ2ZXJzIGFib3V0IGEgY2hhbmdlIGluIHRoZSBkYXRhYmFzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUgd2hlcmUgdGhlIGNoYW5nZSBvY2N1cnJlZFxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN8QnVsa0NydWRPcGVyYXRpb25LZXlzfHN0cmluZ30gZXZlbnQgLSBUaGUgdHlwZSBvZiBvcGVyYXRpb24gdGhhdCBvY2N1cnJlZFxuICAgKiBAcGFyYW0ge0V2ZW50SWRzfSBpZCAtIFRoZSBpZGVudGlmaWVyKHMpIG9mIHRoZSBhZmZlY3RlZCByZWNvcmQocylcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgb2JzZXJ2ZXJzIGhhdmUgYmVlbiBub3RpZmllZFxuICAgKi9cbiAgYXN5bmMgdXBkYXRlT2JzZXJ2ZXJzKFxuICAgIHRhYmxlOiBzdHJpbmcsXG4gICAgZXZlbnQ6IE9wZXJhdGlvbktleXMgfCBCdWxrQ3J1ZE9wZXJhdGlvbktleXMgfCBzdHJpbmcsXG4gICAgaWQ6IEV2ZW50SWRzXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5hZGFwdGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIGFkYXB0ZXIgb2JzZXJ2ZWQgZm9yIGRpc3BhdGNoYCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYWRhcHRlci5yZWZyZXNoKHRhYmxlLCBldmVudCwgaWQpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBGYWlsZWQgdG8gcmVmcmVzaCBkaXNwYXRjaDogJHtlfWApO1xuICAgIH1cbiAgfVxufVxuIl19