velocious 1.0.641 → 1.0.643

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 (60) hide show
  1. package/README.md +25 -2
  2. package/build/authorization/base-resource.js +18 -5
  3. package/build/background-jobs/main.js +21 -6
  4. package/build/background-jobs/store.js +116 -7
  5. package/build/configuration-types.js +34 -2
  6. package/build/database/record/index.js +42 -11
  7. package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +17 -3
  8. package/build/frontend-model-controller.js +10 -5
  9. package/build/frontend-model-resource/base-resource.js +95 -41
  10. package/build/frontend-models/base.js +1 -1
  11. package/build/src/authorization/base-resource.d.ts +19 -6
  12. package/build/src/authorization/base-resource.d.ts.map +1 -1
  13. package/build/src/authorization/base-resource.js +16 -6
  14. package/build/src/background-jobs/main.d.ts +3 -2
  15. package/build/src/background-jobs/main.d.ts.map +1 -1
  16. package/build/src/background-jobs/main.js +26 -7
  17. package/build/src/background-jobs/store.d.ts +16 -0
  18. package/build/src/background-jobs/store.d.ts.map +1 -1
  19. package/build/src/background-jobs/store.js +103 -7
  20. package/build/src/configuration-types.d.ts +72 -5
  21. package/build/src/configuration-types.d.ts.map +1 -1
  22. package/build/src/configuration-types.js +31 -3
  23. package/build/src/database/record/index.d.ts +44 -46
  24. package/build/src/database/record/index.d.ts.map +1 -1
  25. package/build/src/database/record/index.js +39 -12
  26. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
  27. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +19 -4
  28. package/build/src/frontend-model-controller.d.ts +1 -1
  29. package/build/src/frontend-model-controller.d.ts.map +1 -1
  30. package/build/src/frontend-model-controller.js +9 -6
  31. package/build/src/frontend-model-resource/base-resource.d.ts +66 -32
  32. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  33. package/build/src/frontend-model-resource/base-resource.js +89 -42
  34. package/build/src/frontend-models/base.d.ts +1 -0
  35. package/build/src/frontend-models/base.d.ts.map +1 -1
  36. package/build/src/frontend-models/base.js +2 -2
  37. package/build/src/sync/sync-api-controller.d.ts.map +1 -1
  38. package/build/src/sync/sync-api-controller.js +6 -5
  39. package/build/src/sync/sync-envelope-replay-service.d.ts +1 -1
  40. package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
  41. package/build/src/sync/sync-envelope-replay-service.js +3 -2
  42. package/build/src/sync/sync-resource-base.d.ts +2 -0
  43. package/build/src/sync/sync-resource-base.d.ts.map +1 -1
  44. package/build/src/sync/sync-resource-base.js +3 -1
  45. package/build/sync/sync-api-controller.js +5 -5
  46. package/build/sync/sync-envelope-replay-service.js +2 -1
  47. package/build/sync/sync-resource-base.js +3 -0
  48. package/package.json +1 -1
  49. package/src/authorization/base-resource.js +18 -5
  50. package/src/background-jobs/main.js +21 -6
  51. package/src/background-jobs/store.js +116 -7
  52. package/src/configuration-types.js +34 -2
  53. package/src/database/record/index.js +42 -11
  54. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +17 -3
  55. package/src/frontend-model-controller.js +10 -5
  56. package/src/frontend-model-resource/base-resource.js +95 -41
  57. package/src/frontend-models/base.js +1 -1
  58. package/src/sync/sync-api-controller.js +5 -5
  59. package/src/sync/sync-envelope-replay-service.js +2 -1
  60. package/src/sync/sync-resource-base.js +3 -0
@@ -5,6 +5,11 @@ import * as inflection from "inflection"
5
5
  import isPlainObject from "../utils/plain-object.js"
6
6
  import VelociousError from "../velocious-error.js"
7
7
 
8
+ /**
9
+ * Backend or frontend model class bound to a frontend-model resource.
10
+ * @typedef {import("../authorization/base-resource.js").AuthorizationResourceModelClass & {attachmentDefinitions: () => Record<string, import("../configuration-types.js").FrontendModelAttachmentConfiguration>, primaryKey: () => string}} FrontendModelResourceModelClass
11
+ */
12
+
8
13
  /**
9
14
  * Built-in frontend-model resource action.
10
15
  * @typedef {"index" | "find" | "create" | "update" | "destroy" | "attach" | "attachmentList" | "download" | "url"} FrontendModelResourceAction
@@ -20,7 +25,7 @@ import VelociousError from "../velocious-error.js"
20
25
  * frontendModelAbilityAction: (action: FrontendModelResourceAction) => string,
21
26
  * frontendModelAbilityAuthorizedQuery: (action: FrontendModelResourceAction) => import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>,
22
27
  * frontendModelAuthorizedQuery: (action: FrontendModelResourceAction) => import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>,
23
- * frontendModelIndexQuery: (options?: FrontendModelResourceIndexQueryOptions & {resource?: FrontendModelBaseResource}) => import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>,
28
+ * frontendModelIndexQuery: (options?: FrontendModelResourceIndexQueryOptions & {resource?: Pick<FrontendModelBaseResource<FrontendModelResourceModelClass>, "applyFrontendModelIndexPagination" | "applyFrontendModelIndexSearch" | "applyFrontendModelIndexSort">}) => import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>,
24
29
  * frontendModelParams: () => import("../configuration-types.js").VelociousParams,
25
30
  * frontendModelPreload: () => import("../database/query/index.js").NestedPreloadRecord | null,
26
31
  * frontendModelResourceConfigurationForModelClass: (modelClass: typeof import("../database/record/index.js").default) => FrontendModelResolvedResourceConfiguration | null,
@@ -68,9 +73,10 @@ import VelociousError from "../velocious-error.js"
68
73
 
69
74
  /**
70
75
  * FrontendModelResourceControllerArgs type.
76
+ * @template {typeof import("../database/record/index.js").default} [TDatabaseModelClass=typeof import("../database/record/index.js").default]
71
77
  * @typedef {object} FrontendModelResourceControllerArgs
72
78
  * @property {FrontendModelResourceController} controller - Frontend-model controller instance.
73
- * @property {typeof import("../database/record/index.js").default} modelClass - Backing model class.
79
+ * @property {TDatabaseModelClass} modelClass - Backing model class.
74
80
  * @property {string} modelName - Model name.
75
81
  * @property {import("../configuration-types.js").VelociousParams} params - Request params.
76
82
  * @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration} resourceConfiguration - Normalized resource configuration (or raw input shape during early bootstrap).
@@ -78,17 +84,26 @@ import VelociousError from "../velocious-error.js"
78
84
 
79
85
  /**
80
86
  * FrontendModelResourceAbilityArgs type.
87
+ * @template {FrontendModelResourceModelClass} [TModelClass=FrontendModelResourceModelClass]
81
88
  * @typedef {object} FrontendModelResourceAbilityArgs
82
89
  * @property {import("../authorization/ability.js").default} [ability] - Ability instance when the resource is used directly for authorization.
83
90
  * @property {import("../configuration.js").default} [configuration] - Velocious configuration for controller-less construction (for example the sync websocket channel); the controller path derives it from the controller instead.
84
91
  * @property {import("../configuration-types.js").VelociousLooseObject} [context] - Ability context.
85
92
  * @property {import("../configuration-types.js").VelociousLooseObject} [locals] - Ability locals.
86
- * @property {typeof import("../database/record/index.js").default} [modelClass] - Optional backing model class override.
93
+ * @property {TModelClass} [modelClass] - Optional backing model class override.
87
94
  * @property {string} [modelName] - Optional model name override.
88
95
  * @property {import("../configuration-types.js").VelociousParams} [params] - Optional params override.
89
96
  * @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration} [resourceConfiguration] - Optional normalized resource configuration.
90
97
  */
91
98
 
99
+ /**
100
+ * Internal constructor contract used when a resource instantiates its shared
101
+ * counterpart across the frontend/backend model boundary.
102
+ * @template {FrontendModelResourceModelClass} TModelClass
103
+ * @template {typeof import("../database/record/index.js").default} TDatabaseModelClass
104
+ * @typedef {{new (args: FrontendModelResourceAbilityArgs<FrontendModelResourceModelClass> | FrontendModelResourceControllerArgs): FrontendModelBaseResource<TModelClass, TDatabaseModelClass>}} FrontendModelResourceInternalConstructor
105
+ */
106
+
92
107
  /**
93
108
  * Normalized sync replay mutation passed to the resource sync hooks.
94
109
  * @typedef {import("../sync/sync-envelope-replay-service.js").SyncReplayMutation} FrontendModelSyncMutation
@@ -163,19 +178,30 @@ import VelociousError from "../velocious-error.js"
163
178
  * @typedef {FrontendModelResourceAttributePayload & {id?: string | number, _destroy?: boolean, attributes?: FrontendModelResourceAttributePayload, attachments?: FrontendModelResourceAttributePayload, nestedAttributes?: FrontendModelResourceAttributePayload}} FrontendModelResourceNestedEntry
164
179
  */
165
180
 
