@skedulo/mexwex-bridge 0.0.3 → 0.0.5
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/dist/index.d.mts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +21 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -16,6 +16,7 @@ declare const BridgeMethods: {
|
|
|
16
16
|
readonly collectTapToPayPayment: "collectTapToPayPayment";
|
|
17
17
|
readonly captureSignature: "captureSignature";
|
|
18
18
|
readonly addSignature: "addSignature";
|
|
19
|
+
readonly getInitialContext: "getInitialContext";
|
|
19
20
|
};
|
|
20
21
|
/** Available attachment picker sources */
|
|
21
22
|
type AttachmentSource = 'camera' | 'photoLibrary' | 'files';
|
|
@@ -105,6 +106,26 @@ interface AddSignatureParams {
|
|
|
105
106
|
/** Optional category name for the signature */
|
|
106
107
|
categoryName?: string;
|
|
107
108
|
}
|
|
109
|
+
/** Salesforce-style entity name for the form's context object */
|
|
110
|
+
type ContextObject = 'Jobs' | 'Shifts';
|
|
111
|
+
/**
|
|
112
|
+
* Initial context delivered to a MEXWEX form on demand.
|
|
113
|
+
*
|
|
114
|
+
* Returned by `getInitialContext()` and reflects the currently-active form's
|
|
115
|
+
* context — re-evaluates fresh on in-app re-navigation between MEX forms.
|
|
116
|
+
*
|
|
117
|
+
* `deepLinkUrl` is the full URL the form was opened with (when applicable).
|
|
118
|
+
* `queryParams` is the parsed query string of `deepLinkUrl`. Both are absent
|
|
119
|
+
* when the form was opened without a deep link, or via the legacy URL pattern
|
|
120
|
+
* which strips query parameters.
|
|
121
|
+
*/
|
|
122
|
+
interface InitialContext {
|
|
123
|
+
deepLinkUrl?: string;
|
|
124
|
+
mexId: string;
|
|
125
|
+
contextObject?: ContextObject;
|
|
126
|
+
contextObjectId?: string;
|
|
127
|
+
queryParams: Record<string, string>;
|
|
128
|
+
}
|
|
108
129
|
|
|
109
130
|
declare global {
|
|
110
131
|
interface Window {
|
|
@@ -119,6 +140,11 @@ declare class MexBridge {
|
|
|
119
140
|
private _initialized;
|
|
120
141
|
constructor();
|
|
121
142
|
private _initialize;
|
|
143
|
+
/**
|
|
144
|
+
* Send a bridge call. Pass `timeoutMs: 0` to disable the timeout entirely —
|
|
145
|
+
* required for user-interactive methods (e.g. captureSignature, captureAttachments)
|
|
146
|
+
* because the user can take arbitrarily long to interact.
|
|
147
|
+
*/
|
|
122
148
|
private _call;
|
|
123
149
|
private _generateId;
|
|
124
150
|
/** Fetch the current form instance data */
|
|
@@ -153,8 +179,15 @@ declare class MexBridge {
|
|
|
153
179
|
captureSignature(options?: CaptureSignatureOptions): Promise<CaptureSignatureResult | null>;
|
|
154
180
|
/** Persist a captured signature to the native mobile layer */
|
|
155
181
|
addSignature(params: AddSignatureParams): Promise<any>;
|
|
182
|
+
/**
|
|
183
|
+
* Fetch the initial context for the current form — deep-link URL (if any),
|
|
184
|
+
* mex ID, context object/id, and parsed query parameters. Always reflects
|
|
185
|
+
* the currently-active form, so calling again after in-app re-navigation
|
|
186
|
+
* returns the new form's context.
|
|
187
|
+
*/
|
|
188
|
+
getInitialContext(): Promise<InitialContext>;
|
|
156
189
|
}
|
|
157
190
|
|
|
158
191
|
declare const mexBridge: MexBridge;
|
|
159
192
|
|
|
160
|
-
export { type AddAttachmentsParams, type AddSignatureParams, type AttachmentMetadata, type AttachmentSource, type AttachmentsByParentIdResult, type AuthenticationInfo, BridgeMethods, type CaptureAttachmentsParams, type CaptureSignatureOptions, type CaptureSignatureResult, type FormMetadata, MexBridge, type PickedFile, type TapToPayParams, type TapToPayResult, mexBridge };
|
|
193
|
+
export { type AddAttachmentsParams, type AddSignatureParams, type AttachmentMetadata, type AttachmentSource, type AttachmentsByParentIdResult, type AuthenticationInfo, BridgeMethods, type CaptureAttachmentsParams, type CaptureSignatureOptions, type CaptureSignatureResult, type ContextObject, type FormMetadata, type InitialContext, MexBridge, type PickedFile, type TapToPayParams, type TapToPayResult, mexBridge };
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ declare const BridgeMethods: {
|
|
|
16
16
|
readonly collectTapToPayPayment: "collectTapToPayPayment";
|
|
17
17
|
readonly captureSignature: "captureSignature";
|
|
18
18
|
readonly addSignature: "addSignature";
|
|
19
|
+
readonly getInitialContext: "getInitialContext";
|
|
19
20
|
};
|
|
20
21
|
/** Available attachment picker sources */
|
|
21
22
|
type AttachmentSource = 'camera' | 'photoLibrary' | 'files';
|
|
@@ -105,6 +106,26 @@ interface AddSignatureParams {
|
|
|
105
106
|
/** Optional category name for the signature */
|
|
106
107
|
categoryName?: string;
|
|
107
108
|
}
|
|
109
|
+
/** Salesforce-style entity name for the form's context object */
|
|
110
|
+
type ContextObject = 'Jobs' | 'Shifts';
|
|
111
|
+
/**
|
|
112
|
+
* Initial context delivered to a MEXWEX form on demand.
|
|
113
|
+
*
|
|
114
|
+
* Returned by `getInitialContext()` and reflects the currently-active form's
|
|
115
|
+
* context — re-evaluates fresh on in-app re-navigation between MEX forms.
|
|
116
|
+
*
|
|
117
|
+
* `deepLinkUrl` is the full URL the form was opened with (when applicable).
|
|
118
|
+
* `queryParams` is the parsed query string of `deepLinkUrl`. Both are absent
|
|
119
|
+
* when the form was opened without a deep link, or via the legacy URL pattern
|
|
120
|
+
* which strips query parameters.
|
|
121
|
+
*/
|
|
122
|
+
interface InitialContext {
|
|
123
|
+
deepLinkUrl?: string;
|
|
124
|
+
mexId: string;
|
|
125
|
+
contextObject?: ContextObject;
|
|
126
|
+
contextObjectId?: string;
|
|
127
|
+
queryParams: Record<string, string>;
|
|
128
|
+
}
|
|
108
129
|
|
|
109
130
|
declare global {
|
|
110
131
|
interface Window {
|
|
@@ -119,6 +140,11 @@ declare class MexBridge {
|
|
|
119
140
|
private _initialized;
|
|
120
141
|
constructor();
|
|
121
142
|
private _initialize;
|
|
143
|
+
/**
|
|
144
|
+
* Send a bridge call. Pass `timeoutMs: 0` to disable the timeout entirely —
|
|
145
|
+
* required for user-interactive methods (e.g. captureSignature, captureAttachments)
|
|
146
|
+
* because the user can take arbitrarily long to interact.
|
|
147
|
+
*/
|
|
122
148
|
private _call;
|
|
123
149
|
private _generateId;
|
|
124
150
|
/** Fetch the current form instance data */
|
|
@@ -153,8 +179,15 @@ declare class MexBridge {
|
|
|
153
179
|
captureSignature(options?: CaptureSignatureOptions): Promise<CaptureSignatureResult | null>;
|
|
154
180
|
/** Persist a captured signature to the native mobile layer */
|
|
155
181
|
addSignature(params: AddSignatureParams): Promise<any>;
|
|
182
|
+
/**
|
|
183
|
+
* Fetch the initial context for the current form — deep-link URL (if any),
|
|
184
|
+
* mex ID, context object/id, and parsed query parameters. Always reflects
|
|
185
|
+
* the currently-active form, so calling again after in-app re-navigation
|
|
186
|
+
* returns the new form's context.
|
|
187
|
+
*/
|
|
188
|
+
getInitialContext(): Promise<InitialContext>;
|
|
156
189
|
}
|
|
157
190
|
|
|
158
191
|
declare const mexBridge: MexBridge;
|
|
159
192
|
|
|
160
|
-
export { type AddAttachmentsParams, type AddSignatureParams, type AttachmentMetadata, type AttachmentSource, type AttachmentsByParentIdResult, type AuthenticationInfo, BridgeMethods, type CaptureAttachmentsParams, type CaptureSignatureOptions, type CaptureSignatureResult, type FormMetadata, MexBridge, type PickedFile, type TapToPayParams, type TapToPayResult, mexBridge };
|
|
193
|
+
export { type AddAttachmentsParams, type AddSignatureParams, type AttachmentMetadata, type AttachmentSource, type AttachmentsByParentIdResult, type AuthenticationInfo, BridgeMethods, type CaptureAttachmentsParams, type CaptureSignatureOptions, type CaptureSignatureResult, type ContextObject, type FormMetadata, type InitialContext, MexBridge, type PickedFile, type TapToPayParams, type TapToPayResult, mexBridge };
|
package/dist/index.js
CHANGED
|
@@ -43,7 +43,8 @@ var BridgeMethods = {
|
|
|
43
43
|
exit: "exit",
|
|
44
44
|
collectTapToPayPayment: "collectTapToPayPayment",
|
|
45
45
|
captureSignature: "captureSignature",
|
|
46
|
-
addSignature: "addSignature"
|
|
46
|
+
addSignature: "addSignature",
|
|
47
|
+
getInitialContext: "getInitialContext"
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
// src/MexBridge.ts
|
|
@@ -63,7 +64,7 @@ var MexBridge = class {
|
|
|
63
64
|
if (message.type !== "bridge_response" || !message.requestId) return;
|
|
64
65
|
const pending = this._callbacks.get(message.requestId);
|
|
65
66
|
if (!pending) return;
|
|
66
|
-
clearTimeout(pending.timeoutId);
|
|
67
|
+
if (pending.timeoutId !== null) clearTimeout(pending.timeoutId);
|
|
67
68
|
this._callbacks.delete(message.requestId);
|
|
68
69
|
if (message.error) {
|
|
69
70
|
pending.reject(new Error(message.error));
|
|
@@ -75,6 +76,11 @@ var MexBridge = class {
|
|
|
75
76
|
}
|
|
76
77
|
};
|
|
77
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Send a bridge call. Pass `timeoutMs: 0` to disable the timeout entirely —
|
|
81
|
+
* required for user-interactive methods (e.g. captureSignature, captureAttachments)
|
|
82
|
+
* because the user can take arbitrarily long to interact.
|
|
83
|
+
*/
|
|
78
84
|
_call(method, params, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
79
85
|
return new Promise((resolve, reject) => {
|
|
80
86
|
if (!window.ReactNativeWebView) {
|
|
@@ -82,10 +88,10 @@ var MexBridge = class {
|
|
|
82
88
|
return;
|
|
83
89
|
}
|
|
84
90
|
const requestId = this._generateId();
|
|
85
|
-
const timeoutId = setTimeout(() => {
|
|
91
|
+
const timeoutId = timeoutMs > 0 ? setTimeout(() => {
|
|
86
92
|
this._callbacks.delete(requestId);
|
|
87
93
|
reject(new Error(`[MexBridge] Timeout: ${method} did not respond within ${timeoutMs}ms`));
|
|
88
|
-
}, timeoutMs);
|
|
94
|
+
}, timeoutMs) : null;
|
|
89
95
|
this._callbacks.set(requestId, { resolve, reject, timeoutId });
|
|
90
96
|
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
91
97
|
type: "bridge_call",
|
|
@@ -108,7 +114,7 @@ var MexBridge = class {
|
|
|
108
114
|
}
|
|
109
115
|
/** Open native picker(s) for camera, photo library, or files. Returns picked files or null if cancelled. */
|
|
110
116
|
captureAttachments(params) {
|
|
111
|
-
return this._call(BridgeMethods.captureAttachments, params);
|
|
117
|
+
return this._call(BridgeMethods.captureAttachments, params, 0);
|
|
112
118
|
}
|
|
113
119
|
/** Persist captured attachments to the native mobile layer */
|
|
114
120
|
addAttachments(params) {
|
|
@@ -156,12 +162,21 @@ var MexBridge = class {
|
|
|
156
162
|
}
|
|
157
163
|
/** Open the native signature screen. Resolves with the captured signature, or null if the user cancels. */
|
|
158
164
|
captureSignature(options) {
|
|
159
|
-
return this._call(BridgeMethods.captureSignature, options,
|
|
165
|
+
return this._call(BridgeMethods.captureSignature, options, 0);
|
|
160
166
|
}
|
|
161
167
|
/** Persist a captured signature to the native mobile layer */
|
|
162
168
|
addSignature(params) {
|
|
163
169
|
return this._call(BridgeMethods.addSignature, params);
|
|
164
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Fetch the initial context for the current form — deep-link URL (if any),
|
|
173
|
+
* mex ID, context object/id, and parsed query parameters. Always reflects
|
|
174
|
+
* the currently-active form, so calling again after in-app re-navigation
|
|
175
|
+
* returns the new form's context.
|
|
176
|
+
*/
|
|
177
|
+
getInitialContext() {
|
|
178
|
+
return this._call(BridgeMethods.getInitialContext);
|
|
179
|
+
}
|
|
165
180
|
};
|
|
166
181
|
|
|
167
182
|
// src/index.ts
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/MexBridge.ts"],"sourcesContent":["export { MexBridge } from './MexBridge'\nexport { BridgeMethods } from './types'\nexport type {\n CaptureAttachmentsParams,\n AddAttachmentsParams,\n AttachmentSource,\n PickedFile,\n AttachmentMetadata,\n AttachmentsByParentIdResult,\n AuthenticationInfo,\n FormMetadata,\n TapToPayParams,\n TapToPayResult,\n CaptureSignatureOptions,\n CaptureSignatureResult,\n AddSignatureParams,\n} from './types'\n\n// Singleton instance for convenience\nimport { MexBridge } from './MexBridge'\nexport const mexBridge = new MexBridge()\n","/** Bridge method name constants — shared between web SDK and native handlers */\nexport const BridgeMethods = {\n getInstanceData: 'getInstanceData',\n getStaticData: 'getStaticData',\n captureAttachments: 'captureAttachments',\n addAttachments: 'addAttachments',\n removeAttachment: 'removeAttachment',\n getAttachment: 'getAttachment',\n getAttachmentsByParentId: 'getAttachmentsByParentId',\n saveInstanceData: 'saveInstanceData',\n getMetadata: 'getMetadata',\n getAuthenticationInfo: 'getAuthenticationInfo',\n getLocalizedString: 'getLocalizedString',\n sendExtensionMandatoryStatus: 'sendExtensionMandatoryStatus',\n exit: 'exit',\n collectTapToPayPayment: 'collectTapToPayPayment',\n captureSignature: 'captureSignature',\n addSignature: 'addSignature',\n} as const\n\n/** Available attachment picker sources */\nexport type AttachmentSource = 'camera' | 'photoLibrary' | 'files'\n\n/** Parameters for capturing attachments via native pickers */\nexport interface CaptureAttachmentsParams {\n /** Which picker sources to offer. Defaults to all three. If only one, opens directly without bottom sheet. */\n sources?: AttachmentSource[]\n}\n\n/** A file picked from a native picker (camera, photo library, or file browser) */\nexport interface PickedFile {\n uri: string\n fileName: string\n}\n\n/** Parameters for persisting captured attachments to the native layer */\nexport interface AddAttachmentsParams {\n /** The picked files to persist */\n attachments: PickedFile[]\n /** The parent object ID to associate attachments with */\n parentContextId: string\n /** Optional category name for the attachments */\n categoryName?: string\n}\n\n/** Metadata about a stored attachment (returned by getAttachment) */\nexport interface AttachmentMetadata {\n uid: string\n fileName: string\n downloadURL?: string\n status?: string\n contentType?: string\n}\n\n/** Result of getAttachmentsByParentId — matches MexAttachmentsOnParentContextChangedResult */\nexport interface AttachmentsByParentIdResult {\n attachments: AttachmentMetadata[]\n parentId: string\n}\n\n/** Authentication information for the current user */\nexport interface AuthenticationInfo {\n accessToken: string\n apiUrl: string\n userId?: string\n}\n\n/** Form metadata */\nexport interface FormMetadata {\n contextObjectId: string\n packageId: string\n formName?: string\n contextObject?: string\n user?: Record<string, any>\n job?: Record<string, any>\n timezone?: Record<string, any>\n}\n\n/** Parameters for initiating a Tap to Pay payment via Stripe Terminal */\nexport interface TapToPayParams {\n connectionToken: string\n clientSecret: string\n locationId: string\n}\n\n/** Result of a Tap to Pay payment attempt */\nexport interface TapToPayResult {\n success: boolean\n paymentIntentId?: string\n error?: string\n}\n\n/** Parameters for capturing a signature via the native signature screen */\nexport interface CaptureSignatureOptions {\n /** Show the full-name field on the native screen. Defaults to false. */\n enableFullName?: boolean\n}\n\n/** Result of a successful signature capture */\nexport interface CaptureSignatureResult {\n /** Local file path to the captured signature image */\n uri: string\n /** Generated file name, e.g. \"signature-<uuid>.png\". Informational only — addSignature ignores it. */\n fileName: string\n /** Full name entered by the signer. Only present when CaptureSignatureOptions.enableFullName === true. */\n fullName?: string\n}\n\n/** Parameters for persisting a captured signature to the native layer */\nexport interface AddSignatureParams {\n /** The captured signature to persist */\n signature: {\n uri: string\n fullName?: string\n }\n /** The parent object ID to associate the signature with */\n parentContextId: string\n /** Optional category name for the signature */\n categoryName?: string\n}\n\n/** Internal bridge message from web to RN */\nexport interface BridgeCallMessage {\n type: 'bridge_call'\n method: string\n requestId: string\n params?: any\n}\n\n/** Internal bridge response from RN to web */\nexport interface BridgeResponseMessage {\n type: 'bridge_response'\n requestId: string\n result?: any\n error?: string\n}\n","import { BridgeMethods } from './types'\nimport type { CaptureAttachmentsParams, AddAttachmentsParams, PickedFile, AttachmentMetadata, AttachmentsByParentIdResult, AuthenticationInfo, FormMetadata, BridgeResponseMessage, TapToPayParams, TapToPayResult, CaptureSignatureOptions, CaptureSignatureResult, AddSignatureParams } from './types'\n\ntype PendingCallback = {\n resolve: (value: any) => void\n reject: (reason: any) => void\n timeoutId: ReturnType<typeof setTimeout>\n}\n\ndeclare global {\n interface Window {\n ReactNativeWebView?: {\n postMessage(message: string): void\n }\n onNativeMessage?: (messageString: string) => void\n }\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000\n\nclass MexBridge {\n private _callbacks = new Map<string, PendingCallback>()\n private _initialized = false\n\n constructor() {\n this._initialize()\n }\n\n private _initialize(): void {\n if (this._initialized) return\n this._initialized = true\n\n window.onNativeMessage = (messageString: string) => {\n try {\n const message: BridgeResponseMessage = JSON.parse(messageString)\n if (message.type !== 'bridge_response' || !message.requestId) return\n\n const pending = this._callbacks.get(message.requestId)\n if (!pending) return\n\n clearTimeout(pending.timeoutId)\n this._callbacks.delete(message.requestId)\n\n if (message.error) {\n pending.reject(new Error(message.error))\n } else {\n pending.resolve(message.result)\n }\n } catch (e) {\n console.warn('[MexBridge] Failed to parse native message:', e)\n }\n }\n }\n\n private _call<T = any>(method: string, params?: any, timeoutMs = DEFAULT_TIMEOUT_MS): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n if (!window.ReactNativeWebView) {\n reject(new Error('[MexBridge] Not running inside a React Native WebView'))\n return\n }\n\n const requestId = this._generateId()\n\n const timeoutId = setTimeout(() => {\n this._callbacks.delete(requestId)\n reject(new Error(`[MexBridge] Timeout: ${method} did not respond within ${timeoutMs}ms`))\n }, timeoutMs)\n\n this._callbacks.set(requestId, { resolve, reject, timeoutId })\n\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: 'bridge_call',\n method,\n requestId,\n params,\n }))\n })\n }\n\n private _generateId(): string {\n return Math.random().toString(36).substring(2) + Date.now().toString(36)\n }\n\n /** Fetch the current form instance data */\n getInstanceData(): Promise<any> {\n return this._call(BridgeMethods.getInstanceData)\n }\n\n /** Fetch static/shared data for the form */\n getStaticData(): Promise<any> {\n return this._call(BridgeMethods.getStaticData)\n }\n\n /** Open native picker(s) for camera, photo library, or files. Returns picked files or null if cancelled. */\n captureAttachments(params?: CaptureAttachmentsParams): Promise<PickedFile[] | null> {\n return this._call<PickedFile[] | null>(BridgeMethods.captureAttachments, params)\n }\n\n /** Persist captured attachments to the native mobile layer */\n addAttachments(params: AddAttachmentsParams): Promise<any> {\n return this._call(BridgeMethods.addAttachments, params)\n }\n\n /** Remove an existing attachment by ID */\n removeAttachment(attachmentId: string): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.removeAttachment, { attachmentId })\n }\n\n /** Retrieve attachment metadata by ID */\n getAttachment(attachmentId: string): Promise<AttachmentMetadata> {\n return this._call<AttachmentMetadata>(BridgeMethods.getAttachment, { attachmentId })\n }\n\n /** Get all attachments for a parent object (one-shot, not observable) */\n getAttachmentsByParentId(parentContextId: string): Promise<AttachmentsByParentIdResult> {\n return this._call<AttachmentsByParentIdResult>(BridgeMethods.getAttachmentsByParentId, { parentContextId })\n }\n\n /** Persist form data back to the engine */\n saveInstanceData(data: any): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.saveInstanceData, { data })\n }\n\n /** Retrieve form metadata (form name, context, user info, etc.) */\n getMetadata(): Promise<FormMetadata> {\n return this._call<FormMetadata>(BridgeMethods.getMetadata)\n }\n\n /** Get the current user's auth token and identity */\n getAuthenticationInfo(): Promise<AuthenticationInfo> {\n return this._call<AuthenticationInfo>(BridgeMethods.getAuthenticationInfo)\n }\n\n /** Get a localized string by key from the form's locale files */\n getLocalizedString(key: string): Promise<string> {\n return this._call<string>(BridgeMethods.getLocalizedString, { key })\n }\n\n /** Signal whether the form's mandatory requirements are satisfied */\n sendExtensionMandatoryStatus(isCompleted: boolean): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.sendExtensionMandatoryStatus, { isCompleted })\n }\n\n /** Exit the form and return to the native app */\n exit(): Promise<void> {\n return this._call<void>(BridgeMethods.exit)\n }\n\n /** Initiate a Tap to Pay payment via Stripe Terminal on the native device */\n collectTapToPayPayment(params: TapToPayParams): Promise<TapToPayResult> {\n return this._call<TapToPayResult>(BridgeMethods.collectTapToPayPayment, params, 120_000)\n }\n\n /** Open the native signature screen. Resolves with the captured signature, or null if the user cancels. */\n captureSignature(options?: CaptureSignatureOptions): Promise<CaptureSignatureResult | null> {\n return this._call<CaptureSignatureResult | null>(BridgeMethods.captureSignature, options, 120_000)\n }\n\n /** Persist a captured signature to the native mobile layer */\n addSignature(params: AddSignatureParams): Promise<any> {\n return this._call(BridgeMethods.addSignature, params)\n }\n}\n\nexport { MexBridge }\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/MexBridge.ts"],"sourcesContent":["export { MexBridge } from './MexBridge'\nexport { BridgeMethods } from './types'\nexport type {\n CaptureAttachmentsParams,\n AddAttachmentsParams,\n AttachmentSource,\n PickedFile,\n AttachmentMetadata,\n AttachmentsByParentIdResult,\n AuthenticationInfo,\n FormMetadata,\n TapToPayParams,\n TapToPayResult,\n CaptureSignatureOptions,\n CaptureSignatureResult,\n AddSignatureParams,\n ContextObject,\n InitialContext,\n} from './types'\n\n// Singleton instance for convenience\nimport { MexBridge } from './MexBridge'\nexport const mexBridge = new MexBridge()\n","/** Bridge method name constants — shared between web SDK and native handlers */\nexport const BridgeMethods = {\n getInstanceData: 'getInstanceData',\n getStaticData: 'getStaticData',\n captureAttachments: 'captureAttachments',\n addAttachments: 'addAttachments',\n removeAttachment: 'removeAttachment',\n getAttachment: 'getAttachment',\n getAttachmentsByParentId: 'getAttachmentsByParentId',\n saveInstanceData: 'saveInstanceData',\n getMetadata: 'getMetadata',\n getAuthenticationInfo: 'getAuthenticationInfo',\n getLocalizedString: 'getLocalizedString',\n sendExtensionMandatoryStatus: 'sendExtensionMandatoryStatus',\n exit: 'exit',\n collectTapToPayPayment: 'collectTapToPayPayment',\n captureSignature: 'captureSignature',\n addSignature: 'addSignature',\n getInitialContext: 'getInitialContext',\n} as const\n\n/** Available attachment picker sources */\nexport type AttachmentSource = 'camera' | 'photoLibrary' | 'files'\n\n/** Parameters for capturing attachments via native pickers */\nexport interface CaptureAttachmentsParams {\n /** Which picker sources to offer. Defaults to all three. If only one, opens directly without bottom sheet. */\n sources?: AttachmentSource[]\n}\n\n/** A file picked from a native picker (camera, photo library, or file browser) */\nexport interface PickedFile {\n uri: string\n fileName: string\n}\n\n/** Parameters for persisting captured attachments to the native layer */\nexport interface AddAttachmentsParams {\n /** The picked files to persist */\n attachments: PickedFile[]\n /** The parent object ID to associate attachments with */\n parentContextId: string\n /** Optional category name for the attachments */\n categoryName?: string\n}\n\n/** Metadata about a stored attachment (returned by getAttachment) */\nexport interface AttachmentMetadata {\n uid: string\n fileName: string\n downloadURL?: string\n status?: string\n contentType?: string\n}\n\n/** Result of getAttachmentsByParentId — matches MexAttachmentsOnParentContextChangedResult */\nexport interface AttachmentsByParentIdResult {\n attachments: AttachmentMetadata[]\n parentId: string\n}\n\n/** Authentication information for the current user */\nexport interface AuthenticationInfo {\n accessToken: string\n apiUrl: string\n userId?: string\n}\n\n/** Form metadata */\nexport interface FormMetadata {\n contextObjectId: string\n packageId: string\n formName?: string\n contextObject?: string\n user?: Record<string, any>\n job?: Record<string, any>\n timezone?: Record<string, any>\n}\n\n/** Parameters for initiating a Tap to Pay payment via Stripe Terminal */\nexport interface TapToPayParams {\n connectionToken: string\n clientSecret: string\n locationId: string\n}\n\n/** Result of a Tap to Pay payment attempt */\nexport interface TapToPayResult {\n success: boolean\n paymentIntentId?: string\n error?: string\n}\n\n/** Parameters for capturing a signature via the native signature screen */\nexport interface CaptureSignatureOptions {\n /** Show the full-name field on the native screen. Defaults to false. */\n enableFullName?: boolean\n}\n\n/** Result of a successful signature capture */\nexport interface CaptureSignatureResult {\n /** Local file path to the captured signature image */\n uri: string\n /** Generated file name, e.g. \"signature-<uuid>.png\". Informational only — addSignature ignores it. */\n fileName: string\n /** Full name entered by the signer. Only present when CaptureSignatureOptions.enableFullName === true. */\n fullName?: string\n}\n\n/** Parameters for persisting a captured signature to the native layer */\nexport interface AddSignatureParams {\n /** The captured signature to persist */\n signature: {\n uri: string\n fullName?: string\n }\n /** The parent object ID to associate the signature with */\n parentContextId: string\n /** Optional category name for the signature */\n categoryName?: string\n}\n\n/** Salesforce-style entity name for the form's context object */\nexport type ContextObject = 'Jobs' | 'Shifts'\n\n/**\n * Initial context delivered to a MEXWEX form on demand.\n *\n * Returned by `getInitialContext()` and reflects the currently-active form's\n * context — re-evaluates fresh on in-app re-navigation between MEX forms.\n *\n * `deepLinkUrl` is the full URL the form was opened with (when applicable).\n * `queryParams` is the parsed query string of `deepLinkUrl`. Both are absent\n * when the form was opened without a deep link, or via the legacy URL pattern\n * which strips query parameters.\n */\nexport interface InitialContext {\n deepLinkUrl?: string\n mexId: string\n contextObject?: ContextObject\n contextObjectId?: string\n queryParams: Record<string, string>\n}\n\n/** Internal bridge message from web to RN */\nexport interface BridgeCallMessage {\n type: 'bridge_call'\n method: string\n requestId: string\n params?: any\n}\n\n/** Internal bridge response from RN to web */\nexport interface BridgeResponseMessage {\n type: 'bridge_response'\n requestId: string\n result?: any\n error?: string\n}\n","import { BridgeMethods } from './types'\nimport type { CaptureAttachmentsParams, AddAttachmentsParams, PickedFile, AttachmentMetadata, AttachmentsByParentIdResult, AuthenticationInfo, FormMetadata, BridgeResponseMessage, TapToPayParams, TapToPayResult, CaptureSignatureOptions, CaptureSignatureResult, AddSignatureParams, InitialContext } from './types'\n\ntype PendingCallback = {\n resolve: (value: any) => void\n reject: (reason: any) => void\n timeoutId: ReturnType<typeof setTimeout> | null\n}\n\ndeclare global {\n interface Window {\n ReactNativeWebView?: {\n postMessage(message: string): void\n }\n onNativeMessage?: (messageString: string) => void\n }\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000\n\nclass MexBridge {\n private _callbacks = new Map<string, PendingCallback>()\n private _initialized = false\n\n constructor() {\n this._initialize()\n }\n\n private _initialize(): void {\n if (this._initialized) return\n this._initialized = true\n\n window.onNativeMessage = (messageString: string) => {\n try {\n const message: BridgeResponseMessage = JSON.parse(messageString)\n if (message.type !== 'bridge_response' || !message.requestId) return\n\n const pending = this._callbacks.get(message.requestId)\n if (!pending) return\n\n if (pending.timeoutId !== null) clearTimeout(pending.timeoutId)\n this._callbacks.delete(message.requestId)\n\n if (message.error) {\n pending.reject(new Error(message.error))\n } else {\n pending.resolve(message.result)\n }\n } catch (e) {\n console.warn('[MexBridge] Failed to parse native message:', e)\n }\n }\n }\n\n /**\n * Send a bridge call. Pass `timeoutMs: 0` to disable the timeout entirely —\n * required for user-interactive methods (e.g. captureSignature, captureAttachments)\n * because the user can take arbitrarily long to interact.\n */\n private _call<T = any>(method: string, params?: any, timeoutMs: number = DEFAULT_TIMEOUT_MS): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n if (!window.ReactNativeWebView) {\n reject(new Error('[MexBridge] Not running inside a React Native WebView'))\n return\n }\n\n const requestId = this._generateId()\n\n const timeoutId = timeoutMs > 0\n ? setTimeout(() => {\n this._callbacks.delete(requestId)\n reject(new Error(`[MexBridge] Timeout: ${method} did not respond within ${timeoutMs}ms`))\n }, timeoutMs)\n : null\n\n this._callbacks.set(requestId, { resolve, reject, timeoutId })\n\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: 'bridge_call',\n method,\n requestId,\n params,\n }))\n })\n }\n\n private _generateId(): string {\n return Math.random().toString(36).substring(2) + Date.now().toString(36)\n }\n\n /** Fetch the current form instance data */\n getInstanceData(): Promise<any> {\n return this._call(BridgeMethods.getInstanceData)\n }\n\n /** Fetch static/shared data for the form */\n getStaticData(): Promise<any> {\n return this._call(BridgeMethods.getStaticData)\n }\n\n /** Open native picker(s) for camera, photo library, or files. Returns picked files or null if cancelled. */\n captureAttachments(params?: CaptureAttachmentsParams): Promise<PickedFile[] | null> {\n return this._call<PickedFile[] | null>(BridgeMethods.captureAttachments, params, 0)\n }\n\n /** Persist captured attachments to the native mobile layer */\n addAttachments(params: AddAttachmentsParams): Promise<any> {\n return this._call(BridgeMethods.addAttachments, params)\n }\n\n /** Remove an existing attachment by ID */\n removeAttachment(attachmentId: string): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.removeAttachment, { attachmentId })\n }\n\n /** Retrieve attachment metadata by ID */\n getAttachment(attachmentId: string): Promise<AttachmentMetadata> {\n return this._call<AttachmentMetadata>(BridgeMethods.getAttachment, { attachmentId })\n }\n\n /** Get all attachments for a parent object (one-shot, not observable) */\n getAttachmentsByParentId(parentContextId: string): Promise<AttachmentsByParentIdResult> {\n return this._call<AttachmentsByParentIdResult>(BridgeMethods.getAttachmentsByParentId, { parentContextId })\n }\n\n /** Persist form data back to the engine */\n saveInstanceData(data: any): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.saveInstanceData, { data })\n }\n\n /** Retrieve form metadata (form name, context, user info, etc.) */\n getMetadata(): Promise<FormMetadata> {\n return this._call<FormMetadata>(BridgeMethods.getMetadata)\n }\n\n /** Get the current user's auth token and identity */\n getAuthenticationInfo(): Promise<AuthenticationInfo> {\n return this._call<AuthenticationInfo>(BridgeMethods.getAuthenticationInfo)\n }\n\n /** Get a localized string by key from the form's locale files */\n getLocalizedString(key: string): Promise<string> {\n return this._call<string>(BridgeMethods.getLocalizedString, { key })\n }\n\n /** Signal whether the form's mandatory requirements are satisfied */\n sendExtensionMandatoryStatus(isCompleted: boolean): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.sendExtensionMandatoryStatus, { isCompleted })\n }\n\n /** Exit the form and return to the native app */\n exit(): Promise<void> {\n return this._call<void>(BridgeMethods.exit)\n }\n\n /** Initiate a Tap to Pay payment via Stripe Terminal on the native device */\n collectTapToPayPayment(params: TapToPayParams): Promise<TapToPayResult> {\n return this._call<TapToPayResult>(BridgeMethods.collectTapToPayPayment, params, 120_000)\n }\n\n /** Open the native signature screen. Resolves with the captured signature, or null if the user cancels. */\n captureSignature(options?: CaptureSignatureOptions): Promise<CaptureSignatureResult | null> {\n return this._call<CaptureSignatureResult | null>(BridgeMethods.captureSignature, options, 0)\n }\n\n /** Persist a captured signature to the native mobile layer */\n addSignature(params: AddSignatureParams): Promise<any> {\n return this._call(BridgeMethods.addSignature, params)\n }\n\n /**\n * Fetch the initial context for the current form — deep-link URL (if any),\n * mex ID, context object/id, and parsed query parameters. Always reflects\n * the currently-active form, so calling again after in-app re-navigation\n * returns the new form's context.\n */\n getInitialContext(): Promise<InitialContext> {\n return this._call<InitialContext>(BridgeMethods.getInitialContext)\n }\n}\n\nexport { MexBridge }\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -15,7 +15,8 @@ var BridgeMethods = {
|
|
|
15
15
|
exit: "exit",
|
|
16
16
|
collectTapToPayPayment: "collectTapToPayPayment",
|
|
17
17
|
captureSignature: "captureSignature",
|
|
18
|
-
addSignature: "addSignature"
|
|
18
|
+
addSignature: "addSignature",
|
|
19
|
+
getInitialContext: "getInitialContext"
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
// src/MexBridge.ts
|
|
@@ -35,7 +36,7 @@ var MexBridge = class {
|
|
|
35
36
|
if (message.type !== "bridge_response" || !message.requestId) return;
|
|
36
37
|
const pending = this._callbacks.get(message.requestId);
|
|
37
38
|
if (!pending) return;
|
|
38
|
-
clearTimeout(pending.timeoutId);
|
|
39
|
+
if (pending.timeoutId !== null) clearTimeout(pending.timeoutId);
|
|
39
40
|
this._callbacks.delete(message.requestId);
|
|
40
41
|
if (message.error) {
|
|
41
42
|
pending.reject(new Error(message.error));
|
|
@@ -47,6 +48,11 @@ var MexBridge = class {
|
|
|
47
48
|
}
|
|
48
49
|
};
|
|
49
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Send a bridge call. Pass `timeoutMs: 0` to disable the timeout entirely —
|
|
53
|
+
* required for user-interactive methods (e.g. captureSignature, captureAttachments)
|
|
54
|
+
* because the user can take arbitrarily long to interact.
|
|
55
|
+
*/
|
|
50
56
|
_call(method, params, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
51
57
|
return new Promise((resolve, reject) => {
|
|
52
58
|
if (!window.ReactNativeWebView) {
|
|
@@ -54,10 +60,10 @@ var MexBridge = class {
|
|
|
54
60
|
return;
|
|
55
61
|
}
|
|
56
62
|
const requestId = this._generateId();
|
|
57
|
-
const timeoutId = setTimeout(() => {
|
|
63
|
+
const timeoutId = timeoutMs > 0 ? setTimeout(() => {
|
|
58
64
|
this._callbacks.delete(requestId);
|
|
59
65
|
reject(new Error(`[MexBridge] Timeout: ${method} did not respond within ${timeoutMs}ms`));
|
|
60
|
-
}, timeoutMs);
|
|
66
|
+
}, timeoutMs) : null;
|
|
61
67
|
this._callbacks.set(requestId, { resolve, reject, timeoutId });
|
|
62
68
|
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
63
69
|
type: "bridge_call",
|
|
@@ -80,7 +86,7 @@ var MexBridge = class {
|
|
|
80
86
|
}
|
|
81
87
|
/** Open native picker(s) for camera, photo library, or files. Returns picked files or null if cancelled. */
|
|
82
88
|
captureAttachments(params) {
|
|
83
|
-
return this._call(BridgeMethods.captureAttachments, params);
|
|
89
|
+
return this._call(BridgeMethods.captureAttachments, params, 0);
|
|
84
90
|
}
|
|
85
91
|
/** Persist captured attachments to the native mobile layer */
|
|
86
92
|
addAttachments(params) {
|
|
@@ -128,12 +134,21 @@ var MexBridge = class {
|
|
|
128
134
|
}
|
|
129
135
|
/** Open the native signature screen. Resolves with the captured signature, or null if the user cancels. */
|
|
130
136
|
captureSignature(options) {
|
|
131
|
-
return this._call(BridgeMethods.captureSignature, options,
|
|
137
|
+
return this._call(BridgeMethods.captureSignature, options, 0);
|
|
132
138
|
}
|
|
133
139
|
/** Persist a captured signature to the native mobile layer */
|
|
134
140
|
addSignature(params) {
|
|
135
141
|
return this._call(BridgeMethods.addSignature, params);
|
|
136
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Fetch the initial context for the current form — deep-link URL (if any),
|
|
145
|
+
* mex ID, context object/id, and parsed query parameters. Always reflects
|
|
146
|
+
* the currently-active form, so calling again after in-app re-navigation
|
|
147
|
+
* returns the new form's context.
|
|
148
|
+
*/
|
|
149
|
+
getInitialContext() {
|
|
150
|
+
return this._call(BridgeMethods.getInitialContext);
|
|
151
|
+
}
|
|
137
152
|
};
|
|
138
153
|
|
|
139
154
|
// src/index.ts
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/MexBridge.ts","../src/index.ts"],"sourcesContent":["/** Bridge method name constants — shared between web SDK and native handlers */\nexport const BridgeMethods = {\n getInstanceData: 'getInstanceData',\n getStaticData: 'getStaticData',\n captureAttachments: 'captureAttachments',\n addAttachments: 'addAttachments',\n removeAttachment: 'removeAttachment',\n getAttachment: 'getAttachment',\n getAttachmentsByParentId: 'getAttachmentsByParentId',\n saveInstanceData: 'saveInstanceData',\n getMetadata: 'getMetadata',\n getAuthenticationInfo: 'getAuthenticationInfo',\n getLocalizedString: 'getLocalizedString',\n sendExtensionMandatoryStatus: 'sendExtensionMandatoryStatus',\n exit: 'exit',\n collectTapToPayPayment: 'collectTapToPayPayment',\n captureSignature: 'captureSignature',\n addSignature: 'addSignature',\n} as const\n\n/** Available attachment picker sources */\nexport type AttachmentSource = 'camera' | 'photoLibrary' | 'files'\n\n/** Parameters for capturing attachments via native pickers */\nexport interface CaptureAttachmentsParams {\n /** Which picker sources to offer. Defaults to all three. If only one, opens directly without bottom sheet. */\n sources?: AttachmentSource[]\n}\n\n/** A file picked from a native picker (camera, photo library, or file browser) */\nexport interface PickedFile {\n uri: string\n fileName: string\n}\n\n/** Parameters for persisting captured attachments to the native layer */\nexport interface AddAttachmentsParams {\n /** The picked files to persist */\n attachments: PickedFile[]\n /** The parent object ID to associate attachments with */\n parentContextId: string\n /** Optional category name for the attachments */\n categoryName?: string\n}\n\n/** Metadata about a stored attachment (returned by getAttachment) */\nexport interface AttachmentMetadata {\n uid: string\n fileName: string\n downloadURL?: string\n status?: string\n contentType?: string\n}\n\n/** Result of getAttachmentsByParentId — matches MexAttachmentsOnParentContextChangedResult */\nexport interface AttachmentsByParentIdResult {\n attachments: AttachmentMetadata[]\n parentId: string\n}\n\n/** Authentication information for the current user */\nexport interface AuthenticationInfo {\n accessToken: string\n apiUrl: string\n userId?: string\n}\n\n/** Form metadata */\nexport interface FormMetadata {\n contextObjectId: string\n packageId: string\n formName?: string\n contextObject?: string\n user?: Record<string, any>\n job?: Record<string, any>\n timezone?: Record<string, any>\n}\n\n/** Parameters for initiating a Tap to Pay payment via Stripe Terminal */\nexport interface TapToPayParams {\n connectionToken: string\n clientSecret: string\n locationId: string\n}\n\n/** Result of a Tap to Pay payment attempt */\nexport interface TapToPayResult {\n success: boolean\n paymentIntentId?: string\n error?: string\n}\n\n/** Parameters for capturing a signature via the native signature screen */\nexport interface CaptureSignatureOptions {\n /** Show the full-name field on the native screen. Defaults to false. */\n enableFullName?: boolean\n}\n\n/** Result of a successful signature capture */\nexport interface CaptureSignatureResult {\n /** Local file path to the captured signature image */\n uri: string\n /** Generated file name, e.g. \"signature-<uuid>.png\". Informational only — addSignature ignores it. */\n fileName: string\n /** Full name entered by the signer. Only present when CaptureSignatureOptions.enableFullName === true. */\n fullName?: string\n}\n\n/** Parameters for persisting a captured signature to the native layer */\nexport interface AddSignatureParams {\n /** The captured signature to persist */\n signature: {\n uri: string\n fullName?: string\n }\n /** The parent object ID to associate the signature with */\n parentContextId: string\n /** Optional category name for the signature */\n categoryName?: string\n}\n\n/** Internal bridge message from web to RN */\nexport interface BridgeCallMessage {\n type: 'bridge_call'\n method: string\n requestId: string\n params?: any\n}\n\n/** Internal bridge response from RN to web */\nexport interface BridgeResponseMessage {\n type: 'bridge_response'\n requestId: string\n result?: any\n error?: string\n}\n","import { BridgeMethods } from './types'\nimport type { CaptureAttachmentsParams, AddAttachmentsParams, PickedFile, AttachmentMetadata, AttachmentsByParentIdResult, AuthenticationInfo, FormMetadata, BridgeResponseMessage, TapToPayParams, TapToPayResult, CaptureSignatureOptions, CaptureSignatureResult, AddSignatureParams } from './types'\n\ntype PendingCallback = {\n resolve: (value: any) => void\n reject: (reason: any) => void\n timeoutId: ReturnType<typeof setTimeout>\n}\n\ndeclare global {\n interface Window {\n ReactNativeWebView?: {\n postMessage(message: string): void\n }\n onNativeMessage?: (messageString: string) => void\n }\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000\n\nclass MexBridge {\n private _callbacks = new Map<string, PendingCallback>()\n private _initialized = false\n\n constructor() {\n this._initialize()\n }\n\n private _initialize(): void {\n if (this._initialized) return\n this._initialized = true\n\n window.onNativeMessage = (messageString: string) => {\n try {\n const message: BridgeResponseMessage = JSON.parse(messageString)\n if (message.type !== 'bridge_response' || !message.requestId) return\n\n const pending = this._callbacks.get(message.requestId)\n if (!pending) return\n\n clearTimeout(pending.timeoutId)\n this._callbacks.delete(message.requestId)\n\n if (message.error) {\n pending.reject(new Error(message.error))\n } else {\n pending.resolve(message.result)\n }\n } catch (e) {\n console.warn('[MexBridge] Failed to parse native message:', e)\n }\n }\n }\n\n private _call<T = any>(method: string, params?: any, timeoutMs = DEFAULT_TIMEOUT_MS): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n if (!window.ReactNativeWebView) {\n reject(new Error('[MexBridge] Not running inside a React Native WebView'))\n return\n }\n\n const requestId = this._generateId()\n\n const timeoutId = setTimeout(() => {\n this._callbacks.delete(requestId)\n reject(new Error(`[MexBridge] Timeout: ${method} did not respond within ${timeoutMs}ms`))\n }, timeoutMs)\n\n this._callbacks.set(requestId, { resolve, reject, timeoutId })\n\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: 'bridge_call',\n method,\n requestId,\n params,\n }))\n })\n }\n\n private _generateId(): string {\n return Math.random().toString(36).substring(2) + Date.now().toString(36)\n }\n\n /** Fetch the current form instance data */\n getInstanceData(): Promise<any> {\n return this._call(BridgeMethods.getInstanceData)\n }\n\n /** Fetch static/shared data for the form */\n getStaticData(): Promise<any> {\n return this._call(BridgeMethods.getStaticData)\n }\n\n /** Open native picker(s) for camera, photo library, or files. Returns picked files or null if cancelled. */\n captureAttachments(params?: CaptureAttachmentsParams): Promise<PickedFile[] | null> {\n return this._call<PickedFile[] | null>(BridgeMethods.captureAttachments, params)\n }\n\n /** Persist captured attachments to the native mobile layer */\n addAttachments(params: AddAttachmentsParams): Promise<any> {\n return this._call(BridgeMethods.addAttachments, params)\n }\n\n /** Remove an existing attachment by ID */\n removeAttachment(attachmentId: string): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.removeAttachment, { attachmentId })\n }\n\n /** Retrieve attachment metadata by ID */\n getAttachment(attachmentId: string): Promise<AttachmentMetadata> {\n return this._call<AttachmentMetadata>(BridgeMethods.getAttachment, { attachmentId })\n }\n\n /** Get all attachments for a parent object (one-shot, not observable) */\n getAttachmentsByParentId(parentContextId: string): Promise<AttachmentsByParentIdResult> {\n return this._call<AttachmentsByParentIdResult>(BridgeMethods.getAttachmentsByParentId, { parentContextId })\n }\n\n /** Persist form data back to the engine */\n saveInstanceData(data: any): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.saveInstanceData, { data })\n }\n\n /** Retrieve form metadata (form name, context, user info, etc.) */\n getMetadata(): Promise<FormMetadata> {\n return this._call<FormMetadata>(BridgeMethods.getMetadata)\n }\n\n /** Get the current user's auth token and identity */\n getAuthenticationInfo(): Promise<AuthenticationInfo> {\n return this._call<AuthenticationInfo>(BridgeMethods.getAuthenticationInfo)\n }\n\n /** Get a localized string by key from the form's locale files */\n getLocalizedString(key: string): Promise<string> {\n return this._call<string>(BridgeMethods.getLocalizedString, { key })\n }\n\n /** Signal whether the form's mandatory requirements are satisfied */\n sendExtensionMandatoryStatus(isCompleted: boolean): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.sendExtensionMandatoryStatus, { isCompleted })\n }\n\n /** Exit the form and return to the native app */\n exit(): Promise<void> {\n return this._call<void>(BridgeMethods.exit)\n }\n\n /** Initiate a Tap to Pay payment via Stripe Terminal on the native device */\n collectTapToPayPayment(params: TapToPayParams): Promise<TapToPayResult> {\n return this._call<TapToPayResult>(BridgeMethods.collectTapToPayPayment, params, 120_000)\n }\n\n /** Open the native signature screen. Resolves with the captured signature, or null if the user cancels. */\n captureSignature(options?: CaptureSignatureOptions): Promise<CaptureSignatureResult | null> {\n return this._call<CaptureSignatureResult | null>(BridgeMethods.captureSignature, options, 120_000)\n }\n\n /** Persist a captured signature to the native mobile layer */\n addSignature(params: AddSignatureParams): Promise<any> {\n return this._call(BridgeMethods.addSignature, params)\n }\n}\n\nexport { MexBridge }\n","export { MexBridge } from './MexBridge'\nexport { BridgeMethods } from './types'\nexport type {\n CaptureAttachmentsParams,\n AddAttachmentsParams,\n AttachmentSource,\n PickedFile,\n AttachmentMetadata,\n AttachmentsByParentIdResult,\n AuthenticationInfo,\n FormMetadata,\n TapToPayParams,\n TapToPayResult,\n CaptureSignatureOptions,\n CaptureSignatureResult,\n AddSignatureParams,\n} from './types'\n\n// Singleton instance for convenience\nimport { MexBridge } from './MexBridge'\nexport const mexBridge = new MexBridge()\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/MexBridge.ts","../src/index.ts"],"sourcesContent":["/** Bridge method name constants — shared between web SDK and native handlers */\nexport const BridgeMethods = {\n getInstanceData: 'getInstanceData',\n getStaticData: 'getStaticData',\n captureAttachments: 'captureAttachments',\n addAttachments: 'addAttachments',\n removeAttachment: 'removeAttachment',\n getAttachment: 'getAttachment',\n getAttachmentsByParentId: 'getAttachmentsByParentId',\n saveInstanceData: 'saveInstanceData',\n getMetadata: 'getMetadata',\n getAuthenticationInfo: 'getAuthenticationInfo',\n getLocalizedString: 'getLocalizedString',\n sendExtensionMandatoryStatus: 'sendExtensionMandatoryStatus',\n exit: 'exit',\n collectTapToPayPayment: 'collectTapToPayPayment',\n captureSignature: 'captureSignature',\n addSignature: 'addSignature',\n getInitialContext: 'getInitialContext',\n} as const\n\n/** Available attachment picker sources */\nexport type AttachmentSource = 'camera' | 'photoLibrary' | 'files'\n\n/** Parameters for capturing attachments via native pickers */\nexport interface CaptureAttachmentsParams {\n /** Which picker sources to offer. Defaults to all three. If only one, opens directly without bottom sheet. */\n sources?: AttachmentSource[]\n}\n\n/** A file picked from a native picker (camera, photo library, or file browser) */\nexport interface PickedFile {\n uri: string\n fileName: string\n}\n\n/** Parameters for persisting captured attachments to the native layer */\nexport interface AddAttachmentsParams {\n /** The picked files to persist */\n attachments: PickedFile[]\n /** The parent object ID to associate attachments with */\n parentContextId: string\n /** Optional category name for the attachments */\n categoryName?: string\n}\n\n/** Metadata about a stored attachment (returned by getAttachment) */\nexport interface AttachmentMetadata {\n uid: string\n fileName: string\n downloadURL?: string\n status?: string\n contentType?: string\n}\n\n/** Result of getAttachmentsByParentId — matches MexAttachmentsOnParentContextChangedResult */\nexport interface AttachmentsByParentIdResult {\n attachments: AttachmentMetadata[]\n parentId: string\n}\n\n/** Authentication information for the current user */\nexport interface AuthenticationInfo {\n accessToken: string\n apiUrl: string\n userId?: string\n}\n\n/** Form metadata */\nexport interface FormMetadata {\n contextObjectId: string\n packageId: string\n formName?: string\n contextObject?: string\n user?: Record<string, any>\n job?: Record<string, any>\n timezone?: Record<string, any>\n}\n\n/** Parameters for initiating a Tap to Pay payment via Stripe Terminal */\nexport interface TapToPayParams {\n connectionToken: string\n clientSecret: string\n locationId: string\n}\n\n/** Result of a Tap to Pay payment attempt */\nexport interface TapToPayResult {\n success: boolean\n paymentIntentId?: string\n error?: string\n}\n\n/** Parameters for capturing a signature via the native signature screen */\nexport interface CaptureSignatureOptions {\n /** Show the full-name field on the native screen. Defaults to false. */\n enableFullName?: boolean\n}\n\n/** Result of a successful signature capture */\nexport interface CaptureSignatureResult {\n /** Local file path to the captured signature image */\n uri: string\n /** Generated file name, e.g. \"signature-<uuid>.png\". Informational only — addSignature ignores it. */\n fileName: string\n /** Full name entered by the signer. Only present when CaptureSignatureOptions.enableFullName === true. */\n fullName?: string\n}\n\n/** Parameters for persisting a captured signature to the native layer */\nexport interface AddSignatureParams {\n /** The captured signature to persist */\n signature: {\n uri: string\n fullName?: string\n }\n /** The parent object ID to associate the signature with */\n parentContextId: string\n /** Optional category name for the signature */\n categoryName?: string\n}\n\n/** Salesforce-style entity name for the form's context object */\nexport type ContextObject = 'Jobs' | 'Shifts'\n\n/**\n * Initial context delivered to a MEXWEX form on demand.\n *\n * Returned by `getInitialContext()` and reflects the currently-active form's\n * context — re-evaluates fresh on in-app re-navigation between MEX forms.\n *\n * `deepLinkUrl` is the full URL the form was opened with (when applicable).\n * `queryParams` is the parsed query string of `deepLinkUrl`. Both are absent\n * when the form was opened without a deep link, or via the legacy URL pattern\n * which strips query parameters.\n */\nexport interface InitialContext {\n deepLinkUrl?: string\n mexId: string\n contextObject?: ContextObject\n contextObjectId?: string\n queryParams: Record<string, string>\n}\n\n/** Internal bridge message from web to RN */\nexport interface BridgeCallMessage {\n type: 'bridge_call'\n method: string\n requestId: string\n params?: any\n}\n\n/** Internal bridge response from RN to web */\nexport interface BridgeResponseMessage {\n type: 'bridge_response'\n requestId: string\n result?: any\n error?: string\n}\n","import { BridgeMethods } from './types'\nimport type { CaptureAttachmentsParams, AddAttachmentsParams, PickedFile, AttachmentMetadata, AttachmentsByParentIdResult, AuthenticationInfo, FormMetadata, BridgeResponseMessage, TapToPayParams, TapToPayResult, CaptureSignatureOptions, CaptureSignatureResult, AddSignatureParams, InitialContext } from './types'\n\ntype PendingCallback = {\n resolve: (value: any) => void\n reject: (reason: any) => void\n timeoutId: ReturnType<typeof setTimeout> | null\n}\n\ndeclare global {\n interface Window {\n ReactNativeWebView?: {\n postMessage(message: string): void\n }\n onNativeMessage?: (messageString: string) => void\n }\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000\n\nclass MexBridge {\n private _callbacks = new Map<string, PendingCallback>()\n private _initialized = false\n\n constructor() {\n this._initialize()\n }\n\n private _initialize(): void {\n if (this._initialized) return\n this._initialized = true\n\n window.onNativeMessage = (messageString: string) => {\n try {\n const message: BridgeResponseMessage = JSON.parse(messageString)\n if (message.type !== 'bridge_response' || !message.requestId) return\n\n const pending = this._callbacks.get(message.requestId)\n if (!pending) return\n\n if (pending.timeoutId !== null) clearTimeout(pending.timeoutId)\n this._callbacks.delete(message.requestId)\n\n if (message.error) {\n pending.reject(new Error(message.error))\n } else {\n pending.resolve(message.result)\n }\n } catch (e) {\n console.warn('[MexBridge] Failed to parse native message:', e)\n }\n }\n }\n\n /**\n * Send a bridge call. Pass `timeoutMs: 0` to disable the timeout entirely —\n * required for user-interactive methods (e.g. captureSignature, captureAttachments)\n * because the user can take arbitrarily long to interact.\n */\n private _call<T = any>(method: string, params?: any, timeoutMs: number = DEFAULT_TIMEOUT_MS): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n if (!window.ReactNativeWebView) {\n reject(new Error('[MexBridge] Not running inside a React Native WebView'))\n return\n }\n\n const requestId = this._generateId()\n\n const timeoutId = timeoutMs > 0\n ? setTimeout(() => {\n this._callbacks.delete(requestId)\n reject(new Error(`[MexBridge] Timeout: ${method} did not respond within ${timeoutMs}ms`))\n }, timeoutMs)\n : null\n\n this._callbacks.set(requestId, { resolve, reject, timeoutId })\n\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: 'bridge_call',\n method,\n requestId,\n params,\n }))\n })\n }\n\n private _generateId(): string {\n return Math.random().toString(36).substring(2) + Date.now().toString(36)\n }\n\n /** Fetch the current form instance data */\n getInstanceData(): Promise<any> {\n return this._call(BridgeMethods.getInstanceData)\n }\n\n /** Fetch static/shared data for the form */\n getStaticData(): Promise<any> {\n return this._call(BridgeMethods.getStaticData)\n }\n\n /** Open native picker(s) for camera, photo library, or files. Returns picked files or null if cancelled. */\n captureAttachments(params?: CaptureAttachmentsParams): Promise<PickedFile[] | null> {\n return this._call<PickedFile[] | null>(BridgeMethods.captureAttachments, params, 0)\n }\n\n /** Persist captured attachments to the native mobile layer */\n addAttachments(params: AddAttachmentsParams): Promise<any> {\n return this._call(BridgeMethods.addAttachments, params)\n }\n\n /** Remove an existing attachment by ID */\n removeAttachment(attachmentId: string): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.removeAttachment, { attachmentId })\n }\n\n /** Retrieve attachment metadata by ID */\n getAttachment(attachmentId: string): Promise<AttachmentMetadata> {\n return this._call<AttachmentMetadata>(BridgeMethods.getAttachment, { attachmentId })\n }\n\n /** Get all attachments for a parent object (one-shot, not observable) */\n getAttachmentsByParentId(parentContextId: string): Promise<AttachmentsByParentIdResult> {\n return this._call<AttachmentsByParentIdResult>(BridgeMethods.getAttachmentsByParentId, { parentContextId })\n }\n\n /** Persist form data back to the engine */\n saveInstanceData(data: any): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.saveInstanceData, { data })\n }\n\n /** Retrieve form metadata (form name, context, user info, etc.) */\n getMetadata(): Promise<FormMetadata> {\n return this._call<FormMetadata>(BridgeMethods.getMetadata)\n }\n\n /** Get the current user's auth token and identity */\n getAuthenticationInfo(): Promise<AuthenticationInfo> {\n return this._call<AuthenticationInfo>(BridgeMethods.getAuthenticationInfo)\n }\n\n /** Get a localized string by key from the form's locale files */\n getLocalizedString(key: string): Promise<string> {\n return this._call<string>(BridgeMethods.getLocalizedString, { key })\n }\n\n /** Signal whether the form's mandatory requirements are satisfied */\n sendExtensionMandatoryStatus(isCompleted: boolean): Promise<boolean> {\n return this._call<boolean>(BridgeMethods.sendExtensionMandatoryStatus, { isCompleted })\n }\n\n /** Exit the form and return to the native app */\n exit(): Promise<void> {\n return this._call<void>(BridgeMethods.exit)\n }\n\n /** Initiate a Tap to Pay payment via Stripe Terminal on the native device */\n collectTapToPayPayment(params: TapToPayParams): Promise<TapToPayResult> {\n return this._call<TapToPayResult>(BridgeMethods.collectTapToPayPayment, params, 120_000)\n }\n\n /** Open the native signature screen. Resolves with the captured signature, or null if the user cancels. */\n captureSignature(options?: CaptureSignatureOptions): Promise<CaptureSignatureResult | null> {\n return this._call<CaptureSignatureResult | null>(BridgeMethods.captureSignature, options, 0)\n }\n\n /** Persist a captured signature to the native mobile layer */\n addSignature(params: AddSignatureParams): Promise<any> {\n return this._call(BridgeMethods.addSignature, params)\n }\n\n /**\n * Fetch the initial context for the current form — deep-link URL (if any),\n * mex ID, context object/id, and parsed query parameters. Always reflects\n * the currently-active form, so calling again after in-app re-navigation\n * returns the new form's context.\n */\n getInitialContext(): Promise<InitialContext> {\n return this._call<InitialContext>(BridgeMethods.getInitialContext)\n }\n}\n\nexport { MexBridge }\n","export { MexBridge } from './MexBridge'\nexport { BridgeMethods } from './types'\nexport type {\n CaptureAttachmentsParams,\n AddAttachmentsParams,\n AttachmentSource,\n PickedFile,\n AttachmentMetadata,\n AttachmentsByParentIdResult,\n AuthenticationInfo,\n FormMetadata,\n TapToPayParams,\n TapToPayResult,\n CaptureSignatureOptions,\n CaptureSignatureResult,\n AddSignatureParams,\n ContextObject,\n InitialContext,\n} from './types'\n\n// Singleton instance for convenience\nimport { MexBridge } from './MexBridge'\nexport const mexBridge = new MexBridge()\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED