velocious 1.0.571 → 1.0.573
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/build/background-jobs/web/authorization.js +2 -33
- package/build/background-jobs/web/path-matcher.js +5 -30
- package/build/database/drivers/base.js +17 -0
- package/build/database/drivers/mssql/index.js +30 -0
- package/build/database/record/index.js +22 -10
- package/build/deployment-api/controller.js +437 -0
- package/build/deployment-api/index.js +210 -0
- package/build/deployment-api/path-matcher.js +45 -0
- package/build/deployment-api/registry.js +84 -0
- package/build/deployment-api/run-store.js +798 -0
- package/build/deployment-api/sanitize.js +114 -0
- package/build/http-client/request.js +3 -1
- package/build/src/background-jobs/web/authorization.d.ts.map +1 -1
- package/build/src/background-jobs/web/authorization.js +3 -29
- package/build/src/background-jobs/web/path-matcher.d.ts +2 -12
- package/build/src/background-jobs/web/path-matcher.d.ts.map +1 -1
- package/build/src/background-jobs/web/path-matcher.js +5 -30
- package/build/src/database/drivers/base.d.ts +16 -0
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +16 -1
- package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/index.js +29 -1
- package/build/src/database/record/index.d.ts +3 -2
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +21 -10
- package/build/src/deployment-api/controller.d.ts +117 -0
- package/build/src/deployment-api/controller.d.ts.map +1 -0
- package/build/src/deployment-api/controller.js +384 -0
- package/build/src/deployment-api/index.d.ts +46 -0
- package/build/src/deployment-api/index.d.ts.map +1 -0
- package/build/src/deployment-api/index.js +178 -0
- package/build/src/deployment-api/path-matcher.d.ts +31 -0
- package/build/src/deployment-api/path-matcher.d.ts.map +1 -0
- package/build/src/deployment-api/path-matcher.js +39 -0
- package/build/src/deployment-api/registry.d.ts +106 -0
- package/build/src/deployment-api/registry.d.ts.map +1 -0
- package/build/src/deployment-api/registry.js +74 -0
- package/build/src/deployment-api/run-store.d.ts +402 -0
- package/build/src/deployment-api/run-store.d.ts.map +1 -0
- package/build/src/deployment-api/run-store.js +711 -0
- package/build/src/deployment-api/sanitize.d.ts +27 -0
- package/build/src/deployment-api/sanitize.d.ts.map +1 -0
- package/build/src/deployment-api/sanitize.js +100 -0
- package/build/src/http-client/request.d.ts.map +1 -1
- package/build/src/http-client/request.js +4 -2
- package/build/src/sync/signed-sync-envelope-replay-service.d.ts +154 -0
- package/build/src/sync/signed-sync-envelope-replay-service.d.ts.map +1 -0
- package/build/src/sync/signed-sync-envelope-replay-service.js +294 -0
- package/build/src/sync/sync-envelope-replay-service.d.ts +84 -15
- package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
- package/build/src/sync/sync-envelope-replay-service.js +98 -16
- package/build/src/utils/bearer-token.d.ts +15 -0
- package/build/src/utils/bearer-token.d.ts.map +1 -0
- package/build/src/utils/bearer-token.js +29 -0
- package/build/src/utils/mount-prefix.d.ts +21 -0
- package/build/src/utils/mount-prefix.d.ts.map +1 -0
- package/build/src/utils/mount-prefix.js +35 -0
- package/build/sync/signed-sync-envelope-replay-service.js +342 -0
- package/build/sync/sync-envelope-replay-service.js +110 -15
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/utils/bearer-token.js +34 -0
- package/build/utils/mount-prefix.js +36 -0
- package/package.json +2 -1
- package/src/background-jobs/web/authorization.js +2 -33
- package/src/background-jobs/web/path-matcher.js +5 -30
- package/src/database/drivers/base.js +17 -0
- package/src/database/drivers/mssql/index.js +30 -0
- package/src/database/record/index.js +22 -10
- package/src/deployment-api/controller.js +437 -0
- package/src/deployment-api/index.js +210 -0
- package/src/deployment-api/path-matcher.js +45 -0
- package/src/deployment-api/registry.js +84 -0
- package/src/deployment-api/run-store.js +798 -0
- package/src/deployment-api/sanitize.js +114 -0
- package/src/http-client/request.js +3 -1
- package/src/sync/signed-sync-envelope-replay-service.js +342 -0
- package/src/sync/sync-envelope-replay-service.js +110 -15
- package/src/utils/bearer-token.js +34 -0
- package/src/utils/mount-prefix.js +36 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import SyncEnvelopeReplayService from "./sync-envelope-replay-service.js";
|
|
3
|
+
import { frontendModelSyncManifestForBackendProjects } from "../frontend-models/resource-definition.js";
|
|
4
|
+
import { verifyOfflineGrant } from "./offline-grant.js";
|
|
5
|
+
import { mutationIdempotencyKey, verifySignedMutation } from "./device-identity.js";
|
|
6
|
+
import VelociousError from "../velocious-error.js";
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import("./device-identity.js").SignedSyncMutation} SignedSyncMutation
|
|
9
|
+
* @typedef {import("./offline-grant.js").SignedOfflineGrant} SignedOfflineGrant
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Sync-envelope replay service that authenticates via backend-signed device
|
|
13
|
+
* certificates and signed offline grants instead of online session tokens.
|
|
14
|
+
*
|
|
15
|
+
* This is the generic Velocious primitive for long-offline and peer-forwarded
|
|
16
|
+
* mutations: the HTTP uploader may differ from the mutation actor, but replay
|
|
17
|
+
* authority is derived from the signed envelope and grant, not the uploader's
|
|
18
|
+
* session.
|
|
19
|
+
*
|
|
20
|
+
* Every mutation is validated against the current sync manifest (the same
|
|
21
|
+
* contract as the controller's sync replay endpoint): the model and operation
|
|
22
|
+
* must be enabled in the current manifest, the grant resource entry must be
|
|
23
|
+
* enabled and list the operation, and the grant policy hash must equal both the
|
|
24
|
+
* mutation policy hash and the current manifest policy hash. Routed resources
|
|
25
|
+
* are authorized through an actor/grant-scoped ability built by the configured
|
|
26
|
+
* `abilityFactory`; without one, routed signed replay fails closed.
|
|
27
|
+
*/
|
|
28
|
+
export default class SignedSyncEnvelopeReplayService extends SyncEnvelopeReplayService {
|
|
29
|
+
/**
|
|
30
|
+
* Creates a signed sync-envelope replay service.
|
|
31
|
+
* @param {object} args - Constructor arguments.
|
|
32
|
+
* @param {import("./device-identity.js").SyncJsonWebKey} args.backendPublicKey - Backend public key used to verify device certificates.
|
|
33
|
+
* @param {Array<import("./offline-grant.js").OfflineGrantSigningKey>} [args.offlineGrantSigningKeys] - Offline-grant verification keys.
|
|
34
|
+
* @param {(userId: string) => Promise<{id: () => string} | null>} [args.actorLookup] - Optional lookup from grant user id to an actor object with an `id()` method. Defaults to a wrapper around the grant user id.
|
|
35
|
+
* @param {(args: {actor: ?, configuration: import("../configuration.js").default | null, grant: import("./offline-grant.js").OfflineGrant}) => Promise<import("../authorization/ability.js").default | null> | import("../authorization/ability.js").default | null} [args.abilityFactory] - Builds the actor/grant-scoped ability used to authorize routed resources. Required for routed signed replay; without it every routed sync fails closed.
|
|
36
|
+
* @param {Record<string, ?>} [args.rest] - Remaining arguments forwarded to {@link SyncEnvelopeReplayService}.
|
|
37
|
+
*/
|
|
38
|
+
constructor({ abilityFactory, backendPublicKey, offlineGrantSigningKeys, actorLookup, ...rest }) {
|
|
39
|
+
super({
|
|
40
|
+
actorForeignKeyColumn: "authenticationTokenId",
|
|
41
|
+
...rest
|
|
42
|
+
});
|
|
43
|
+
if (!backendPublicKey)
|
|
44
|
+
throw new Error("SignedSyncEnvelopeReplayService requires backendPublicKey");
|
|
45
|
+
this.abilityFactory = abilityFactory || null;
|
|
46
|
+
this.backendPublicKey = backendPublicKey;
|
|
47
|
+
this.offlineGrantSigningKeys = offlineGrantSigningKeys || [];
|
|
48
|
+
this.actorLookup = actorLookup || null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Verifies signed mutations and then runs the generic replay loop over the
|
|
52
|
+
* derived sync envelopes. Verified actor, grant, and derived syncs are kept
|
|
53
|
+
* in the request-local `requestState` object so concurrent replay calls on
|
|
54
|
+
* one service instance cannot cross their authentication state.
|
|
55
|
+
* @param {Record<string, ?>} params - Request params.
|
|
56
|
+
* @param {Record<string, ?>} [requestState] - Request-local state shared with the base replay hooks.
|
|
57
|
+
* @returns {Promise<{syncs: Array<Record<string, ?>>}>} Replay response.
|
|
58
|
+
*/
|
|
59
|
+
async replay(params, requestState = {}) {
|
|
60
|
+
const verified = await this.verifyAndTransformSignedReplay(params);
|
|
61
|
+
requestState.signedReplayActor = verified.actor;
|
|
62
|
+
requestState.signedReplayGrant = verified.grant;
|
|
63
|
+
requestState.signedReplaySyncs = verified.syncs;
|
|
64
|
+
const result = await super.replay(params, requestState);
|
|
65
|
+
return {
|
|
66
|
+
syncs: result.syncs.map((syncResponse, index) => {
|
|
67
|
+
const { id: _id, ...rest } = syncResponse;
|
|
68
|
+
const idempotencyKey = verified.syncs[index]?.idempotencyKey;
|
|
69
|
+
return idempotencyKey ? { ...rest, idempotencyKey } : syncResponse;
|
|
70
|
+
})
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns the verified actor prepared during {@link SignedSyncEnvelopeReplayService#replay}.
|
|
75
|
+
* @param {Record<string, ?>} _params - Request params.
|
|
76
|
+
* @param {Record<string, ?>} requestState - Request-local state.
|
|
77
|
+
* @returns {Promise<{authenticated: true, actor: ?} | {authenticated: false, errorCode: string, errorMessage: string}>} Auth result.
|
|
78
|
+
*/
|
|
79
|
+
async authenticateReplay(_params, requestState) {
|
|
80
|
+
const actor = requestState?.signedReplayActor;
|
|
81
|
+
if (!actor) {
|
|
82
|
+
return {
|
|
83
|
+
authenticated: false,
|
|
84
|
+
errorCode: "missing-signed-replay",
|
|
85
|
+
errorMessage: "Expected a pre-verified signed replay"
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return { actor, authenticated: true };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns the sync envelopes derived from the verified signed mutations.
|
|
92
|
+
* @param {Record<string, ?>} _params - Request params.
|
|
93
|
+
* @param {Record<string, ?>} requestState - Request-local state.
|
|
94
|
+
* @returns {Array<Record<string, ?>>} Sync envelopes.
|
|
95
|
+
*/
|
|
96
|
+
replaySyncs(_params, requestState) {
|
|
97
|
+
return requestState?.signedReplaySyncs || [];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Builds the replay context carrying the verified signed actor and grant
|
|
101
|
+
* (with its scopes) plus the offline runtime marker, so resource hooks and
|
|
102
|
+
* ability factories authorize against the signer instead of the uploader.
|
|
103
|
+
* @param {{actor: ?, params: Record<string, ?>, requestState: Record<string, ?>}} args - Actor, request params, and request-local state.
|
|
104
|
+
* @returns {Promise<Record<string, ?>>} Replay context.
|
|
105
|
+
*/
|
|
106
|
+
async buildReplayContext({ actor, requestState }) {
|
|
107
|
+
const grant = /** @type {import("./offline-grant.js").OfflineGrant | undefined} */ (requestState?.signedReplayGrant);
|
|
108
|
+
return {
|
|
109
|
+
currentUser: actor,
|
|
110
|
+
offlineGrant: grant,
|
|
111
|
+
offlineGrantScopes: grant?.scopes || {},
|
|
112
|
+
resourceRuntime: "offline"
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Derives the routed-resource ability from the verified signed actor and
|
|
117
|
+
* grant through the configured `abilityFactory`. The constructor-wide
|
|
118
|
+
* uploader ability is never used for signed replay: without a factory (or a
|
|
119
|
+
* factory result) every routed sync fails closed with a client-safe error.
|
|
120
|
+
* @param {{actor: ?, context: Record<string, ?>}} args - Verified actor and replay context.
|
|
121
|
+
* @returns {Promise<{ability: import("../authorization/ability.js").default, abilityContext: Record<string, ?>}>} Scoped ability and resource context.
|
|
122
|
+
*/
|
|
123
|
+
async replayAbilityFor({ actor, context }) {
|
|
124
|
+
const grant = /** @type {import("./offline-grant.js").OfflineGrant} */ (context.offlineGrant);
|
|
125
|
+
const ability = this.abilityFactory
|
|
126
|
+
? await this.abilityFactory({ actor, configuration: this.configuration, grant })
|
|
127
|
+
: null;
|
|
128
|
+
if (!ability) {
|
|
129
|
+
throw VelociousError.safe("Signed sync replay requires an actor/grant-scoped abilityFactory.", { code: "signed-replay-ability-missing" });
|
|
130
|
+
}
|
|
131
|
+
return { ability, abilityContext: context };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Verifies every signed mutation, its offline grant, and the actor/grant
|
|
135
|
+
* consistency, then transforms the envelopes into the sync format the base
|
|
136
|
+
* replay service understands.
|
|
137
|
+
* @param {Record<string, ?>} params - Request params.
|
|
138
|
+
* @returns {Promise<{actor: ?, grant: import("./offline-grant.js").OfflineGrant, syncs: Array<Record<string, ?>>}>} Verified actor, common grant, and derived syncs.
|
|
139
|
+
*/
|
|
140
|
+
async verifyAndTransformSignedReplay(params) {
|
|
141
|
+
const rawEntries = Array.isArray(params.signedMutations) ? params.signedMutations : [];
|
|
142
|
+
if (rawEntries.length === 0) {
|
|
143
|
+
throw VelociousError.safe("Expected signed mutations.", { code: "missing-signed-mutations" });
|
|
144
|
+
}
|
|
145
|
+
const syncManifest = this.configuration
|
|
146
|
+
? frontendModelSyncManifestForBackendProjects(this.configuration.getBackendProjects())
|
|
147
|
+
: {};
|
|
148
|
+
/** @type {string | null} */
|
|
149
|
+
let grantUserId = null;
|
|
150
|
+
/** @type {string | null} */
|
|
151
|
+
let grantDeviceId = null;
|
|
152
|
+
/** @type {string | null} */
|
|
153
|
+
let grantId = null;
|
|
154
|
+
/** @type {import("./offline-grant.js").OfflineGrant | null} */
|
|
155
|
+
let commonGrant = null;
|
|
156
|
+
/** @type {Array<Record<string, ?>>} */
|
|
157
|
+
const syncs = [];
|
|
158
|
+
for (const rawEntry of rawEntries) {
|
|
159
|
+
if (!rawEntry || typeof rawEntry !== "object") {
|
|
160
|
+
throw VelociousError.safe("Invalid signed mutation entry.", { code: "invalid-signed-mutation-entry" });
|
|
161
|
+
}
|
|
162
|
+
const signedMutation = /** @type {SignedSyncMutation} */ (rawEntry.signedMutation);
|
|
163
|
+
const signedOfflineGrant = /** @type {SignedOfflineGrant} */ (rawEntry.signedOfflineGrant);
|
|
164
|
+
if (!signedMutation || !signedOfflineGrant) {
|
|
165
|
+
throw VelociousError.safe("Expected signed mutation and signed offline grant.", { code: "incomplete-signed-mutation" });
|
|
166
|
+
}
|
|
167
|
+
const mutation = await verifySignedMutation({
|
|
168
|
+
backendPublicKey: this.backendPublicKey,
|
|
169
|
+
signedMutation
|
|
170
|
+
});
|
|
171
|
+
const offlineGrant = await verifyOfflineGrant({
|
|
172
|
+
signedGrant: signedOfflineGrant,
|
|
173
|
+
signingKeys: this.offlineGrantSigningKeys
|
|
174
|
+
});
|
|
175
|
+
if (mutation.actorUserId !== offlineGrant.userId) {
|
|
176
|
+
throw VelociousError.safe("Mutation actor does not match offline grant.", { code: "actor-grant-mismatch" });
|
|
177
|
+
}
|
|
178
|
+
if (mutation.actorDeviceId !== offlineGrant.deviceId) {
|
|
179
|
+
throw VelociousError.safe("Mutation device does not match offline grant.", { code: "device-grant-mismatch" });
|
|
180
|
+
}
|
|
181
|
+
if (mutation.offlineGrantId !== offlineGrant.grantId) {
|
|
182
|
+
throw VelociousError.safe("Mutation grant id does not match offline grant.", { code: "grant-id-mismatch" });
|
|
183
|
+
}
|
|
184
|
+
if (grantUserId === null) {
|
|
185
|
+
grantUserId = offlineGrant.userId;
|
|
186
|
+
grantDeviceId = offlineGrant.deviceId;
|
|
187
|
+
grantId = offlineGrant.grantId;
|
|
188
|
+
commonGrant = offlineGrant;
|
|
189
|
+
}
|
|
190
|
+
else if (grantUserId !== offlineGrant.userId ||
|
|
191
|
+
grantDeviceId !== offlineGrant.deviceId ||
|
|
192
|
+
grantId !== offlineGrant.grantId) {
|
|
193
|
+
throw VelociousError.safe("All signed mutations in a batch must share actor, device, and grant.", { code: "mixed-signed-replay-batch" });
|
|
194
|
+
}
|
|
195
|
+
this.validateCurrentSyncPolicy({ mutation, syncManifest });
|
|
196
|
+
this.validateGrantAgainstSyncPolicy({ mutation, offlineGrant, syncManifest });
|
|
197
|
+
const sync = this.syncFromSignedMutation({ mutation });
|
|
198
|
+
const idempotencyKey = mutationIdempotencyKey({ mutation });
|
|
199
|
+
syncs.push({ ...sync, id: idempotencyKey, idempotencyKey });
|
|
200
|
+
}
|
|
201
|
+
if (!grantUserId || !commonGrant) {
|
|
202
|
+
throw VelociousError.safe("Could not resolve signed replay actor.", { code: "missing-signed-replay-actor" });
|
|
203
|
+
}
|
|
204
|
+
if (this.actorLookup) {
|
|
205
|
+
const lookedUpActor = await this.actorLookup(grantUserId);
|
|
206
|
+
if (!lookedUpActor) {
|
|
207
|
+
throw VelociousError.safe("Signed replay actor not found.", { code: "signed-replay-actor-missing" });
|
|
208
|
+
}
|
|
209
|
+
return { actor: lookedUpActor, grant: commonGrant, syncs };
|
|
210
|
+
}
|
|
211
|
+
return { actor: { id: () => grantUserId }, grant: commonGrant, syncs };
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Validates a mutation against the current sync manifest: the model and the
|
|
215
|
+
* operation must be enabled, and the mutation's policy hash must match the
|
|
216
|
+
* current manifest policy hash.
|
|
217
|
+
* @param {{mutation: import("./device-identity.js").SyncMutation, syncManifest: Record<string, import("../configuration-types.js").NormalizedFrontendModelResourceSyncConfiguration>}} args - Validation args.
|
|
218
|
+
* @returns {void} Throws a client-safe error when the current policy denies the mutation.
|
|
219
|
+
*/
|
|
220
|
+
validateCurrentSyncPolicy({ mutation, syncManifest }) {
|
|
221
|
+
const syncResource = syncManifest[mutation.model];
|
|
222
|
+
if (!syncResource) {
|
|
223
|
+
throw VelociousError.safe(`Sync replay model is not enabled: ${mutation.model}.`, { code: "sync-replay-model-not-enabled" });
|
|
224
|
+
}
|
|
225
|
+
if (!syncResource.operations.includes(mutation.operation)) {
|
|
226
|
+
throw VelociousError.safe(`Sync replay operation is not enabled for ${mutation.model}: ${mutation.operation}.`, { code: "sync-replay-operation-not-enabled" });
|
|
227
|
+
}
|
|
228
|
+
if (syncResource.policyHash !== mutation.policyHash) {
|
|
229
|
+
throw VelociousError.safe(`Sync replay policy hash mismatch for ${mutation.model}.`, { code: "sync-replay-policy-hash-mismatch" });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Validates the verified offline grant against the current sync policy, the
|
|
234
|
+
* same contract as the controller's sync replay endpoint: the grant resource
|
|
235
|
+
* entry must be a normalized manifest entry (enabled with an operations list
|
|
236
|
+
* and the current policy hash), it must list the mutation operation, and its
|
|
237
|
+
* policy hash must equal both the mutation and current manifest hashes.
|
|
238
|
+
* Legacy array/true grant-resource shortcuts are not the bootstrap contract
|
|
239
|
+
* and never authorize a mutation.
|
|
240
|
+
* @param {{mutation: import("./device-identity.js").SyncMutation, offlineGrant: import("./offline-grant.js").OfflineGrant, syncManifest: Record<string, import("../configuration-types.js").NormalizedFrontendModelResourceSyncConfiguration>}} args - Validation args.
|
|
241
|
+
* @returns {void} Throws a client-safe error when the grant does not authorize the mutation.
|
|
242
|
+
*/
|
|
243
|
+
validateGrantAgainstSyncPolicy({ mutation, offlineGrant, syncManifest }) {
|
|
244
|
+
const grantResource = /** @type {Record<string, ?> | undefined} */ (offlineGrant.resources[mutation.model]);
|
|
245
|
+
const grantOperations = Array.isArray(grantResource?.operations) ? grantResource.operations : [];
|
|
246
|
+
const grantPolicyHash = grantResource?.policyHash;
|
|
247
|
+
if (!grantResource || grantResource.enabled !== true) {
|
|
248
|
+
throw VelociousError.safe(`Offline grant does not authorize ${mutation.model}.`, { code: "offline-grant-denied" });
|
|
249
|
+
}
|
|
250
|
+
if (!grantOperations.includes(mutation.operation)) {
|
|
251
|
+
throw VelociousError.safe(`Offline grant does not authorize ${mutation.model}: ${mutation.operation}.`, { code: "offline-grant-denied" });
|
|
252
|
+
}
|
|
253
|
+
if (grantPolicyHash !== mutation.policyHash || grantPolicyHash !== syncManifest[mutation.model]?.policyHash) {
|
|
254
|
+
throw VelociousError.safe(`Offline grant policy hash mismatch for ${mutation.model}.`, { code: "offline-grant-policy-hash-mismatch" });
|
|
255
|
+
}
|
|
256
|
+
if (!offlineGrant.scopes || typeof offlineGrant.scopes !== "object" || Array.isArray(offlineGrant.scopes)) {
|
|
257
|
+
throw VelociousError.safe("Offline grant scopes are invalid.", { code: "offline-grant-scopes-invalid" });
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Transforms a verified signed mutation into a generic sync envelope.
|
|
262
|
+
* @param {{mutation: import("./device-identity.js").SyncMutation}} args - Transform args.
|
|
263
|
+
* @returns {Record<string, ?>} Sync envelope.
|
|
264
|
+
*/
|
|
265
|
+
syncFromSignedMutation({ mutation }) {
|
|
266
|
+
const operation = mutation.operation;
|
|
267
|
+
const attributes = mutation.attributes || {};
|
|
268
|
+
const payload = mutation.payload || {};
|
|
269
|
+
let resourceId;
|
|
270
|
+
let data;
|
|
271
|
+
if (operation === "create") {
|
|
272
|
+
resourceId = String(attributes.id);
|
|
273
|
+
data = { ...attributes };
|
|
274
|
+
}
|
|
275
|
+
else if (operation === "update") {
|
|
276
|
+
resourceId = String(payload.id);
|
|
277
|
+
data = { ...attributes };
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
// Domain commands carry their target identity in `payload.id`.
|
|
281
|
+
resourceId = String(payload.id);
|
|
282
|
+
data = { ...payload };
|
|
283
|
+
delete data.id;
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
clientUpdatedAt: mutation.occurredAt,
|
|
287
|
+
data,
|
|
288
|
+
resourceId,
|
|
289
|
+
resourceType: mutation.model,
|
|
290
|
+
syncType: operation
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmVkLXN5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3luYy9zaWduZWQtc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyx5QkFBeUIsTUFBTSxtQ0FBbUMsQ0FBQTtBQUN6RSxPQUFPLEVBQUMsMkNBQTJDLEVBQUMsTUFBTSwyQ0FBMkMsQ0FBQTtBQUNyRyxPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQTtBQUNyRCxPQUFPLEVBQUMsc0JBQXNCLEVBQUUsb0JBQW9CLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQTtBQUNqRixPQUFPLGNBQWMsTUFBTSx1QkFBdUIsQ0FBQTtBQUVsRDs7O0dBR0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sK0JBQWdDLFNBQVEseUJBQXlCO0lBQ3BGOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxFQUFDLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSx1QkFBdUIsRUFBRSxXQUFXLEVBQUUsR0FBRyxJQUFJLEVBQUM7UUFDM0YsS0FBSyxDQUFDO1lBQ0oscUJBQXFCLEVBQUUsdUJBQXVCO1lBQzlDLEdBQUcsSUFBSTtTQUNSLENBQUMsQ0FBQTtRQUVGLElBQUksQ0FBQyxnQkFBZ0I7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUE7UUFFbkcsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLElBQUksSUFBSSxDQUFBO1FBQzVDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQTtRQUN4QyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsdUJBQXVCLElBQUksRUFBRSxDQUFBO1FBQzVELElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxJQUFJLElBQUksQ0FBQTtJQUN4QyxDQUFDO0lB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O1lBQy9CLElBQUksR0FBRyxFQUFDLEdBQUcsT0FBTyxFQUFDLENBQUE7WUFDbkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFBO1FBQ2hCLENBQUM7UUFFRCxPQUFPO1lBQ0wsZUFBZSxFQUFFLFFBQVEsQ0FBQyxVQUFVO1lBQ3BDLElBQUk7WUFDSixVQUFVO1lBQ1YsWUFBWSxFQUFFLFFBQVEsQ0FBQyxLQUFLO1lBQzVCLFFBQVEsRUFBRSxTQUFTO1NBQ3BCLENBQUE7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IFN5bmNFbnZlbG9wZVJlcGxheVNlcnZpY2UgZnJvbSBcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiXG5pbXBvcnQge2Zyb250ZW5kTW9kZWxTeW5jTWFuaWZlc3RGb3JCYWNrZW5kUHJvamVjdHN9IGZyb20gXCIuLi9mcm9udGVuZC1tb2RlbHMvcmVzb3VyY2UtZGVmaW5pdGlvbi5qc1wiXG5pbXBvcnQge3ZlcmlmeU9mZmxpbmVHcmFudH0gZnJvbSBcIi4vb2ZmbGluZS1ncmFudC5qc1wiXG5pbXBvcnQge211dGF0aW9uSWRlbXBvdGVuY3lLZXksIHZlcmlmeVNpZ25lZE11dGF0aW9ufSBmcm9tIFwiLi9kZXZpY2UtaWRlbnRpdHkuanNcIlxuaW1wb3J0IFZlbG9jaW91c0Vycm9yIGZyb20gXCIuLi92ZWxvY2lvdXMtZXJyb3IuanNcIlxuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2RldmljZS1pZGVudGl0eS5qc1wiKS5TaWduZWRTeW5jTXV0YXRpb259IFNpZ25lZFN5bmNNdXRhdGlvblxuICogQHR5cGVkZWYge2ltcG9ydChcIi4vb2ZmbGluZS1ncmFudC5qc1wiKS5TaWduZWRPZmZsaW5lR3JhbnR9IFNpZ25lZE9mZmxpbmVHcmFudFxuICovXG5cbi8qKlxuICogU3luYy1lbnZlbG9wZSByZXBsYXkgc2VydmljZSB0aGF0IGF1dGhlbnRpY2F0ZXMgdmlhIGJhY2tlbmQtc2lnbmVkIGRldmljZVxuICogY2VydGlmaWNhdGVzIGFuZCBzaWduZWQgb2ZmbGluZSBncmFudHMgaW5zdGVhZCBvZiBvbmxpbmUgc2Vzc2lvbiB0b2tlbnMuXG4gKlxuICogVGhpcyBpcyB0aGUgZ2VuZXJpYyBWZWxvY2lvdXMgcHJpbWl0aXZlIGZvciBsb25nLW9mZmxpbmUgYW5kIHBlZXItZm9yd2FyZGVkXG4gKiBtdXRhdGlvbnM6IHRoZSBIVFRQIHVwbG9hZGVyIG1heSBkaWZmZXIgZnJvbSB0aGUgbXV0YXRpb24gYWN0b3IsIGJ1dCByZXBsYXlcbiAqIGF1dGhvcml0eSBpcyBkZXJpdmVkIGZyb20gdGhlIHNpZ25lZCBlbnZlbG9wZSBhbmQgZ3JhbnQsIG5vdCB0aGUgdXBsb2FkZXInc1xuICogc2Vzc2lvbi5cbiAqXG4gKiBFdmVyeSBtdXRhdGlvbiBpcyB2YWxpZGF0ZWQgYWdhaW5zdCB0aGUgY3VycmVudCBzeW5jIG1hbmlmZXN0ICh0aGUgc2FtZVxuICogY29udHJhY3QgYXMgdGhlIGNvbnRyb2xsZXIncyBzeW5jIHJlcGxheSBlbmRwb2ludCk6IHRoZSBtb2RlbCBhbmQgb3BlcmF0aW9uXG4gKiBtdXN0IGJlIGVuYWJsZWQgaW4gdGhlIGN1cnJlbnQgbWFuaWZlc3QsIHRoZSBncmFudCByZXNvdXJjZSBlbnRyeSBtdXN0IGJlXG4gKiBlbmFibGVkIGFuZCBsaXN0IHRoZSBvcGVyYXRpb24sIGFuZCB0aGUgZ3JhbnQgcG9saWN5IGhhc2ggbXVzdCBlcXVhbCBib3RoIHRoZVxuICogbXV0YXRpb24gcG9saWN5IGhhc2ggYW5kIHRoZSBjdXJyZW50IG1hbmlmZXN0IHBvbGljeSBoYXNoLiBSb3V0ZWQgcmVzb3VyY2VzXG4gKiBhcmUgYXV0aG9yaXplZCB0aHJvdWdoIGFuIGFjdG9yL2dyYW50LXNjb3BlZCBhYmlsaXR5IGJ1aWx0IGJ5IHRoZSBjb25maWd1cmVkXG4gKiBgYWJpbGl0eUZhY3RvcnlgOyB3aXRob3V0IG9uZSwgcm91dGVkIHNpZ25lZCByZXBsYXkgZmFpbHMgY2xvc2VkLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTaWduZWRTeW5jRW52ZWxvcGVSZXBsYXlTZXJ2aWNlIGV4dGVuZHMgU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgc2lnbmVkIHN5bmMtZW52ZWxvcGUgcmVwbGF5IHNlcnZpY2UuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZGV2aWNlLWlkZW50aXR5LmpzXCIpLlN5bmNKc29uV2ViS2V5fSBhcmdzLmJhY2tlbmRQdWJsaWNLZXkgLSBCYWNrZW5kIHB1YmxpYyBrZXkgdXNlZCB0byB2ZXJpZnkgZGV2aWNlIGNlcnRpZmljYXRlcy5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL29mZmxpbmUtZ3JhbnQuanNcIikuT2ZmbGluZUdyYW50U2lnbmluZ0tleT59IFthcmdzLm9mZmxpbmVHcmFudFNpZ25pbmdLZXlzXSAtIE9mZmxpbmUtZ3JhbnQgdmVyaWZpY2F0aW9uIGtleXMuXG4gICAqIEBwYXJhbSB7KHVzZXJJZDogc3RyaW5nKSA9PiBQcm9taXNlPHtpZDogKCkgPT4gc3RyaW5nfSB8IG51bGw+fSBbYXJncy5hY3Rvckxvb2t1cF0gLSBPcHRpb25hbCBsb29rdXAgZnJvbSBncmFudCB1c2VyIGlkIHRvIGFuIGFjdG9yIG9iamVjdCB3aXRoIGFuIGBpZCgpYCBtZXRob2QuIERlZmF1bHRzIHRvIGEgd3JhcHBlciBhcm91bmQgdGhlIGdyYW50IHVzZXIgaWQuXG4gICAqIEBwYXJhbSB7KGFyZ3M6IHthY3RvcjogPywgY29uZmlndXJhdGlvbjogaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0IHwgbnVsbCwgZ3JhbnQ6IGltcG9ydChcIi4vb2ZmbGluZS1ncmFudC5qc1wiKS5PZmZsaW5lR3JhbnR9KSA9PiBQcm9taXNlPGltcG9ydChcIi4uL2F1dGhvcml6YXRpb24vYWJpbGl0eS5qc1wiKS5kZWZhdWx0IHwgbnVsbD4gfCBpbXBvcnQoXCIuLi9hdXRob3JpemF0aW9uL2FiaWxpdHkuanNcIikuZGVmYXVsdCB8IG51bGx9IFthcmdzLmFiaWxpdHlGYWN0b3J5XSAtIEJ1aWxkcyB0aGUgYWN0b3IvZ3JhbnQtc2NvcGVkIGFiaWxpdHkgdXNlZCB0byBhdXRob3JpemUgcm91dGVkIHJlc291cmNlcy4gUmVxdWlyZWQgZm9yIHJvdXRlZCBzaWduZWQgcmVwbGF5OyB3aXRob3V0IGl0IGV2ZXJ5IHJvdXRlZCBzeW5jIGZhaWxzIGNsb3NlZC5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gW2FyZ3MucmVzdF0gLSBSZW1haW5pbmcgYXJndW1lbnRzIGZvcndhcmRlZCB0byB7QGxpbmsgU3luY0VudmVsb3BlUmVwbGF5U2VydmljZX0uXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7YWJpbGl0eUZhY3RvcnksIGJhY2tlbmRQdWJsaWNLZXksIG9mZmxpbmVHcmFudFNpZ25pbmdLZXlzLCBhY3Rvckxvb2t1cCwgLi4ucmVzdH0pIHtcbiAgICBzdXBlcih7XG4gICAgICBhY3RvckZvcmVpZ25LZXlDb2x1bW46IFwiYXV0aGVudGljYXRpb25Ub2tlbklkXCIsXG4gICAgICAuLi5yZXN0XG4gICAgfSlcblxuICAgIGlmICghYmFja2VuZFB1YmxpY0tleSkgdGhyb3cgbmV3IEVycm9yKFwiU2lnbmVkU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSByZXF1aXJlcyBiYWNrZW5kUHVibGljS2V5XCIpXG5cbiAgICB0aGlzLmFiaWxpdHlGYWN0b3J5ID0gYWJpbGl0eUZhY3RvcnkgfHwgbnVsbFxuICAgIHRoaXMuYmFja2VuZFB1YmxpY0tleSA9IGJhY2tlbmRQdWJsaWNLZXlcbiAgICB0aGlzLm9mZmxpbmVHcmFudFNpZ25pbmdLZXlzID0gb2ZmbGluZUdyYW50U2lnbmluZ0tleXMgfHwgW11cbiAgICB0aGlzLmFjdG9yTG9va3VwID0gYWN0b3JMb29rdXAgfHwgbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHNpZ25lZCBtdXRhdGlvbnMgYW5kIHRoZW4gcnVucyB0aGUgZ2VuZXJpYyByZXBsYXkgbG9vcCBvdmVyIHRoZVxuICAgKiBkZXJpdmVkIHN5bmMgZW52ZWxvcGVzLiBWZXJpZmllZCBhY3RvciwgZ3JhbnQsIGFuZCBkZXJpdmVkIHN5bmNzIGFyZSBrZXB0XG4gICAqIGluIHRoZSByZXF1ZXN0LWxvY2FsIGByZXF1ZXN0U3RhdGVgIG9iamVjdCBzbyBjb25jdXJyZW50IHJlcGxheSBjYWxscyBvblxuICAgKiBvbmUgc2VydmljZSBpbnN0YW5jZSBjYW5ub3QgY3Jvc3MgdGhlaXIgYXV0aGVudGljYXRpb24gc3RhdGUuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IHBhcmFtcyAtIFJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBbcmVxdWVzdFN0YXRlXSAtIFJlcXVlc3QtbG9jYWwgc3RhdGUgc2hhcmVkIHdpdGggdGhlIGJhc2UgcmVwbGF5IGhvb2tzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7c3luY3M6IEFycmF5PFJlY29yZDxzdHJpbmcsID8+Pn0+fSBSZXBsYXkgcmVzcG9uc2UuXG4gICAqL1xuICBhc3luYyByZXBsYXkocGFyYW1zLCByZXF1ZXN0U3RhdGUgPSB7fSkge1xuICAgIGNvbnN0IHZlcmlmaWVkID0gYXdhaXQgdGhpcy52ZXJpZnlBbmRUcmFuc2Zvcm1TaWduZWRSZXBsYXkocGFyYW1zKVxuXG4gICAgcmVxdWVzdFN0YXRlLnNpZ25lZFJlcGxheUFjdG9yID0gdmVyaWZpZWQuYWN0b3JcbiAgICByZXF1ZXN0U3RhdGUuc2lnbmVkUmVwbGF5R3JhbnQgPSB2ZXJpZmllZC5ncmFudFxuICAgIHJlcXVlc3RTdGF0ZS5zaWduZWRSZXBsYXlTeW5jcyA9IHZlcmlmaWVkLnN5bmNzXG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdXBlci5yZXBsYXkocGFyYW1zLCByZXF1ZXN0U3RhdGUpXG5cbiAgICByZXR1cm4ge1xuICAgICAgc3luY3M6IHJlc3VsdC5zeW5jcy5tYXAoKHN5bmNSZXNwb25zZSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3Qge2lkOiBfaWQsIC4uLnJlc3R9ID0gc3luY1Jlc3BvbnNlXG4gICAgICAgIGNvbnN0IGlkZW1wb3RlbmN5S2V5ID0gdmVyaWZpZWQuc3luY3NbaW5kZXhdPy5pZGVtcG90ZW5jeUtleVxuXG4gICAgICAgIHJldHVybiBpZGVtcG90ZW5jeUtleSA/IHsuLi5yZXN0LCBpZGVtcG90ZW5jeUtleX0gOiBzeW5jUmVzcG9uc2VcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHZlcmlmaWVkIGFjdG9yIHByZXBhcmVkIGR1cmluZyB7QGxpbmsgU2lnbmVkU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSNyZXBsYXl9LlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBfcGFyYW1zIC0gUmVxdWVzdCBwYXJhbXMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IHJlcXVlc3RTdGF0ZSAtIFJlcXVlc3QtbG9jYWwgc3RhdGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHthdXRoZW50aWNhdGVkOiB0cnVlLCBhY3RvcjogP30gfCB7YXV0aGVudGljYXRlZDogZmFsc2UsIGVycm9yQ29kZTogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZ30+fSBBdXRoIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIGF1dGhlbnRpY2F0ZVJlcGxheShfcGFyYW1zLCByZXF1ZXN0U3RhdGUpIHtcbiAgICBjb25zdCBhY3RvciA9IHJlcXVlc3RTdGF0ZT8uc2lnbmVkUmVwbGF5QWN0b3JcblxuICAgIGlmICghYWN0b3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGF1dGhlbnRpY2F0ZWQ6IGZhbHNlLFxuICAgICAgICBlcnJvckNvZGU6IFwibWlzc2luZy1zaWduZWQtcmVwbGF5XCIsXG4gICAgICAgIGVycm9yTWVzc2FnZTogXCJFeHBlY3RlZCBhIHByZS12ZXJpZmllZCBzaWduZWQgcmVwbGF5XCJcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge2FjdG9yLCBhdXRoZW50aWNhdGVkOiB0cnVlfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHN5bmMgZW52ZWxvcGVzIGRlcml2ZWQgZnJvbSB0aGUgdmVyaWZpZWQgc2lnbmVkIG11dGF0aW9ucy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gX3BhcmFtcyAtIFJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSByZXF1ZXN0U3RhdGUgLSBSZXF1ZXN0LWxvY2FsIHN0YXRlLlxuICAgKiBAcmV0dXJucyB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSBTeW5jIGVudmVsb3Blcy5cbiAgICovXG4gIHJlcGxheVN5bmNzKF9wYXJhbXMsIHJlcXVlc3RTdGF0ZSkge1xuICAgIHJldHVybiByZXF1ZXN0U3RhdGU/LnNpZ25lZFJlcGxheVN5bmNzIHx8IFtdXG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIHRoZSByZXBsYXkgY29udGV4dCBjYXJyeWluZyB0aGUgdmVyaWZpZWQgc2lnbmVkIGFjdG9yIGFuZCBncmFudFxuICAgKiAod2l0aCBpdHMgc2NvcGVzKSBwbHVzIHRoZSBvZmZsaW5lIHJ1bnRpbWUgbWFya2VyLCBzbyByZXNvdXJjZSBob29rcyBhbmRcbiAgICogYWJpbGl0eSBmYWN0b3JpZXMgYXV0aG9yaXplIGFnYWluc3QgdGhlIHNpZ25lciBpbnN0ZWFkIG9mIHRoZSB1cGxvYWRlci5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIHBhcmFtczogUmVjb3JkPHN0cmluZywgPz4sIHJlcXVlc3RTdGF0ZTogUmVjb3JkPHN0cmluZywgPz59fSBhcmdzIC0gQWN0b3IsIHJlcXVlc3QgcGFyYW1zLCBhbmQgcmVxdWVzdC1sb2NhbCBzdGF0ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSBSZXBsYXkgY29udGV4dC5cbiAgICovXG4gIGFzeW5jIGJ1aWxkUmVwbGF5Q29udGV4dCh7YWN0b3IsIHJlcXVlc3RTdGF0ZX0pIHtcbiAgICBjb25zdCBncmFudCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9vZmZsaW5lLWdyYW50LmpzXCIpLk9mZmxpbmVHcmFudCB8IHVuZGVmaW5lZH0gKi8gKHJlcXVlc3RTdGF0ZT8uc2lnbmVkUmVwbGF5R3JhbnQpXG5cbiAgICByZXR1cm4ge1xuICAgICAgY3VycmVudFVzZXI6IGFjdG9yLFxuICAgICAgb2ZmbGluZUdyYW50OiBncmFudCxcbiAgICAgIG9mZmxpbmVHcmFudFNjb3BlczogZ3JhbnQ/LnNjb3BlcyB8fCB7fSxcbiAgICAgIHJlc291cmNlUnVudGltZTogXCJvZmZsaW5lXCJcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVyaXZlcyB0aGUgcm91dGVkLXJlc291cmNlIGFiaWxpdHkgZnJvbSB0aGUgdmVyaWZpZWQgc2lnbmVkIGFjdG9yIGFuZFxuICAgKiBncmFudCB0aHJvdWdoIHRoZSBjb25maWd1cmVkIGBhYmlsaXR5RmFjdG9yeWAuIFRoZSBjb25zdHJ1Y3Rvci13aWRlXG4gICAqIHVwbG9hZGVyIGFiaWxpdHkgaXMgbmV2ZXIgdXNlZCBmb3Igc2lnbmVkIHJlcGxheTogd2l0aG91dCBhIGZhY3RvcnkgKG9yIGFcbiAgICogZmFjdG9yeSByZXN1bHQpIGV2ZXJ5IHJvdXRlZCBzeW5jIGZhaWxzIGNsb3NlZCB3aXRoIGEgY2xpZW50LXNhZmUgZXJyb3IuXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/Pn19IGFyZ3MgLSBWZXJpZmllZCBhY3RvciBhbmQgcmVwbGF5IGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHthYmlsaXR5OiBpbXBvcnQoXCIuLi9hdXRob3JpemF0aW9uL2FiaWxpdHkuanNcIikuZGVmYXVsdCwgYWJpbGl0eUNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+fT59IFNjb3BlZCBhYmlsaXR5IGFuZCByZXNvdXJjZSBjb250ZXh0LlxuICAgKi9cbiAgYXN5bmMgcmVwbGF5QWJpbGl0eUZvcih7YWN0b3IsIGNvbnRleHR9KSB7XG4gICAgY29uc3QgZ3JhbnQgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vb2ZmbGluZS1ncmFudC5qc1wiKS5PZmZsaW5lR3JhbnR9ICovIChjb250ZXh0Lm9mZmxpbmVHcmFudClcbiAgICBjb25zdCBhYmlsaXR5ID0gdGhpcy5hYmlsaXR5RmFjdG9yeVxuICAgICAgPyBhd2FpdCB0aGlzLmFiaWxpdHlGYWN0b3J5KHthY3RvciwgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLCBncmFudH0pXG4gICAgICA6IG51bGxcblxuICAgIGlmICghYWJpbGl0eSkge1xuICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShcIlNpZ25lZCBzeW5jIHJlcGxheSByZXF1aXJlcyBhbiBhY3Rvci9ncmFudC1zY29wZWQgYWJpbGl0eUZhY3RvcnkuXCIsIHtjb2RlOiBcInNpZ25lZC1yZXBsYXktYWJpbGl0eS1taXNzaW5nXCJ9KVxuICAgIH1cblxuICAgIHJldHVybiB7YWJpbGl0eSwgYWJpbGl0eUNvbnRleHQ6IGNvbnRleHR9XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZpZXMgZXZlcnkgc2lnbmVkIG11dGF0aW9uLCBpdHMgb2ZmbGluZSBncmFudCwgYW5kIHRoZSBhY3Rvci9ncmFudFxuICAgKiBjb25zaXN0ZW5jeSwgdGhlbiB0cmFuc2Zvcm1zIHRoZSBlbnZlbG9wZXMgaW50byB0aGUgc3luYyBmb3JtYXQgdGhlIGJhc2VcbiAgICogcmVwbGF5IHNlcnZpY2UgdW5kZXJzdGFuZHMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IHBhcmFtcyAtIFJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7YWN0b3I6ID8sIGdyYW50OiBpbXBvcnQoXCIuL29mZmxpbmUtZ3JhbnQuanNcIikuT2ZmbGluZUdyYW50LCBzeW5jczogQXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fT59IFZlcmlmaWVkIGFjdG9yLCBjb21tb24gZ3JhbnQsIGFuZCBkZXJpdmVkIHN5bmNzLlxuICAgKi9cbiAgYXN5bmMgdmVyaWZ5QW5kVHJhbnNmb3JtU2lnbmVkUmVwbGF5KHBhcmFtcykge1xuICAgIGNvbnN0IHJhd0VudHJpZXMgPSBBcnJheS5pc0FycmF5KHBhcmFtcy5zaWduZWRNdXRhdGlvbnMpID8gcGFyYW1zLnNpZ25lZE11dGF0aW9ucyA6IFtdXG5cbiAgICBpZiAocmF3RW50cmllcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoXCJFeHBlY3RlZCBzaWduZWQgbXV0YXRpb25zLlwiLCB7Y29kZTogXCJtaXNzaW5nLXNpZ25lZC1tdXRhdGlvbnNcIn0pXG4gICAgfVxuXG4gICAgY29uc3Qgc3luY01hbmlmZXN0ID0gdGhpcy5jb25maWd1cmF0aW9uXG4gICAgICA/IGZyb250ZW5kTW9kZWxTeW5jTWFuaWZlc3RGb3JCYWNrZW5kUHJvamVjdHModGhpcy5jb25maWd1cmF0aW9uLmdldEJhY2tlbmRQcm9qZWN0cygpKVxuICAgICAgOiB7fVxuXG4gICAgLyoqIEB0eXBlIHtzdHJpbmcgfCBudWxsfSAqL1xuICAgIGxldCBncmFudFVzZXJJZCA9IG51bGxcbiAgICAvKiogQHR5cGUge3N0cmluZyB8IG51bGx9ICovXG4gICAgbGV0IGdyYW50RGV2aWNlSWQgPSBudWxsXG4gICAgLyoqIEB0eXBlIHtzdHJpbmcgfCBudWxsfSAqL1xuICAgIGxldCBncmFudElkID0gbnVsbFxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9vZmZsaW5lLWdyYW50LmpzXCIpLk9mZmxpbmVHcmFudCB8IG51bGx9ICovXG4gICAgbGV0IGNvbW1vbkdyYW50ID0gbnVsbFxuICAgIC8qKiBAdHlwZSB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSAqL1xuICAgIGNvbnN0IHN5bmNzID0gW11cblxuICAgIGZvciAoY29uc3QgcmF3RW50cnkgb2YgcmF3RW50cmllcykge1xuICAgICAgaWYgKCFyYXdFbnRyeSB8fCB0eXBlb2YgcmF3RW50cnkgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShcIkludmFsaWQgc2lnbmVkIG11dGF0aW9uIGVudHJ5LlwiLCB7Y29kZTogXCJpbnZhbGlkLXNpZ25lZC1tdXRhdGlvbi1lbnRyeVwifSlcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2lnbmVkTXV0YXRpb24gPSAvKiogQHR5cGUge1NpZ25lZFN5bmNNdXRhdGlvbn0gKi8gKHJhd0VudHJ5LnNpZ25lZE11dGF0aW9uKVxuICAgICAgY29uc3Qgc2lnbmVkT2ZmbGluZUdyYW50ID0gLyoqIEB0eXBlIHtTaWduZWRPZmZsaW5lR3JhbnR9ICovIChyYXdFbnRyeS5zaWduZWRPZmZsaW5lR3JhbnQpXG5cbiAgICAgIGlmICghc2lnbmVkTXV0YXRpb24gfHwgIXNpZ25lZE9mZmxpbmVHcmFudCkge1xuICAgICAgICB0aHJvdyBWZWxvY2lvdXNFcnJvci5zYWZlKFwiRXhwZWN0ZWQgc2lnbmVkIG11dGF0aW9uIGFuZCBzaWduZWQgb2ZmbGluZSBncmFudC5cIiwge2NvZGU6IFwiaW5jb21wbGV0ZS1zaWduZWQtbXV0YXRpb25cIn0pXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG11dGF0aW9uID0gYXdhaXQgdmVyaWZ5U2lnbmVkTXV0YXRpb24oe1xuICAgICAgICBiYWNrZW5kUHVibGljS2V5OiB0aGlzLmJhY2tlbmRQdWJsaWNLZXksXG4gICAgICAgIHNpZ25lZE11dGF0aW9uXG4gICAgICB9KVxuICAgICAgY29uc3Qgb2ZmbGluZUdyYW50ID0gYXdhaXQgdmVyaWZ5T2ZmbGluZUdyYW50KHtcbiAgICAgICAgc2lnbmVkR3JhbnQ6IHNpZ25lZE9mZmxpbmVHcmFudCxcbiAgICAgICAgc2lnbmluZ0tleXM6IHRoaXMub2ZmbGluZUdyYW50U2lnbmluZ0tleXNcbiAgICAgIH0pXG5cbiAgICAgIGlmIChtdXRhdGlvbi5hY3RvclVzZXJJZCAhPT0gb2ZmbGluZUdyYW50LnVzZXJJZCkge1xuICAgICAgICB0aHJvdyBWZWxvY2lvdXNFcnJvci5zYWZlKFwiTXV0YXRpb24gYWN0b3IgZG9lcyBub3QgbWF0Y2ggb2ZmbGluZSBncmFudC5cIiwge2NvZGU6IFwiYWN0b3ItZ3JhbnQtbWlzbWF0Y2hcIn0pXG4gICAgICB9XG5cbiAgICAgIGlmIChtdXRhdGlvbi5hY3RvckRldmljZUlkICE9PSBvZmZsaW5lR3JhbnQuZGV2aWNlSWQpIHtcbiAgICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShcIk11dGF0aW9uIGRldmljZSBkb2VzIG5vdCBtYXRjaCBvZmZsaW5lIGdyYW50LlwiLCB7Y29kZTogXCJkZXZpY2UtZ3JhbnQtbWlzbWF0Y2hcIn0pXG4gICAgICB9XG5cbiAgICAgIGlmIChtdXRhdGlvbi5vZmZsaW5lR3JhbnRJZCAhPT0gb2ZmbGluZUdyYW50LmdyYW50SWQpIHtcbiAgICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShcIk11dGF0aW9uIGdyYW50IGlkIGRvZXMgbm90IG1hdGNoIG9mZmxpbmUgZ3JhbnQuXCIsIHtjb2RlOiBcImdyYW50LWlkLW1pc21hdGNoXCJ9KVxuICAgICAgfVxuXG4gICAgICBpZiAoZ3JhbnRVc2VySWQgPT09IG51bGwpIHtcbiAgICAgICAgZ3JhbnRVc2VySWQgPSBvZmZsaW5lR3JhbnQudXNlcklkXG4gICAgICAgIGdyYW50RGV2aWNlSWQgPSBvZmZsaW5lR3JhbnQuZGV2aWNlSWRcbiAgICAgICAgZ3JhbnRJZCA9IG9mZmxpbmVHcmFudC5ncmFudElkXG4gICAgICAgIGNvbW1vbkdyYW50ID0gb2ZmbGluZUdyYW50XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBncmFudFVzZXJJZCAhPT0gb2ZmbGluZUdyYW50LnVzZXJJZCB8fFxuICAgICAgICBncmFudERldmljZUlkICE9PSBvZmZsaW5lR3JhbnQuZGV2aWNlSWQgfHxcbiAgICAgICAgZ3JhbnRJZCAhPT0gb2ZmbGluZUdyYW50LmdyYW50SWRcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBWZWxvY2lvdXNFcnJvci5zYWZlKFwiQWxsIHNpZ25lZCBtdXRhdGlvbnMgaW4gYSBiYXRjaCBtdXN0IHNoYXJlIGFjdG9yLCBkZXZpY2UsIGFuZCBncmFudC5cIiwge2NvZGU6IFwibWl4ZWQtc2lnbmVkLXJlcGxheS1iYXRjaFwifSlcbiAgICAgIH1cblxuICAgICAgdGhpcy52YWxpZGF0ZUN1cnJlbnRTeW5jUG9saWN5KHttdXRhdGlvbiwgc3luY01hbmlmZXN0fSlcbiAgICAgIHRoaXMudmFsaWRhdGVHcmFudEFnYWluc3RTeW5jUG9saWN5KHttdXRhdGlvbiwgb2ZmbGluZUdyYW50LCBzeW5jTWFuaWZlc3R9KVxuXG4gICAgICBjb25zdCBzeW5jID0gdGhpcy5zeW5jRnJvbVNpZ25lZE11dGF0aW9uKHttdXRhdGlvbn0pXG4gICAgICBjb25zdCBpZGVtcG90ZW5jeUtleSA9IG11dGF0aW9uSWRlbXBvdGVuY3lLZXkoe211dGF0aW9ufSlcblxuICAgICAgc3luY3MucHVzaCh7Li4uc3luYywgaWQ6IGlkZW1wb3RlbmN5S2V5LCBpZGVtcG90ZW5jeUtleX0pXG4gICAgfVxuXG4gICAgaWYgKCFncmFudFVzZXJJZCB8fCAhY29tbW9uR3JhbnQpIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoXCJDb3VsZCBub3QgcmVzb2x2ZSBzaWduZWQgcmVwbGF5IGFjdG9yLlwiLCB7Y29kZTogXCJtaXNzaW5nLXNpZ25lZC1yZXBsYXktYWN0b3JcIn0pXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWN0b3JMb29rdXApIHtcbiAgICAgIGNvbnN0IGxvb2tlZFVwQWN0b3IgPSBhd2FpdCB0aGlzLmFjdG9yTG9va3VwKGdyYW50VXNlcklkKVxuXG4gICAgICBpZiAoIWxvb2tlZFVwQWN0b3IpIHtcbiAgICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShcIlNpZ25lZCByZXBsYXkgYWN0b3Igbm90IGZvdW5kLlwiLCB7Y29kZTogXCJzaWduZWQtcmVwbGF5LWFjdG9yLW1pc3NpbmdcIn0pXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7YWN0b3I6IGxvb2tlZFVwQWN0b3IsIGdyYW50OiBjb21tb25HcmFudCwgc3luY3N9XG4gICAgfVxuXG4gICAgcmV0dXJuIHthY3Rvcjoge2lkOiAoKSA9PiBncmFudFVzZXJJZH0sIGdyYW50OiBjb21tb25HcmFudCwgc3luY3N9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgbXV0YXRpb24gYWdhaW5zdCB0aGUgY3VycmVudCBzeW5jIG1hbmlmZXN0OiB0aGUgbW9kZWwgYW5kIHRoZVxuICAgKiBvcGVyYXRpb24gbXVzdCBiZSBlbmFibGVkLCBhbmQgdGhlIG11dGF0aW9uJ3MgcG9saWN5IGhhc2ggbXVzdCBtYXRjaCB0aGVcbiAgICogY3VycmVudCBtYW5pZmVzdCBwb2xpY3kgaGFzaC5cbiAgICogQHBhcmFtIHt7bXV0YXRpb246IGltcG9ydChcIi4vZGV2aWNlLWlkZW50aXR5LmpzXCIpLlN5bmNNdXRhdGlvbiwgc3luY01hbmlmZXN0OiBSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLk5vcm1hbGl6ZWRGcm9udGVuZE1vZGVsUmVzb3VyY2VTeW5jQ29uZmlndXJhdGlvbj59fSBhcmdzIC0gVmFsaWRhdGlvbiBhcmdzLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gVGhyb3dzIGEgY2xpZW50LXNhZmUgZXJyb3Igd2hlbiB0aGUgY3VycmVudCBwb2xpY3kgZGVuaWVzIHRoZSBtdXRhdGlvbi5cbiAgICovXG4gIHZhbGlkYXRlQ3VycmVudFN5bmNQb2xpY3koe211dGF0aW9uLCBzeW5jTWFuaWZlc3R9KSB7XG4gICAgY29uc3Qgc3luY1Jlc291cmNlID0gc3luY01hbmlmZXN0W211dGF0aW9uLm1vZGVsXVxuXG4gICAgaWYgKCFzeW5jUmVzb3VyY2UpIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoYFN5bmMgcmVwbGF5IG1vZGVsIGlzIG5vdCBlbmFibGVkOiAke211dGF0aW9uLm1vZGVsfS5gLCB7Y29kZTogXCJzeW5jLXJlcGxheS1tb2RlbC1ub3QtZW5hYmxlZFwifSlcbiAgICB9XG5cbiAgICBpZiAoIXN5bmNSZXNvdXJjZS5vcGVyYXRpb25zLmluY2x1ZGVzKG11dGF0aW9uLm9wZXJhdGlvbikpIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoYFN5bmMgcmVwbGF5IG9wZXJhdGlvbiBpcyBub3QgZW5hYmxlZCBmb3IgJHttdXRhdGlvbi5tb2RlbH06ICR7bXV0YXRpb24ub3BlcmF0aW9ufS5gLCB7Y29kZTogXCJzeW5jLXJlcGxheS1vcGVyYXRpb24tbm90LWVuYWJsZWRcIn0pXG4gICAgfVxuXG4gICAgaWYgKHN5bmNSZXNvdXJjZS5wb2xpY3lIYXNoICE9PSBtdXRhdGlvbi5wb2xpY3lIYXNoKSB7XG4gICAgICB0aHJvdyBWZWxvY2lvdXNFcnJvci5zYWZlKGBTeW5jIHJlcGxheSBwb2xpY3kgaGFzaCBtaXNtYXRjaCBmb3IgJHttdXRhdGlvbi5tb2RlbH0uYCwge2NvZGU6IFwic3luYy1yZXBsYXktcG9saWN5LWhhc2gtbWlzbWF0Y2hcIn0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgdmVyaWZpZWQgb2ZmbGluZSBncmFudCBhZ2FpbnN0IHRoZSBjdXJyZW50IHN5bmMgcG9saWN5LCB0aGVcbiAgICogc2FtZSBjb250cmFjdCBhcyB0aGUgY29udHJvbGxlcidzIHN5bmMgcmVwbGF5IGVuZHBvaW50OiB0aGUgZ3JhbnQgcmVzb3VyY2VcbiAgICogZW50cnkgbXVzdCBiZSBhIG5vcm1hbGl6ZWQgbWFuaWZlc3QgZW50cnkgKGVuYWJsZWQgd2l0aCBhbiBvcGVyYXRpb25zIGxpc3RcbiAgICogYW5kIHRoZSBjdXJyZW50IHBvbGljeSBoYXNoKSwgaXQgbXVzdCBsaXN0IHRoZSBtdXRhdGlvbiBvcGVyYXRpb24sIGFuZCBpdHNcbiAgICogcG9saWN5IGhhc2ggbXVzdCBlcXVhbCBib3RoIHRoZSBtdXRhdGlvbiBhbmQgY3VycmVudCBtYW5pZmVzdCBoYXNoZXMuXG4gICAqIExlZ2FjeSBhcnJheS90cnVlIGdyYW50LXJlc291cmNlIHNob3J0Y3V0cyBhcmUgbm90IHRoZSBib290c3RyYXAgY29udHJhY3RcbiAgICogYW5kIG5ldmVyIGF1dGhvcml6ZSBhIG11dGF0aW9uLlxuICAgKiBAcGFyYW0ge3ttdXRhdGlvbjogaW1wb3J0KFwiLi9kZXZpY2UtaWRlbnRpdHkuanNcIikuU3luY011dGF0aW9uLCBvZmZsaW5lR3JhbnQ6IGltcG9ydChcIi4vb2ZmbGluZS1ncmFudC5qc1wiKS5PZmZsaW5lR3JhbnQsIHN5bmNNYW5pZmVzdDogUmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Ob3JtYWxpemVkRnJvbnRlbmRNb2RlbFJlc291cmNlU3luY0NvbmZpZ3VyYXRpb24+fX0gYXJncyAtIFZhbGlkYXRpb24gYXJncy5cbiAgICogQHJldHVybnMge3ZvaWR9IFRocm93cyBhIGNsaWVudC1zYWZlIGVycm9yIHdoZW4gdGhlIGdyYW50IGRvZXMgbm90IGF1dGhvcml6ZSB0aGUgbXV0YXRpb24uXG4gICAqL1xuICB2YWxpZGF0ZUdyYW50QWdhaW5zdFN5bmNQb2xpY3koe211dGF0aW9uLCBvZmZsaW5lR3JhbnQsIHN5bmNNYW5pZmVzdH0pIHtcbiAgICBjb25zdCBncmFudFJlc291cmNlID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/PiB8IHVuZGVmaW5lZH0gKi8gKG9mZmxpbmVHcmFudC5yZXNvdXJjZXNbbXV0YXRpb24ubW9kZWxdKVxuICAgIGNvbnN0IGdyYW50T3BlcmF0aW9ucyA9IEFycmF5LmlzQXJyYXkoZ3JhbnRSZXNvdXJjZT8ub3BlcmF0aW9ucykgPyBncmFudFJlc291cmNlLm9wZXJhdGlvbnMgOiBbXVxuICAgIGNvbnN0IGdyYW50UG9saWN5SGFzaCA9IGdyYW50UmVzb3VyY2U/LnBvbGljeUhhc2hcblxuICAgIGlmICghZ3JhbnRSZXNvdXJjZSB8fCBncmFudFJlc291cmNlLmVuYWJsZWQgIT09IHRydWUpIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoYE9mZmxpbmUgZ3JhbnQgZG9lcyBub3QgYXV0aG9yaXplICR7bXV0YXRpb24ubW9kZWx9LmAsIHtjb2RlOiBcIm9mZmxpbmUtZ3JhbnQtZGVuaWVkXCJ9KVxuICAgIH1cblxuICAgIGlmICghZ3JhbnRPcGVyYXRpb25zLmluY2x1ZGVzKG11dGF0aW9uLm9wZXJhdGlvbikpIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoYE9mZmxpbmUgZ3JhbnQgZG9lcyBub3QgYXV0aG9yaXplICR7bXV0YXRpb24ubW9kZWx9OiAke211dGF0aW9uLm9wZXJhdGlvbn0uYCwge2NvZGU6IFwib2ZmbGluZS1ncmFudC1kZW5pZWRcIn0pXG4gICAgfVxuXG4gICAgaWYgKGdyYW50UG9saWN5SGFzaCAhPT0gbXV0YXRpb24ucG9saWN5SGFzaCB8fCBncmFudFBvbGljeUhhc2ggIT09IHN5bmNNYW5pZmVzdFttdXRhdGlvbi5tb2RlbF0/LnBvbGljeUhhc2gpIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoYE9mZmxpbmUgZ3JhbnQgcG9saWN5IGhhc2ggbWlzbWF0Y2ggZm9yICR7bXV0YXRpb24ubW9kZWx9LmAsIHtjb2RlOiBcIm9mZmxpbmUtZ3JhbnQtcG9saWN5LWhhc2gtbWlzbWF0Y2hcIn0pXG4gICAgfVxuXG4gICAgaWYgKCFvZmZsaW5lR3JhbnQuc2NvcGVzIHx8IHR5cGVvZiBvZmZsaW5lR3JhbnQuc2NvcGVzICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkob2ZmbGluZUdyYW50LnNjb3BlcykpIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoXCJPZmZsaW5lIGdyYW50IHNjb3BlcyBhcmUgaW52YWxpZC5cIiwge2NvZGU6IFwib2ZmbGluZS1ncmFudC1zY29wZXMtaW52YWxpZFwifSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtcyBhIHZlcmlmaWVkIHNpZ25lZCBtdXRhdGlvbiBpbnRvIGEgZ2VuZXJpYyBzeW5jIGVudmVsb3BlLlxuICAgKiBAcGFyYW0ge3ttdXRhdGlvbjogaW1wb3J0KFwiLi9kZXZpY2UtaWRlbnRpdHkuanNcIikuU3luY011dGF0aW9ufX0gYXJncyAtIFRyYW5zZm9ybSBhcmdzLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IFN5bmMgZW52ZWxvcGUuXG4gICAqL1xuICBzeW5jRnJvbVNpZ25lZE11dGF0aW9uKHttdXRhdGlvbn0pIHtcbiAgICBjb25zdCBvcGVyYXRpb24gPSBtdXRhdGlvbi5vcGVyYXRpb25cbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gbXV0YXRpb24uYXR0cmlidXRlcyB8fCB7fVxuICAgIGNvbnN0IHBheWxvYWQgPSBtdXRhdGlvbi5wYXlsb2FkIHx8IHt9XG4gICAgbGV0IHJlc291cmNlSWRcbiAgICBsZXQgZGF0YVxuXG4gICAgaWYgKG9wZXJhdGlvbiA9PT0gXCJjcmVhdGVcIikge1xuICAgICAgcmVzb3VyY2VJZCA9IFN0cmluZyhhdHRyaWJ1dGVzLmlkKVxuICAgICAgZGF0YSA9IHsuLi5hdHRyaWJ1dGVzfVxuICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSBcInVwZGF0ZVwiKSB7XG4gICAgICByZXNvdXJjZUlkID0gU3RyaW5nKHBheWxvYWQuaWQpXG4gICAgICBkYXRhID0gey4uLmF0dHJpYnV0ZXN9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERvbWFpbiBjb21tYW5kcyBjYXJyeSB0aGVpciB0YXJnZXQgaWRlbnRpdHkgaW4gYHBheWxvYWQuaWRgLlxuICAgICAgcmVzb3VyY2VJZCA9IFN0cmluZyhwYXlsb2FkLmlkKVxuICAgICAgZGF0YSA9IHsuLi5wYXlsb2FkfVxuICAgICAgZGVsZXRlIGRhdGEuaWRcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY2xpZW50VXBkYXRlZEF0OiBtdXRhdGlvbi5vY2N1cnJlZEF0LFxuICAgICAgZGF0YSxcbiAgICAgIHJlc291cmNlSWQsXG4gICAgICByZXNvdXJjZVR5cGU6IG11dGF0aW9uLm1vZGVsLFxuICAgICAgc3luY1R5cGU6IG9wZXJhdGlvblxuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -54,7 +54,7 @@ export default class SyncEnvelopeReplayService {
|
|
|
54
54
|
* @param {(args: {mutation: ?, applyResult: ?}) => ?} [args.persistSerializedData] - Overrides the persisted data payload (object results are JSON stringified).
|
|
55
55
|
* @param {(broadcast: {channel: string, params: Record<string, ?>, body: ?}) => Promise<void>} [args.broadcaster] - Delivers declarative broadcasts. Required when broadcasts are configured.
|
|
56
56
|
* @param {SyncReplayBroadcast[]} [args.broadcasts] - Broadcasts fanned out by the default afterReplayMutation.
|
|
57
|
-
* @param {
|
|
57
|
+
* @param {import("../configuration.js").default} [args.configuration] - Configuration whose frontend-model registry routes mutations to resource classes.
|
|
58
58
|
* @param {Record<string, import("../configuration-types.js").FrontendModelResourceClassType | string>} [args.resourceTypeOverrides] - Per-resourceType routing overrides: a resource class, or a string alias resolved through the registry.
|
|
59
59
|
* @param {import("../authorization/ability.js").default} [args.ability] - Ability scoping routed record lookups and create membership checks.
|
|
60
60
|
* @param {Record<string, ?>} [args.abilityContext] - Ability context passed to routed resources.
|
|
@@ -109,9 +109,7 @@ export default class SyncEnvelopeReplayService {
|
|
|
109
109
|
body: unknown;
|
|
110
110
|
}) => Promise<void>) | undefined;
|
|
111
111
|
broadcasts?: SyncReplayBroadcast[] | undefined;
|
|
112
|
-
configuration?:
|
|
113
|
-
getBackendProjects: () => import("../configuration-types.js").BackendProjectConfiguration[];
|
|
114
|
-
} | undefined;
|
|
112
|
+
configuration?: import("../configuration.js").default | undefined;
|
|
115
113
|
resourceTypeOverrides?: Record<string, string | import("../configuration-types.js").FrontendModelResourceClassType> | undefined;
|
|
116
114
|
ability?: import("../authorization/ability.js").default | undefined;
|
|
117
115
|
abilityContext?: Record<string, any> | undefined;
|
|
@@ -138,9 +136,7 @@ export default class SyncEnvelopeReplayService {
|
|
|
138
136
|
}) => Promise<void>) | null;
|
|
139
137
|
broadcasts: SyncReplayBroadcast[] | null;
|
|
140
138
|
applyHandlers: Record<string, (args: Record<string, unknown>) => Promise<unknown>> | null;
|
|
141
|
-
configuration:
|
|
142
|
-
getBackendProjects: () => import("../configuration-types.js").BackendProjectConfiguration[];
|
|
143
|
-
} | null;
|
|
139
|
+
configuration: import("../configuration.js").default | null;
|
|
144
140
|
resourceTypeOverrides: Record<string, string | import("../configuration-types.js").FrontendModelResourceClassType> | null;
|
|
145
141
|
ability: import("../authorization/ability.js").default | null;
|
|
146
142
|
abilityContext: Record<string, any> | null;
|
|
@@ -156,9 +152,10 @@ export default class SyncEnvelopeReplayService {
|
|
|
156
152
|
/**
|
|
157
153
|
* Replays a sync batch.
|
|
158
154
|
* @param {Record<string, ?>} params - Request params carrying authentication and syncs.
|
|
155
|
+
* @param {Record<string, ?>} [requestState] - Request-local state passed to authentication/sync extraction hooks; subclasses may use this to share pre-computed per-request data without instance mutation.
|
|
159
156
|
* @returns {Promise<{syncs: Array<Record<string, ?>>, status?: string, errorCode?: string, errorMessage?: string}>} Replay response.
|
|
160
157
|
*/
|
|
161
|
-
replay(params: Record<string, unknown>): Promise<{
|
|
158
|
+
replay(params: Record<string, unknown>, requestState?: Record<string, unknown>): Promise<{
|
|
162
159
|
syncs: Array<Record<string, unknown>>;
|
|
163
160
|
status?: string;
|
|
164
161
|
errorCode?: string;
|
|
@@ -170,9 +167,10 @@ export default class SyncEnvelopeReplayService {
|
|
|
170
167
|
* Defaults to a token-model lookup when `authenticationTokenModel` is
|
|
171
168
|
* configured; otherwise apps override this hook.
|
|
172
169
|
* @param {Record<string, ?>} params - Request params.
|
|
170
|
+
* @param {Record<string, ?>} [_requestState] - Request-local state populated by subclasses before the base replay loop runs.
|
|
173
171
|
* @returns {Promise<{authenticated: true, actor: ?} | {authenticated: false, errorCode: string, errorMessage: string}>} Auth result.
|
|
174
172
|
*/
|
|
175
|
-
authenticateReplay(params: Record<string, unknown>): Promise<{
|
|
173
|
+
authenticateReplay(params: Record<string, unknown>, _requestState?: Record<string, unknown>): Promise<{
|
|
176
174
|
authenticated: true;
|
|
177
175
|
actor: unknown;
|
|
178
176
|
} | {
|
|
@@ -182,19 +180,21 @@ export default class SyncEnvelopeReplayService {
|
|
|
182
180
|
}>;
|
|
183
181
|
/**
|
|
184
182
|
* Builds per-batch mutable context for caches shared across sync items.
|
|
185
|
-
* @param {{actor: ?, params: Record<string, ?>}} _args - Actor and request
|
|
183
|
+
* @param {{actor: ?, params: Record<string, ?>, requestState: Record<string, ?>}} _args - Actor, request params, and request-local state.
|
|
186
184
|
* @returns {Promise<Record<string, ?>>} Replay context.
|
|
187
185
|
*/
|
|
188
186
|
buildReplayContext(_args: {
|
|
189
187
|
actor: unknown;
|
|
190
188
|
params: Record<string, unknown>;
|
|
189
|
+
requestState: Record<string, unknown>;
|
|
191
190
|
}): Promise<Record<string, unknown>>;
|
|
192
191
|
/**
|
|
193
192
|
* Returns raw sync entries from request params.
|
|
194
193
|
* @param {Record<string, ?>} params - Request params.
|
|
194
|
+
* @param {Record<string, ?>} [_requestState] - Request-local state populated by subclasses before the base replay loop runs.
|
|
195
195
|
* @returns {Array<?>} Raw sync entries.
|
|
196
196
|
*/
|
|
197
|
-
replaySyncs(params: Record<string, unknown>): Array<unknown>;
|
|
197
|
+
replaySyncs(params: Record<string, unknown>, _requestState?: Record<string, unknown>): Array<unknown>;
|
|
198
198
|
/**
|
|
199
199
|
* Normalizes one sync entry.
|
|
200
200
|
* @param {?} rawSync - Raw sync entry.
|
|
@@ -308,17 +308,36 @@ export default class SyncEnvelopeReplayService {
|
|
|
308
308
|
* @returns {SyncReplayResourceRegistration | null} Resolved registration or null when unroutable.
|
|
309
309
|
*/
|
|
310
310
|
resolveReplayResourceRegistration(resourceType: string): SyncReplayResourceRegistration | null;
|
|
311
|
+
/**
|
|
312
|
+
* Resolves the ability and resource context used to authorize routed
|
|
313
|
+
* resources. Defaults to the constructor-wide ability/abilityContext;
|
|
314
|
+
* subclasses (signed replay) override this to derive authorization from a
|
|
315
|
+
* verified actor/grant instead of uploader-global state.
|
|
316
|
+
* @param {{actor: ?, context: Record<string, ?>}} _args - Replay actor and batch context.
|
|
317
|
+
* @returns {Promise<{ability: import("../authorization/ability.js").default | undefined, abilityContext: Record<string, ?>}>} Ability and resource context.
|
|
318
|
+
*/
|
|
319
|
+
replayAbilityFor(_args: {
|
|
320
|
+
actor: unknown;
|
|
321
|
+
context: Record<string, unknown>;
|
|
322
|
+
}): Promise<{
|
|
323
|
+
ability: import("../authorization/ability.js").default | undefined;
|
|
324
|
+
abilityContext: Record<string, unknown>;
|
|
325
|
+
}>;
|
|
311
326
|
/**
|
|
312
327
|
* Builds the routed resource instance handling one mutation.
|
|
313
328
|
* @param {object} args - Options.
|
|
329
|
+
* @param {?} args.actor - Replay actor.
|
|
330
|
+
* @param {Record<string, ?>} args.context - Replay context.
|
|
314
331
|
* @param {import("./sync-envelope-replay-service.js").SyncReplayMutation} args.mutation - Normalized replay mutation.
|
|
315
332
|
* @param {SyncReplayResourceRegistration} args.registration - Resolved resource registration.
|
|
316
|
-
* @returns {import("../frontend-model-resource/base-resource.js").default} Routed resource instance.
|
|
333
|
+
* @returns {Promise<import("../frontend-model-resource/base-resource.js").default>} Routed resource instance.
|
|
317
334
|
*/
|
|
318
|
-
buildReplayResource({ mutation, registration }: {
|
|
335
|
+
buildReplayResource({ actor, context, mutation, registration }: {
|
|
336
|
+
actor: unknown;
|
|
337
|
+
context: Record<string, unknown>;
|
|
319
338
|
mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation;
|
|
320
339
|
registration: SyncReplayResourceRegistration;
|
|
321
|
-
}): import("../frontend-model-resource/base-resource.js").default
|
|
340
|
+
}): Promise<import("../frontend-model-resource/base-resource.js").default>;
|
|
322
341
|
/**
|
|
323
342
|
* Applies one mutation through its routed frontend-model resource:
|
|
324
343
|
* authorization, ability-scoped record lookup, schema normalization and
|
|
@@ -328,12 +347,62 @@ export default class SyncEnvelopeReplayService {
|
|
|
328
347
|
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation}} args - Actor, batch context, existing sync row, and mutation.
|
|
329
348
|
* @returns {Promise<Record<string, ?>>} Apply result with record, created/deleted flags, and afterSyncApply extras.
|
|
330
349
|
*/
|
|
331
|
-
applyRoutedReplayMutation({ context, existingSync, mutation }: {
|
|
350
|
+
applyRoutedReplayMutation({ actor, context, existingSync, mutation }: {
|
|
332
351
|
actor: unknown;
|
|
333
352
|
context: Record<string, unknown>;
|
|
334
353
|
existingSync: unknown;
|
|
335
354
|
mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation;
|
|
336
355
|
}): Promise<Record<string, unknown>>;
|
|
356
|
+
/**
|
|
357
|
+
* Dispatches a routed sync mutation whose syncType matches a resource-declared
|
|
358
|
+
* custom command. Returns null when the mutation is not a command so the
|
|
359
|
+
* caller can fall through to the default upsert path.
|
|
360
|
+
* @param {{context: Record<string, ?>, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation, resource: import("../frontend-model-resource/base-resource.js").default}} args - Command dispatch args.
|
|
361
|
+
* @returns {Promise<Record<string, ?> | null>} Command apply result or null.
|
|
362
|
+
*/
|
|
363
|
+
applyRoutedReplayCommand({ context, mutation, resource }: {
|
|
364
|
+
context: Record<string, unknown>;
|
|
365
|
+
mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation;
|
|
366
|
+
resource: import("../frontend-model-resource/base-resource.js").default;
|
|
367
|
+
}): Promise<Record<string, unknown> | null>;
|
|
368
|
+
/**
|
|
369
|
+
* Resolves the custom-command configuration declared on a routed resource.
|
|
370
|
+
* @param {import("../frontend-model-resource/base-resource.js").default} resource - Routed resource instance.
|
|
371
|
+
* @returns {{collectionCommands: Record<string, string>, memberCommands: Record<string, string>}} Command config.
|
|
372
|
+
*/
|
|
373
|
+
resourceCommandConfig(resource: import("../frontend-model-resource/base-resource.js").default): {
|
|
374
|
+
collectionCommands: Record<string, string>;
|
|
375
|
+
memberCommands: Record<string, string>;
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Resolves the resource method name for a syncType when it names a declared
|
|
379
|
+
* custom command.
|
|
380
|
+
* @param {{commandConfig: {collectionCommands: Record<string, string>, memberCommands: Record<string, string>}, syncType: string}} args - Lookup args.
|
|
381
|
+
* @returns {string | null} Method name or null.
|
|
382
|
+
*/
|
|
383
|
+
commandMethodNameForSyncType({ commandConfig, syncType }: {
|
|
384
|
+
commandConfig: {
|
|
385
|
+
collectionCommands: Record<string, string>;
|
|
386
|
+
memberCommands: Record<string, string>;
|
|
387
|
+
};
|
|
388
|
+
syncType: string;
|
|
389
|
+
}): string | null;
|
|
390
|
+
/**
|
|
391
|
+
* Builds the arguments object passed to a resource command method. Member
|
|
392
|
+
* commands receive the envelope's resourceId as `id`; the envelope identity
|
|
393
|
+
* is assigned after the payload so a payload `id` can never retarget the
|
|
394
|
+
* command away from the resource the authorization hooks approved.
|
|
395
|
+
* @param {{commandConfig: {collectionCommands: Record<string, string>, memberCommands: Record<string, string>}, commandMethodName: string, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation}} args - Args builder args.
|
|
396
|
+
* @returns {Record<string, ?>} Command method arguments.
|
|
397
|
+
*/
|
|
398
|
+
commandArgsForMutation({ commandConfig, commandMethodName, mutation }: {
|
|
399
|
+
commandConfig: {
|
|
400
|
+
collectionCommands: Record<string, string>;
|
|
401
|
+
memberCommands: Record<string, string>;
|
|
402
|
+
};
|
|
403
|
+
commandMethodName: string;
|
|
404
|
+
mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation;
|
|
405
|
+
}): Record<string, unknown>;
|
|
337
406
|
/**
|
|
338
407
|
* Applies a routed delete mutation. The record is marked as a server apply
|
|
339
408
|
* for the duration of the replay-owned destroy - an active SyncPublisher
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-envelope-replay-service.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-envelope-replay-service.js"],"names":[],"mappings":"AASA;;;;;;GAMG;AACH;;;;;;;;;GASG;AACH;;;;;;;GAOG;AAEH;;;;;;;;GAQG;AACH;IACE;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,mBAjBG;QAAqG,MAAM;oBAA1F,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI;mBAAS,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI;;QAC3E,SAAS,GAAlB,OAAC;QACa,qBAAqB;QAC1B,wBAAwB,GAAjC,OAAC;QACa,yBAAyB;QACzB,wBAAwB;QACsF,aAAa;;;;sBAflH,CAAA;;;;;;;;;;;;;;;;;;;;;;;oBAeA,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,KAAK,OAAO,CAAC,OAAC,CAAC;QACD,sBAAsB,WAArE,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC;QACI,qBAAqB,WAAhE;YAAC,QAAQ,EAAE,OAAC,CAAC;YAAC,WAAW,EAAE,OAAC,CAAA;SAAC,KAAK,OAAC;QACiD,WAAW,gBAA1F;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,CAAC;YAAC,IAAI,EAAE,OAAC,CAAA;SAAC,KAAK,OAAO,CAAC,IAAI,CAAC;QACtD,UAAU;
|
|
1
|
+
{"version":3,"file":"sync-envelope-replay-service.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-envelope-replay-service.js"],"names":[],"mappings":"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"}
|