181
+ /**
182
+ * Narrows an unbound resource registry entry at framework-owned construction
183
+ * sites where the backing database model has already been resolved.
184
+ * @param {import("../configuration-types.js").FrontendModelResourceClassType} ResourceClass - Unbound resource class.
185
+ * @returns {FrontendModelResourceInternalConstructor<typeof import("../database/record/index.js").default, typeof import("../database/record/index.js").default>} Runtime constructor.
186
+ */
187
+ export function frontendModelResourceInternalConstructor(ResourceClass) {
188
+ return /** @type {FrontendModelResourceInternalConstructor<typeof import("../database/record/index.js").default, typeof import("../database/record/index.js").default>} */ (/** @type {unknown} */ (ResourceClass))
189
+ }
190
+
166
191
  /**
167
192
  * Base class for backend frontend-model resources.
168
- * @template {typeof import("../database/record/index.js").default} [TModelClass=typeof import("../database/record/index.js").default]
193
+ * @template {FrontendModelResourceModelClass} [TModelClass=typeof import("../database/record/index.js").default]
194
+ * @template {typeof import("../database/record/index.js").default} [TDatabaseModelClass=Extract<TModelClass, typeof import("../database/record/index.js").default>]
169
195
  */
170
196
  export default class FrontendModelBaseResource extends AuthorizationBaseResource {
171
- /** @type {typeof import("../database/record/index.js").default | undefined} */
197
+ /** @type {FrontendModelResourceModelClass | undefined} */
172
198
  static ModelClass = undefined
173
199
 
174
200
  /** @type {Record<string, ReturnType<typeof JSON.parse>> | string[] | undefined} */
175
201
  static attributes = undefined
176
202
  /** @type {string[] | undefined} */
177
203
  static abilities = undefined
178
- /** @type {Record<string, ReturnType<typeof JSON.parse>> | undefined} */
204
+ /** @type {Record<string, import("../configuration-types.js").FrontendModelAttachmentConfiguration> | undefined} */
179
205
  static attachments = undefined
180
206
  /** @type {string[] | undefined} */
181
207
  static commands = undefined
@@ -214,7 +240,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
214
240
 
215
241
  /**
216
242
  * Runs constructor.
217
- * @param {FrontendModelResourceAbilityArgs | FrontendModelResourceControllerArgs} args - Resource args.
243
+ * @param {FrontendModelResourceAbilityArgs<TModelClass> | FrontendModelResourceControllerArgs<TDatabaseModelClass>} args - Resource args.
218
244
  */
219
245
  constructor(args) {
220
246
  super({
@@ -223,16 +249,18 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
223
249
  locals: "locals" in args ? args.locals || {} : {}
224
250
  })
225
251
 
226
- const ResourceClass = /** @type {typeof FrontendModelBaseResource} */ (this.constructor)
252
+ // Narrows the subclass static side to the model class carried by this resource generic.
253
+ const ResourceClass = /** @type {typeof FrontendModelBaseResource & {ModelClass: TModelClass | undefined, modelClass: () => TModelClass}} */ (this.constructor)
227
254
  const defaultResourceConfiguration = /** @type {import("../configuration-types.js").FrontendModelResourceConfiguration} */ ({attributes: []})
228
255
 
229
256
  this.controller = "controller" in args ? args.controller : undefined
230
257
  this.configurationValue = "configuration" in args ? args.configuration : undefined
231
- this.modelClassValue = "modelClass" in args ? args.modelClass : ResourceClass.modelClass()
258
+ // Narrows the internal controller/shared-resource construction path to the resource's declared model generic.
259
+ this.modelClassValue = /** @type {TModelClass} */ ("modelClass" in args ? args.modelClass : ResourceClass.modelClass())
232
260
  this.modelNameValue = "modelName" in args ? args.modelName : this.modelClass().getModelName()
233
261
  this.paramsValue = "params" in args ? args.params : undefined
234
262
  this.resourceConfigurationValue = "resourceConfiguration" in args ? args.resourceConfiguration : defaultResourceConfiguration
235
- /** @type {FrontendModelBaseResource | null | undefined} */
263
+ /** @type {FrontendModelBaseResource<TModelClass, TDatabaseModelClass> | null | undefined} */
236
264
  this.sharedResourceInstanceValue = undefined
237
265
  }
238
266
 
@@ -269,15 +297,37 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
269
297
  return /** @type {string[] | undefined} */ (this.sharedResourceStaticValue("translatedAttributes"))
270
298
  }
271
299
 
300
+ /**
301
+ * Resolves frontend-safe attachment declarations from the backing model.
302
+ * Resource-level declarations remain as a fallback for frontend-only resources.
303
+ * @returns {Record<string, import("../configuration-types.js").FrontendModelAttachmentConfiguration>} - Client attachment configuration keyed by name.
304
+ */
305
+ static attachmentConfigurations() {
306
+ const configuredAttachments = /** @type {Record<string, import("../configuration-types.js").FrontendModelAttachmentConfiguration> | undefined} */ (this.sharedResourceStaticValue("attachments"))
307
+ const attachments = configuredAttachments ? {...configuredAttachments} : {}
308
+
309
+ if (!this.ModelClass) return attachments
310
+
311
+ for (const [attachmentName, definition] of Object.entries(this.ModelClass.attachmentDefinitions())) {
312
+ const attachmentConfig = /** @type {import("../configuration-types.js").FrontendModelAttachmentConfiguration} */ ({type: definition.type})
313
+
314
+ if (definition.sync) attachmentConfig.sync = {...definition.sync}
315
+
316
+ attachments[attachmentName] = attachmentConfig
317
+ }
318
+
319
+ return attachments
320
+ }
321
+
272
322
  /**
273
323
  * Builds a resource instance for shared-resource fallback calls.
274
- * @returns {FrontendModelBaseResource | null} - Shared resource instance when configured.
324
+ * @returns {FrontendModelBaseResource<TModelClass, TDatabaseModelClass> | null} - Shared resource instance when configured.
275
325
  */
