@paypal/checkout-components 5.0.207 → 5.0.209-alpha.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## <small>5.0.209-alpha.1 (2022-04-12)</small>
2
+
3
+ * bump version for publishing ([02ed39d](https://github.com/paypal/paypal-checkout-components/commit/02ed39d))
4
+
5
+
6
+
7
+ ## <small>5.0.208 (2022-04-06)</small>
8
+
9
+ * onComplete (#1906) ([426178d](https://github.com/paypal/paypal-checkout-components/commit/426178d)), closes [#1906](https://github.com/paypal/paypal-checkout-components/issues/1906)
10
+
11
+
12
+
1
13
  ## <small>5.0.207 (2022-04-05)</small>
2
14
 
3
15
  * chore: update packages to krakenjs scope (#1885) ([fd1bb83](https://github.com/paypal/paypal-checkout-components/commit/fd1bb83)), closes [#1885](https://github.com/paypal/paypal-checkout-components/issues/1885)
package/README.md CHANGED
@@ -73,7 +73,7 @@ npm run lint -- --fix
73
73
  # attempt to automatically fix any problems
74
74
  ```
75
75
 
76
- Runs [eslint](https://eslint.org/) using [definitions](./.eslinter.js) extended from [Grumbler-Scripts](https://github.com/krakenjs/grumbler-scripts/blob/main/config/.eslintrc-browser.js).
76
+ Runs [eslint](https://eslint.org/) using [definitions](./.eslinter.js) extended from [Grumbler-Scripts](https://github.com/krakenjs/@krakenjs/grumbler-scripts/blob/main/config/.eslintrc-browser.js).
77
77
 
78
78
  ### flow
79
79
 
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@paypal/checkout-components",
3
- "version": "5.0.207",
3
+ "version": "5.0.209-alpha.1",
4
4
  "description": "PayPal Checkout components, for integrating checkout products.",
5
5
  "main": "index.js",
6
6
  "engines": {
7
- "node": ">=14.13.1",
7
+ "node": ">=14.13.1 <16",
8
8
  "npm": ">=6"
9
9
  },
10
10
  "scripts": {
@@ -62,6 +62,7 @@
62
62
  "license": "Apache-2.0",
63
63
  "readmeFilename": "README.md",
64
64
  "devDependencies": {
65
+ "@krakenjs/grumbler-scripts": "^6.0.2",
65
66
  "@krakenjs/sync-browser-mocks": "^3.0.0",
66
67
  "babel-core": "^7.0.0-bridge.0",
67
68
  "bundlemon": "^1.1.0",
@@ -13,4 +13,11 @@ export const ATTRIBUTE = {
13
13
  PAY_NOW: ('data-pay-now' : 'data-pay-now')
14
14
  };
15
15
 
16
+ export const FPTI_CPL_KEY = {
17
+ PAGE_NAME: ('page_name' : 'page_name'),
18
+ CPL_COMP_METRICS: ('cpl_comp_metrics' : 'cpl_comp_metrics'),
19
+ CPL_CHUNK_METRICS: ('cpl_chunk_metrics' : 'cpl_chunk_metrics'),
20
+ CPL_QUERY_METRICS: ('cpl_query_metrics' : 'cpl_query_metrics')
21
+ };
22
+
16
23
  export const DEFAULT = ('default' : 'default');
package/src/lib/cpl.js ADDED
@@ -0,0 +1,97 @@
1
+ /* @flow */
2
+ import { getLogger } from '@paypal/sdk-client/src';
3
+ import { FPTI_KEY } from '@paypal/sdk-constants/src';
4
+
5
+ import { FPTI_CPL_KEY } from '../constants';
6
+
7
+ /* To Track time spent in each phase(cdn download, chunks download, etc)
8
+ logCPLPhase('first_interactable_render')
9
+ logCPLPhase('html_body', 'comp', true);
10
+ logCPLPhase('html_body', 'comp');
11
+ */
12
+ const cplPhases = {};
13
+ export const logCPLPhase = (buttonID : string, phase : string, category : string, isStart : ?boolean) => {
14
+ try {
15
+ // to remove Query from phase
16
+ phase = phase.replace(/Query/g, '');
17
+ if (!cplPhases[buttonID]) {
18
+ cplPhases[buttonID] = {
19
+ query: {},
20
+ chunk: {},
21
+ comp: {}
22
+ };
23
+ }
24
+ const epochNow = Date.now();
25
+ if (category && cplPhases[buttonID][category] && phase) {
26
+ if (isStart && !cplPhases[buttonID][category][phase]) {
27
+ cplPhases[buttonID][category][phase] = {
28
+ start: epochNow
29
+ };
30
+ } else if (cplPhases[buttonID][category][phase]) {
31
+ if (
32
+ cplPhases[buttonID][category][phase].start &&
33
+ !cplPhases[buttonID][category][phase].tt
34
+ ) {
35
+ cplPhases[buttonID][category][phase].tt =
36
+ epochNow - cplPhases[buttonID][category][phase].start;
37
+ }
38
+ } else {
39
+ getLogger().info('CPL_LOG_PHASE_UNHANDLED_CONDITION').track({
40
+ phase,
41
+ category,
42
+ isStart
43
+ }).flush();
44
+ }
45
+ } else if (phase && !cplPhases[buttonID][category][phase]) {
46
+ if (performance && performance.timing) {
47
+ cplPhases[buttonID][category][phase] = epochNow - performance.timing.fetchStart;
48
+ }
49
+ }
50
+ } catch (err) {
51
+ getLogger().info('CPL_LOG_PHASE_ERROR').track({
52
+ phase,
53
+ category,
54
+ isStart,
55
+ err: err.message || 'CPL_LOG_PHASE_ERROR',
56
+ details: err.details,
57
+ stack: JSON.stringify(err.stack || err)
58
+ }).flush();
59
+ }
60
+ };
61
+
62
+ const _store = {
63
+ triggerInitialCPLEvent: true,
64
+ hasContingencies: false
65
+ };
66
+
67
+ const triggerCPLLatencyMetricsFPTI = (buttonId : string) => {
68
+ const cplLatencyMetrics = {
69
+ [FPTI_KEY.STATE]: 'CPL_LATENCY_METRICS',
70
+ [FPTI_KEY.TRANSITION]: 'process_client_metrics',
71
+ [FPTI_KEY.CONTEXT_ID]: buttonId,
72
+ [FPTI_CPL_KEY.PAGE_NAME]: `main:xo:paypal-components:smart-payment-buttons`,
73
+ [FPTI_CPL_KEY.CPL_COMP_METRICS]: JSON.stringify(cplPhases?.[buttonId]?.comp || {}),
74
+ [FPTI_CPL_KEY.CPL_QUERY_METRICS]: JSON.stringify(cplPhases?.[buttonId]?.query || {}),
75
+ [FPTI_CPL_KEY.CPL_CHUNK_METRICS]: JSON.stringify(cplPhases?.[buttonId]?.chunk || {})
76
+ };
77
+
78
+ getLogger().info('CPL_LATENCY_METRICS_FIRST_RENDER').track(cplLatencyMetrics).flush();
79
+ };
80
+
81
+ export const updateTriggerInitialCPLEvent = (state : boolean) => {
82
+ getLogger().info(`CPL_UPDATE_TRIGGER_INITIAL_CPL_EVENT_TO_${ state.toString() }`).flush();
83
+ _store.triggerInitialCPLEvent = state;
84
+ };
85
+
86
+ export const shouldTriggerInitialCPLEvent = () : boolean => {
87
+ return _store.triggerInitialCPLEvent;
88
+ };
89
+
90
+ export const triggerInitialCPLEvent = (buttonId : string) => {
91
+ if (shouldTriggerInitialCPLEvent()) {
92
+ // Set the flag to false so that CPL call is not triggered again
93
+ updateTriggerInitialCPLEvent(false);
94
+ // Trigger FPTI event to capture the time spent on different phases.
95
+ triggerCPLLatencyMetricsFPTI(buttonId);
96
+ }
97
+ };
package/src/lib/index.js CHANGED
@@ -4,3 +4,4 @@ export * from './errors';
4
4
  export * from './isRTLLanguage';
5
5
  export * from './security';
6
6
  export * from './session';
7
+ export * from './cpl';
@@ -36,6 +36,8 @@ export type OnApproveData = {|
36
36
  paymentID? : string
37
37
  |};
38
38
 
39
+ export type OnCompleteData = {||};
40
+
39
41
  export type CreateBillingAgreement = () => ZalgoPromise<string> | string;
40
42
 
41
43
  export type CreateSubscriptionRequest = {||};
@@ -65,7 +67,12 @@ export type OnApproveActions = {|
65
67
  |}
66
68
  |};
67
69
 
70
+ export type OnCompleteActions = {|
71
+ redirect : (string, CrossDomainWindowType) => ZalgoPromise<void>
72
+ |};
73
+
68
74
  export type OnApprove = (data : OnApproveData, actions : OnApproveActions) => ZalgoPromise<void> | void;
75
+ export type OnComplete = (data : OnCompleteData, actions : OnCompleteActions) => ZalgoPromise<void> | void;
69
76
 
70
77
  type OnShippingChangeAddress = {|
71
78
  city : string,
@@ -201,7 +208,7 @@ export type ApplePayShippingMethod = {|
201
208
  |};
202
209
 
203
210
  export type ApplePayShippingContactUpdate = {|
204
- errors? : $ReadOnlyArray<ApplePayErrorCode>,
211
+ errors? : $ReadOnlyArray<ApplePayError>,
205
212
  newShippingMethods? : $ReadOnlyArray<ApplePayShippingMethod>,
206
213
  newTotal : ApplePayLineItem,
207
214
  newLineItems? : $ReadOnlyArray<ApplePayLineItem>
@@ -283,6 +290,7 @@ export type ButtonProps = {|
283
290
  createSubscription : CreateSubscription,
284
291
  oncancel : OnCancel,
285
292
  onApprove : OnApprove,
293
+ onComplete : OnComplete,
286
294
  onClick : OnClick,
287
295
  getPrerenderDetails : GetPrerenderDetails,
288
296
  style : ButtonStyle,
@@ -13,7 +13,7 @@ import { uniqueID, memoize, isApplePaySupported, supportsPopups as userAgentSupp
13
13
  import { FUNDING, FUNDING_BRAND_LABEL, QUERY_BOOL, ENV, FPTI_KEY } from '@paypal/sdk-constants/src';
14
14
  import { node, dom } from '@krakenjs/jsx-pragmatic/src';
15
15
 
16
- import { getSessionID, storageState, sessionState } from '../../lib';
16
+ import { getSessionID, storageState, sessionState, logCPLPhase } from '../../lib';
17
17
  import { normalizeButtonStyle, type ButtonProps } from '../../ui/buttons/props';
18
18
  import { isFundingEligible } from '../../funding';
19
19
  import { EXPERIENCE } from '../../constants';
@@ -203,6 +203,11 @@ export const getButtonsComponent : () => ButtonsComponent = memoize(() => {
203
203
  required: false
204
204
  },
205
205
 
206
+ onComplete: {
207
+ type: 'function',
208
+ required: false
209
+ },
210
+
206
211
  onShippingChange: {
207
212
  type: 'function',
208
213
  required: false,
@@ -257,6 +262,7 @@ export const getButtonsComponent : () => ButtonsComponent = memoize(() => {
257
262
  required: false,
258
263
  default: () => noop,
259
264
  decorate: ({ props, value = noop }) => {
265
+ logCPLPhase(props.buttonSessionID, 'first_render', 'comp', true);
260
266
  return (...args) => {
261
267
  const { fundingSource } = props;
262
268
  const venmoExperiment = createVenmoExperiment();
@@ -12,6 +12,7 @@ import type { ZoidProps } from '@krakenjs/zoid/src';
12
12
  import { DEFAULT_POPUP_SIZE } from '../checkout';
13
13
  import { Buttons } from '../../ui';
14
14
  import { type ButtonProps } from '../../ui/buttons/props';
15
+ import { logCPLPhase, triggerInitialCPLEvent } from '../../lib';
15
16
 
16
17
  type PrerenderedButtonsProps = {|
17
18
  nonce : ?string,
@@ -66,7 +67,8 @@ export function PrerenderedButtons({ nonce, onRenderCheckout, props } : Prerende
66
67
  onRenderCheckout({ fundingSource, card });
67
68
  }
68
69
  };
69
-
70
+ logCPLPhase(props.buttonSessionID, 'first_render', 'comp');
71
+ triggerInitialCPLEvent(props.buttonSessionID);
70
72
  return (
71
73
  <html>
72
74
  <body>
@@ -172,12 +172,10 @@ export function applePaySession() : ?ApplePaySessionConfigRequest {
172
172
  }
173
173
 
174
174
  const convertErrorsFromUpdate = (update) => {
175
- if (update.errors && update.errors.length) {
176
- // $FlowFixMe
177
- return update.errors.map(error => new window.ApplePayError(error.code, error.contactField, error.message));
178
- }
179
-
180
- return update;
175
+ return {
176
+ ...update,
177
+ errors: (update.errors || []).map(error => new window.ApplePayError(error.code, error.contactField, error.message))
178
+ };
181
179
  };
182
180
 
183
181
  return (version, request) => {
@@ -47,6 +47,7 @@ type CardFieldsProps = {|
47
47
 
48
48
  createOrder : () => ZalgoPromise<string> | string,
49
49
  onApprove : ({| returnUrl : string |}, {| redirect : (?CrossDomainWindowType, ?string) => ZalgoPromise<void> |}) => ?ZalgoPromise<void>,
50
+ onComplete : ({| returnUrl : string |}, {| redirect : (?CrossDomainWindowType, ?string) => ZalgoPromise<void> |}) => ?ZalgoPromise<void>,
50
51
  onCancel ? : ({| cancelUrl : string |}, {| redirect : (? CrossDomainWindowType, ? string) => ZalgoPromise<void> |}) => ?ZalgoPromise<void>
51
52
  |};
52
53
 
@@ -165,6 +166,12 @@ export const getCardFieldsComponent : () => CardFieldsComponent = memoize(() : C
165
166
  value: ({ props }) => props.parent.props.onApprove
166
167
  },
167
168
 
169
+ onComplete: {
170
+ type: 'function',
171
+ required: false,
172
+ value: ({ props }) => props.parent.props.onComplete
173
+ },
174
+
168
175
  onCancel: {
169
176
  type: 'function',
170
177
  required: false,
@@ -336,6 +343,11 @@ export const getCardFieldsComponent : () => CardFieldsComponent = memoize(() : C
336
343
  required: false
337
344
  },
338
345
 
346
+ onComplete: {
347
+ type: 'function',
348
+ required: false
349
+ },
350
+
339
351
  onCancel: {
340
352
  type: 'function',
341
353
  required: false
@@ -103,6 +103,11 @@ export function getCardFormComponent() : CardFormComponent {
103
103
  alias: 'onAuthorize'
104
104
  },
105
105
 
106
+ onComplete: {
107
+ type: 'function',
108
+ required: false
109
+ },
110
+
106
111
  onAuth: {
107
112
  type: 'function',
108
113
  required: false,
@@ -191,6 +191,11 @@ export function getCheckoutComponent() : CheckoutComponent {
191
191
  type: 'function',
192
192
  alias: 'onAuthorize'
193
193
  },
194
+
195
+ onComplete: {
196
+ type: 'function',
197
+ required: false
198
+ },
194
199
 
195
200
  onShippingChange: {
196
201
  type: 'function',
@@ -1,6 +1,7 @@
1
1
  /* @flow */
2
2
 
3
3
  import type { ZalgoPromise } from '@krakenjs/zalgo-promise/src';
4
+ import type { CrossDomainWindowType } from '@krakenjs/cross-domain-utils/src';
4
5
  import { FUNDING, ENV, type LocaleType } from '@paypal/sdk-constants/src';
5
6
 
6
7
  export type OnApproveData = {|
@@ -13,6 +14,10 @@ export type OnApproveActions = {|
13
14
 
14
15
  |};
15
16
 
17
+ export type OnCompleteData = {||};
18
+ export type OnCompleteActions = {|
19
+ redirect : (string, CrossDomainWindowType) => ZalgoPromise<void>
20
+ |};
16
21
  export type OnCancelData = {|
17
22
  orderID : string,
18
23
  paymentID? : string
@@ -26,6 +31,7 @@ export type CheckoutPropsType = {|
26
31
  createOrder : () => ZalgoPromise<string>,
27
32
  createAuthCode : () => ZalgoPromise<string>,
28
33
  onApprove : (OnApproveData, OnApproveActions) => ?ZalgoPromise<void>,
34
+ onComplete : (OnCompleteData, OnCompleteActions) => ?ZalgoPromise<void>,
29
35
  onCancel? : (OnCancelData, OnCancelActions) => ?ZalgoPromise<void>,
30
36
  fundingSource : $Values<typeof FUNDING>,
31
37
  env : $Values<typeof ENV>,