@mparticle/web-sdk 2.66.0 → 2.67.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.
package/dist/mparticle.js CHANGED
@@ -203,7 +203,7 @@ var mParticle = (function () {
203
203
  Base64: Base64$1
204
204
  };
205
205
 
206
- var version = "2.66.0";
206
+ var version = "2.67.0";
207
207
 
208
208
  var Constants = {
209
209
  sdkVersion: version,
@@ -417,6 +417,7 @@ var mParticle = (function () {
417
417
  var HTTP_OK = 200;
418
418
  var HTTP_ACCEPTED = 202;
419
419
  var HTTP_BAD_REQUEST = 400;
420
+ var HTTP_NOT_FOUND = 404;
420
421
  var HTTP_SERVER_ERROR = 500;
421
422
 
422
423
  function _typeof$1(o) {
@@ -524,7 +525,7 @@ var mParticle = (function () {
524
525
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
525
526
  };
526
527
 
527
- var Messages$9 = Constants.Messages;
528
+ var Messages$a = Constants.Messages;
528
529
  var createCookieString = function createCookieString(value) {
529
530
  return replaceCommasWithPipes(replaceQuotesWithApostrophes(value));
530
531
  };
@@ -560,12 +561,12 @@ var mParticle = (function () {
560
561
  var generateDeprecationMessage = function generateDeprecationMessage(methodName, isDeprecated, alternateMethod, docsUrl) {
561
562
  var messageArray = [methodName];
562
563
  if (isDeprecated) {
563
- messageArray.push(Messages$9.DeprecationMessages.MethodHasBeenDeprecated);
564
+ messageArray.push(Messages$a.DeprecationMessages.MethodHasBeenDeprecated);
564
565
  } else {
565
- messageArray.push(Messages$9.DeprecationMessages.MethodMarkedForDeprecationPostfix);
566
+ messageArray.push(Messages$a.DeprecationMessages.MethodMarkedForDeprecationPostfix);
566
567
  }
567
568
  if (alternateMethod) {
568
- messageArray.push(Messages$9.DeprecationMessages.AlternativeMethodPrefix);
569
+ messageArray.push(Messages$a.DeprecationMessages.AlternativeMethodPrefix);
569
570
  messageArray.push(alternateMethod + ".");
570
571
  }
571
572
  if (docsUrl) {
@@ -3118,11 +3119,278 @@ var mParticle = (function () {
3118
3119
  return BatchUploader;
3119
3120
  }();
3120
3121
 
3122
+ var ErrorCodes = {
3123
+ UNKNOWN_ERROR: 'UNKNOWN_ERROR',
3124
+ UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',
3125
+ IDENTITY_REQUEST: 'IDENTITY_REQUEST',
3126
+ IDENTITY_MISMATCH: 'IDENTITY_MISMATCH',
3127
+ ROKT_KIT_ATTACHED: 'ROKT_KIT_ATTACHED'
3128
+ };
3129
+ var WSDKErrorSeverity = {
3130
+ ERROR: 'ERROR',
3131
+ INFO: 'INFO',
3132
+ WARNING: 'WARNING'
3133
+ };
3134
+
3135
+ var Modify$4 = Constants.IdentityMethods.Modify;
3136
+ var Validators = {
3137
+ // From ./utils
3138
+ // Utility Functions for backwards compatability
3139
+ isNumber: isNumber,
3140
+ isFunction: isFunction,
3141
+ isStringOrNumber: isStringOrNumber,
3142
+ // Validator Functions
3143
+ isValidAttributeValue: isValidAttributeValue,
3144
+ // Validator Functions
3145
+ // Neither null nor undefined can be a valid Key
3146
+ isValidKeyValue: function isValidKeyValue(key) {
3147
+ return Boolean(key && !isObject(key) && !Array.isArray(key) && !this.isFunction(key));
3148
+ },
3149
+ removeFalsyIdentityValues: function removeFalsyIdentityValues(identityApiData, logger) {
3150
+ if (!identityApiData || !identityApiData.userIdentities) {
3151
+ return identityApiData;
3152
+ }
3153
+ var cleanedData = {};
3154
+ var cleanedUserIdentities = __assign({}, identityApiData.userIdentities);
3155
+ for (var identityType in identityApiData.userIdentities) {
3156
+ if (identityApiData.userIdentities.hasOwnProperty(identityType)) {
3157
+ var value = identityApiData.userIdentities[identityType];
3158
+ // Check if value is falsy (undefined, false, 0, '', etc.) but not null
3159
+ if (value !== null && !value) {
3160
+ logger.warning("Identity value for '".concat(identityType, "' is falsy (").concat(value, "). This value will be removed from the request."));
3161
+ delete cleanedUserIdentities[identityType];
3162
+ }
3163
+ }
3164
+ }
3165
+ cleanedData.userIdentities = cleanedUserIdentities;
3166
+ return cleanedData;
3167
+ },
3168
+ validateIdentities: function validateIdentities(identityApiData, method) {
3169
+ var validIdentityRequestKeys = {
3170
+ userIdentities: 1,
3171
+ onUserAlias: 1,
3172
+ copyUserAttributes: 1
3173
+ };
3174
+ if (identityApiData) {
3175
+ if (method === Modify$4) {
3176
+ if (isObject(identityApiData.userIdentities) && !Object.keys(identityApiData.userIdentities).length || !isObject(identityApiData.userIdentities)) {
3177
+ return {
3178
+ valid: false,
3179
+ error: Constants.Messages.ValidationMessages.ModifyIdentityRequestUserIdentitiesPresent
3180
+ };
3181
+ }
3182
+ }
3183
+ for (var key in identityApiData) {
3184
+ if (identityApiData.hasOwnProperty(key)) {
3185
+ if (!validIdentityRequestKeys[key]) {
3186
+ return {
3187
+ valid: false,
3188
+ error: Constants.Messages.ValidationMessages.IdentityRequesetInvalidKey
3189
+ };
3190
+ }
3191
+ if (key === 'onUserAlias' && !Validators.isFunction(identityApiData[key])) {
3192
+ return {
3193
+ valid: false,
3194
+ error: Constants.Messages.ValidationMessages.OnUserAliasType
3195
+ };
3196
+ }
3197
+ }
3198
+ }
3199
+ if (Object.keys(identityApiData).length === 0) {
3200
+ return {
3201
+ valid: true
3202
+ };
3203
+ } else {
3204
+ // identityApiData.userIdentities can't be undefined
3205
+ if (identityApiData.userIdentities === undefined) {
3206
+ return {
3207
+ valid: false,
3208
+ error: Constants.Messages.ValidationMessages.UserIdentities
3209
+ };
3210
+ // identityApiData.userIdentities can be null, but if it isn't null or undefined (above conditional), it must be an object
3211
+ } else if (identityApiData.userIdentities !== null && !isObject(identityApiData.userIdentities)) {
3212
+ return {
3213
+ valid: false,
3214
+ error: Constants.Messages.ValidationMessages.UserIdentities
3215
+ };
3216
+ }
3217
+ if (isObject(identityApiData.userIdentities) && Object.keys(identityApiData.userIdentities).length) {
3218
+ for (var identityType in identityApiData.userIdentities) {
3219
+ if (identityApiData.userIdentities.hasOwnProperty(identityType)) {
3220
+ if (Types.IdentityType.getIdentityType(identityType) === false) {
3221
+ return {
3222
+ valid: false,
3223
+ error: Constants.Messages.ValidationMessages.UserIdentitiesInvalidKey
3224
+ };
3225
+ }
3226
+ if (!(typeof identityApiData.userIdentities[identityType] === 'string' || identityApiData.userIdentities[identityType] === null)) {
3227
+ return {
3228
+ valid: false,
3229
+ error: Constants.Messages.ValidationMessages.UserIdentitiesInvalidValues
3230
+ };
3231
+ }
3232
+ }
3233
+ }
3234
+ }
3235
+ }
3236
+ }
3237
+ return {
3238
+ valid: true
3239
+ };
3240
+ }
3241
+ };
3242
+
3243
+ var HTTPCodes$4 = Constants.HTTPCodes;
3244
+ /**
3245
+ * Sends a POST to mParticle's IDSync Search endpoint and invokes `callback`
3246
+ * with the HTTP status and parsed body.
3247
+ *
3248
+ * Defensive contract:
3249
+ * - No identifier with a non-empty string value -> callback with
3250
+ * `{ httpCode: noHttpCoverage }`, no network call.
3251
+ * - Missing `apiKey` -> callback with `{ httpCode: noHttpCoverage }`,
3252
+ * no network call.
3253
+ * - Network/JSON-parse errors are caught and surfaced via the callback,
3254
+ * never thrown. Network errors are also reported through the optional
3255
+ * `errorReporter` so any registered IErrorReportingService can observe
3256
+ * them (matches the pattern used by identifyRequest in identityApiClient).
3257
+ */
3258
+ var sendSearchRequest = function sendSearchRequest(knownIdentities, apiKey, requestBuilder, searchUrl, callback, logger, uploader, errorReporter) {
3259
+ return __awaiter(void 0, void 0, void 0, function () {
3260
+ var safeInvoke, cleanedKnownIdentities, requestEnvelope, requestBody, fetchPayload, api, response, body, xhrLike, e_2, message, reportMessage;
3261
+ return __generator(this, function (_a) {
3262
+ switch (_a.label) {
3263
+ case 0:
3264
+ // Validate the callback up front. If it isn't a function we have nowhere
3265
+ // to deliver a result to, so log and bail out without invoking anything.
3266
+ if (!isFunction(callback)) {
3267
+ logger.error('search called without a callback function; skipping request.');
3268
+ return [2 /*return*/];
3269
+ }
3270
+
3271
+ safeInvoke = function safeInvoke(result) {
3272
+ try {
3273
+ callback(result);
3274
+ } catch (e) {
3275
+ logger.error('Error invoking search callback: ' + ((e === null || e === void 0 ? void 0 : e.message) || String(e)));
3276
+ }
3277
+ };
3278
+ cleanedKnownIdentities = Validators.removeFalsyIdentityValues({
3279
+ userIdentities: knownIdentities !== null && knownIdentities !== void 0 ? knownIdentities : {}
3280
+ }, logger).userIdentities;
3281
+ // No usable identifier -> deliver httpCode: noHttpCoverage so callers
3282
+ // waiting on the callback (e.g. to clear a loading state) don't hang.
3283
+ if (!Object.values(cleanedKnownIdentities !== null && cleanedKnownIdentities !== void 0 ? cleanedKnownIdentities : {}).some(function (v) {
3284
+ return typeof v === 'string' && v.length > 0;
3285
+ })) {
3286
+ logger.verbose('Identity search called with empty identifiers; skipping request.');
3287
+ safeInvoke({
3288
+ httpCode: HTTPCodes$4.noHttpCoverage
3289
+ });
3290
+ return [2 /*return*/];
3291
+ }
3292
+ // No API key -> same: deliver noHttpCoverage rather than hanging.
3293
+ if (!apiKey) {
3294
+ logger.verbose('search called without a workspace API key; skipping request.');
3295
+ safeInvoke({
3296
+ httpCode: HTTPCodes$4.noHttpCoverage
3297
+ });
3298
+ return [2 /*return*/];
3299
+ }
3300
+
3301
+ _a.label = 1;
3302
+ case 1:
3303
+ _a.trys.push([1, 9,, 10]);
3304
+ requestEnvelope = requestBuilder();
3305
+ requestBody = __assign(__assign({}, requestEnvelope), {
3306
+ known_identities: __assign({}, cleanedKnownIdentities)
3307
+ });
3308
+ fetchPayload = {
3309
+ method: 'post',
3310
+ headers: {
3311
+ Accept: 'application/json',
3312
+ 'Content-Type': 'application/json',
3313
+ 'x-mp-key': apiKey
3314
+ },
3315
+ body: JSON.stringify(requestBody)
3316
+ };
3317
+ api = uploader || (window.fetch ? new FetchUploader(searchUrl) : new XHRUploader(searchUrl));
3318
+ logger.verbose('Sending search request to ' + searchUrl);
3319
+ return [4 /*yield*/, api.upload(fetchPayload, searchUrl)];
3320
+ case 2:
3321
+ response = _a.sent();
3322
+ body = void 0;
3323
+ if (!isFunction(response.json)) return [3 /*break*/, 7];
3324
+ _a.label = 3;
3325
+ case 3:
3326
+ _a.trys.push([3, 5,, 6]);
3327
+ return [4 /*yield*/, response.json()];
3328
+ case 4:
3329
+ body = _a.sent();
3330
+ return [3 /*break*/, 6];
3331
+ case 5:
3332
+ _a.sent();
3333
+ logger.verbose('search response had no parseable JSON body.');
3334
+ return [3 /*break*/, 6];
3335
+ case 6:
3336
+ return [3 /*break*/, 8];
3337
+ case 7:
3338
+ xhrLike = response;
3339
+ if (xhrLike === null || xhrLike === void 0 ? void 0 : xhrLike.responseText) {
3340
+ try {
3341
+ body = JSON.parse(xhrLike.responseText);
3342
+ } catch (e) {
3343
+ logger.verbose('search XHR response was not valid JSON.');
3344
+ }
3345
+ }
3346
+ _a.label = 8;
3347
+ case 8:
3348
+ if (response.status === HTTP_OK) {
3349
+ logger.verbose('search received 200 OK.');
3350
+ } else if (response.status === HTTP_NOT_FOUND) {
3351
+ // 404 NOT_FOUND_ERROR is an expected steady-state outcome and is
3352
+ // intentionally not logged as an error.
3353
+ logger.verbose('search received 404 (no match).');
3354
+ } else {
3355
+ logger.verbose('search received non-success status ' + response.status);
3356
+ }
3357
+ safeInvoke({
3358
+ httpCode: response.status,
3359
+ body: body
3360
+ });
3361
+ return [3 /*break*/, 10];
3362
+ case 9:
3363
+ e_2 = _a.sent();
3364
+ message = (e_2 === null || e_2 === void 0 ? void 0 : e_2.message) || String(e_2);
3365
+ reportMessage = 'Error sending search request: ' + message;
3366
+ logger.error(reportMessage);
3367
+ // Mirror the identity-route pattern in identityApiClient.ts: log to
3368
+ // console AND push a structured report through the dispatcher so any
3369
+ // registered IErrorReportingService (e.g. the Rokt kit's) can observe
3370
+ // the failure.
3371
+ errorReporter === null || errorReporter === void 0 ? void 0 : errorReporter.report({
3372
+ message: reportMessage,
3373
+ code: ErrorCodes.IDENTITY_REQUEST,
3374
+ severity: WSDKErrorSeverity.ERROR
3375
+ });
3376
+ safeInvoke({
3377
+ httpCode: HTTPCodes$4.noHttpCoverage
3378
+ });
3379
+ return [3 /*break*/, 10];
3380
+ case 10:
3381
+ return [2 /*return*/];
3382
+ }
3383
+ });
3384
+ });
3385
+ };
3386
+
3121
3387
  var _a = Constants.IdentityMethods,
3122
3388
  Identify$2 = _a.Identify,
3123
- Modify$4 = _a.Modify,
3389
+ Modify$3 = _a.Modify,
3124
3390
  Login$2 = _a.Login,
3125
3391
  Logout$2 = _a.Logout;
3392
+ var HTTPCodes$3 = Constants.HTTPCodes,
3393
+ Messages$9 = Constants.Messages;
3126
3394
  var CACHE_HEADER = 'x-mp-max-age';
3127
3395
  var cacheOrClearIdCache = function cacheOrClearIdCache(method, knownIdentities, idCache, identityResponse, parsingCachedResponse) {
3128
3396
  // when parsing a response that has already been cached, simply return instead of attempting another cache
@@ -3136,7 +3404,7 @@ var mParticle = (function () {
3136
3404
  case Identify$2:
3137
3405
  cacheIdentityRequest(method, knownIdentities, expireTimestamp, idCache, identityResponse);
3138
3406
  break;
3139
- case Modify$4:
3407
+ case Modify$3:
3140
3408
  case Logout$2:
3141
3409
  idCache.purge();
3142
3410
  break;
@@ -3292,6 +3560,61 @@ var mParticle = (function () {
3292
3560
  }
3293
3561
  return !!((_c = store === null || store === void 0 ? void 0 : store.SDKConfig) === null || _c === void 0 ? void 0 : _c.deviceId);
3294
3562
  };
3563
+ /**
3564
+ * Builds the /v1/identify-style envelope (client_sdk, environment,
3565
+ * request_id, request_timestamp_ms) used to correlate IDSync requests
3566
+ * across endpoints. `known_identities` is omitted so the caller can
3567
+ * fold in the search-specific identifiers alongside the envelope.
3568
+ */
3569
+ var buildIdentitySearchEnvelope = function buildIdentitySearchEnvelope(environment) {
3570
+ return {
3571
+ client_sdk: {
3572
+ platform: Constants.platform,
3573
+ sdk_vendor: Constants.sdkVendor,
3574
+ sdk_version: Constants.sdkVersion
3575
+ },
3576
+ environment: environment,
3577
+ request_id: generateUniqueId(),
3578
+ request_timestamp_ms: Date.now()
3579
+ };
3580
+ };
3581
+ /**
3582
+ * Wires the SDK instance into `sendSearchRequest`: gates on `canLog`,
3583
+ * builds the `/v1/search` URL and request envelope, and dispatches.
3584
+ * Lives here so the SDK glue (URL building, opt-out gate, dispatcher
3585
+ * plumbing) is type-checked instead of being expressed in plain JS.
3586
+ */
3587
+ var executeSearchRequest = function executeSearchRequest(mpInstance, workspaceApiKey, knownIdentities, callback) {
3588
+ var _Helpers = mpInstance._Helpers,
3589
+ _Store = mpInstance._Store,
3590
+ Logger = mpInstance.Logger,
3591
+ _ErrorReportingDispatcher = mpInstance._ErrorReportingDispatcher;
3592
+ var _a = _Store.SDKConfig,
3593
+ identityUrl = _a.identityUrl,
3594
+ isDevelopmentMode = _a.isDevelopmentMode;
3595
+ if (!_Helpers.canLog()) {
3596
+ Logger.verbose(Messages$9.InformationMessages.AbandonLogEvent);
3597
+ if (isFunction(callback)) {
3598
+ try {
3599
+ callback({
3600
+ httpCode: HTTPCodes$3.loggingDisabledOrMissingAPIKey
3601
+ });
3602
+ } catch (e) {
3603
+ Logger.error('Error invoking search callback: ' + ((e === null || e === void 0 ? void 0 : e.message) || String(e)));
3604
+ }
3605
+ }
3606
+ return;
3607
+ }
3608
+ // The Search endpoint is colocated with /v1/identify under
3609
+ // identityUrl, so we reuse the same service URL builder. We do
3610
+ // NOT append the apiKey to the URL — auth is done via x-mp-key.
3611
+ var serviceUrl = _Helpers.createServiceUrl(identityUrl);
3612
+ var searchUrl = serviceUrl + 'search?cb=1';
3613
+ var environment = isDevelopmentMode ? 'development' : 'production';
3614
+ sendSearchRequest(knownIdentities, workspaceApiKey, function () {
3615
+ return buildIdentitySearchEnvelope(environment);
3616
+ }, searchUrl, callback, Logger, undefined, _ErrorReportingDispatcher);
3617
+ };
3295
3618
 
3296
3619
  function APIClient(mpInstance, kitBlocker) {
3297
3620
  this.uploader = null;
@@ -3454,114 +3777,6 @@ var mParticle = (function () {
3454
3777
  };
3455
3778
  }
3456
3779
 
3457
- var Modify$3 = Constants.IdentityMethods.Modify;
3458
- var Validators = {
3459
- // From ./utils
3460
- // Utility Functions for backwards compatability
3461
- isNumber: isNumber,
3462
- isFunction: isFunction,
3463
- isStringOrNumber: isStringOrNumber,
3464
- // Validator Functions
3465
- isValidAttributeValue: isValidAttributeValue,
3466
- // Validator Functions
3467
- // Neither null nor undefined can be a valid Key
3468
- isValidKeyValue: function isValidKeyValue(key) {
3469
- return Boolean(key && !isObject(key) && !Array.isArray(key) && !this.isFunction(key));
3470
- },
3471
- removeFalsyIdentityValues: function removeFalsyIdentityValues(identityApiData, logger) {
3472
- if (!identityApiData || !identityApiData.userIdentities) {
3473
- return identityApiData;
3474
- }
3475
- var cleanedData = {};
3476
- var cleanedUserIdentities = __assign({}, identityApiData.userIdentities);
3477
- for (var identityType in identityApiData.userIdentities) {
3478
- if (identityApiData.userIdentities.hasOwnProperty(identityType)) {
3479
- var value = identityApiData.userIdentities[identityType];
3480
- // Check if value is falsy (undefined, false, 0, '', etc.) but not null
3481
- if (value !== null && !value) {
3482
- logger.warning("Identity value for '".concat(identityType, "' is falsy (").concat(value, "). This value will be removed from the request."));
3483
- delete cleanedUserIdentities[identityType];
3484
- }
3485
- }
3486
- }
3487
- cleanedData.userIdentities = cleanedUserIdentities;
3488
- return cleanedData;
3489
- },
3490
- validateIdentities: function validateIdentities(identityApiData, method) {
3491
- var validIdentityRequestKeys = {
3492
- userIdentities: 1,
3493
- onUserAlias: 1,
3494
- copyUserAttributes: 1
3495
- };
3496
- if (identityApiData) {
3497
- if (method === Modify$3) {
3498
- if (isObject(identityApiData.userIdentities) && !Object.keys(identityApiData.userIdentities).length || !isObject(identityApiData.userIdentities)) {
3499
- return {
3500
- valid: false,
3501
- error: Constants.Messages.ValidationMessages.ModifyIdentityRequestUserIdentitiesPresent
3502
- };
3503
- }
3504
- }
3505
- for (var key in identityApiData) {
3506
- if (identityApiData.hasOwnProperty(key)) {
3507
- if (!validIdentityRequestKeys[key]) {
3508
- return {
3509
- valid: false,
3510
- error: Constants.Messages.ValidationMessages.IdentityRequesetInvalidKey
3511
- };
3512
- }
3513
- if (key === 'onUserAlias' && !Validators.isFunction(identityApiData[key])) {
3514
- return {
3515
- valid: false,
3516
- error: Constants.Messages.ValidationMessages.OnUserAliasType
3517
- };
3518
- }
3519
- }
3520
- }
3521
- if (Object.keys(identityApiData).length === 0) {
3522
- return {
3523
- valid: true
3524
- };
3525
- } else {
3526
- // identityApiData.userIdentities can't be undefined
3527
- if (identityApiData.userIdentities === undefined) {
3528
- return {
3529
- valid: false,
3530
- error: Constants.Messages.ValidationMessages.UserIdentities
3531
- };
3532
- // identityApiData.userIdentities can be null, but if it isn't null or undefined (above conditional), it must be an object
3533
- } else if (identityApiData.userIdentities !== null && !isObject(identityApiData.userIdentities)) {
3534
- return {
3535
- valid: false,
3536
- error: Constants.Messages.ValidationMessages.UserIdentities
3537
- };
3538
- }
3539
- if (isObject(identityApiData.userIdentities) && Object.keys(identityApiData.userIdentities).length) {
3540
- for (var identityType in identityApiData.userIdentities) {
3541
- if (identityApiData.userIdentities.hasOwnProperty(identityType)) {
3542
- if (Types.IdentityType.getIdentityType(identityType) === false) {
3543
- return {
3544
- valid: false,
3545
- error: Constants.Messages.ValidationMessages.UserIdentitiesInvalidKey
3546
- };
3547
- }
3548
- if (!(typeof identityApiData.userIdentities[identityType] === 'string' || identityApiData.userIdentities[identityType] === null)) {
3549
- return {
3550
- valid: false,
3551
- error: Constants.Messages.ValidationMessages.UserIdentitiesInvalidValues
3552
- };
3553
- }
3554
- }
3555
- }
3556
- }
3557
- }
3558
- }
3559
- return {
3560
- valid: true
3561
- };
3562
- }
3563
- };
3564
-
3565
3780
  var KitFilterHelper = /** @class */function () {
3566
3781
  function KitFilterHelper() {}
3567
3782
  KitFilterHelper.hashEventType = function (eventType) {
@@ -8130,6 +8345,26 @@ var mParticle = (function () {
8130
8345
  mpInstance.Logger.verbose(Messages$2.InformationMessages.AbandonAliasUsers);
8131
8346
  }
8132
8347
  },
8348
+ /**
8349
+ * Search the IDSync Workspace endpoint for a known identity.
8350
+ *
8351
+ * POSTs to mParticle's `/v1/search` endpoint and invokes `callback`
8352
+ * with `{ httpCode, body? }`.
8353
+ *
8354
+ * The `workspaceApiKey` is a workspace-specific API key supplied by
8355
+ * the caller (passed in from a kit's settings). It is intentionally
8356
+ * NOT read from the SDK's own workspace token, so that workspace
8357
+ * searches can be authorised independently of the host SDK's
8358
+ * workspace.
8359
+ *
8360
+ * @method search
8361
+ * @param {String} workspaceApiKey Workspace API key (sent as x-mp-key).
8362
+ * @param {Object} knownIdentities A `UserIdentities` map.
8363
+ * @param {Function} callback Invoked with the `IIdentitySearchResult`.
8364
+ */
8365
+ search: function search(workspaceApiKey, knownIdentities, callback) {
8366
+ executeSearchRequest(mpInstance, workspaceApiKey, knownIdentities, callback);
8367
+ },
8133
8368
  /**
8134
8369
  Create a default AliasRequest for 2 MParticleUsers. This will construct the request
8135
8370
  using the sourceUser's firstSeenTime as the startTime, and its lastSeenTime as the endTime.
@@ -9599,19 +9834,6 @@ var mParticle = (function () {
9599
9834
  };
9600
9835
  }
9601
9836
 
9602
- var ErrorCodes = {
9603
- UNKNOWN_ERROR: 'UNKNOWN_ERROR',
9604
- UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',
9605
- IDENTITY_REQUEST: 'IDENTITY_REQUEST',
9606
- IDENTITY_MISMATCH: 'IDENTITY_MISMATCH',
9607
- ROKT_KIT_ATTACHED: 'ROKT_KIT_ATTACHED'
9608
- };
9609
- var WSDKErrorSeverity = {
9610
- ERROR: 'ERROR',
9611
- INFO: 'INFO',
9612
- WARNING: 'WARNING'
9613
- };
9614
-
9615
9837
  var HTTPCodes$1 = Constants.HTTPCodes,
9616
9838
  Messages$1 = Constants.Messages,
9617
9839
  IdentityMethods = Constants.IdentityMethods;
@@ -12446,6 +12668,9 @@ var mParticle = (function () {
12446
12668
  },
12447
12669
  modify: function modify(identityApiData, callback) {
12448
12670
  self.getInstance().Identity.modify(identityApiData, callback);
12671
+ },
12672
+ search: function search(workspaceApiKey, knownIdentities, callback) {
12673
+ self.getInstance().Identity.search(workspaceApiKey, knownIdentities, callback);
12449
12674
  }
12450
12675
  };
12451
12676
  this.sessionManager = {
@@ -0,0 +1,64 @@
1
+ import { SDKLoggerApi } from '../sdkRuntimeModels';
2
+ import { Environment } from '../utils';
3
+ import { AsyncUploader } from '../uploaders';
4
+ import { IErrorReportingService } from '../reporting/types';
5
+ import { UserIdentities } from '@mparticle/web-sdk';
6
+ /**
7
+ * Body payload returned by the `/v1/search` endpoint, as parsed JSON.
8
+ *
9
+ * The shape mirrors `/v1/identify` responses. All fields are optional because
10
+ * non-200 responses (e.g. 404 NOT_FOUND_ERROR) may include partial or
11
+ * error-shaped bodies, and the consumer should only rely on body fields when
12
+ * `httpCode === 200`.
13
+ */
14
+ export interface IIdentitySearchResponseBody {
15
+ context?: string | null;
16
+ mpid?: string;
17
+ matched_identities?: Record<string, string>;
18
+ is_ephemeral?: boolean;
19
+ is_logged_in?: boolean;
20
+ }
21
+ /**
22
+ * Result delivered to the consumer's callback. `httpCode` is always present;
23
+ * `body` is present whenever the response had a parseable JSON body.
24
+ *
25
+ * For non-network errors (missing API key, validation failures, JSON parse
26
+ * errors) `httpCode` will be `HTTPCodes.noHttpCoverage` (-1) and `body` will
27
+ * be omitted. The consumer is expected to gate behaviour on
28
+ * `httpCode === 200`.
29
+ */
30
+ export interface IIdentitySearchResult {
31
+ httpCode: number;
32
+ body?: IIdentitySearchResponseBody;
33
+ }
34
+ export type IdentitySearchCallback = (result: IIdentitySearchResult) => void;
35
+ /**
36
+ * Body posted to `/v1/search`. Mirrors the `/v1/identify` request envelope so
37
+ * that the IDSync service can correlate requests across endpoints.
38
+ */
39
+ export interface IIdentitySearchRequestBody {
40
+ client_sdk: {
41
+ platform: string;
42
+ sdk_vendor: string;
43
+ sdk_version: string;
44
+ };
45
+ environment: Environment;
46
+ request_id: string;
47
+ request_timestamp_ms: number;
48
+ known_identities: UserIdentities;
49
+ }
50
+ /**
51
+ * Sends a POST to mParticle's IDSync Search endpoint and invokes `callback`
52
+ * with the HTTP status and parsed body.
53
+ *
54
+ * Defensive contract:
55
+ * - No identifier with a non-empty string value -> callback with
56
+ * `{ httpCode: noHttpCoverage }`, no network call.
57
+ * - Missing `apiKey` -> callback with `{ httpCode: noHttpCoverage }`,
58
+ * no network call.
59
+ * - Network/JSON-parse errors are caught and surfaced via the callback,
60
+ * never thrown. Network errors are also reported through the optional
61
+ * `errorReporter` so any registered IErrorReportingService can observe
62
+ * them (matches the pattern used by identifyRequest in identityApiClient).
63
+ */
64
+ export declare const sendSearchRequest: (knownIdentities: UserIdentities, apiKey: string, requestBuilder: () => Omit<IIdentitySearchRequestBody, 'known_identities'>, searchUrl: string, callback: IdentitySearchCallback, logger: SDKLoggerApi, uploader?: AsyncUploader, errorReporter?: IErrorReportingService) => Promise<void>;
@@ -1,9 +1,11 @@
1
- import { Dictionary } from './utils';
1
+ import { Dictionary, Environment } from './utils';
2
2
  import { BaseVault } from './vault';
3
3
  import { IdentityApiData, UserIdentities, IdentityCallback } from '@mparticle/web-sdk';
4
4
  import { IdentityAPIMethod } from './identity.interfaces';
5
5
  import { IIdentityResponse, IMParticleUser } from './identity-user-interfaces';
6
6
  import { IStore } from './store';
7
+ import type { IMParticleWebSDKInstance } from './mp-instance';
8
+ import { IIdentitySearchRequestBody, IdentitySearchCallback } from './identity/search';
7
9
  export declare const CACHE_HEADER: "x-mp-max-age";
8
10
  export type IdentityCache = BaseVault<Dictionary<ICachedIdentityCall>>;
9
11
  export type IParseCachedIdentityResponse = (cachedIdentity: IIdentityResponse, mpid: string, callback: IdentityCallback, identityApiData: IdentityApiData, identityMethod: string, knownIdentities: IKnownIdentities, fromCachedIdentity: boolean) => void;
@@ -34,3 +36,17 @@ export declare const hasIdentityRequestChanged: (currentUser: IMParticleUser, ne
34
36
  * @returns true if deviceId or other identifiers were explicitly provided in config, false otherwise
35
37
  */
36
38
  export declare const hasExplicitIdentifier: (store: IStore | undefined | null) => boolean;
39
+ /**
40
+ * Builds the /v1/identify-style envelope (client_sdk, environment,
41
+ * request_id, request_timestamp_ms) used to correlate IDSync requests
42
+ * across endpoints. `known_identities` is omitted so the caller can
43
+ * fold in the search-specific identifiers alongside the envelope.
44
+ */
45
+ export declare const buildIdentitySearchEnvelope: (environment: Environment) => Omit<IIdentitySearchRequestBody, 'known_identities'>;
46
+ /**
47
+ * Wires the SDK instance into `sendSearchRequest`: gates on `canLog`,
48
+ * builds the `/v1/search` URL and request envelope, and dispatches.
49
+ * Lives here so the SDK glue (URL building, opt-out gate, dispatcher
50
+ * plumbing) is type-checked instead of being expressed in plain JS.
51
+ */
52
+ export declare const executeSearchRequest: (mpInstance: IMParticleWebSDKInstance, workspaceApiKey: string, knownIdentities: UserIdentities, callback: IdentitySearchCallback) => void;