@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.
Files changed (59) hide show
  1. package/README.md +235 -0
  2. package/lib/campaign-association-asset/index.js +48413 -0
  3. package/lib/constants.d.ts +122 -0
  4. package/lib/constants.js +125 -0
  5. package/lib/construct.d.ts +283 -0
  6. package/lib/construct.js +824 -0
  7. package/lib/factory.d.ts +53 -0
  8. package/lib/factory.js +158 -0
  9. package/lib/handler-asset/index.js +530 -0
  10. package/lib/index.d.ts +7 -0
  11. package/lib/index.js +5 -0
  12. package/lib/lambda/campaign-association/handler.d.ts +29 -0
  13. package/lib/lambda/campaign-association/handler.js +80 -0
  14. package/lib/lambda/campaign-association/integration.d.ts +59 -0
  15. package/lib/lambda/campaign-association/integration.js +108 -0
  16. package/lib/lambda/campaign-association/onboarding.d.ts +25 -0
  17. package/lib/lambda/campaign-association/onboarding.js +74 -0
  18. package/lib/lambda/identify/device_resolver.d.ts +18 -0
  19. package/lib/lambda/identify/device_resolver.js +56 -0
  20. package/lib/lambda/identify/handler.d.ts +17 -0
  21. package/lib/lambda/identify/handler.js +124 -0
  22. package/lib/lambda/identify/mapping.d.ts +61 -0
  23. package/lib/lambda/identify/mapping.js +171 -0
  24. package/lib/lambda/identify/merge_resolver.d.ts +26 -0
  25. package/lib/lambda/identify/merge_resolver.js +36 -0
  26. package/lib/lambda/identify/principal.d.ts +68 -0
  27. package/lib/lambda/identify/principal.js +48 -0
  28. package/lib/lambda/identify/profile_resolver.d.ts +35 -0
  29. package/lib/lambda/identify/profile_resolver.js +65 -0
  30. package/lib/lambda/identify/types.d.ts +90 -0
  31. package/lib/lambda/identify/types.js +10 -0
  32. package/lib/lambda/identify/validation.d.ts +15 -0
  33. package/lib/lambda/identify/validation.js +99 -0
  34. package/lib/lambda/push/delivery.d.ts +49 -0
  35. package/lib/lambda/push/delivery.js +120 -0
  36. package/lib/lambda/push/device_lookup.d.ts +35 -0
  37. package/lib/lambda/push/device_lookup.js +88 -0
  38. package/lib/lambda/push/eum_client.d.ts +31 -0
  39. package/lib/lambda/push/eum_client.js +140 -0
  40. package/lib/lambda/push/event.d.ts +32 -0
  41. package/lib/lambda/push/event.js +122 -0
  42. package/lib/lambda/push/fixtures/real_journey_event.d.ts +19 -0
  43. package/lib/lambda/push/fixtures/real_journey_event.js +22 -0
  44. package/lib/lambda/push/handler.d.ts +15 -0
  45. package/lib/lambda/push/handler.js +86 -0
  46. package/lib/lambda/push/message_template.d.ts +72 -0
  47. package/lib/lambda/push/message_template.js +270 -0
  48. package/lib/lambda/push/payload.d.ts +25 -0
  49. package/lib/lambda/push/payload.js +53 -0
  50. package/lib/lambda/push/types.d.ts +153 -0
  51. package/lib/lambda/push/types.js +4 -0
  52. package/lib/lambda/shared/retry.d.ts +18 -0
  53. package/lib/lambda/shared/retry.js +45 -0
  54. package/lib/object_types.d.ts +63 -0
  55. package/lib/object_types.js +131 -0
  56. package/lib/push-handler-asset/index.js +75517 -0
  57. package/lib/types.d.ts +125 -0
  58. package/lib/types.js +2 -0
  59. package/package.json +49 -0
@@ -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==