@aws-amplify/backend-notifications 0.0.0-test-20260708085627
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 +235 -0
- package/lib/campaign-association-asset/index.js +48413 -0
- package/lib/constants.d.ts +122 -0
- package/lib/constants.js +125 -0
- package/lib/construct.d.ts +283 -0
- package/lib/construct.js +824 -0
- package/lib/factory.d.ts +53 -0
- package/lib/factory.js +158 -0
- package/lib/handler-asset/index.js +530 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +5 -0
- package/lib/lambda/campaign-association/handler.d.ts +29 -0
- package/lib/lambda/campaign-association/handler.js +80 -0
- package/lib/lambda/campaign-association/integration.d.ts +59 -0
- package/lib/lambda/campaign-association/integration.js +108 -0
- package/lib/lambda/campaign-association/onboarding.d.ts +25 -0
- package/lib/lambda/campaign-association/onboarding.js +74 -0
- package/lib/lambda/identify/device_resolver.d.ts +18 -0
- package/lib/lambda/identify/device_resolver.js +56 -0
- package/lib/lambda/identify/handler.d.ts +17 -0
- package/lib/lambda/identify/handler.js +124 -0
- package/lib/lambda/identify/mapping.d.ts +61 -0
- package/lib/lambda/identify/mapping.js +171 -0
- package/lib/lambda/identify/merge_resolver.d.ts +26 -0
- package/lib/lambda/identify/merge_resolver.js +36 -0
- package/lib/lambda/identify/principal.d.ts +68 -0
- package/lib/lambda/identify/principal.js +48 -0
- package/lib/lambda/identify/profile_resolver.d.ts +35 -0
- package/lib/lambda/identify/profile_resolver.js +65 -0
- package/lib/lambda/identify/types.d.ts +90 -0
- package/lib/lambda/identify/types.js +10 -0
- package/lib/lambda/identify/validation.d.ts +15 -0
- package/lib/lambda/identify/validation.js +99 -0
- package/lib/lambda/push/delivery.d.ts +49 -0
- package/lib/lambda/push/delivery.js +120 -0
- package/lib/lambda/push/device_lookup.d.ts +35 -0
- package/lib/lambda/push/device_lookup.js +88 -0
- package/lib/lambda/push/eum_client.d.ts +31 -0
- package/lib/lambda/push/eum_client.js +140 -0
- package/lib/lambda/push/event.d.ts +32 -0
- package/lib/lambda/push/event.js +122 -0
- package/lib/lambda/push/fixtures/real_journey_event.d.ts +19 -0
- package/lib/lambda/push/fixtures/real_journey_event.js +22 -0
- package/lib/lambda/push/handler.d.ts +15 -0
- package/lib/lambda/push/handler.js +86 -0
- package/lib/lambda/push/message_template.d.ts +72 -0
- package/lib/lambda/push/message_template.js +270 -0
- package/lib/lambda/push/payload.d.ts +25 -0
- package/lib/lambda/push/payload.js +53 -0
- package/lib/lambda/push/types.d.ts +153 -0
- package/lib/lambda/push/types.js +4 -0
- package/lib/lambda/shared/retry.d.ts +18 -0
- package/lib/lambda/shared/retry.js +45 -0
- package/lib/object_types.d.ts +63 -0
- package/lib/object_types.js +131 -0
- package/lib/push-handler-asset/index.js +75517 -0
- package/lib/types.d.ts +125 -0
- package/lib/types.js +2 -0
- package/package.json +49 -0
package/lib/factory.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ConstructFactory } from '@aws-amplify/plugin-types';
|
|
2
|
+
import { AmplifyNotifications } from './construct.js';
|
|
3
|
+
import { NotificationsFactoryProps } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Include an Amazon Connect Customer Profiles-backed notifications resource in
|
|
6
|
+
* your Amplify backend. It registers the AmplifyProfile / AmplifyDevice object
|
|
7
|
+
* types, a least-privilege identify-user Lambda + a JWT-authorized HTTP API, and
|
|
8
|
+
* the push-delivery Lambda (invoked by a Connect Journey Custom-action) with a
|
|
9
|
+
* minimal AWS End User Messaging application. The invoke endpoint / region /
|
|
10
|
+
* domain name are surfaced under `custom.CustomerProfiles` in
|
|
11
|
+
* `amplify_outputs.json`.
|
|
12
|
+
*
|
|
13
|
+
* By DEFAULT (no `domainName`) it CREATES FROM SCRATCH: a brand-new Amazon
|
|
14
|
+
* Connect instance AND a brand-new Customer Profiles domain (generated, stable
|
|
15
|
+
* names) are provisioned and the object types are registered into that new
|
|
16
|
+
* domain — zero pre-existing Connect setup required, and Connect is fully hidden
|
|
17
|
+
* from the caller.
|
|
18
|
+
*
|
|
19
|
+
* Provide `domainName` to ATTACH to an EXISTING Customer Profiles domain — e.g.
|
|
20
|
+
* the domain Amazon Connect auto-creates for your instance — registering the
|
|
21
|
+
* object types into it (additive), without creating an instance or a domain.
|
|
22
|
+
*
|
|
23
|
+
* Optionally provide `apns` and/or `fcm` to enable the corresponding push
|
|
24
|
+
* channel on the created End User Messaging (Pinpoint) application. The
|
|
25
|
+
* sensitive key material (APNs `.p8`, FCM service-account JSON) is supplied via
|
|
26
|
+
* Amplify `secret()` and resolved at deploy time; non-secret identifiers are
|
|
27
|
+
* plain props. Omit them to leave the channels not configured (unchanged
|
|
28
|
+
* behavior).
|
|
29
|
+
* @example
|
|
30
|
+
* import { defineBackend } from '@aws-amplify/backend';
|
|
31
|
+
* import { defineNotifications } from '@aws-amplify/backend-notifications';
|
|
32
|
+
* import { auth } from './auth/resource';
|
|
33
|
+
* import { secret } from '@aws-amplify/backend';
|
|
34
|
+
*
|
|
35
|
+
* defineBackend({
|
|
36
|
+
* auth,
|
|
37
|
+
* // Zero-config: creates a Connect instance + Customer Profiles domain:
|
|
38
|
+
* notifications: defineNotifications(),
|
|
39
|
+
* // ...or attach to an existing domain and enable push channels:
|
|
40
|
+
* // notifications: defineNotifications({
|
|
41
|
+
* // domainName: 'amazon-connect-amplify',
|
|
42
|
+
* // apns: {
|
|
43
|
+
* // keySecret: secret('APNS_SIGNING_KEY'),
|
|
44
|
+
* // keyId: 'ABC123DEFG',
|
|
45
|
+
* // teamId: 'DEF456GHIJ',
|
|
46
|
+
* // bundleId: 'com.example.app',
|
|
47
|
+
* // },
|
|
48
|
+
* // fcm: { credentialsSecret: secret('FCM_SERVICE_ACCOUNT_JSON') },
|
|
49
|
+
* // }),
|
|
50
|
+
* });
|
|
51
|
+
*/
|
|
52
|
+
export declare const defineNotifications: (props?: NotificationsFactoryProps) => ConstructFactory<AmplifyNotifications>;
|
|
53
|
+
//# sourceMappingURL=factory.d.ts.map
|
package/lib/factory.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Stack } from 'aws-cdk-lib';
|
|
2
|
+
import { customOutputKey } from '@aws-amplify/backend-output-schemas';
|
|
3
|
+
import { AmplifyUserError } from '@aws-amplify/platform-core';
|
|
4
|
+
import { AmplifyNotifications } from './construct.js';
|
|
5
|
+
import { OUTPUT_KEY } from './constants.js';
|
|
6
|
+
/**
|
|
7
|
+
* Generates the {@link AmplifyNotifications} construct in the resolved stack,
|
|
8
|
+
* wiring the HTTP API's JWT authorizer to the app's Cognito user pool.
|
|
9
|
+
*/
|
|
10
|
+
class NotificationsGenerator {
|
|
11
|
+
props;
|
|
12
|
+
authResources;
|
|
13
|
+
resourceGroupName = 'notifications';
|
|
14
|
+
constructor(props, authResources) {
|
|
15
|
+
this.props = props;
|
|
16
|
+
this.authResources = authResources;
|
|
17
|
+
}
|
|
18
|
+
generateContainerEntry = ({ scope, backendSecretResolver, }) => {
|
|
19
|
+
const { userPool, userPoolClient } = this.authResources.resources;
|
|
20
|
+
const region = Stack.of(scope).region;
|
|
21
|
+
return new AmplifyNotifications(scope, 'notifications', {
|
|
22
|
+
// Build the Cognito issuer / audience from THIS app's user pool so the
|
|
23
|
+
// HTTP API JWT authorizer only trusts tokens minted by this backend.
|
|
24
|
+
jwtIssuer: `https://cognito-idp.${region}.amazonaws.com/${userPool.userPoolId}`,
|
|
25
|
+
jwtAudience: [userPoolClient.userPoolClientId],
|
|
26
|
+
// `domainName` omitted => create-from-scratch (default); provided => attach.
|
|
27
|
+
domainName: this.props.domainName,
|
|
28
|
+
instanceAlias: this.props.instanceAlias,
|
|
29
|
+
expirationDays: this.props.expirationDays,
|
|
30
|
+
// Resolve the optional push-channel secret material (Amplify `secret()`) to
|
|
31
|
+
// deploy-time CFN tokens here — the construct stays framework-agnostic and
|
|
32
|
+
// receives only plain strings. Mirrors how `defineAuth` resolves external
|
|
33
|
+
// provider secrets in `translate_auth_props`.
|
|
34
|
+
apnsChannel: this.props.apns
|
|
35
|
+
? {
|
|
36
|
+
tokenKey: backendSecretResolver
|
|
37
|
+
.resolveSecret(this.props.apns.keySecret)
|
|
38
|
+
.unsafeUnwrap(),
|
|
39
|
+
keyId: this.props.apns.keyId,
|
|
40
|
+
teamId: this.props.apns.teamId,
|
|
41
|
+
bundleId: this.props.apns.bundleId,
|
|
42
|
+
sandbox: this.props.apns.sandbox,
|
|
43
|
+
}
|
|
44
|
+
: undefined,
|
|
45
|
+
fcmChannel: this.props.fcm
|
|
46
|
+
? {
|
|
47
|
+
serviceJson: backendSecretResolver
|
|
48
|
+
.resolveSecret(this.props.fcm.credentialsSecret)
|
|
49
|
+
.unsafeUnwrap(),
|
|
50
|
+
}
|
|
51
|
+
: undefined,
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Singleton factory for the notifications backend, used in a Gen2
|
|
57
|
+
* `defineBackend` definition.
|
|
58
|
+
*/
|
|
59
|
+
class AmplifyNotificationsFactory {
|
|
60
|
+
props;
|
|
61
|
+
generator;
|
|
62
|
+
outputStored = false;
|
|
63
|
+
constructor(props) {
|
|
64
|
+
this.props = props;
|
|
65
|
+
}
|
|
66
|
+
getInstance = (getInstanceProps) => {
|
|
67
|
+
const { constructContainer, outputStorageStrategy } = getInstanceProps;
|
|
68
|
+
// Resolve THIS app's auth resource (Cognito user pool + client) so the JWT
|
|
69
|
+
// authorizer trusts only tokens issued by this backend.
|
|
70
|
+
const authResources = constructContainer
|
|
71
|
+
.getConstructFactory('AuthResources')
|
|
72
|
+
?.getInstance(getInstanceProps);
|
|
73
|
+
if (!authResources) {
|
|
74
|
+
throw new AmplifyUserError('NotificationsMissingAuthError', {
|
|
75
|
+
message: 'defineNotifications requires an auth resource to be present in the backend.',
|
|
76
|
+
resolution: 'Add `auth` to your backend definition, e.g. `defineBackend({ auth, notifications })`.',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (!this.generator) {
|
|
80
|
+
this.generator = new NotificationsGenerator(this.props, authResources);
|
|
81
|
+
}
|
|
82
|
+
const notifications = constructContainer.getOrCompute(this.generator);
|
|
83
|
+
// Surface the endpoint / region to the client via a custom backend output
|
|
84
|
+
// (written once, even though getInstance is a memoized singleton lookup).
|
|
85
|
+
if (!this.outputStored) {
|
|
86
|
+
this.storeOutput(outputStorageStrategy, notifications);
|
|
87
|
+
this.outputStored = true;
|
|
88
|
+
}
|
|
89
|
+
return notifications;
|
|
90
|
+
};
|
|
91
|
+
storeOutput = (outputStorageStrategy, notifications) => {
|
|
92
|
+
outputStorageStrategy.addBackendOutputEntry(customOutputKey, {
|
|
93
|
+
version: '1',
|
|
94
|
+
payload: {
|
|
95
|
+
// Serialized `Partial<ClientConfig>` — surfaced under `custom` in
|
|
96
|
+
// `amplify_outputs.json`, matching `backend.addOutput({ custom })`.
|
|
97
|
+
customOutputs: JSON.stringify({
|
|
98
|
+
custom: {
|
|
99
|
+
[OUTPUT_KEY]: {
|
|
100
|
+
endpoint: notifications.apiEndpoint,
|
|
101
|
+
region: notifications.stack.region,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
}),
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Include an Amazon Connect Customer Profiles-backed notifications resource in
|
|
111
|
+
* your Amplify backend. It registers the AmplifyProfile / AmplifyDevice object
|
|
112
|
+
* types, a least-privilege identify-user Lambda + a JWT-authorized HTTP API, and
|
|
113
|
+
* the push-delivery Lambda (invoked by a Connect Journey Custom-action) with a
|
|
114
|
+
* minimal AWS End User Messaging application. The invoke endpoint / region /
|
|
115
|
+
* domain name are surfaced under `custom.CustomerProfiles` in
|
|
116
|
+
* `amplify_outputs.json`.
|
|
117
|
+
*
|
|
118
|
+
* By DEFAULT (no `domainName`) it CREATES FROM SCRATCH: a brand-new Amazon
|
|
119
|
+
* Connect instance AND a brand-new Customer Profiles domain (generated, stable
|
|
120
|
+
* names) are provisioned and the object types are registered into that new
|
|
121
|
+
* domain — zero pre-existing Connect setup required, and Connect is fully hidden
|
|
122
|
+
* from the caller.
|
|
123
|
+
*
|
|
124
|
+
* Provide `domainName` to ATTACH to an EXISTING Customer Profiles domain — e.g.
|
|
125
|
+
* the domain Amazon Connect auto-creates for your instance — registering the
|
|
126
|
+
* object types into it (additive), without creating an instance or a domain.
|
|
127
|
+
*
|
|
128
|
+
* Optionally provide `apns` and/or `fcm` to enable the corresponding push
|
|
129
|
+
* channel on the created End User Messaging (Pinpoint) application. The
|
|
130
|
+
* sensitive key material (APNs `.p8`, FCM service-account JSON) is supplied via
|
|
131
|
+
* Amplify `secret()` and resolved at deploy time; non-secret identifiers are
|
|
132
|
+
* plain props. Omit them to leave the channels not configured (unchanged
|
|
133
|
+
* behavior).
|
|
134
|
+
* @example
|
|
135
|
+
* import { defineBackend } from '@aws-amplify/backend';
|
|
136
|
+
* import { defineNotifications } from '@aws-amplify/backend-notifications';
|
|
137
|
+
* import { auth } from './auth/resource';
|
|
138
|
+
* import { secret } from '@aws-amplify/backend';
|
|
139
|
+
*
|
|
140
|
+
* defineBackend({
|
|
141
|
+
* auth,
|
|
142
|
+
* // Zero-config: creates a Connect instance + Customer Profiles domain:
|
|
143
|
+
* notifications: defineNotifications(),
|
|
144
|
+
* // ...or attach to an existing domain and enable push channels:
|
|
145
|
+
* // notifications: defineNotifications({
|
|
146
|
+
* // domainName: 'amazon-connect-amplify',
|
|
147
|
+
* // apns: {
|
|
148
|
+
* // keySecret: secret('APNS_SIGNING_KEY'),
|
|
149
|
+
* // keyId: 'ABC123DEFG',
|
|
150
|
+
* // teamId: 'DEF456GHIJ',
|
|
151
|
+
* // bundleId: 'com.example.app',
|
|
152
|
+
* // },
|
|
153
|
+
* // fcm: { credentialsSecret: secret('FCM_SERVICE_ACCOUNT_JSON') },
|
|
154
|
+
* // }),
|
|
155
|
+
* });
|
|
156
|
+
*/
|
|
157
|
+
export const defineNotifications = (props = {}) => new AmplifyNotificationsFactory(props);
|
|
158
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVdBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDcEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1Qzs7O0dBR0c7QUFDSCxNQUFNLHNCQUFzQjtJQUlQO0lBQ0E7SUFKVixpQkFBaUIsR0FBVyxlQUFlLENBQUM7SUFFckQsWUFDbUIsS0FBZ0MsRUFDaEMsYUFFaEI7UUFIZ0IsVUFBSyxHQUFMLEtBQUssQ0FBMkI7UUFDaEMsa0JBQWEsR0FBYixhQUFhLENBRTdCO0lBQ0EsQ0FBQztJQUVKLHNCQUFzQixHQUFHLENBQUMsRUFDeEIsS0FBSyxFQUNMLHFCQUFxQixHQUNPLEVBQXdCLEVBQUU7UUFDdEQsTUFBTSxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQztRQUNsRSxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUV0QyxPQUFPLElBQUksb0JBQW9CLENBQUMsS0FBSyxFQUFFLGVBQWUsRUFBRTtZQUN0RCx1RUFBdUU7WUFDdkUscUVBQXFFO1lBQ3JFLFNBQVMsRUFBRSx1QkFBdUIsTUFBTSxrQkFBa0IsUUFBUSxDQUFDLFVBQVUsRUFBRTtZQUMvRSxXQUFXLEVBQUUsQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUM7WUFDOUMsNkVBQTZFO1lBQzdFLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFD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Q3BFLGFBQWEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDO29CQUM1QixNQUFNLEVBQUU7d0JBQ04sQ0FBQyxVQUFVLENBQUMsRUFBRTs0QkFDWixRQUFRLEVBQUUsYUFBYSxDQUFDLFdBQVc7NEJBQ25DLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU07eUJBQ25DO3FCQUNGO2lCQUNGLENBQUM7YUFDSDtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztDQUNIO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0NHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FDakMsUUFBbUMsRUFBRSxFQUNHLEVBQUUsQ0FDMUMsSUFBSSwyQkFBMkIsQ0FBQyxLQUFLLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEF1dGhSZXNvdXJjZXMsXG4gIEJhY2tlbmRPdXRwdXRFbnRyeSxcbiAgQmFja2VuZE91dHB1dFN0b3JhZ2VTdHJhdGVneSxcbiAgQ29uc3RydWN0Q29udGFpbmVyRW50cnlHZW5lcmF0b3IsXG4gIENvbnN0cnVjdEZhY3RvcnksXG4gIENvbnN0cnVjdEZhY3RvcnlHZXRJbnN0YW5jZVByb3BzLFxuICBHZW5lcmF0ZUNvbnRhaW5lckVudHJ5UHJvcHMsXG4gIFJlZmVyZW5jZUF1dGhSZXNvdXJjZXMsXG4gIFJlc291cmNlUHJvdmlkZXIsXG59IGZyb20gJ0Bhd3MtYW1wbGlmeS9wbHVnaW4tdHlwZXMnO1xuaW1wb3J0IHsgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBjdXN0b21PdXRwdXRLZXkgfSBmcm9tICdAYXdzLWFtcGxpZnkvYmFja2VuZC1vdXRwdXQtc2NoZW1hcyc7XG5pbXBvcnQgeyBBbXBsaWZ5VXNlckVycm9yIH0gZnJvbSAnQGF3cy1hbXBsaWZ5L3BsYXRmb3JtLWNvcmUnO1xuaW1wb3J0IHsgQW1wbGlmeU5vdGlmaWNhdGlvbnMgfSBmcm9tICcuL2NvbnN0cnVjdC5qcyc7XG5pbXBvcnQgeyBOb3RpZmljYXRpb25zRmFjdG9yeVByb3BzIH0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBPVVRQVVRfS0VZIH0gZnJvbSAnLi9jb25zdGFudHMuanMnO1xuXG4vKipcbiAqIEdlbmVyYXRlcyB0aGUge0BsaW5rIEFtcGxpZnlOb3RpZmljYXRpb25zfSBjb25zdHJ1Y3QgaW4gdGhlIHJlc29sdmVkIHN0YWNrLFxuICogd2lyaW5nIHRoZSBIVFRQIEFQSSdzIEpXVCBhdXRob3JpemVyIHRvIHRoZSBhcHAncyBDb2duaXRvIHVzZXIgcG9vbC5cbiAqL1xuY2xhc3MgTm90aWZpY2F0aW9uc0dlbmVyYXRvciBpbXBsZW1lbnRzIENvbnN0cnVjdENvbnRhaW5lckVudHJ5R2VuZXJhdG9yIHtcbiAgcmVhZG9ubHkgcmVzb3VyY2VHcm91cE5hbWU6IHN0cmluZyA9ICdub3RpZmljYXRpb25zJztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBOb3RpZmljYXRpb25zRmFjdG9yeVByb3BzLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXV0aFJlc291cmNlczogUmVzb3VyY2VQcm92aWRlcjxcbiAgICAgIEF1dGhSZXNvdXJjZXMgfCBSZWZlcmVuY2VBdXRoUmVzb3VyY2VzXG4gICAgPixcbiAgKSB7fVxuXG4gIGdlbmVyYXRlQ29udGFpbmVyRW50cnkgPSAoe1xuICAgIHNjb3BlLFxuICAgIGJhY2tlbmRTZWNyZXRSZXNvbHZlcixcbiAgfTogR2VuZXJhdGVDb250YWluZXJFbnRyeVByb3BzKTogQW1wbGlmeU5vdGlmaWNhdGlvbnMgPT4ge1xuICAgIGNvbnN0IHsgdXNlclBvb2wsIHVzZXJQb29sQ2xpZW50IH0gPSB0aGlzLmF1dGhSZXNvdXJjZXMucmVzb3VyY2VzO1xuICAgIGNvbnN0IHJlZ2lvbiA9IFN0YWNrLm9mKHNjb3BlKS5yZWdpb247XG5cbiAgICByZXR1cm4gbmV3IEFtcGxpZnlOb3RpZmljYXRpb25zKHNjb3BlLCAnbm90aWZpY2F0aW9ucycsIHtcbiAgICAgIC8vIEJ1aWxkIHRoZSBDb2duaXRvIGlzc3VlciAvIGF1ZGllbmNlIGZyb20gVEhJUyBhcHAncyB1c2VyIHBvb2wgc28gdGhlXG4gICAgICAvLyBIVFRQIEFQSSBKV1QgYXV0aG9yaXplciBvbmx5IHRydXN0cyB0b2tlbnMgbWludGVkIGJ5IHRoaXMgYmFja2VuZC5cbiAgICAgIGp3dElzc3VlcjogYGh0dHBzOi8vY29nbml0by1pZHAuJHtyZWdpb259LmFtYXpvbmF3cy5jb20vJHt1c2VyUG9vbC51c2VyUG9vbElkfWAsXG4gICAgICBqd3RBdWRpZW5jZTogW3VzZXJQb29sQ2xpZW50LnVzZXJQb29sQ2xpZW50SWRdLFxuICAgICAgLy8gYGRvbWFpbk5hbWVgIG9taXR0ZWQgPT4gY3JlYXRlLWZyb20tc2NyYXRjaCAoZGVmYXVsdCk7IHByb3ZpZGVkID0+IGF0dGFjaC5cbiAgICAgIGRvbWFpbk5hbWU6IHRoaXMucHJvcHMuZG9tYWluTmFtZSxcbiAgICAgIGluc3RhbmNlQWxpYXM6IHRoaXMucHJvcHMuaW5zdGFuY2VBbGlhcyxcbiAgICAgIGV4cGlyYXRpb25EYXlzOiB0aGlzLnByb3BzLmV4cGlyYXRpb25EYXlzLFxuICAgICAgLy8gUmVzb2x2ZSB0aGUgb3B0aW9uYWwgcHVzaC1jaGFubmVsIHNlY3JldCBtYXRlcmlhbCAoQW1wbGlmeSBgc2VjcmV0KClgKSB0b1xuICAgICAgLy8gZGVwbG95LXRpbWUgQ0ZOIHRva2VucyBoZXJlIOKAlCB0aGUgY29uc3RydWN0IHN0YXlzIGZyYW1ld29yay1hZ25vc3RpYyBhbmRcbiAgICAgIC8vIHJlY2VpdmVzIG9ubHkgcGxhaW4gc3RyaW5ncy4gTWlycm9ycyBob3cgYGRlZmluZUF1dGhgIHJlc29sdmVzIGV4dGVybmFsXG4gICAgICAvLyBwcm92aWRlciBzZWNyZXRzIGluIGB0cmFuc2xhdGVfYXV0aF9wcm9wc2AuXG4gICAgICBhcG5zQ2hhbm5lbDogdGhpcy5wcm9wcy5hcG5zXG4gICAgICAgID8ge1xuICAgICAgICAgICAgdG9rZW5LZXk6IGJhY2tlbmRTZWNyZXRSZXNvbHZlclxuICAgICAgICAgICAgICAucmVzb2x2ZVNlY3JldCh0aGlzLnByb3BzLmFwbnMua2V5U2VjcmV0KVxuICAgICAgICAgICAgICAudW5zYWZlVW53cmFwKCksXG4gICAgICAgICAgICBrZXlJZDogdGhpcy5wcm9wcy5hcG5zLmtleUlkLFxuICAgICAgICAgICAgdGVhbUlkOiB0aGlzLnByb3BzLmFwbnMudGVhbUlkLFxuICAgICAgICAgICAgYnVuZGxlSWQ6IHRoaXMucHJvcHMuYXBucy5idW5kbGVJZCxcbiAgICAgICAgICAgIHNhbmRib3g6IHRoaXMucHJvcHMuYXBucy5zYW5kYm94LFxuICAgICAgICAgIH1cbiAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICBmY21DaGFubmVsOiB0aGlzLnByb3BzLmZjbVxuICAgICAgICA/IHtcbiAgICAgICAgICAgIHNlcnZpY2VKc29uOiBiYWNrZW5kU2VjcmV0UmVzb2x2ZXJcbiAgICAgICAgICAgICAgLnJlc29sdmVTZWNyZXQodGhpcy5wcm9wcy5mY20uY3JlZGVudGlhbHNTZWNyZXQpXG4gICAgICAgICAgICAgIC51bnNhZmVVbndyYXAoKSxcbiAgICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgIH0pO1xuICB9O1xufVxuXG4vKipcbiAqIFNpbmdsZXRvbiBmYWN0b3J5IGZvciB0aGUgbm90aWZpY2F0aW9ucyBiYWNrZW5kLCB1c2VkIGluIGEgR2VuMlxuICogYGRlZmluZUJhY2tlbmRgIGRlZmluaXRpb24uXG4gKi9cbmNsYXNzIEFtcGxpZnlOb3RpZmljYXRpb25zRmFjdG9yeSBpbXBsZW1lbnRzIENvbnN0cnVjdEZhY3Rvcnk8QW1wbGlmeU5vdGlmaWNhdGlvbnM+IHtcbiAgcHJpdmF0ZSBnZW5lcmF0b3I6IENvbnN0cnVjdENvbnRhaW5lckVudHJ5R2VuZXJhdG9yIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG91dHB1dFN0b3JlZCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcHJvcHM6IE5vdGlmaWNhdGlvbnNGYWN0b3J5UHJvcHMpIHt9XG5cbiAgZ2V0SW5zdGFuY2UgPSAoXG4gICAgZ2V0SW5zdGFuY2VQcm9wczogQ29uc3RydWN0RmFjdG9yeUdldEluc3RhbmNlUHJvcHMsXG4gICk6IEFtcGxpZnlOb3RpZmljYXRpb25zID0+IHtcbiAgICBjb25zdCB7IGNvbnN0cnVjdENvbnRhaW5lciwgb3V0cHV0U3RvcmFnZVN0cmF0ZWd5IH0gPSBnZXRJbnN0YW5jZVByb3BzO1xuXG4gICAgLy8gUmVzb2x2ZSBUSElTIGFwcCdzIGF1dGggcmVzb3VyY2UgKENvZ25pdG8gdXNlciBwb29sICsgY2xpZW50KSBzbyB0aGUgSldUXG4gICAgLy8gYXV0aG9yaXplciB0cnVzdHMgb25seSB0b2tlbnMgaXNzdWVkIGJ5IHRoaXMgYmFja2VuZC5cbiAgICBjb25zdCBhdXRoUmVzb3VyY2VzID0gY29uc3RydWN0Q29udGFpbmVyXG4gICAgICAuZ2V0Q29uc3RydWN0RmFjdG9yeTxcbiAgICAgICAgUmVzb3VyY2VQcm92aWRlcjxBdXRoUmVzb3VyY2VzIHwgUmVmZXJlbmNlQXV0aFJlc291cmNlcz5cbiAgICAgID4oJ0F1dGhSZXNvdXJjZXMnKVxuICAgICAgPy5nZXRJbnN0YW5jZShnZXRJbnN0YW5jZVByb3BzKTtcblxuICAgIGlmICghYXV0aFJlc291cmNlcykge1xuICAgICAgdGhyb3cgbmV3IEFtcGxpZnlVc2VyRXJyb3IoJ05vdGlmaWNhdGlvbnNNaXNzaW5nQXV0aEVycm9yJywge1xuICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICdkZWZpbmVOb3RpZmljYXRpb25zIHJlcXVpcmVzIGFuIGF1dGggcmVzb3VyY2UgdG8gYmUgcHJlc2VudCBpbiB0aGUgYmFja2VuZC4nLFxuICAgICAgICByZXNvbHV0aW9uOlxuICAgICAgICAgICdBZGQgYGF1dGhgIHRvIHlvdXIgYmFja2VuZCBkZWZpbml0aW9uLCBlLmcuIGBkZWZpbmVCYWNrZW5kKHsgYXV0aCwgbm90aWZpY2F0aW9ucyB9KWAuJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5nZW5lcmF0b3IpIHtcbiAgICAgIHRoaXMuZ2VuZXJhdG9yID0gbmV3IE5vdGlmaWNhdGlvbnNHZW5lcmF0b3IodGhpcy5wcm9wcywgYXV0aFJlc291cmNlcyk7XG4gICAgfVxuICAgIGNvbnN0IG5vdGlmaWNhdGlvbnMgPSBjb25zdHJ1Y3RDb250YWluZXIuZ2V0T3JDb21wdXRlKFxuICAgICAgdGhpcy5nZW5lcmF0b3IsXG4gICAgKSBhcyBBbXBsaWZ5Tm90aWZpY2F0aW9ucztcblxuICAgIC8vIFN1cmZhY2UgdGhlIGVuZHBvaW50IC8gcmVnaW9uIHRvIHRoZSBjbGllbnQgdmlhIGEgY3VzdG9tIGJhY2tlbmQgb3V0cHV0XG4gICAgLy8gKHdyaXR0ZW4gb25jZSwgZXZlbiB0aG91Z2ggZ2V0SW5zdGFuY2UgaXMgYSBtZW1vaXplZCBzaW5nbGV0b24gbG9va3VwKS5cbiAgICBpZiAoIXRoaXMub3V0cHV0U3RvcmVkKSB7XG4gICAgICB0aGlzLnN0b3JlT3V0cHV0KG91dHB1dFN0b3JhZ2VTdHJhdGVneSwgbm90aWZpY2F0aW9ucyk7XG4gICAgICB0aGlzLm91dHB1dFN0b3JlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vdGlmaWNhdGlvbnM7XG4gIH07XG5cbiAgcHJpdmF0ZSBzdG9yZU91dHB1dCA9IChcbiAgICBvdXRwdXRTdG9yYWdlU3RyYXRlZ3k6IEJhY2tlbmRPdXRwdXRTdG9yYWdlU3RyYXRlZ3k8QmFja2VuZE91dHB1dEVudHJ5PixcbiAgICBub3RpZmljYXRpb25zOiBBbXBsaWZ5Tm90aWZpY2F0aW9ucyxcbiAgKTogdm9pZCA9PiB7XG4gICAgb3V0cHV0U3RvcmFnZVN0cmF0ZWd5LmFkZEJhY2tlbmRPdXRwdXRFbnRyeShjdXN0b21PdXRwdXRLZXksIHtcbiAgICAgIHZlcnNpb246ICcxJyxcbiAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgLy8gU2VyaWFsaXplZCBgUGFydGlhbDxDbGllbnRDb25maWc+YCDigJQgc3VyZmFjZWQgdW5kZXIgYGN1c3RvbWAgaW5cbiAgICAgICAgLy8gYGFtcGxpZnlfb3V0cHV0cy5qc29uYCwgbWF0Y2hpbmcgYGJhY2tlbmQuYWRkT3V0cHV0KHsgY3VzdG9tIH0pYC5cbiAgICAgICAgY3VzdG9tT3V0cHV0czogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIGN1c3RvbToge1xuICAgICAgICAgICAgW09VVFBVVF9LRVldOiB7XG4gICAgICAgICAgICAgIGVuZHBvaW50OiBub3RpZmljYXRpb25zLmFwaUVuZHBvaW50LFxuICAgICAgICAgICAgICByZWdpb246IG5vdGlmaWNhdGlvbnMuc3RhY2sucmVnaW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG59XG5cbi8qKlxuICogSW5jbHVkZSBhbiBBbWF6b24gQ29ubmVjdCBDdXN0b21lciBQcm9maWxlcy1iYWNrZWQgbm90aWZpY2F0aW9ucyByZXNvdXJjZSBpblxuICogeW91ciBBbXBsaWZ5IGJhY2tlbmQuIEl0IHJlZ2lzdGVycyB0aGUgQW1wbGlmeVByb2ZpbGUgLyBBbXBsaWZ5RGV2aWNlIG9iamVjdFxuICogdHlwZXMsIGEgbGVhc3QtcHJpdmlsZWdlIGlkZW50aWZ5LXVzZXIgTGFtYmRhICsgYSBKV1QtYXV0aG9yaXplZCBIVFRQIEFQSSwgYW5kXG4gKiB0aGUgcHVzaC1kZWxpdmVyeSBMYW1iZGEgKGludm9rZWQgYnkgYSBDb25uZWN0IEpvdXJuZXkgQ3VzdG9tLWFjdGlvbikgd2l0aCBhXG4gKiBtaW5pbWFsIEFXUyBFbmQgVXNlciBNZXNzYWdpbmcgYXBwbGljYXRpb24uIFRoZSBpbnZva2UgZW5kcG9pbnQgLyByZWdpb24gL1xuICogZG9tYWluIG5hbWUgYXJlIHN1cmZhY2VkIHVuZGVyIGBjdXN0b20uQ3VzdG9tZXJQcm9maWxlc2AgaW5cbiAqIGBhbXBsaWZ5X291dHB1dHMuanNvbmAuXG4gKlxuICogQnkgREVGQVVMVCAobm8gYGRvbWFpbk5hbWVgKSBpdCBDUkVBVEVTIEZST00gU0NSQVRDSDogYSBicmFuZC1uZXcgQW1hem9uXG4gKiBDb25uZWN0IGluc3RhbmNlIEFORCBhIGJyYW5kLW5ldyBDdXN0b21lciBQcm9maWxlcyBkb21haW4gKGdlbmVyYXRlZCwgc3RhYmxlXG4gKiBuYW1lcykgYXJlIHByb3Zpc2lvbmVkIGFuZCB0aGUgb2JqZWN0IHR5cGVzIGFyZSByZWdpc3RlcmVkIGludG8gdGhhdCBuZXdcbiAqIGRvbWFpbiDigJQgemVybyBwcmUtZXhpc3RpbmcgQ29ubmVjdCBzZXR1cCByZXF1aXJlZCwgYW5kIENvbm5lY3QgaXMgZnVsbHkgaGlkZGVuXG4gKiBmcm9tIHRoZSBjYWxsZXIuXG4gKlxuICogUHJvdmlkZSBgZG9tYWluTmFtZWAgdG8gQVRUQUNIIHRvIGFuIEVYSVNUSU5HIEN1c3RvbWVyIFByb2ZpbGVzIGRvbWFpbiDigJQgZS5nLlxuICogdGhlIGRvbWFpbiBBbWF6b24gQ29ubmVjdCBhdXRvLWNyZWF0ZXMgZm9yIHlvdXIgaW5zdGFuY2Ug4oCUIHJlZ2lzdGVyaW5nIHRoZVxuICogb2JqZWN0IHR5cGVzIGludG8gaXQgKGFkZGl0aXZlKSwgd2l0aG91dCBjcmVhdGluZyBhbiBpbnN0YW5jZSBvciBhIGRvbWFpbi5cbiAqXG4gKiBPcHRpb25hbGx5IHByb3ZpZGUgYGFwbnNgIGFuZC9vciBgZmNtYCB0byBlbmFibGUgdGhlIGNvcnJlc3BvbmRpbmcgcHVzaFxuICogY2hhbm5lbCBvbiB0aGUgY3JlYXRlZCBFbmQgVXNlciBNZXNzYWdpbmcgKFBpbnBvaW50KSBhcHBsaWNhdGlvbi4gVGhlXG4gKiBzZW5zaXRpdmUga2V5IG1hdGVyaWFsIChBUE5zIGAucDhgLCBGQ00gc2VydmljZS1hY2NvdW50IEpTT04pIGlzIHN1cHBsaWVkIHZpYVxuICogQW1wbGlmeSBgc2VjcmV0KClgIGFuZCByZXNvbHZlZCBhdCBkZXBsb3kgdGltZTsgbm9uLXNlY3JldCBpZGVudGlmaWVycyBhcmVcbiAqIHBsYWluIHByb3BzLiBPbWl0IHRoZW0gdG8gbGVhdmUgdGhlIGNoYW5uZWxzIG5vdCBjb25maWd1cmVkICh1bmNoYW5nZWRcbiAqIGJlaGF2aW9yKS5cbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQgeyBkZWZpbmVCYWNrZW5kIH0gZnJvbSAnQGF3cy1hbXBsaWZ5L2JhY2tlbmQnO1xuICogaW1wb3J0IHsgZGVmaW5lTm90aWZpY2F0aW9ucyB9IGZyb20gJ0Bhd3MtYW1wbGlmeS9iYWNrZW5kLW5vdGlmaWNhdGlvbnMnO1xuICogaW1wb3J0IHsgYXV0aCB9IGZyb20gJy4vYXV0aC9yZXNvdXJjZSc7XG4gKiBpbXBvcnQgeyBzZWNyZXQgfSBmcm9tICdAYXdzLWFtcGxpZnkvYmFja2VuZCc7XG4gKlxuICogZGVmaW5lQmFja2VuZCh7XG4gKiAgIGF1dGgsXG4gKiAgIC8vIFplcm8tY29uZmlnOiBjcmVhdGVzIGEgQ29ubmVjdCBpbnN0YW5jZSArIEN1c3RvbWVyIFByb2ZpbGVzIGRvbWFpbjpcbiAqICAgbm90aWZpY2F0aW9uczogZGVmaW5lTm90aWZpY2F0aW9ucygpLFxuICogICAvLyAuLi5vciBhdHRhY2ggdG8gYW4gZXhpc3RpbmcgZG9tYWluIGFuZCBlbmFibGUgcHVzaCBjaGFubmVsczpcbiAqICAgLy8gbm90aWZpY2F0aW9uczogZGVmaW5lTm90aWZpY2F0aW9ucyh7XG4gKiAgIC8vICAgZG9tYWluTmFtZTogJ2FtYXpvbi1jb25uZWN0LWFtcGxpZnknLFxuICogICAvLyAgIGFwbnM6IHtcbiAqICAgLy8gICAgIGtleVNlY3JldDogc2VjcmV0KCdBUE5TX1NJR05JTkdfS0VZJyksXG4gKiAgIC8vICAgICBrZXlJZDogJ0FCQzEyM0RFRkcnLFxuICogICAvLyAgICAgdGVhbUlkOiAnREVGNDU2R0hJSicsXG4gKiAgIC8vICAgICBidW5kbGVJZDogJ2NvbS5leGFtcGxlLmFwcCcsXG4gKiAgIC8vICAgfSxcbiAqICAgLy8gICBmY206IHsgY3JlZGVudGlhbHNTZWNyZXQ6IHNlY3JldCgnRkNNX1NFUlZJQ0VfQUNDT1VOVF9KU09OJykgfSxcbiAqICAgLy8gfSksXG4gKiB9KTtcbiAqL1xuZXhwb3J0IGNvbnN0IGRlZmluZU5vdGlmaWNhdGlvbnMgPSAoXG4gIHByb3BzOiBOb3RpZmljYXRpb25zRmFjdG9yeVByb3BzID0ge30sXG4pOiBDb25zdHJ1Y3RGYWN0b3J5PEFtcGxpZnlOb3RpZmljYXRpb25zPiA9PlxuICBuZXcgQW1wbGlmeU5vdGlmaWNhdGlvbnNGYWN0b3J5KHByb3BzKTtcbiJdfQ==
|