@qafka/react-native 2.0.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.
Files changed (178) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/CONTRIBUTING.md +92 -0
  3. package/LICENSE +22 -0
  4. package/README.md +109 -0
  5. package/SECURITY.md +67 -0
  6. package/android/build.gradle +35 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/java/com/qafka/attestation/QafkaAttestationModule.kt +92 -0
  9. package/android/src/main/java/com/qafka/attestation/QafkaAttestationPackage.kt +22 -0
  10. package/android/src/main/java/com/qafka/audio/QafkaAudioModule.kt +290 -0
  11. package/android/src/main/java/com/qafka/clipboard/QafkaClipboardModule.kt +28 -0
  12. package/android/src/main/java/com/qafka/storage/QafkaStorageModule.kt +80 -0
  13. package/app.plugin.js +1 -0
  14. package/dist/QafkaSDK.d.ts +174 -0
  15. package/dist/QafkaSDK.js +461 -0
  16. package/dist/cards/bindings/resolveFieldName.d.ts +25 -0
  17. package/dist/cards/bindings/resolveFieldName.js +82 -0
  18. package/dist/cards/cta/CardContext.d.ts +16 -0
  19. package/dist/cards/cta/CardContext.js +58 -0
  20. package/dist/cards/cta/dispatcher.d.ts +7 -0
  21. package/dist/cards/cta/dispatcher.js +90 -0
  22. package/dist/cards/cta/types.d.ts +66 -0
  23. package/dist/cards/cta/types.js +2 -0
  24. package/dist/cards/index.d.ts +20 -0
  25. package/dist/cards/index.js +34 -0
  26. package/dist/cards/primitives/QButton.d.ts +10 -0
  27. package/dist/cards/primitives/QButton.js +115 -0
  28. package/dist/cards/primitives/QDivider.d.ts +7 -0
  29. package/dist/cards/primitives/QDivider.js +17 -0
  30. package/dist/cards/primitives/QIcon.d.ts +13 -0
  31. package/dist/cards/primitives/QIcon.js +26 -0
  32. package/dist/cards/primitives/QImage.d.ts +9 -0
  33. package/dist/cards/primitives/QImage.js +22 -0
  34. package/dist/cards/primitives/QText.d.ts +9 -0
  35. package/dist/cards/primitives/QText.js +30 -0
  36. package/dist/cards/primitives/QView.d.ts +8 -0
  37. package/dist/cards/primitives/QView.js +19 -0
  38. package/dist/cards/renderer/CardRenderer.d.ts +19 -0
  39. package/dist/cards/renderer/CardRenderer.js +64 -0
  40. package/dist/cards/renderer/renderNode.d.ts +13 -0
  41. package/dist/cards/renderer/renderNode.js +42 -0
  42. package/dist/cards/types.d.ts +110 -0
  43. package/dist/cards/types.js +6 -0
  44. package/dist/components/ActionResultBadge.d.ts +12 -0
  45. package/dist/components/ActionResultBadge.js +58 -0
  46. package/dist/components/ChatPage.d.ts +44 -0
  47. package/dist/components/ChatPage.js +84 -0
  48. package/dist/components/DataChip.d.ts +8 -0
  49. package/dist/components/DataChip.js +80 -0
  50. package/dist/components/DataChipList.d.ts +13 -0
  51. package/dist/components/DataChipList.js +21 -0
  52. package/dist/components/FloatingButton.d.ts +11 -0
  53. package/dist/components/FloatingButton.js +162 -0
  54. package/dist/components/InputArea.d.ts +57 -0
  55. package/dist/components/InputArea.js +142 -0
  56. package/dist/components/MarkdownText.d.ts +15 -0
  57. package/dist/components/MarkdownText.js +283 -0
  58. package/dist/components/MessageBubble.d.ts +134 -0
  59. package/dist/components/MessageBubble.js +384 -0
  60. package/dist/components/NavigationSuggestion.d.ts +11 -0
  61. package/dist/components/NavigationSuggestion.js +109 -0
  62. package/dist/components/Qafka.d.ts +39 -0
  63. package/dist/components/Qafka.handlers.d.ts +21 -0
  64. package/dist/components/Qafka.handlers.js +54 -0
  65. package/dist/components/Qafka.js +493 -0
  66. package/dist/components/Qafka.styles.d.ts +19 -0
  67. package/dist/components/Qafka.styles.js +101 -0
  68. package/dist/components/Qafka.types.d.ts +744 -0
  69. package/dist/components/Qafka.types.js +2 -0
  70. package/dist/components/Qafka.utils.d.ts +7 -0
  71. package/dist/components/Qafka.utils.js +34 -0
  72. package/dist/components/QafkaProvider.d.ts +12 -0
  73. package/dist/components/QafkaProvider.js +87 -0
  74. package/dist/components/QuickReplies.d.ts +14 -0
  75. package/dist/components/QuickReplies.js +48 -0
  76. package/dist/components/StepProgressIndicator.d.ts +12 -0
  77. package/dist/components/StepProgressIndicator.js +48 -0
  78. package/dist/components/SuggestionButton.d.ts +42 -0
  79. package/dist/components/SuggestionButton.js +67 -0
  80. package/dist/components/ToolStatusPill.d.ts +20 -0
  81. package/dist/components/ToolStatusPill.js +43 -0
  82. package/dist/components/TypingIndicator.d.ts +28 -0
  83. package/dist/components/TypingIndicator.js +109 -0
  84. package/dist/components/VoicePage.d.ts +48 -0
  85. package/dist/components/VoicePage.js +683 -0
  86. package/dist/components/defaults/DefaultCard.d.ts +14 -0
  87. package/dist/components/defaults/DefaultCard.js +156 -0
  88. package/dist/components/defaults/DefaultDetail.d.ts +14 -0
  89. package/dist/components/defaults/DefaultDetail.js +138 -0
  90. package/dist/components/defaults/DefaultList.d.ts +12 -0
  91. package/dist/components/defaults/DefaultList.js +98 -0
  92. package/dist/components/defaults/DefaultTable.d.ts +14 -0
  93. package/dist/components/defaults/DefaultTable.js +204 -0
  94. package/dist/components/defaults/index.d.ts +14 -0
  95. package/dist/components/defaults/index.js +25 -0
  96. package/dist/components/index.d.ts +22 -0
  97. package/dist/components/index.js +36 -0
  98. package/dist/constants.d.ts +10 -0
  99. package/dist/constants.js +13 -0
  100. package/dist/hooks/useChatMessages.d.ts +72 -0
  101. package/dist/hooks/useChatMessages.js +505 -0
  102. package/dist/hooks/useContextManager.d.ts +12 -0
  103. package/dist/hooks/useContextManager.js +46 -0
  104. package/dist/hooks/useProjectTheme.d.ts +19 -0
  105. package/dist/hooks/useProjectTheme.js +163 -0
  106. package/dist/hooks/useSDK.d.ts +31 -0
  107. package/dist/hooks/useSDK.js +103 -0
  108. package/dist/hooks/useVoiceChat.d.ts +110 -0
  109. package/dist/hooks/useVoiceChat.js +436 -0
  110. package/dist/index.d.ts +13 -0
  111. package/dist/index.js +59 -0
  112. package/dist/native/QafkaAttestation.d.ts +23 -0
  113. package/dist/native/QafkaAttestation.js +70 -0
  114. package/dist/native/QafkaAudio.d.ts +14 -0
  115. package/dist/native/QafkaAudio.js +31 -0
  116. package/dist/native/QafkaClipboard.d.ts +11 -0
  117. package/dist/native/QafkaClipboard.js +14 -0
  118. package/dist/native/QafkaStorage.d.ts +15 -0
  119. package/dist/native/QafkaStorage.js +12 -0
  120. package/dist/resolve-project-config.d.ts +35 -0
  121. package/dist/resolve-project-config.js +41 -0
  122. package/dist/runtime-config-loader.d.ts +37 -0
  123. package/dist/runtime-config-loader.js +53 -0
  124. package/dist/services/AttestationManager.d.ts +38 -0
  125. package/dist/services/AttestationManager.js +296 -0
  126. package/dist/services/BackendService.d.ts +156 -0
  127. package/dist/services/BackendService.js +755 -0
  128. package/dist/services/ConversationManager.d.ts +43 -0
  129. package/dist/services/ConversationManager.js +96 -0
  130. package/dist/services/NavigationHandler.d.ts +29 -0
  131. package/dist/services/NavigationHandler.js +70 -0
  132. package/dist/services/RealtimeService.d.ts +83 -0
  133. package/dist/services/RealtimeService.js +203 -0
  134. package/dist/services/storage.d.ts +11 -0
  135. package/dist/services/storage.js +15 -0
  136. package/dist/services/storageCore.d.ts +17 -0
  137. package/dist/services/storageCore.js +46 -0
  138. package/dist/themes/dark.d.ts +5 -0
  139. package/dist/themes/dark.js +129 -0
  140. package/dist/themes/index.d.ts +12 -0
  141. package/dist/themes/index.js +33 -0
  142. package/dist/themes/light.d.ts +5 -0
  143. package/dist/themes/light.js +129 -0
  144. package/dist/themes/types.d.ts +155 -0
  145. package/dist/themes/types.js +5 -0
  146. package/dist/types/chat.d.ts +126 -0
  147. package/dist/types/chat.js +5 -0
  148. package/dist/types/components.d.ts +56 -0
  149. package/dist/types/components.js +16 -0
  150. package/dist/types/external-navigation.d.ts +19 -0
  151. package/dist/types/external-navigation.js +8 -0
  152. package/dist/types/index.d.ts +9 -0
  153. package/dist/types/index.js +25 -0
  154. package/dist/types/navigation.d.ts +86 -0
  155. package/dist/types/navigation.js +5 -0
  156. package/dist/types/sdk.d.ts +36 -0
  157. package/dist/types/sdk.js +5 -0
  158. package/dist/utils/deepMerge.d.ts +46 -0
  159. package/dist/utils/deepMerge.js +70 -0
  160. package/dist/utils/fontUtils.d.ts +8 -0
  161. package/dist/utils/fontUtils.js +16 -0
  162. package/dist/validate-end-user.d.ts +18 -0
  163. package/dist/validate-end-user.js +74 -0
  164. package/expo-plugin/withQafkaAttestation.js +57 -0
  165. package/ios/QafkaAttestation.m +25 -0
  166. package/ios/QafkaAttestation.swift +128 -0
  167. package/ios/QafkaAudio.m +23 -0
  168. package/ios/QafkaAudio.swift +519 -0
  169. package/ios/QafkaClipboard.m +10 -0
  170. package/ios/QafkaClipboard.swift +21 -0
  171. package/ios/QafkaReactImports.h +2 -0
  172. package/ios/QafkaStorage.m +26 -0
  173. package/ios/QafkaStorage.swift +118 -0
  174. package/package.json +82 -0
  175. package/qafka.config.d.ts +9 -0
  176. package/qafka.config.js +9 -0
  177. package/react-native-qafka.podspec +28 -0
  178. package/react-native.config.js +14 -0
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dispatchCTA = void 0;
4
+ const react_native_1 = require("react-native");
5
+ const resolveFieldName_1 = require("../bindings/resolveFieldName");
6
+ /**
7
+ * SDK-internal CTA dispatcher.
8
+ * Resolves embedded `{{fieldName}}` templates against the card's data context at click time.
9
+ * Falls back to host callbacks for actions that cross the SDK boundary (deep_link, tool_trigger).
10
+ */
11
+ const dispatchCTA = async (config, ctx) => {
12
+ const action = (0, resolveFieldName_1.resolveDeep)(config.action, ctx.data, ctx.iterationItem);
13
+ ctx.lifecycle.onCTAStart?.(action);
14
+ try {
15
+ const result = await runAction(action, ctx);
16
+ if (result.status === "success") {
17
+ ctx.lifecycle.onCTASuccess?.(action, result.result);
18
+ }
19
+ else if (result.status === "error") {
20
+ ctx.lifecycle.onCTAError?.(action, result.error);
21
+ }
22
+ return result;
23
+ }
24
+ catch (error) {
25
+ ctx.lifecycle.onCTAError?.(action, error);
26
+ return { status: "error", error };
27
+ }
28
+ };
29
+ exports.dispatchCTA = dispatchCTA;
30
+ async function runAction(action, ctx) {
31
+ switch (action.type) {
32
+ case "external_navigation": {
33
+ if (!ctx.hostCallbacks.onExternalNavigation) {
34
+ return { status: "skipped", reason: "no onExternalNavigation handler registered" };
35
+ }
36
+ await ctx.hostCallbacks.onExternalNavigation(action);
37
+ return { status: "success" };
38
+ }
39
+ case "deep_link": {
40
+ if (!ctx.hostCallbacks.onDeepLink) {
41
+ return { status: "skipped", reason: "no onDeepLink handler registered" };
42
+ }
43
+ await ctx.hostCallbacks.onDeepLink(action.path, action);
44
+ return { status: "success" };
45
+ }
46
+ case "suggest_message": {
47
+ if (ctx.hostCallbacks.onSuggestMessage) {
48
+ await ctx.hostCallbacks.onSuggestMessage(action.text);
49
+ return { status: "success" };
50
+ }
51
+ return { status: "skipped", reason: "no onSuggestMessage handler registered" };
52
+ }
53
+ case "copy": {
54
+ if (ctx.hostCallbacks.onCopy) {
55
+ await ctx.hostCallbacks.onCopy(action.value);
56
+ }
57
+ else {
58
+ react_native_1.Clipboard.setString(action.value);
59
+ }
60
+ return { status: "success", result: { copied: action.value } };
61
+ }
62
+ case "dismiss": {
63
+ ctx.dismiss();
64
+ return { status: "success" };
65
+ }
66
+ case "share": {
67
+ if (ctx.hostCallbacks.onShare) {
68
+ await ctx.hostCallbacks.onShare({ text: action.text, url: action.url });
69
+ }
70
+ else {
71
+ await react_native_1.Share.share({
72
+ message: action.text ?? action.url ?? "",
73
+ url: action.url,
74
+ });
75
+ }
76
+ return { status: "success" };
77
+ }
78
+ case "tool_trigger": {
79
+ if (!ctx.hostCallbacks.onToolTrigger) {
80
+ return { status: "skipped", reason: "tool_trigger requires onToolTrigger callback" };
81
+ }
82
+ await ctx.hostCallbacks.onToolTrigger(action.toolName, action.params ?? {}, { ctaDisplayMode: action.ctaDisplayMode ?? "user_message" });
83
+ return { status: "success" };
84
+ }
85
+ default: {
86
+ const exhaustive = action;
87
+ return { status: "error", error: new Error(`Unknown CTA type: ${exhaustive.type}`) };
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,66 @@
1
+ import type { ActionConfig, CardAction, CardActionType, ExternalNavigationAction } from "../types";
2
+ /**
3
+ * Host-provided callbacks for CTA actions that cannot be handled inside the SDK
4
+ * (deep_link requires host navigation; tool_trigger requires backend roundtrip).
5
+ */
6
+ export interface CardCTAHostCallbacks {
7
+ onDeepLink?: (path: string, action: CardAction) => void | Promise<void>;
8
+ onToolTrigger?: (toolName: string, params: Record<string, unknown>, meta: {
9
+ ctaDisplayMode: "user_message" | "silent";
10
+ }) => void | Promise<void>;
11
+ onExternalNavigation?: (action: ExternalNavigationAction) => void | Promise<void>;
12
+ onSuggestMessage?: (text: string) => void | Promise<void>;
13
+ onShare?: (payload: {
14
+ text?: string;
15
+ url?: string;
16
+ }) => void | Promise<void>;
17
+ onCopy?: (value: string) => void | Promise<void>;
18
+ }
19
+ export interface CardCTALifecycle {
20
+ onCTAStart?: (action: CardAction) => void;
21
+ onCTASuccess?: (action: CardAction, result?: unknown) => void;
22
+ onCTAError?: (action: CardAction, error: unknown) => void;
23
+ onCTAClick?: (event: CardCTATelemetryEvent) => void;
24
+ }
25
+ export interface CardCTATelemetryEvent {
26
+ event: "cta_click";
27
+ cardTemplateId: string;
28
+ cardSlug: string;
29
+ actionType: CardActionType;
30
+ toolName?: string;
31
+ messageId?: string;
32
+ /**
33
+ * Position in the list. Present only in list mode; omitted entirely for
34
+ * single-card / detail mode (avoids partners having to handle a `null`).
35
+ */
36
+ itemIndex?: number;
37
+ /**
38
+ * The bound data record for this card. In list mode this is the iterated
39
+ * item; in detail/single mode it's the full tool result. Lets partners
40
+ * react to the click without re-resolving from the original array.
41
+ */
42
+ item: unknown;
43
+ confirmed: boolean;
44
+ }
45
+ export interface CTADispatchContext {
46
+ data: unknown;
47
+ iterationItem?: unknown;
48
+ iterationIndex?: number;
49
+ cardTemplateId: string;
50
+ cardSlug: string;
51
+ messageId?: string;
52
+ hostCallbacks: CardCTAHostCallbacks;
53
+ lifecycle: CardCTALifecycle;
54
+ dismiss: () => void;
55
+ }
56
+ export type CTAResult = {
57
+ status: "success";
58
+ result?: unknown;
59
+ } | {
60
+ status: "error";
61
+ error: unknown;
62
+ } | {
63
+ status: "skipped";
64
+ reason: string;
65
+ };
66
+ export type CTADispatcher = (config: ActionConfig, ctx: CTADispatchContext) => Promise<CTAResult>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Card renderer.
3
+ *
4
+ * Renders Qafka cards from JSON definitions.
5
+ */
6
+ export { CardRenderer } from "./renderer/CardRenderer";
7
+ export type { CardRendererProps } from "./renderer/CardRenderer";
8
+ export { renderNode } from "./renderer/renderNode";
9
+ export type { RenderContext } from "./renderer/renderNode";
10
+ export { CardRuntimeProvider, useCardRuntime, } from "./cta/CardContext";
11
+ export type { CardRuntimeContextValue } from "./cta/CardContext";
12
+ export { dispatchCTA } from "./cta/dispatcher";
13
+ export type { CardCTAHostCallbacks, CardCTALifecycle, CardCTATelemetryEvent, CTADispatchContext, CTADispatcher, CTAResult, } from "./cta/types";
14
+ export { resolveFieldName, resolveTemplateString, resolveDeep, evaluateShowIf, } from "./bindings/resolveFieldName";
15
+ export { QView } from "./primitives/QView";
16
+ export { QText } from "./primitives/QText";
17
+ export { QImage } from "./primitives/QImage";
18
+ export { QIcon } from "./primitives/QIcon";
19
+ export { QDivider } from "./primitives/QDivider";
20
+ export { QButton } from "./primitives/QButton";
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * Card renderer.
4
+ *
5
+ * Renders Qafka cards from JSON definitions.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.QButton = exports.QDivider = exports.QIcon = exports.QImage = exports.QText = exports.QView = exports.evaluateShowIf = exports.resolveDeep = exports.resolveTemplateString = exports.resolveFieldName = exports.dispatchCTA = exports.useCardRuntime = exports.CardRuntimeProvider = exports.renderNode = exports.CardRenderer = void 0;
9
+ var CardRenderer_1 = require("./renderer/CardRenderer");
10
+ Object.defineProperty(exports, "CardRenderer", { enumerable: true, get: function () { return CardRenderer_1.CardRenderer; } });
11
+ var renderNode_1 = require("./renderer/renderNode");
12
+ Object.defineProperty(exports, "renderNode", { enumerable: true, get: function () { return renderNode_1.renderNode; } });
13
+ var CardContext_1 = require("./cta/CardContext");
14
+ Object.defineProperty(exports, "CardRuntimeProvider", { enumerable: true, get: function () { return CardContext_1.CardRuntimeProvider; } });
15
+ Object.defineProperty(exports, "useCardRuntime", { enumerable: true, get: function () { return CardContext_1.useCardRuntime; } });
16
+ var dispatcher_1 = require("./cta/dispatcher");
17
+ Object.defineProperty(exports, "dispatchCTA", { enumerable: true, get: function () { return dispatcher_1.dispatchCTA; } });
18
+ var resolveFieldName_1 = require("./bindings/resolveFieldName");
19
+ Object.defineProperty(exports, "resolveFieldName", { enumerable: true, get: function () { return resolveFieldName_1.resolveFieldName; } });
20
+ Object.defineProperty(exports, "resolveTemplateString", { enumerable: true, get: function () { return resolveFieldName_1.resolveTemplateString; } });
21
+ Object.defineProperty(exports, "resolveDeep", { enumerable: true, get: function () { return resolveFieldName_1.resolveDeep; } });
22
+ Object.defineProperty(exports, "evaluateShowIf", { enumerable: true, get: function () { return resolveFieldName_1.evaluateShowIf; } });
23
+ var QView_1 = require("./primitives/QView");
24
+ Object.defineProperty(exports, "QView", { enumerable: true, get: function () { return QView_1.QView; } });
25
+ var QText_1 = require("./primitives/QText");
26
+ Object.defineProperty(exports, "QText", { enumerable: true, get: function () { return QText_1.QText; } });
27
+ var QImage_1 = require("./primitives/QImage");
28
+ Object.defineProperty(exports, "QImage", { enumerable: true, get: function () { return QImage_1.QImage; } });
29
+ var QIcon_1 = require("./primitives/QIcon");
30
+ Object.defineProperty(exports, "QIcon", { enumerable: true, get: function () { return QIcon_1.QIcon; } });
31
+ var QDivider_1 = require("./primitives/QDivider");
32
+ Object.defineProperty(exports, "QDivider", { enumerable: true, get: function () { return QDivider_1.QDivider; } });
33
+ var QButton_1 = require("./primitives/QButton");
34
+ Object.defineProperty(exports, "QButton", { enumerable: true, get: function () { return QButton_1.QButton; } });
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import type { QButtonNode } from "../types";
3
+ interface QButtonProps {
4
+ node: QButtonNode;
5
+ data: unknown;
6
+ iterationItem?: unknown;
7
+ iterationIndex?: number;
8
+ }
9
+ export declare function QButton({ node, data, iterationItem, iterationIndex, }: QButtonProps): React.ReactElement | null;
10
+ export {};
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.QButton = QButton;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const resolveFieldName_1 = require("../bindings/resolveFieldName");
40
+ const CardContext_1 = require("../cta/CardContext");
41
+ const dispatcher_1 = require("../cta/dispatcher");
42
+ const VARIANT_STYLES = {
43
+ primary: {
44
+ container: { backgroundColor: "#111", borderRadius: 8, paddingVertical: 12, paddingHorizontal: 16 },
45
+ label: { color: "#fff", fontWeight: "600", fontSize: 14 },
46
+ },
47
+ secondary: {
48
+ container: { backgroundColor: "#f3f3f3", borderRadius: 8, paddingVertical: 12, paddingHorizontal: 16 },
49
+ label: { color: "#111", fontWeight: "600", fontSize: 14 },
50
+ },
51
+ ghost: {
52
+ container: { backgroundColor: "transparent", borderRadius: 8, paddingVertical: 12, paddingHorizontal: 16 },
53
+ label: { color: "#111", fontWeight: "500", fontSize: 14 },
54
+ },
55
+ destructive: {
56
+ container: { backgroundColor: "#d92d20", borderRadius: 8, paddingVertical: 12, paddingHorizontal: 16 },
57
+ label: { color: "#fff", fontWeight: "600", fontSize: 14 },
58
+ },
59
+ };
60
+ function QButton({ node, data, iterationItem, iterationIndex, }) {
61
+ const runtime = (0, CardContext_1.useCardRuntime)();
62
+ const [state, setState] = (0, react_1.useState)("idle");
63
+ const boundLabel = (0, resolveFieldName_1.resolveFieldName)(node.labelFieldName, data, iterationItem);
64
+ const label = typeof boundLabel === "string" ? boundLabel : (node.label ?? "");
65
+ const variant = VARIANT_STYLES[node.variant ?? "primary"];
66
+ const handlePress = (0, react_1.useCallback)(async () => {
67
+ if (state === "loading" || !node.action)
68
+ return;
69
+ setState("loading");
70
+ // `data` is whatever this card is bound against — the iterated item in
71
+ // list mode, the full tool result in detail mode. Either way, that's what
72
+ // the partner needs in the click event. `itemIndex` is only meaningful in
73
+ // list mode; omit it otherwise so partners don't see `null`.
74
+ runtime.lifecycle.onCTAClick?.({
75
+ event: "cta_click",
76
+ cardTemplateId: runtime.cardTemplateId,
77
+ cardSlug: runtime.cardSlug,
78
+ actionType: node.action.action.type,
79
+ messageId: runtime.messageId,
80
+ ...(typeof iterationIndex === "number" ? { itemIndex: iterationIndex } : {}),
81
+ item: data,
82
+ confirmed: !node.action.requiresConfirmation,
83
+ });
84
+ const result = await (0, dispatcher_1.dispatchCTA)(node.action, {
85
+ data: runtime.data,
86
+ iterationItem,
87
+ iterationIndex,
88
+ cardTemplateId: runtime.cardTemplateId,
89
+ cardSlug: runtime.cardSlug,
90
+ messageId: runtime.messageId,
91
+ hostCallbacks: runtime.hostCallbacks,
92
+ lifecycle: runtime.lifecycle,
93
+ dismiss: runtime.dismiss,
94
+ });
95
+ setState(result.status === "success" ? "success" : "error");
96
+ setTimeout(() => setState("idle"), 1200);
97
+ }, [state, node.action, runtime, iterationItem, iterationIndex]);
98
+ if (label === "" && !node.labelFieldName)
99
+ return null;
100
+ const disabled = state === "loading" || !node.action;
101
+ const containerStyle = {
102
+ ...variant.container,
103
+ opacity: disabled ? 0.6 : 1,
104
+ flexDirection: "row",
105
+ alignItems: "center",
106
+ justifyContent: "center",
107
+ gap: 8,
108
+ ...node.style,
109
+ };
110
+ return (<react_native_1.Pressable onPress={handlePress} disabled={disabled} style={containerStyle}>
111
+ {state === "loading" ? (<react_native_1.ActivityIndicator size="small" color={variant.label.color}/>) : (<react_native_1.View>
112
+ <react_native_1.Text style={variant.label}>{label}</react_native_1.Text>
113
+ </react_native_1.View>)}
114
+ </react_native_1.Pressable>);
115
+ }
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import type { QDividerNode } from "../types";
3
+ interface QDividerProps {
4
+ node: QDividerNode;
5
+ }
6
+ export declare function QDivider({ node }: QDividerProps): React.ReactElement;
7
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.QDivider = QDivider;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ function QDivider({ node }) {
10
+ const style = {
11
+ height: node.thickness ?? 1,
12
+ width: "100%",
13
+ backgroundColor: node.color ?? "rgba(0,0,0,0.1)",
14
+ ...node.style,
15
+ };
16
+ return <react_native_1.View style={style}/>;
17
+ }
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import type { QIconNode } from "../types";
3
+ interface QIconProps {
4
+ node: QIconNode;
5
+ data: unknown;
6
+ iterationItem?: unknown;
7
+ }
8
+ /**
9
+ * Icon = unicode/emoji string rendered via <Text>. No icon font dependency.
10
+ * Future versions may add a pluggable icon resolver (e.g. `@expo/vector-icons`).
11
+ */
12
+ export declare function QIcon({ node, data, iterationItem }: QIconProps): React.ReactElement | null;
13
+ export {};
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.QIcon = QIcon;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const resolveFieldName_1 = require("../bindings/resolveFieldName");
10
+ /**
11
+ * Icon = unicode/emoji string rendered via <Text>. No icon font dependency.
12
+ * Future versions may add a pluggable icon resolver (e.g. `@expo/vector-icons`).
13
+ */
14
+ function QIcon({ node, data, iterationItem }) {
15
+ const bound = (0, resolveFieldName_1.resolveFieldName)(node.nameFieldName, data, iterationItem);
16
+ const name = typeof bound === "string" ? bound : node.name;
17
+ if (!name)
18
+ return null;
19
+ const style = {
20
+ fontSize: node.size ?? 16,
21
+ color: node.color,
22
+ lineHeight: node.size ?? 16,
23
+ ...node.style,
24
+ };
25
+ return <react_native_1.Text style={style}>{name}</react_native_1.Text>;
26
+ }
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { QImageNode } from "../types";
3
+ interface QImageProps {
4
+ node: QImageNode;
5
+ data: unknown;
6
+ iterationItem?: unknown;
7
+ }
8
+ export declare function QImage({ node, data, iterationItem }: QImageProps): React.ReactElement | null;
9
+ export {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.QImage = QImage;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const resolveFieldName_1 = require("../bindings/resolveFieldName");
10
+ function QImage({ node, data, iterationItem }) {
11
+ const boundSrc = (0, resolveFieldName_1.resolveFieldName)(node.srcFieldName, data, iterationItem);
12
+ const src = typeof boundSrc === "string" ? boundSrc : node.src;
13
+ if (!src)
14
+ return null;
15
+ const style = {
16
+ width: "100%",
17
+ aspectRatio: node.aspectRatio ?? 1,
18
+ resizeMode: node.fit ?? "cover",
19
+ ...node.style,
20
+ };
21
+ return <react_native_1.Image source={{ uri: src }} style={style}/>;
22
+ }
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { QTextNode } from "../types";
3
+ interface QTextProps {
4
+ node: QTextNode;
5
+ data: unknown;
6
+ iterationItem?: unknown;
7
+ }
8
+ export declare function QText({ node, data, iterationItem }: QTextProps): React.ReactElement | null;
9
+ export {};
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.QText = QText;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const resolveFieldName_1 = require("../bindings/resolveFieldName");
10
+ const VARIANT_STYLE = {
11
+ title: { fontSize: 18, fontWeight: "600", lineHeight: 24 },
12
+ body: { fontSize: 14, fontWeight: "400", lineHeight: 20 },
13
+ caption: { fontSize: 12, fontWeight: "400", lineHeight: 16, opacity: 0.7 },
14
+ };
15
+ function QText({ node, data, iterationItem }) {
16
+ const variantStyle = VARIANT_STYLE[node.variant ?? "body"];
17
+ const bound = (0, resolveFieldName_1.resolveFieldName)(node.fieldName, data, iterationItem);
18
+ const value = bound !== undefined ? String(bound) : (node.text ?? "");
19
+ if (value === "" && node.fieldName)
20
+ return null;
21
+ const style = {
22
+ ...variantStyle,
23
+ textAlign: node.align,
24
+ color: node.color,
25
+ ...node.style,
26
+ };
27
+ return (<react_native_1.Text style={style} numberOfLines={node.numberOfLines} ellipsizeMode={node.ellipsizeMode}>
28
+ {value}
29
+ </react_native_1.Text>);
30
+ }
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import type { QViewNode } from "../types";
3
+ interface QViewProps {
4
+ node: QViewNode;
5
+ children?: React.ReactNode;
6
+ }
7
+ export declare function QView({ node, children }: QViewProps): React.ReactElement;
8
+ export {};
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.QView = QView;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ function QView({ node, children }) {
10
+ const style = {
11
+ flexDirection: node.direction ?? "column",
12
+ gap: node.gap,
13
+ padding: node.padding,
14
+ backgroundColor: node.background,
15
+ borderRadius: node.borderRadius,
16
+ ...node.style,
17
+ };
18
+ return <react_native_1.View style={style}>{children}</react_native_1.View>;
19
+ }
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import type { CardDefinition } from "../types";
3
+ import type { CardCTAHostCallbacks, CardCTALifecycle } from "../cta/types";
4
+ export interface CardRendererProps {
5
+ definition: CardDefinition;
6
+ data: unknown;
7
+ cardTemplateId: string;
8
+ cardSlug: string;
9
+ messageId?: string;
10
+ /**
11
+ * Position when this card is one of many in a list-mode render. Threaded
12
+ * down through renderNode so QButton can attach it to CTA telemetry events.
13
+ * Omit for single-card / detail mode.
14
+ */
15
+ iterationIndex?: number;
16
+ hostCallbacks?: CardCTAHostCallbacks;
17
+ lifecycle?: CardCTALifecycle;
18
+ }
19
+ export declare function CardRenderer({ definition, data, cardTemplateId, cardSlug, messageId, iterationIndex, hostCallbacks, lifecycle, }: CardRendererProps): React.ReactElement | null;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CardRenderer = CardRenderer;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const CardContext_1 = require("../cta/CardContext");
40
+ const renderNode_1 = require("./renderNode");
41
+ function CardRenderer({ definition, data, cardTemplateId, cardSlug, messageId, iterationIndex, hostCallbacks = {}, lifecycle = {}, }) {
42
+ const [dismissed, setDismissed] = (0, react_1.useState)(false);
43
+ const dismiss = (0, react_1.useCallback)(() => setDismissed(true), []);
44
+ if (dismissed)
45
+ return null;
46
+ if (definition.schemaVersion !== 1) {
47
+ if (__DEV__) {
48
+ console.warn(`[card-renderer] Unsupported schemaVersion ${definition.schemaVersion}; skipping render.`);
49
+ }
50
+ return null;
51
+ }
52
+ const runtime = {
53
+ data,
54
+ cardTemplateId,
55
+ cardSlug,
56
+ messageId,
57
+ hostCallbacks,
58
+ lifecycle,
59
+ dismiss,
60
+ };
61
+ return (<CardContext_1.CardRuntimeProvider value={runtime}>
62
+ <react_native_1.View>{(0, renderNode_1.renderNode)(definition.root, { data, iterationIndex })}</react_native_1.View>
63
+ </CardContext_1.CardRuntimeProvider>);
64
+ }
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import type { CardNode } from "../types";
3
+ export interface RenderContext {
4
+ data: unknown;
5
+ iterationItem?: unknown;
6
+ iterationIndex?: number;
7
+ }
8
+ /**
9
+ * Walks a CardNode tree and produces RN elements.
10
+ * Unknown components silently skip (whitelist enforcement at render layer).
11
+ * `showIf` evaluated against the same data context the node would bind against.
12
+ */
13
+ export declare function renderNode(node: CardNode, ctx: RenderContext, key?: string | number): React.ReactNode;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.renderNode = renderNode;
7
+ const react_1 = __importDefault(require("react"));
8
+ const QView_1 = require("../primitives/QView");
9
+ const QText_1 = require("../primitives/QText");
10
+ const QImage_1 = require("../primitives/QImage");
11
+ const QIcon_1 = require("../primitives/QIcon");
12
+ const QDivider_1 = require("../primitives/QDivider");
13
+ const QButton_1 = require("../primitives/QButton");
14
+ const resolveFieldName_1 = require("../bindings/resolveFieldName");
15
+ /**
16
+ * Walks a CardNode tree and produces RN elements.
17
+ * Unknown components silently skip (whitelist enforcement at render layer).
18
+ * `showIf` evaluated against the same data context the node would bind against.
19
+ */
20
+ function renderNode(node, ctx, key) {
21
+ if (!(0, resolveFieldName_1.evaluateShowIf)(node.showIf, ctx.data, ctx.iterationItem))
22
+ return null;
23
+ const children = node.children?.map((child, idx) => renderNode(child, ctx, `${key ?? "n"}-${idx}`));
24
+ switch (node.component) {
25
+ case "QView":
26
+ return (<QView_1.QView key={key} node={node}>
27
+ {children}
28
+ </QView_1.QView>);
29
+ case "QText":
30
+ return <QText_1.QText key={key} node={node} data={ctx.data} iterationItem={ctx.iterationItem}/>;
31
+ case "QImage":
32
+ return <QImage_1.QImage key={key} node={node} data={ctx.data} iterationItem={ctx.iterationItem}/>;
33
+ case "QIcon":
34
+ return <QIcon_1.QIcon key={key} node={node} data={ctx.data} iterationItem={ctx.iterationItem}/>;
35
+ case "QDivider":
36
+ return <QDivider_1.QDivider key={key} node={node}/>;
37
+ case "QButton":
38
+ return (<QButton_1.QButton key={key} node={node} data={ctx.data} iterationItem={ctx.iterationItem} iterationIndex={ctx.iterationIndex}/>);
39
+ default:
40
+ return null;
41
+ }
42
+ }