@duffel/react-native-components-assistant 0.2.0 → 0.3.0

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.
@@ -8,6 +8,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
8
8
  export const DuffelAssistant = ({
9
9
  isOpen,
10
10
  onClose,
11
+ onNewMessage,
11
12
  ...properties
12
13
  }) => {
13
14
  if (!hasJsonWebTokenFormat(properties.clientKey)) {
@@ -20,7 +21,12 @@ export const DuffelAssistant = ({
20
21
  children: /*#__PURE__*/_jsx(View, {
21
22
  style: styles.container,
22
23
  children: Platform.OS === 'ios' ? /*#__PURE__*/_jsx(WebView, {
23
- injectedJavaScriptObject: properties,
24
+ injectedJavaScriptObject: properties
25
+ // When you are running this in development iOS doesn't allow request from hosts with invalid https certificates.
26
+ // If you try ngrok with the local esbuild server it will fail because ngrok requests in https and the dev server rejects http requests.
27
+ // Easiest solution is to use the production URL with test data.
28
+ // If that's not possible, you can also upload the assistant built assets to a different folder in assets.duffel and work with that.
29
+ ,
24
30
  source: {
25
31
  uri: 'https://assets.duffel.com/assistant/iframe.html'
26
32
  },
@@ -28,6 +34,17 @@ export const DuffelAssistant = ({
28
34
  if (event.nativeEvent.data === 'duffel-assistant-close') {
29
35
  onClose();
30
36
  }
37
+ try {
38
+ const parsedData = JSON.parse(event.nativeEvent.data);
39
+ if (parsedData.type === 'duffel-assistant-new-message' && typeof parsedData.userId === 'string' && typeof parsedData.resourceId === 'string' && onNewMessage !== undefined) {
40
+ onNewMessage({
41
+ userId: parsedData.userId,
42
+ resourceId: parsedData.resourceId
43
+ });
44
+ }
45
+ } catch (error) {
46
+ // do nothing, invalid JSON
47
+ }
31
48
  }
32
49
  }) : /*#__PURE__*/_jsx(WebView
33
50
  // Required for Android
@@ -1 +1 @@
1
- {"version":3,"names":["React","Modal","Platform","StyleSheet","View","WebView","hasJsonWebTokenFormat","jsx","_jsx","DuffelAssistant","isOpen","onClose","properties","clientKey","Error","visible","onRequestClose","animationType","children","style","styles","container","OS","injectedJavaScriptObject","source","uri","onMessage","event","nativeEvent","data","injectedJavaScript","JSON","stringify","create","height","width","paddingHorizontal","paddingTop","paddingBottom"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,KAAK,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAChE,SAASC,OAAO,QAAQ,sBAAsB;AAE9C,SAASC,qBAAqB,QAAQ,gCAA6B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAIpE,OAAO,MAAMC,eAA+C,GAAGA,CAAC;EAC9DC,MAAM;EACNC,OAAO;EACP,GAAGC;AACL,CAAC,KAAK;EACJ,IAAI,CAACN,qBAAqB,CAACM,UAAU,CAACC,SAAS,CAAC,EAAE;IAChD,MAAM,IAAIC,KAAK,CAAC,yDAAyD,CAAC;EAC5E;EAEA,oBACEN,IAAA,CAACP,KAAK;IACJc,OAAO,EAAEL,MAAO;IAChBM,cAAc,EAAEA,CAAA,KAAML,OAAO,CAAC,CAAE;IAChCM,aAAa,EAAC,OAAO;IAAAC,QAAA,eAErBV,IAAA,CAACJ,IAAI;MAACe,KAAK,EAAEC,MAAM,CAACC,SAAU;MAAAH,QAAA,EAC3BhB,QAAQ,CAACoB,EAAE,KAAK,KAAK,gBACpBd,IAAA,CAACH,OAAO;QACNkB,wBAAwB,EAAEX,UAAW;QACrCY,MAAM,EAAE;UAAEC,GAAG,EAAE;QAAkD,CAAE;QACnEC,SAAS,EAAGC,KAAK,IAAK;UACpB,IAAIA,KAAK,CAACC,WAAW,CAACC,IAAI,KAAK,wBAAwB,EAAE;YACvDlB,OAAO,CAAC,CAAC;UACX;QACF;MAAE,CACH,CAAC,gBAEFH,IAAA,CAACH;MACC;MAAA;QACAyB,kBAAkB,EAAE;AAChC;AACA;AACA;AACA,4BAA4BC,IAAI,CAACC,SAAS,CAACpB,UAAU,CAAC;AACtD;AACA;AACA;AACA,gBAAiB;QACLY,MAAM,EAAE;UAAEC,GAAG,EAAE;QAAkD,CAAE;QACnEC,SAAS,EAAGC,KAAK,IAAK;UACpB,IAAIA,KAAK,CAACC,WAAW,CAACC,IAAI,KAAK,wBAAwB,EAAE;YACvDlB,OAAO,CAAC,CAAC;UACX;QACF;MAAE,CACH;IACF,CACG;EAAC,CACF,CAAC;AAEZ,CAAC;AAED,MAAMS,MAAM,GAAGjB,UAAU,CAAC8B,MAAM,CAAC;EAC/BZ,SAAS,EAAE;IACTa,MAAM,EAAE,MAAM;IACdC,KAAK,EAAE,MAAM;IACbC,iBAAiB,EAAE,EAAE;IACrBC,UAAU,EAAE,EAAE;IACdC,aAAa,EAAE;EACjB;AACF,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["React","Modal","Platform","StyleSheet","View","WebView","hasJsonWebTokenFormat","jsx","_jsx","DuffelAssistant","isOpen","onClose","onNewMessage","properties","clientKey","Error","visible","onRequestClose","animationType","children","style","styles","container","OS","injectedJavaScriptObject","source","uri","onMessage","event","nativeEvent","data","parsedData","JSON","parse","type","userId","resourceId","undefined","error","injectedJavaScript","stringify","create","height","width","paddingHorizontal","paddingTop","paddingBottom"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,KAAK,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAChE,SAASC,OAAO,QAAQ,sBAAsB;AAE9C,SAASC,qBAAqB,QAAQ,gCAA6B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAIpE,OAAO,MAAMC,eAA+C,GAAGA,CAAC;EAC9DC,MAAM;EACNC,OAAO;EACPC,YAAY;EACZ,GAAGC;AACL,CAAC,KAAK;EACJ,IAAI,CAACP,qBAAqB,CAACO,UAAU,CAACC,SAAS,CAAC,EAAE;IAChD,MAAM,IAAIC,KAAK,CAAC,yDAAyD,CAAC;EAC5E;EAEA,oBACEP,IAAA,CAACP,KAAK;IACJe,OAAO,EAAEN,MAAO;IAChBO,cAAc,EAAEA,CAAA,KAAMN,OAAO,CAAC,CAAE;IAChCO,aAAa,EAAC,OAAO;IAAAC,QAAA,eAErBX,IAAA,CAACJ,IAAI;MAACgB,KAAK,EAAEC,MAAM,CAACC,SAAU;MAAAH,QAAA,EAC3BjB,QAAQ,CAACqB,EAAE,KAAK,KAAK,gBACpBf,IAAA,CAACH,OAAO;QACNmB,wBAAwB,EAAEX;QAC1B;QACA;QACA;QACA;QAAA;QACAY,MAAM,EAAE;UAAEC,GAAG,EAAE;QAAkD,CAAE;QACnEC,SAAS,EAAGC,KAAK,IAAK;UACpB,IAAIA,KAAK,CAACC,WAAW,CAACC,IAAI,KAAK,wBAAwB,EAAE;YACvDnB,OAAO,CAAC,CAAC;UACX;UACA,IAAI;YACF,MAAMoB,UAAU,GAAGC,IAAI,CAACC,KAAK,CAACL,KAAK,CAACC,WAAW,CAACC,IAAI,CAAC;YACrD,IACEC,UAAU,CAACG,IAAI,KAAK,8BAA8B,IAClD,OAAOH,UAAU,CAACI,MAAM,KAAK,QAAQ,IACrC,OAAOJ,UAAU,CAACK,UAAU,KAAK,QAAQ,IACzCxB,YAAY,KAAKyB,SAAS,EAC1B;cACAzB,YAAY,CAAC;gBACXuB,MAAM,EAAEJ,UAAU,CAACI,MAAM;gBACzBC,UAAU,EAAEL,UAAU,CAACK;cACzB,CAAC,CAAC;YACJ;UACF,CAAC,CAAC,OAAOE,KAAK,EAAE;YACd;UAAA;QAEJ;MAAE,CACH,CAAC,gBAEF9B,IAAA,CAACH;MACC;MAAA;QACAkC,kBAAkB,EAAE;AAChC;AACA;AACA;AACA,4BAA4BP,IAAI,CAACQ,SAAS,CAAC3B,UAAU,CAAC;AACtD;AACA;AACA;AACA,gBAAiB;QACLY,MAAM,EAAE;UAAEC,GAAG,EAAE;QAAkD,CAAE;QACnEC,SAAS,EAAGC,KAAK,IAAK;UACpB,IAAIA,KAAK,CAACC,WAAW,CAACC,IAAI,KAAK,wBAAwB,EAAE;YACvDnB,OAAO,CAAC,CAAC;UACX;QACF;MAAE,CACH;IACF,CACG;EAAC,CACF,CAAC;AAEZ,CAAC;AAED,MAAMU,MAAM,GAAGlB,UAAU,CAACsC,MAAM,CAAC;EAC/BnB,SAAS,EAAE;IACToB,MAAM,EAAE,MAAM;IACdC,KAAK,EAAE,MAAM;IACbC,iBAAiB,EAAE,EAAE;IACrBC,UAAU,EAAE,EAAE;IACdC,aAAa,EAAE;EACjB;AACF,CAAC,CAAC","ignoreList":[]}
@@ -28,5 +28,15 @@ export interface DuffelAssistantProps {
28
28
  * @default undefined
29
29
  */
30
30
  issueType?: 'cancellation' | 'change' | 'other';
31
+ /**
32
+ * This callback is called when a new message is received from the Assistant.
33
+ * You can react to this to notify users that a new message has been received.
34
+ *
35
+ * @param eventPayload - The event payload containing the user ID and resource ID associated with the message.
36
+ */
37
+ onNewMessage?: (eventPayload: {
38
+ userId: string;
39
+ resourceId: string;
40
+ }) => void;
31
41
  }
32
42
  //# sourceMappingURL=DuffelAssistantProps.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DuffelAssistantProps.d.ts","sourceRoot":"","sources":["../../../src/DuffelAssistantProps.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC;IAEvD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,cAAc,GAAG,QAAQ,GAAG,OAAO,CAAC;CACjD"}
1
+ {"version":3,"file":"DuffelAssistantProps.d.ts","sourceRoot":"","sources":["../../../src/DuffelAssistantProps.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC;IAEvD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,cAAc,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEhD;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/E"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,KAAK,oBAAoB,IAAI,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAGnG,MAAM,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AAEhE,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAiD1D,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,KAAK,oBAAoB,IAAI,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAGnG,MAAM,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AAEhE,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAsE1D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duffel/react-native-components-assistant",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Duffel Assistant component in React Native",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  ],
34
34
  "scripts": {
35
35
  "example": "yarn workspace duffel-react-native-components-assistant-example",
36
- "test": "jest",
36
+ "test": "jest --passWithNoTests",
37
37
  "typecheck": "tsc",
38
38
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
39
39
  "clean": "del-cli lib",
@@ -76,10 +76,10 @@
76
76
  "eslint-plugin-prettier": "^5.2.3",
77
77
  "jest": "^29.7.0",
78
78
  "prettier": "^3.0.3",
79
- "react": "19.0.0",
80
- "react-native": "0.79.5",
79
+ "react": "19.1.0",
80
+ "react-native": "0.81.5",
81
81
  "react-native-builder-bob": "^0.40.12",
82
- "react-native-webview": "^13.16.0",
82
+ "react-native-webview": "13.15.0",
83
83
  "release-it": "^17.10.0",
84
84
  "typescript": "^5.8.3"
85
85
  },
@@ -152,5 +152,8 @@
152
152
  "languages": "js",
153
153
  "type": "library",
154
154
  "version": "0.51.1"
155
+ },
156
+ "dependencies": {
157
+ "expo": "^54.0.0"
155
158
  }
156
159
  }
@@ -32,4 +32,12 @@ export interface DuffelAssistantProps {
32
32
  * @default undefined
33
33
  */
34
34
  issueType?: 'cancellation' | 'change' | 'other';
35
+
36
+ /**
37
+ * This callback is called when a new message is received from the Assistant.
38
+ * You can react to this to notify users that a new message has been received.
39
+ *
40
+ * @param eventPayload - The event payload containing the user ID and resource ID associated with the message.
41
+ */
42
+ onNewMessage?: (eventPayload: { userId: string; resourceId: string }) => void;
35
43
  }
package/src/index.tsx CHANGED
@@ -9,6 +9,7 @@ export type DuffelAssistantProps = DuffelAssistantPropsImported;
9
9
  export const DuffelAssistant: React.FC<DuffelAssistantProps> = ({
10
10
  isOpen,
11
11
  onClose,
12
+ onNewMessage,
12
13
  ...properties
13
14
  }) => {
14
15
  if (!hasJsonWebTokenFormat(properties.clientKey)) {
@@ -25,11 +26,31 @@ export const DuffelAssistant: React.FC<DuffelAssistantProps> = ({
25
26
  {Platform.OS === 'ios' ? (
26
27
  <WebView
27
28
  injectedJavaScriptObject={properties}
29
+ // When you are running this in development iOS doesn't allow request from hosts with invalid https certificates.
30
+ // If you try ngrok with the local esbuild server it will fail because ngrok requests in https and the dev server rejects http requests.
31
+ // Easiest solution is to use the production URL with test data.
32
+ // If that's not possible, you can also upload the assistant built assets to a different folder in assets.duffel and work with that.
28
33
  source={{ uri: 'https://assets.duffel.com/assistant/iframe.html' }}
29
34
  onMessage={(event) => {
30
35
  if (event.nativeEvent.data === 'duffel-assistant-close') {
31
36
  onClose();
32
37
  }
38
+ try {
39
+ const parsedData = JSON.parse(event.nativeEvent.data);
40
+ if (
41
+ parsedData.type === 'duffel-assistant-new-message' &&
42
+ typeof parsedData.userId === 'string' &&
43
+ typeof parsedData.resourceId === 'string' &&
44
+ onNewMessage !== undefined
45
+ ) {
46
+ onNewMessage({
47
+ userId: parsedData.userId,
48
+ resourceId: parsedData.resourceId,
49
+ });
50
+ }
51
+ } catch (error) {
52
+ // do nothing, invalid JSON
53
+ }
33
54
  }}
34
55
  />
35
56
  ) : (