276
326
  sharedResourceInstance() {
277
327
  if (this.sharedResourceInstanceValue !== undefined) return this.sharedResourceInstanceValue
278
328
 
279
- const ResourceClass = /** @type {typeof FrontendModelBaseResource} */ (this.constructor)
280
- const SharedResource = /** @type {typeof FrontendModelBaseResource | undefined} */ (ResourceClass.sharedResourceClass())
329
+ const ResourceClass = /** @type {import("../configuration-types.js").FrontendModelResourceClassType<TModelClass, TDatabaseModelClass>} */ (this.constructor)
330
+ const SharedResource = /** @type {import("../configuration-types.js").FrontendModelResourceClassType<TModelClass, TDatabaseModelClass> | undefined} */ (ResourceClass.sharedResourceClass())
281
331
 
282
332
  if (!SharedResource) {
283
333
  this.sharedResourceInstanceValue = null
@@ -288,7 +338,8 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
288
338
  throw new Error(`${ResourceClass.name}.SharedResource cannot point to itself.`)
289
339
  }
290
340
 
291
- this.sharedResourceInstanceValue = new SharedResource({
341
+ const SharedResourceConstructor = /** @type {FrontendModelResourceInternalConstructor<TModelClass, TDatabaseModelClass>} */ (/** @type {unknown} */ (SharedResource))
342
+ const sharedResource = new SharedResourceConstructor({
292
343
  ability: this.ability,
293
344
  controller: this.controller,
294
345
  context: this.context,
@@ -298,8 +349,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
298
349
  params: this.params(),
299
350
  resourceConfiguration: this.resourceConfiguration()
300
351
  })
352
+ this.sharedResourceInstanceValue = sharedResource
301
353
 
302
- return this.sharedResourceInstanceValue
354
+ return sharedResource
303
355
  }
304
356
 
305
357
  /**
@@ -343,7 +395,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
343
395
  /**
344
396
  * Resolves a method on this resource or its shared fallback.
345
397
  * @param {string} methodName - Method name.
346
- * @returns {{method: (...methodArgs: unknown[]) => unknown, resource: FrontendModelBaseResource} | null} - Resolved method and receiver.
398
+ * @returns {{method: (...methodArgs: unknown[]) => unknown, resource: FrontendModelBaseResource<TModelClass, TDatabaseModelClass>} | null} - Resolved method and receiver.
347
399
  */
348
400
  resourceMethod(methodName) {
349
401
  const ownMethod = /** @type {Record<string, unknown>} */ (/** @type {unknown} */ (this))[methodName]
@@ -392,7 +444,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
392
444
  static resourceConfig() {
393
445
  const attributes = this.sharedResourceStaticValue("attributes")
394
446
  const abilities = this.sharedResourceStaticValue("abilities")
395
- const attachments = this.sharedResourceStaticValue("attachments")
447
+ const attachments = this.attachmentConfigurations()
396
448
  const commands = this.sharedResourceStaticValue("commands")
397
449
  const builtInCollectionCommands = this.sharedResourceStaticValue("builtInCollectionCommands")
398
450
  const builtInMemberCommands = this.sharedResourceStaticValue("builtInMemberCommands")
@@ -409,7 +461,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
409
461
  }
410
462
 
411
463
  if (abilities) config.abilities = /** @type {string[]} */ (abilities)
412
- if (attachments) config.attachments = /** @type {Record<string, ReturnType<typeof JSON.parse>>} */ (attachments)
464
+ if (Object.keys(attachments).length > 0) config.attachments = attachments
413
465
  if (commands) config.commands = /** @type {string[]} */ (commands)
414
466
  if (builtInCollectionCommands) config.builtInCollectionCommands = /** @type {string[]} */ (builtInCollectionCommands)
415
467
  if (builtInMemberCommands) config.builtInMemberCommands = /** @type {string[]} */ (builtInMemberCommands)
@@ -424,16 +476,6 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
424
476
  return config
425
477
  }
426
478
 
427
- /**
428
- * Runs static model class.
429
- * @returns {typeof import("../database/record/index.js").default} - Backing model class.
430
- */
431
- static modelClass() {
432
- if (!this.ModelClass) throw new Error(`${this.name} requires a static ModelClass.`)
433
-
434
- return this.ModelClass
435
- }
436
-
437
479
  /**
438
480
  * Runs controller instance.
439
481
  * @returns {import("../controller.js").default} - Controller instance.
@@ -466,7 +508,16 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
466
508
  throw new Error(`${this.constructor.name} requires a model class.`)
467
509
  }
468
510
 
469
- return /** @type {TModelClass} */ (this.modelClassValue)
511
+ return this.modelClassValue
512
+ }
513
+
514
+ /**
515
+ * Returns the database model class used by server-only resource operations.
516
+ * @returns {TDatabaseModelClass} - Database model class.
517
+ */
518
+ databaseModelClass() {
519
+ // Narrows the portable resource generic at the explicit backend-operation boundary.
520
+ return /** @type {TDatabaseModelClass} */ (/** @type {unknown} */ (this.modelClass()))
470
521
  }
471
522
 
472
523
  /**
@@ -619,7 +670,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
619
670
  * @returns {Promise<import("../database/record/index.js").default | null>} Existing record or null.
620
671
  */
621
672
  async findSyncRecord({ability = this.ability, forDelete = false, mutation}) {
622
- const ModelClass = this.modelClass()
673
+ const ModelClass = this.databaseModelClass()
623
674
  const primaryKey = ModelClass.primaryKey()
624
675
  const query = ability
625
676
  ? ModelClass.accessibleFor(this.syncAbilityAction(forDelete ? "destroy" : "update"), ability)
@@ -819,20 +870,20 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
819
870
  /**
820
871
  * Runs authorized query.
821
872
  * @param {FrontendModelResourceAction} action - Ability action.
822
- * @returns {import("../database/query/model-class-query.js").default<TModelClass>} - Authorized query.
873
+ * @returns {import("../database/query/model-class-query.js").default<TDatabaseModelClass>} - Authorized query.
823
874
  */
824
875
  authorizedQuery(action) {
825
876
  // Narrows the controller query to this resource's model class.
826
- return /** @type {import("../database/query/model-class-query.js").default<TModelClass>} */ (this.typedControllerInstance().frontendModelAbilityAuthorizedQuery(action))
877
+ return /** @type {import("../database/query/model-class-query.js").default<TDatabaseModelClass>} */ (this.typedControllerInstance().frontendModelAbilityAuthorizedQuery(action))
827
878
  }
828
879
 
829
880
  /**
830
881
  * Runs index query.
831
882
  * @param {FrontendModelResourceIndexQueryOptions} [options] - Query options.
832
- * @returns {import("../database/query/model-class-query.js").default<TModelClass>} - Frontend-model index query.
883
+ * @returns {import("../database/query/model-class-query.js").default<TDatabaseModelClass>} - Frontend-model index query.
833
884
  */
834
885
  indexQuery(options = {}) {
835
- return /** @type {import("../database/query/model-class-query.js").default<TModelClass>} */ (this.typedControllerInstance().frontendModelIndexQuery({
886
+ return /** @type {import("../database/query/model-class-query.js").default<TDatabaseModelClass>} */ (this.typedControllerInstance().frontendModelIndexQuery({
836
887
  ...options,
837
888
  resource: this
838
889
  }))
@@ -961,8 +1012,8 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
961
1012
  const normalizedAttributes = await this.normalizeCreateAttributes(attributes, options)
962
1013
  const attachmentSplit = this._extractAttachmentAttributes(normalizedAttributes, options.attachments ?? null)
963
1014
  const permit = parsePermittedParams(this.permittedParams({action: "create", ability: this.ability, locals: this.locals, params: normalizedAttributes}))
964
- const ModelClass = this.modelClass()
965
- const filtered = filterWritableFrontendModelAttributes(this.modelClass().prototype, ModelClass, attachmentSplit.attributes, this, permit.attributes)
1015
+ const ModelClass = this.databaseModelClass()
1016
+ const filtered = filterWritableFrontendModelAttributes(ModelClass.prototype, ModelClass, attachmentSplit.attributes, this, permit.attributes)
966
1017
  const model = new ModelClass()
967
1018
 
968
1019
  return await this.runMutationTransaction({
@@ -1021,7 +1072,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
1021
1072
  * @returns {Promise<import("../database/record/index.js").default>} - Saved model.
1022
1073
  */
1023
1074
  async _saveWithNestedAttributes({filtered, model, options, permit}) {
1024
- await this.modelClass().transaction(async () => {
1075
+ await this.databaseModelClass().transaction(async () => {
1025
1076
  await this._assignWithVirtualSetters(model, filtered)
1026
1077
  this._assignAttachments(model, options.attachments ?? null, permit.attributes)
1027
1078
 
@@ -1079,7 +1130,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
1079
1130
  * @returns {{attributes: Record<string, ReturnType<typeof JSON.parse>>, attachments: Record<string, ReturnType<typeof JSON.parse>> | null}} Attributes with attachment keys removed and merged attachment payload.
1080
1131
  */
1081
1132
  _extractAttachmentAttributes(attributes, attachments) {
1082
- const attachmentDefinitions = this.modelClass().getAttachmentsMap()
1133
+ const attachmentDefinitions = this.modelClass().attachmentDefinitions()
1083
1134
  const attachmentNames = new Set(Object.keys(attachmentDefinitions))
1084
1135
 
1085
1136
  if (attachmentNames.size === 0) return {attributes, attachments}
@@ -1272,7 +1323,8 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
1272
1323
  throw new Error(`No frontend-model resource registered for child model '${targetModelClass.getModelName()}' under relationship '${relationshipName}'.`)
1273
1324
  }
1274
1325
 
1275
- const childResource = new childResourceConfig.resourceClass({
1326
+ const ChildResource = frontendModelResourceInternalConstructor(childResourceConfig.resourceClass)
1327
+ const childResource = new ChildResource({
1276
1328
  ability: this.ability,
1277
1329
  controller,
1278
1330
  context: this.context || {},
@@ -1934,10 +1986,12 @@ function prototypeOwnerForMethod(instance, methodName) {
1934
1986
 
1935
1987
  /**
1936
1988
  * Runs filter writable frontend model attributes.
1989
+ * @template {FrontendModelResourceModelClass} ResourceModelClass
1990
+ * @template {typeof import("../database/record/index.js").default} ResourceDatabaseModelClass
1937
1991
  * @param {Record<string, ReturnType<typeof JSON.parse>>} receiver - Model instance or prototype.
1938
1992
  * @param {WritableAttributeReceiverClass} receiverClass - Static helper owner for the receiver.
1939
1993
  * @param {Record<string, ReturnType<typeof JSON.parse>>} attributes - Incoming frontend-model attributes.
1940
- * @param {FrontendModelBaseResource | null} [resource] - Resource instance for virtual-setter detection.
1994
+ * @param {FrontendModelBaseResource<ResourceModelClass, ResourceDatabaseModelClass> | null} [resource] - Resource instance for virtual-setter detection.
1941
1995
  * @param {string[] | null} [permittedAttributeNames] - Optional explicit permit list. `null` falls back to setter-existence checks only.
1942
1996
  * @returns {Record<string, ReturnType<typeof JSON.parse>>} - Writable attributes only.
1943
1997
  */
@@ -1945,7 +1999,7 @@ function filterWritableFrontendModelAttributes(
1945
1999
  receiver,
1946
2000
  receiverClass,
1947
2001
  attributes,
1948
- resource = /** @type {FrontendModelBaseResource | null} */ (null),
2002
+ resource = /** @type {FrontendModelBaseResource<ResourceModelClass, ResourceDatabaseModelClass> | null} */ (null),
1949
2003
  permittedAttributeNames = null
1950
2004
  ) {
1951
2005
  // Frontend-model writes should fail fast when callers submit read-only or unknown attrs.
@@ -66,7 +66,7 @@ import {readPayloadAssociationCount, readPayloadComputedAbility, readPayloadQuer
66
66
  */
67
67
  /**
68
68
  * Defines this typedef.
69
- * @typedef {{type: "hasOne" | "hasMany"}} FrontendModelAttachmentDefinition
69
+ * @typedef {{sync?: import("../configuration-types.js").AttachmentSyncConfiguration, type: "hasOne" | "hasMany"}} FrontendModelAttachmentDefinition
70
70
  */
71
71
  /**
72
72
  * Defines frontend-model attribute metadata.
@@ -1,3 +1,11 @@
1
+ export type AuthorizationResourceModelClass = {
2
+ new (): import("../database/record/index.js").default | import("../frontend-models/base.js").default;
3
+ getModelName: () => string;
4
+ };
5
+ /**
6
+ * Model class supported by authorization and shared frontend-model resources.
7
+ * @typedef {{new (): import("../database/record/index.js").default | import("../frontend-models/base.js").default, getModelName: () => string}} AuthorizationResourceModelClass
8
+ */
1
9
  /** Base class for authorization resources defining abilities for a model. */
2
10
  export default class AuthorizationBaseResource {
3
11
  ability: import("./ability.js").default | undefined;
@@ -5,8 +13,8 @@ export default class AuthorizationBaseResource {
5
13
  locals: import("../configuration-types.js").VelociousLooseObject;
6
14
  /**
7
15
  * Model class.
8
- * @type {typeof import("../database/record/index.js").default | undefined} */
9
- static ModelClass: typeof import("../database/record/index.js").default | undefined;
16
+ * @type {AuthorizationResourceModelClass | undefined} */
17
+ static ModelClass: AuthorizationResourceModelClass | undefined;
10
18
  /**
11
19
  * Runs constructor.
12
20
  * @param {object} args - Resource args.
@@ -21,9 +29,14 @@ export default class AuthorizationBaseResource {
21
29
  });
22
30
  /**
23
31
  * Runs model class.
24
- * @returns {typeof import("../database/record/index.js").default} - Model class handled by this resource.
32
+ * @template {AuthorizationResourceModelClass} TModelClass
33
+ * @this {{ModelClass: TModelClass | undefined, name: string}}
34
+ * @returns {TModelClass} - Model class handled by this resource.
25
35
  */
26
- static modelClass(): typeof import("../database/record/index.js").default;
36
+ static modelClass<TModelClass extends AuthorizationResourceModelClass>(this: {
37
+ ModelClass: TModelClass | undefined;
38
+ name: string;
39
+ }): TModelClass;
27
40
  /**
28
41
  * Runs can.
29
42
  * @template {typeof import("../database/record/index.js").default} MC
@@ -47,9 +60,9 @@ export default class AuthorizationBaseResource {
47
60
  requiredAbility(): import("./ability.js").default;
48
61
  /**
49
62
  * Runs required model class.
50
- * @returns {typeof import("../database/record/index.js").default} - Model class handled by this resource.
63
+ * @returns {AuthorizationResourceModelClass} - Model class handled by this resource.
51
64
  */
52
- requiredModelClass(): typeof import("../database/record/index.js").default;
65
+ requiredModelClass(): AuthorizationResourceModelClass;
53
66
  /**
54
67
  * Runs assert resource conditions signature.
55
68
  * @param {object} args - Signature args.
@@ -1 +1 @@
1
- {"version":3,"file":"base-resource.d.ts","sourceRoot":"","sources":["../../../src/authorization/base-resource.js"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,MAAM,CAAC,OAAO,OAAO,yBAAyB;IAcrC,OAAO;IACP,OAAO;IACP,MAAM;IAfb;;kFAE8E;IAC9E,MAAM,CAAC,UAAU,EADP,cAAc,6BAA6B,EAAE,OAAO,GAAG,SAAS,CAC7C;IAE7B;;;;;;OAMG;IACH,YAAY,EAAC,OAAO,EAAE,OAAY,EAAE,MAAW,EAAC,EAJ7C;QAA8C,OAAO,AAArD,CACA,EADQ,OAAO,cAAc,EAAE,OAAO,CACtC;QAAwE,OAAO,AAA/E,CACA,EADQ,OAAO,2BAA2B,EAAE,oBAAoB,CAChE;QAAwE,MAAM,AAA9E,CACF,EADU,OAAO,2BAA2B,EAAE,oBAAoB,CAClE;KAC+C,EAI/C;IAED;;;OAGG;IACH,MAAM,CAAC,UAAU,IAFJ,cAAc,6BAA6B,EAAE,OAAO,CAQhE;IAED;;;;;;OAMG;IACH,GAAG,CALiE,EAAE,SAAxD,cAAc,6BAA6B,EAAE,OAAW,EAKlE,OAAO,EAJA,MAAM,GAAG,MAAM,EAIf,EAAE,UAAU,AAHpB,CACA,EADQ,OAAO,cAAc,EAAE,qBAAqB,CAAC,EAAE,CAGnC,GAFV,IAAI,CAKhB;IAED;;;;;;OAMG;IACH,MAAM,CAL8D,EAAE,SAAxD,cAAc,6BAA6B,EAAE,OAAW,EAK/D,OAAO,EAJH,MAAM,GAAG,MAAM,EAIZ,EAAE,UAAU,AAHvB,CACA,EADQ,OAAO,cAAc,EAAE,qBAAqB,CAAC,EAAE,CAGhC,GAFb,IAAI,CAKhB;IAED;;;OAGG;IACH,eAAe,IAFF,OAAO,cAAc,EAAE,OAAO,CAQ1C;IAED;;;OAGG;IACH,kBAAkB,IAFL,cAAc,6BAA6B,EAAE,OAAO,CAMhE;IAED;;;;;;OAMG;IACH,iCAAiC,CAAC,EAAC,UAAU,EAAE,UAAU,EAAC,EAJvD;QAA4C,UAAU,EAA9C,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACrC;QAA+B,UAAU,EAAjC,KAAK,GAAG,QAAQ,CACxB;KAEuD,GAF7C,IAAI,CAMhB;IAED;;;OAGG;IACH,UAAU,IAFG,OAAO,2BAA2B,EAAE,oBAAoB,CAIpE;IAED;;;OAGG;IACH,SAAS,IAFI,OAAO,2BAA2B,EAAE,oBAAoB,CAIpE;IAED;;;OAGG;IACH,WAAW,IAFE,OAAO,CAInB;IAED;;;OAGG;IACH,aAAa,IAFA,OAAO,CAInB;IAED;;;OAGG;IACH,YAAY,IAFC,OAAO,CAInB;IAED;;;OAGG;IACH,GAAG,IAFU,IAAI,CAOhB;IAED;;;OAGG;IACH,eAAe,IAFF,SAAS,GAAG,UAAU,GAAG,SAAS,CAO9C;IAED;;;OAGG;IACH,SAAS,IAFI,OAAO,CAInB;IAED;;;OAGG;IACH,UAAU,IAFG,OAAO,CAInB;IAED;;;OAGG;IACH,SAAS,IAFI,OAAO,CAInB;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAHC,MAGD,GAFG,OAAO,CAgCnB;IAED;;;OAGG;IACH,OAAO,IAFM,OAAO,kCAAkC,EAAE,OAAO,GAAG,OAAO,4CAA4C,EAAE,OAAO,GAAG,SAAS,CAIzI;IAED;;;OAGG;IACH,MAAM,IAFO,OAAO,2BAA2B,EAAE,eAAe,GAAG,SAAS,CAI3E;IAED;;;OAGG;IACH,SAAS,IAFI,IAAI,CAIhB;CACF"}
1
+ {"version":3,"file":"base-resource.d.ts","sourceRoot":"","sources":["../../../src/authorization/base-resource.js"],"names":[],"mappings":"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"}
@@ -1,9 +1,13 @@
1
1
  // @ts-check
2
+ /**
3
+ * Model class supported by authorization and shared frontend-model resources.
4
+ * @typedef {{new (): import("../database/record/index.js").default | import("../frontend-models/base.js").default, getModelName: () => string}} AuthorizationResourceModelClass
5
+ */
2
6
  /** Base class for authorization resources defining abilities for a model. */
3
7
  export default class AuthorizationBaseResource {
4
8
  /**
5
9
  * Model class.
6
- * @type {typeof import("../database/record/index.js").default | undefined} */
10
+ * @type {AuthorizationResourceModelClass | undefined} */
7
11
  static ModelClass = undefined;
8
12
  /**
9
13
  * Runs constructor.
@@ -19,7 +23,9 @@ export default class AuthorizationBaseResource {
19
23
  }
20
24
  /**
21
25
  * Runs model class.
22
- * @returns {typeof import("../database/record/index.js").default} - Model class handled by this resource.
26
+ * @template {AuthorizationResourceModelClass} TModelClass
27
+ * @this {{ModelClass: TModelClass | undefined, name: string}}
28
+ * @returns {TModelClass} - Model class handled by this resource.
23
29
  */
24
30
  static modelClass() {
25
31
  if (!this.ModelClass) {
@@ -36,7 +42,9 @@ export default class AuthorizationBaseResource {
36
42
  */
37
43
  can(actions, conditions) {
38
44
  this.assertResourceConditionsSignature({ conditions, methodName: "can" });
39
- this.requiredAbility().can(actions, this.requiredModelClass(), /** @type {import("./ability.js").AbilityConditionsType<typeof import("../database/record/index.js").default> | undefined} */ (conditions));
45
+ // Authorization query rules are backend-only even when a shared resource is bound to a frontend model.
46
+ const modelClass = /** @type {typeof import("../database/record/index.js").default} */ (this.requiredModelClass());
47
+ this.requiredAbility().can(actions, modelClass, /** @type {import("./ability.js").AbilityConditionsType<typeof import("../database/record/index.js").default> | undefined} */ (conditions));
40
48
  }
41
49
  /**
42
50
  * Runs cannot.
@@ -47,7 +55,9 @@ export default class AuthorizationBaseResource {
47
55
  */
48
56
  cannot(actions, conditions) {
49
57
  this.assertResourceConditionsSignature({ conditions, methodName: "cannot" });
50
- this.requiredAbility().cannot(actions, this.requiredModelClass(), /** @type {import("./ability.js").AbilityConditionsType<typeof import("../database/record/index.js").default> | undefined} */ (conditions));
58
+ // Authorization query rules are backend-only even when a shared resource is bound to a frontend model.
59
+ const modelClass = /** @type {typeof import("../database/record/index.js").default} */ (this.requiredModelClass());
60
+ this.requiredAbility().cannot(actions, modelClass, /** @type {import("./ability.js").AbilityConditionsType<typeof import("../database/record/index.js").default> | undefined} */ (conditions));
51
61
  }
52
62
  /**
53
63
  * Runs required ability.
@@ -61,7 +71,7 @@ export default class AuthorizationBaseResource {
61
71
  }
62
72
  /**
63
73
  * Runs required model class.
64
- * @returns {typeof import("../database/record/index.js").default} - Model class handled by this resource.
74
+ * @returns {AuthorizationResourceModelClass} - Model class handled by this resource.
65
75
  */
66
76
  requiredModelClass() {
67
77
  const ResourceClass = /** @type {typeof AuthorizationBaseResource} */ (this.constructor);
@@ -209,4 +219,4 @@ export default class AuthorizationBaseResource {
209
219
  // No-op by default.
210
220
  }
211
221
  }
212
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1yZXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdXRob3JpemF0aW9uL2Jhc2UtcmVzb3VyY2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLDZFQUE2RTtBQUM3RSxNQUFNLENBQUMsT0FBTyxPQUFPLHlCQUF5QjtJQUM1Qzs7a0ZBRThFO0lBQzlFLE1BQU0sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFBO0lBRTdCOzs7Ozs7T0FNRztJQUNILFlBQVksRUFBQyxPQUFPLEVBQUUsT0FBTyxHQUFHLEVBQUUsRUFBRSxNQUFNLEdBQUcsRUFBRSxFQUFDO1FBQzlDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO1FBQ3RCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO0lBQ3RCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxNQUFNLENBQUMsVUFBVTtRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLGdFQUFnRSxDQUFDLENBQUE7UUFDL0YsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQTtJQUN4QixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsR0FBRyxDQUFDLE9BQU8sRUFBRSxVQUFVO1FBQ3JCLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxFQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQTtRQUN2RSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRSw2SEFBNkgsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUE7SUFDNU0sQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FB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ekgsQ0FBQztJQUVEOzs7T0FHRztJQUNILE9BQU87UUFDTCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFBO0lBQzdCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxNQUFNO1FBQ0osT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQTtJQUM1QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsU0FBUztRQUNQLG9CQUFvQjtJQUN0QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuLyoqIEJhc2UgY2xhc3MgZm9yIGF1dGhvcml6YXRpb24gcmVzb3VyY2VzIGRlZmluaW5nIGFiaWxpdGllcyBmb3IgYSBtb2RlbC4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEF1dGhvcml6YXRpb25CYXNlUmVzb3VyY2Uge1xuICAvKipcbiAgICogTW9kZWwgY2xhc3MuXG4gICAqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9ICovXG4gIHN0YXRpYyBNb2RlbENsYXNzID0gdW5kZWZpbmVkXG5cbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gUmVzb3VyY2UgYXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2FiaWxpdHkuanNcIikuZGVmYXVsdH0gW2FyZ3MuYWJpbGl0eV0gLSBBYmlsaXR5IGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuVmVsb2Npb3VzTG9vc2VPYmplY3R9IFthcmdzLmNvbnRleHRdIC0gQWJpbGl0eSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuVmVsb2Npb3VzTG9vc2VPYmplY3R9IFthcmdzLmxvY2Fsc10gLSBBYmlsaXR5IGxvY2Fscy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHthYmlsaXR5LCBjb250ZXh0ID0ge30sIGxvY2FscyA9IHt9fSkge1xuICAgIHRoaXMuYWJpbGl0eSA9IGFiaWxpdHlcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0XG4gICAgdGhpcy5sb2NhbHMgPSBsb2NhbHNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1vZGVsIGNsYXNzLlxuICAgKiBAcmV0dXJucyB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAtIE1vZGVsIGNsYXNzIGhhbmRsZWQgYnkgdGhpcyByZXNvdXJjZS5cbiAgICovXG4gIHN0YXRpYyBtb2RlbENsYXNzKCkge1xuICAgIGlmICghdGhpcy5Nb2RlbENsYXNzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5uYW1lfSBtdXN0IGRlZmluZSBzdGF0aWMgTW9kZWxDbGFzcyBiZWZvcmUgY2FsbGluZyBhYmlsaXR5IGhlbHBlcnMuYClcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5Nb2RlbENsYXNzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjYW4uXG4gICAqIEB0ZW1wbGF0ZSB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBNQ1xuICAgKiBAcGFyYW0ge3N0cmluZyB8IHN0cmluZ1tdfSBhY3Rpb25zIC0gQWJpbGl0eSBhY3Rpb24ocykuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9hYmlsaXR5LmpzXCIpLkFiaWxpdHlDb25kaXRpb25zVHlwZTxNQz59IFtjb25kaXRpb25zXSAtIENvbmRpdGlvbnMuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGNhbihhY3Rpb25zLCBjb25kaXRpb25zKSB7XG4gICAgdGhpcy5hc3NlcnRSZXNvdXJjZUNvbmRpdGlvbnNTaWduYXR1cmUoe2NvbmRpdGlvbnMsIG1ldGhvZE5hbWU6IFwiY2FuXCJ9KVxuICAgIHRoaXMucmVxdWlyZWRBYmlsaXR5KCkuY2FuKGFjdGlvbnMsIHRoaXMucmVxdWlyZWRNb2RlbENsYXNzKCksIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9hYmlsaXR5LmpzXCIpLkFiaWxpdHlDb25kaXRpb25zVHlwZTx0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+IHwgdW5kZWZpbmVkfSAqLyAoY29uZGl0aW9ucykpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjYW5ub3QuXG4gICAqIEB0ZW1wbGF0ZSB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBNQ1xuICAgKiBAcGFyYW0ge3N0cmluZyB8IHN0cmluZ1tdfSBhY3Rpb25zIC0gQWJpbGl0eSBhY3Rpb24ocykuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9hYmlsaXR5LmpzXCIpLkFiaWxpdHlDb25kaXRpb25zVHlwZTxNQz59IFtjb25kaXRpb25zXSAtIENvbmRpdGlvbnMuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGNhbm5vdChhY3Rpb25zLCBjb25kaXRpb25zKSB7XG4gICAgdGhpcy5hc3NlcnRSZXNvdXJjZUNvbmRpdGlvbnNTaWduYXR1cmUoe2NvbmRpdGlvbnMsIG1ldGhvZE5hbWU6IFwiY2Fubm90XCJ9KVxuICAgIHRoaXMucmVxdWlyZWRBYmlsaXR5KCkuY2Fubm90KGFjdGlvbnMsIHRoaXMucmVxdWlyZWRNb2RlbENsYXNzKCksIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9hYmlsaXR5LmpzXCIpLkFiaWxpdHlDb25kaXRpb25zVHlwZTx0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+IHwgdW5kZWZpbmVkfSAqLyAoY29uZGl0aW9ucykpXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZXF1aXJlZCBhYmlsaXR5LlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9hYmlsaXR5LmpzXCIpLmRlZmF1bHR9IC0gQWJpbGl0eSBpbnN0YW5jZS5cbiAgICovXG4gIHJlcXVpcmVkQWJpbGl0eSgpIHtcbiAgICBpZiAoIXRoaXMuYWJpbGl0eSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gcmVxdWlyZXMgYW4gYWJpbGl0eSBpbnN0YW5jZSBiZWZvcmUgZGVmaW5pbmcgYWJpbGl0aWVzLmApXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWJpbGl0eVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVxdWlyZWQgbW9kZWwgY2xhc3MuXG4gICAqIEByZXR1cm5zIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IC0gTW9kZWwgY2xhc3MgaGFuZGxlZCBieSB0aGlzIHJlc291cmNlLlxuICAgKi9cbiAgcmVxdWlyZWRNb2RlbENsYXNzKCkge1xuICAgIGNvbnN0IFJlc291cmNlQ2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBBdXRob3JpemF0aW9uQmFzZVJlc291cmNlfSAqLyAodGhpcy5jb25zdHJ1Y3RvcilcblxuICAgIHJldHVybiBSZXNvdXJjZUNsYXNzLm1vZGVsQ2xhc3MoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXNzZXJ0IHJlc291cmNlIGNvbmRpdGlvbnMgc2lnbmF0dXJlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFNpZ25hdHVyZSBhcmdzLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhcmdzLmNvbmRpdGlvbnMgLSBDb25kaXRpb25zIHZhbHVlLlxuICAgKiBAcGFyYW0ge1wiY2FuXCIgfCBcImNhbm5vdFwifSBhcmdzLm1ldGhvZE5hbWUgLSBNZXRob2QgbmFtZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhc3NlcnRSZXNvdXJjZUNvbmRpdGlvbnNTaWduYXR1cmUoe2NvbmRpdGlvbnMsIG1ldGhvZE5hbWV9KSB7XG4gICAgaWYgKHR5cGVvZiBjb25kaXRpb25zID09PSBcImZ1bmN0aW9uXCIgJiYgXCJwcmltYXJ5S2V5XCIgaW4gY29uZGl0aW9ucyAmJiBcIl9uZXdRdWVyeVwiIGluIGNvbmRpdGlvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9LiR7bWV0aG9kTmFtZX0oLi4uKSBubyBsb25nZXIgYWNjZXB0cyBhIG1vZGVsIGNsYXNzLiBEZWZpbmUgc3RhdGljIE1vZGVsQ2xhc3MgYW5kIHBhc3Mgb25seSBjb25kaXRpb25zLmApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLlZlbG9jaW91c0xvb3NlT2JqZWN0fSAtIEFiaWxpdHkgY29udGV4dC5cbiAgICovXG4gIGdldENvbnRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGxvY2Fscy5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuVmVsb2Npb3VzTG9vc2VPYmplY3R9IC0gQWJpbGl0eSBsb2NhbHMuXG4gICAqL1xuICBnZXRMb2NhbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9jYWxzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjdXJyZW50IHVzZXIuXG4gICAqIEByZXR1cm5zIHt1bmtub3dufSAtIEN1cnJlbnQgdXNlciBmcm9tIGNvbnRleHQuXG4gICAqL1xuICBjdXJyZW50VXNlcigpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0LmN1cnJlbnRVc2VyXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjdXJyZW50IGRldmljZS5cbiAgICogQHJldHVybnMge3Vua25vd259IC0gQ3VycmVudCBkZXZpY2UgZnJvbSBjb250ZXh0LlxuICAgKi9cbiAgY3VycmVudERldmljZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0LmN1cnJlbnREZXZpY2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG9mZmxpbmUgZ3JhbnQuXG4gICAqIEByZXR1cm5zIHt1bmtub3dufSAtIE9mZmxpbmUgZ3JhbnQgZnJvbSBjb250ZXh0LlxuICAgKi9cbiAgb2ZmbGluZUdyYW50KCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQub2ZmbGluZUdyYW50XG4gIH1cblxuICAvKipcbiAgICogUnVucyBub3cuXG4gICAqIEByZXR1cm5zIHtEYXRlfSAtIEN1cnJlbnQgdGltZSBmcm9tIGNvbnRleHQgb3IgdGhlIHN5c3RlbSBjbG9jay5cbiAgICovXG4gIG5vdygpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuY29udGV4dC5ub3cgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRoaXMuY29udGV4dC5ub3coKVxuICAgIGlmICh0aGlzLmNvbnRleHQubm93IGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIHRoaXMuY29udGV4dC5ub3dcblxuICAgIHJldHVybiBuZXcgRGF0ZSgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZXNvdXJjZSBydW50aW1lLlxuICAgKiBAcmV0dXJucyB7XCJiYWNrZW5kXCIgfCBcImZyb250ZW5kXCIgfCBcIm9mZmxpbmVcIn0gLSBSZXNvdXJjZSBydW50aW1lIGNvbnRleHQuXG4gICAqL1xuICByZXNvdXJjZVJ1bnRpbWUoKSB7XG4gICAgaWYgKHRoaXMuY29udGV4dC5yZXNvdXJjZVJ1bnRpbWUgPT09IFwiZnJvbnRlbmRcIikgcmV0dXJuIFwiZnJvbnRlbmRcIlxuICAgIGlmICh0aGlzLmNvbnRleHQucmVzb3VyY2VSdW50aW1lID09PSBcIm9mZmxpbmVcIikgcmV0dXJuIFwib2ZmbGluZVwiXG5cbiAgICByZXR1cm4gXCJiYWNrZW5kXCJcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGlzIGJhY2tlbmQuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIHJlc291cmNlIGlzIHJ1bm5pbmcgaW4gdGhlIGJhY2tlbmQgcnVudGltZS5cbiAgICovXG4gIGlzQmFja2VuZCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvdXJjZVJ1bnRpbWUoKSA9PT0gXCJiYWNrZW5kXCJcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGlzIGZyb250ZW5kLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSByZXNvdXJjZSBpcyBydW5uaW5nIGluIHRoZSBmcm9udGVuZCBydW50aW1lLlxuICAgKi9cbiAgaXNGcm9udGVuZCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvdXJjZVJ1bnRpbWUoKSA9PT0gXCJmcm9udGVuZFwiXG4gIH1cblxuICAvKipcbiAgICogUnVucyBpcyBvZmZsaW5lLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSByZXNvdXJjZSBpcyBydW5uaW5nIHdpdGggb2ZmbGluZSBjb250ZXh0LlxuICAgKi9cbiAgaXNPZmZsaW5lKCkge1xuICAgIHJldHVybiB0aGlzLnJlc291cmNlUnVudGltZSgpID09PSBcIm9mZmxpbmVcIiB8fCB0aGlzLmNvbnRleHQub2ZmbGluZUdyYW50ICE9PSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIG1vZGVsIGNsYXNzIGZyb20gdGhlIHBvcnRhYmxlIHJlc291cmNlIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTW9kZWwgbmFtZS5cbiAgICogQHJldHVybnMge3Vua25vd259IC0gTW9kZWwgY2xhc3MgZnJvbSByZWdpc3RyeS5cbiAgICovXG4gIG1vZGVsKG5hbWUpIHtcbiAgICBjb25zdCByZWdpc3RyeSA9IHRoaXMuY29udGV4dC5tb2RlbFJlZ2lzdHJ5XG5cbiAgICBpZiAocmVnaXN0cnkgJiYgdHlwZW9mIHJlZ2lzdHJ5ID09PSBcIm9iamVjdFwiKSB7XG4gICAgICBpZiAoXCJtb2RlbFwiIGluIHJlZ2lzdHJ5ICYmIHR5cGVvZiByZWdpc3RyeS5tb2RlbCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSByZWdpc3RyeS5tb2RlbChuYW1lKVxuXG4gICAgICAgIGlmIChtb2RlbENsYXNzKSByZXR1cm4gbW9kZWxDbGFzc1xuICAgICAgfVxuXG4gICAgICBpZiAobmFtZSBpbiByZWdpc3RyeSkgcmV0dXJuIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59ICovIChyZWdpc3RyeSlbbmFtZV1cbiAgICB9XG5cbiAgICBjb25zdCBjb250ZXh0TW9kZWwgPSB0aGlzLmNvbnRleHQubW9kZWxcblxuICAgIGlmICh0eXBlb2YgY29udGV4dE1vZGVsID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSBjb250ZXh0TW9kZWwobmFtZSlcblxuICAgICAgaWYgKG1vZGVsQ2xhc3MpIHJldHVybiBtb2RlbENsYXNzXG4gICAgfVxuXG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IHRoaXMuY29udGV4dC5jb25maWd1cmF0aW9uXG5cbiAgICBpZiAoY29uZmlndXJhdGlvbikge1xuICAgICAgY29uc3QgbW9kZWxDbGFzc2VzID0gY29uZmlndXJhdGlvbi5nZXRNb2RlbENsYXNzZXMoKVxuXG4gICAgICBpZiAobmFtZSBpbiBtb2RlbENsYXNzZXMpIHJldHVybiBtb2RlbENsYXNzZXNbbmFtZV1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfSBjb3VsZCBub3QgcmVzb2x2ZSBtb2RlbCAnJHtuYW1lfScgZnJvbSB0aGUgcmVzb3VyY2UgY29udGV4dCBtb2RlbCByZWdpc3RyeS5gKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVxdWVzdC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2h0dHAtc2VydmVyL2NsaWVudC9yZXF1ZXN0LmpzXCIpLmRlZmF1bHQgfCBpbXBvcnQoXCIuLi9odHRwLXNlcnZlci9jbGllbnQvd2Vic29ja2V0LXJlcXVlc3QuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBSZXF1ZXN0IGZyb20gY29udGV4dC5cbiAgICovXG4gIHJlcXVlc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dC5yZXF1ZXN0XG4gIH1cblxuICAvKipcbiAgICogUnVucyBwYXJhbXMuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLlZlbG9jaW91c1BhcmFtcyB8IHVuZGVmaW5lZH0gLSBQYXJhbXMgZnJvbSBjb250ZXh0LlxuICAgKi9cbiAgcGFyYW1zKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQucGFyYW1zXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhYmlsaXRpZXMuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIEltcGxlbWVudCBpbiBzdWJjbGFzc2VzIHRvIGRlZmluZSBhYmlsaXRpZXMuXG4gICAqL1xuICBhYmlsaXRpZXMoKSB7XG4gICAgLy8gTm8tb3AgYnkgZGVmYXVsdC5cbiAgfVxufVxuIl19
222
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1yZXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdXRob3JpemF0aW9uL2Jhc2UtcmVzb3VyY2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaOzs7R0FHRztBQUVILDZFQUE2RTtBQUM3RSxNQUFNLENBQUMsT0FBTyxPQUFPLHlCQUF5QjtJQUM1Qzs7NkRBRXlEO0lBQ3pELE1BQU0sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFBO0lBRTdCOzs7Ozs7T0FNRztJQUNILFlBQVksRUFBQyxPQUFPLEVBQUUsT0FBTyxHQUFHLEVBQUUsRUFBRSxNQUFNLEdBQUcsRUFBRSxFQUFDO1FBQzlDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO1FBQ3RCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO0lBQ3RCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxVQUFVO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksZ0VBQWdFLENBQUMsQ0FBQTtRQUMvRixDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFBO0lBQ3hCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxHQUFHLENBQUMsT0FBTyxFQUFFLFVBQVU7UUFDckIsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLEVBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFBO1FBQ3ZFLHVHQUF1RztRQUN2RyxNQUFNLFVBQVUsR0FBRyxtRUFBbUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUE7UUFFbEgsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsVUFBVSxF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SSxJQUFJLFlBQVk7Z0JBQUUsT0FBTyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDckQsQ0FBQztRQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksNkJBQTZCLElBQUksNkNBQTZDLENBQUMsQ0FBQTtJQUN6SCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsT0FBTztRQUNMLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUE7SUFDN0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU07UUFDSixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFBO0lBQzVCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxTQUFTO1FBQ1Asb0JBQW9CO0lBQ3RCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG4vKipcbiAqIE1vZGVsIGNsYXNzIHN1cHBvcnRlZCBieSBhdXRob3JpemF0aW9uIGFuZCBzaGFyZWQgZnJvbnRlbmQtbW9kZWwgcmVzb3VyY2VzLlxuICogQHR5cGVkZWYge3tuZXcgKCk6IGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgaW1wb3J0KFwiLi4vZnJvbnRlbmQtbW9kZWxzL2Jhc2UuanNcIikuZGVmYXVsdCwgZ2V0TW9kZWxOYW1lOiAoKSA9PiBzdHJpbmd9fSBBdXRob3JpemF0aW9uUmVzb3VyY2VNb2RlbENsYXNzXG4gKi9cblxuLyoqIEJhc2UgY2xhc3MgZm9yIGF1dGhvcml6YXRpb24gcmVzb3VyY2VzIGRlZmluaW5nIGFiaWxpdGllcyBmb3IgYSBtb2RlbC4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEF1dGhvcml6YXRpb25CYXNlUmVzb3VyY2Uge1xuICAvKipcbiAgICogTW9kZWwgY2xhc3MuXG4gICAqIEB0eXBlIHtBdXRob3JpemF0aW9uUmVzb3VyY2VNb2RlbENsYXNzIHwgdW5kZWZpbmVkfSAqL1xuICBzdGF0aWMgTW9kZWxDbGFzcyA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFJlc291cmNlIGFyZ3MuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9hYmlsaXR5LmpzXCIpLmRlZmF1bHR9IFthcmdzLmFiaWxpdHldIC0gQWJpbGl0eSBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLlZlbG9jaW91c0xvb3NlT2JqZWN0fSBbYXJncy5jb250ZXh0XSAtIEFiaWxpdHkgY29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLlZlbG9jaW91c0xvb3NlT2JqZWN0fSBbYXJncy5sb2NhbHNdIC0gQWJpbGl0eSBsb2NhbHMuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7YWJpbGl0eSwgY29udGV4dCA9IHt9LCBsb2NhbHMgPSB7fX0pIHtcbiAgICB0aGlzLmFiaWxpdHkgPSBhYmlsaXR5XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dFxuICAgIHRoaXMubG9jYWxzID0gbG9jYWxzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBtb2RlbCBjbGFzcy5cbiAgICogQHRlbXBsYXRlIHtBdXRob3JpemF0aW9uUmVzb3VyY2VNb2RlbENsYXNzfSBUTW9kZWxDbGFzc1xuICAgKiBAdGhpcyB7e01vZGVsQ2xhc3M6IFRNb2RlbENsYXNzIHwgdW5kZWZpbmVkLCBuYW1lOiBzdHJpbmd9fVxuICAgKiBAcmV0dXJucyB7VE1vZGVsQ2xhc3N9IC0gTW9kZWwgY2xhc3MgaGFuZGxlZCBieSB0aGlzIHJlc291cmNlLlxuICAgKi9cbiAgc3RhdGljIG1vZGVsQ2xhc3MoKSB7XG4gICAgaWYgKCF0aGlzLk1vZGVsQ2xhc3MpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5hbWV9IG11c3QgZGVmaW5lIHN0YXRpYyBNb2RlbENsYXNzIGJlZm9yZSBjYWxsaW5nIGFiaWxpdHkgaGVscGVycy5gKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLk1vZGVsQ2xhc3NcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNhbi5cbiAgICogQHRlbXBsYXRlIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IE1DXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGFjdGlvbnMgLSBBYmlsaXR5IGFjdGlvbihzKS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2FiaWxpdHkuanNcIikuQWJpbGl0eUNvbmRpdGlvbnNUeXBlPE1DPn0gW2NvbmRpdGlvbnNdIC0gQ29uZGl0aW9ucy5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgY2FuKGFjdGlvbnMsIGNvbmRpdGlvbnMpIHtcbiAgICB0aGlzLmFzc2VydFJlc291cmNlQ29uZGl0aW9uc1NpZ25hdHVyZSh7Y29uZGl0aW9ucywgbWV0aG9kTmFtZTogXCJjYW5cIn0pXG4gICAgLy8gQXV0aG9yaXphdGlvbiBxdWVyeSBydWxlcyBhcmUgYmFja2VuZC1vbmx5IGV2ZW4gd2hlbiBhIHNoYXJlZCByZXNvdXJjZSBpcyBib3VuZCB0byBhIGZyb250ZW5kIG1vZGVsLlxuICAgIGNvbnN0IG1vZGVsQ2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gKi8gKHRoaXMucmVxdWlyZWRNb2RlbENsYXNzKCkpXG5cbiAgICB0aGlzLnJlcXVpcmVkQWJpbGl0eSgpLmNhbihhY3Rpb25zLCBtb2RlbENsYXNzLCAvKiogQHR5cGUge2ltcG9ydChcIi4vYWJpbGl0eS5qc1wiKS5BYmlsaXR5Q29uZGl0aW9uc1R5cGU8dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0PiB8IHVuZGVmaW5lZH0gKi8gKGNvbmRpdGlvbnMpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY2Fubm90LlxuICAgKiBAdGVtcGxhdGUge3R5cGVvZiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gTUNcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBzdHJpbmdbXX0gYWN0aW9ucyAtIEFiaWxpdHkgYWN0aW9uKHMpLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYWJpbGl0eS5qc1wiKS5BYmlsaXR5Q29uZGl0aW9uc1R5cGU8TUM+fSBbY29uZGl0aW9uc10gLSBDb25kaXRpb25zLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBjYW5ub3QoYWN0aW9ucywgY29uZGl0aW9ucykge1xuICAgIHRoaXMuYXNzZXJ0UmVzb3VyY2VDb25kaXRpb25zU2lnbmF0dXJlKHtjb25kaXRpb25zLCBtZXRob2ROYW1lOiBcImNhbm5vdFwifSlcbiAgICAvLyBBdXRob3JpemF0aW9uIHF1ZXJ5IHJ1bGVzIGFyZSBiYWNrZW5kLW9ubHkgZXZlbiB3aGVuIGEgc2hhcmVkIHJlc291cmNlIGlzIGJvdW5kIHRvIGEgZnJvbnRlbmQgbW9kZWwuXG4gICAgY29uc3QgbW9kZWxDbGFzcyA9IC8qKiBAdHlwZSB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAqLyAodGhpcy5yZXF1aXJlZE1vZGVsQ2xhc3MoKSlcblxuICAgIHRoaXMucmVxdWlyZWRBYmlsaXR5KCkuY2Fubm90KGFjdGlvbnMsIG1vZGVsQ2xhc3MsIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9hYmlsaXR5LmpzXCIpLkFiaWxpdHlDb25kaXRpb25zVHlwZTx0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+IHwgdW5kZWZpbmVkfSAqLyAoY29uZGl0aW9ucykpXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZXF1aXJlZCBhYmlsaXR5LlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9hYmlsaXR5LmpzXCIpLmRlZmF1bHR9IC0gQWJpbGl0eSBpbnN0YW5jZS5cbiAgICovXG4gIHJlcXVpcmVkQWJpbGl0eSgpIHtcbiAgICBpZiAoIXRoaXMuYWJpbGl0eSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gcmVxdWlyZXMgYW4gYWJpbGl0eSBpbnN0YW5jZSBiZWZvcmUgZGVmaW5pbmcgYWJpbGl0aWVzLmApXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWJpbGl0eVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVxdWlyZWQgbW9kZWwgY2xhc3MuXG4gICAqIEByZXR1cm5zIHtBdXRob3JpemF0aW9uUmVzb3VyY2VNb2RlbENsYXNzfSAtIE1vZGVsIGNsYXNzIGhhbmRsZWQgYnkgdGhpcyByZXNvdXJjZS5cbiAgICovXG4gIHJlcXVpcmVkTW9kZWxDbGFzcygpIHtcbiAgICBjb25zdCBSZXNvdXJjZUNsYXNzID0gLyoqIEB0eXBlIHt0eXBlb2YgQXV0aG9yaXphdGlvbkJhc2VSZXNvdXJjZX0gKi8gKHRoaXMuY29uc3RydWN0b3IpXG5cbiAgICByZXR1cm4gUmVzb3VyY2VDbGFzcy5tb2RlbENsYXNzKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFzc2VydCByZXNvdXJjZSBjb25kaXRpb25zIHNpZ25hdHVyZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBTaWduYXR1cmUgYXJncy5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gYXJncy5jb25kaXRpb25zIC0gQ29uZGl0aW9ucyB2YWx1ZS5cbiAgICogQHBhcmFtIHtcImNhblwiIHwgXCJjYW5ub3RcIn0gYXJncy5tZXRob2ROYW1lIC0gTWV0aG9kIG5hbWUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXNzZXJ0UmVzb3VyY2VDb25kaXRpb25zU2lnbmF0dXJlKHtjb25kaXRpb25zLCBtZXRob2ROYW1lfSkge1xuICAgIGlmICh0eXBlb2YgY29uZGl0aW9ucyA9PT0gXCJmdW5jdGlvblwiICYmIFwicHJpbWFyeUtleVwiIGluIGNvbmRpdGlvbnMgJiYgXCJfbmV3UXVlcnlcIiBpbiBjb25kaXRpb25zKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfS4ke21ldGhvZE5hbWV9KC4uLikgbm8gbG9uZ2VyIGFjY2VwdHMgYSBtb2RlbCBjbGFzcy4gRGVmaW5lIHN0YXRpYyBNb2RlbENsYXNzIGFuZCBwYXNzIG9ubHkgY29uZGl0aW9ucy5gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5WZWxvY2lvdXNMb29zZU9iamVjdH0gLSBBYmlsaXR5IGNvbnRleHQuXG4gICAqL1xuICBnZXRDb250ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBsb2NhbHMuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLlZlbG9jaW91c0xvb3NlT2JqZWN0fSAtIEFiaWxpdHkgbG9jYWxzLlxuICAgKi9cbiAgZ2V0TG9jYWxzKCkge1xuICAgIHJldHVybiB0aGlzLmxvY2Fsc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3VycmVudCB1c2VyLlxuICAgKiBAcmV0dXJucyB7dW5rbm93bn0gLSBDdXJyZW50IHVzZXIgZnJvbSBjb250ZXh0LlxuICAgKi9cbiAgY3VycmVudFVzZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VXNlclxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3VycmVudCBkZXZpY2UuXG4gICAqIEByZXR1cm5zIHt1bmtub3dufSAtIEN1cnJlbnQgZGV2aWNlIGZyb20gY29udGV4dC5cbiAgICovXG4gIGN1cnJlbnREZXZpY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50RGV2aWNlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBvZmZsaW5lIGdyYW50LlxuICAgKiBAcmV0dXJucyB7dW5rbm93bn0gLSBPZmZsaW5lIGdyYW50IGZyb20gY29udGV4dC5cbiAgICovXG4gIG9mZmxpbmVHcmFudCgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0Lm9mZmxpbmVHcmFudFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbm93LlxuICAgKiBAcmV0dXJucyB7RGF0ZX0gLSBDdXJyZW50IHRpbWUgZnJvbSBjb250ZXh0IG9yIHRoZSBzeXN0ZW0gY2xvY2suXG4gICAqL1xuICBub3coKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmNvbnRleHQubm93ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0aGlzLmNvbnRleHQubm93KClcbiAgICBpZiAodGhpcy5jb250ZXh0Lm5vdyBpbnN0YW5jZW9mIERhdGUpIHJldHVybiB0aGlzLmNvbnRleHQubm93XG5cbiAgICByZXR1cm4gbmV3IERhdGUoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVzb3VyY2UgcnVudGltZS5cbiAgICogQHJldHVybnMge1wiYmFja2VuZFwiIHwgXCJmcm9udGVuZFwiIHwgXCJvZmZsaW5lXCJ9IC0gUmVzb3VyY2UgcnVudGltZSBjb250ZXh0LlxuICAgKi9cbiAgcmVzb3VyY2VSdW50aW1lKCkge1xuICAgIGlmICh0aGlzLmNvbnRleHQucmVzb3VyY2VSdW50aW1lID09PSBcImZyb250ZW5kXCIpIHJldHVybiBcImZyb250ZW5kXCJcbiAgICBpZiAodGhpcy5jb250ZXh0LnJlc291cmNlUnVudGltZSA9PT0gXCJvZmZsaW5lXCIpIHJldHVybiBcIm9mZmxpbmVcIlxuXG4gICAgcmV0dXJuIFwiYmFja2VuZFwiXG4gIH1cblxuICAvKipcbiAgICogUnVucyBpcyBiYWNrZW5kLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSByZXNvdXJjZSBpcyBydW5uaW5nIGluIHRoZSBiYWNrZW5kIHJ1bnRpbWUuXG4gICAqL1xuICBpc0JhY2tlbmQoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2VSdW50aW1lKCkgPT09IFwiYmFja2VuZFwiXG4gIH1cblxuICAvKipcbiAgICogUnVucyBpcyBmcm9udGVuZC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgcmVzb3VyY2UgaXMgcnVubmluZyBpbiB0aGUgZnJvbnRlbmQgcnVudGltZS5cbiAgICovXG4gIGlzRnJvbnRlbmQoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2VSdW50aW1lKCkgPT09IFwiZnJvbnRlbmRcIlxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaXMgb2ZmbGluZS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgcmVzb3VyY2UgaXMgcnVubmluZyB3aXRoIG9mZmxpbmUgY29udGV4dC5cbiAgICovXG4gIGlzT2ZmbGluZSgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvdXJjZVJ1bnRpbWUoKSA9PT0gXCJvZmZsaW5lXCIgfHwgdGhpcy5jb250ZXh0Lm9mZmxpbmVHcmFudCAhPT0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgYSBtb2RlbCBjbGFzcyBmcm9tIHRoZSBwb3J0YWJsZSByZXNvdXJjZSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE1vZGVsIG5hbWUuXG4gICAqIEByZXR1cm5zIHt1bmtub3dufSAtIE1vZGVsIGNsYXNzIGZyb20gcmVnaXN0cnkuXG4gICAqL1xuICBtb2RlbChuYW1lKSB7XG4gICAgY29uc3QgcmVnaXN0cnkgPSB0aGlzLmNvbnRleHQubW9kZWxSZWdpc3RyeVxuXG4gICAgaWYgKHJlZ2lzdHJ5ICYmIHR5cGVvZiByZWdpc3RyeSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgaWYgKFwibW9kZWxcIiBpbiByZWdpc3RyeSAmJiB0eXBlb2YgcmVnaXN0cnkubW9kZWwgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBjb25zdCBtb2RlbENsYXNzID0gcmVnaXN0cnkubW9kZWwobmFtZSlcblxuICAgICAgICBpZiAobW9kZWxDbGFzcykgcmV0dXJuIG1vZGVsQ2xhc3NcbiAgICAgIH1cblxuICAgICAgaWYgKG5hbWUgaW4gcmVnaXN0cnkpIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAocmVnaXN0cnkpW25hbWVdXG4gICAgfVxuXG4gICAgY29uc3QgY29udGV4dE1vZGVsID0gdGhpcy5jb250ZXh0Lm1vZGVsXG5cbiAgICBpZiAodHlwZW9mIGNvbnRleHRNb2RlbCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBjb25zdCBtb2RlbENsYXNzID0gY29udGV4dE1vZGVsKG5hbWUpXG5cbiAgICAgIGlmIChtb2RlbENsYXNzKSByZXR1cm4gbW9kZWxDbGFzc1xuICAgIH1cblxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbnRleHQuY29uZmlndXJhdGlvblxuXG4gICAgaWYgKGNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIGNvbnN0IG1vZGVsQ2xhc3NlcyA9IGNvbmZpZ3VyYXRpb24uZ2V0TW9kZWxDbGFzc2VzKClcblxuICAgICAgaWYgKG5hbWUgaW4gbW9kZWxDbGFzc2VzKSByZXR1cm4gbW9kZWxDbGFzc2VzW25hbWVdXG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gY291bGQgbm90IHJlc29sdmUgbW9kZWwgJyR7bmFtZX0nIGZyb20gdGhlIHJlc291cmNlIGNvbnRleHQgbW9kZWwgcmVnaXN0cnkuYClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJlcXVlc3QuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9odHRwLXNlcnZlci9jbGllbnQvcmVxdWVzdC5qc1wiKS5kZWZhdWx0IHwgaW1wb3J0KFwiLi4vaHR0cC1zZXJ2ZXIvY2xpZW50L3dlYnNvY2tldC1yZXF1ZXN0LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gUmVxdWVzdCBmcm9tIGNvbnRleHQuXG4gICAqL1xuICByZXF1ZXN0KCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQucmVxdWVzdFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5WZWxvY2lvdXNQYXJhbXMgfCB1bmRlZmluZWR9IC0gUGFyYW1zIGZyb20gY29udGV4dC5cbiAgICovXG4gIHBhcmFtcygpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0LnBhcmFtc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYWJpbGl0aWVzLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBJbXBsZW1lbnQgaW4gc3ViY2xhc3NlcyB0byBkZWZpbmUgYWJpbGl0aWVzLlxuICAgKi9cbiAgYWJpbGl0aWVzKCkge1xuICAgIC8vIE5vLW9wIGJ5IGRlZmF1bHQuXG4gIH1cbn1cbiJdfQ==
@@ -284,9 +284,10 @@ export default class BackgroundJobsMain {
284
284
  _generationOwnedHandoffSnapshot(): Promise<import("./types.js").BackgroundJobHandoffSnapshot[]>;
285
285
  /**
286
286
  * Acquires scheduling and dispatch ownership for an active generation.
287
- * @returns {Promise<void>} - Resolves after active ownership is established.
287
+ * @param {"active" | "candidate"} expectedLifecycleState - State that still owns activation.
288
+ * @returns {Promise<boolean>} - Whether active ownership was established.
288
289
  */
289
- _startActiveOwnership(): Promise<void>;
290
+ _startActiveOwnership(expectedLifecycleState: "active" | "candidate"): Promise<boolean>;
290
291
  /** Starts exact recovery duties without acquiring global dispatch ownership. */
291
292
  _startGenerationRecoveryOwnership(): void;
292
293
  /** Starts the generation-fenced orphan sweep. */