@redonvn/zalo-ads-sdk 0.2.14 → 0.2.16

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.mjs CHANGED
@@ -1535,14 +1535,102 @@ function validateEstimateAudienceRequest(input) {
1535
1535
  } : void 0
1536
1536
  };
1537
1537
  }
1538
+ function validateUploadCustomAudiencePhoneListRequest(input) {
1539
+ const errors = [];
1540
+ if (!input || typeof input !== "object") {
1541
+ return {
1542
+ isValid: false,
1543
+ errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u t\u1EA3i danh s\xE1ch s\u1ED1 \u0111i\u1EC7n tho\u1EA1i ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
1544
+ };
1545
+ }
1546
+ const raw = input;
1547
+ const file = raw.File ?? raw.file;
1548
+ if (!file) {
1549
+ errors.push("Tr\u01B0\u1EDDng t\u1EC7p danh s\xE1ch s\u1ED1 \u0111i\u1EC7n tho\u1EA1i ('File') l\xE0 b\u1EAFt bu\u1ED9c.");
1550
+ return { isValid: false, errors };
1551
+ }
1552
+ if (typeof file === "string") {
1553
+ const trimmed = file.trim();
1554
+ if (!trimmed) {
1555
+ errors.push("\u0110\u01B0\u1EDDng d\u1EABn t\u1EC7p danh s\xE1ch s\u1ED1 \u0111i\u1EC7n tho\u1EA1i kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
1556
+ } else if (!/^https?:\/\/.+/i.test(trimmed)) {
1557
+ errors.push(`\u0110\u01B0\u1EDDng d\u1EABn t\u1EC7p '${trimmed}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i l\xE0 URL HTTP ho\u1EB7c HTTPS.`);
1558
+ }
1559
+ const cleanUrl = trimmed.split("?")[0].toLowerCase();
1560
+ if (!cleanUrl.endsWith(".txt") && !cleanUrl.endsWith(".csv")) {
1561
+ errors.push("T\u1EC7p danh s\xE1ch s\u1ED1 \u0111i\u1EC7n tho\u1EA1i ph\u1EA3i c\xF3 \u0111\u1ECBnh d\u1EA1ng .txt ho\u1EB7c .csv.");
1562
+ }
1563
+ }
1564
+ const isHashRaw = raw.isHash !== void 0 ? String(raw.isHash).trim() : "0";
1565
+ if (isHashRaw !== "0" && isHashRaw !== "1") {
1566
+ errors.push(`Gi\xE1 tr\u1ECB 'isHash' kh\xF4ng h\u1EE3p l\u1EC7: '${raw.isHash}'. Ch\u1EC9 h\u1ED7 tr\u1EE3 '0' (danh s\xE1ch S\u0110T th\xF4) ho\u1EB7c '1' (danh s\xE1ch \u0111\xE3 b\u0103m).`);
1567
+ }
1568
+ const cleanData = {
1569
+ File: file,
1570
+ isHash: isHashRaw
1571
+ };
1572
+ return {
1573
+ isValid: errors.length === 0,
1574
+ errors,
1575
+ data: errors.length === 0 ? cleanData : void 0
1576
+ };
1577
+ }
1578
+ function validateCreateCustomAudienceRequest(input) {
1579
+ if (!input || typeof input !== "object") {
1580
+ return {
1581
+ isValid: false,
1582
+ errors: ["D\u1EEF li\u1EC7u t\u1EA1o \u0111\u1ED1i t\u01B0\u1EE3ng t\xF9y ch\u1EC9nh (Custom Audience) ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
1583
+ };
1584
+ }
1585
+ const raw = input;
1586
+ const caType = Number(raw.caType);
1587
+ switch (caType) {
1588
+ case 1:
1589
+ return validateCreateSavedAudienceRequest(raw);
1590
+ case 3:
1591
+ return validateCreatePhoneAudienceRequest(raw);
1592
+ case 6:
1593
+ return validateCreateLookalikeAudienceRequest(raw);
1594
+ case 12:
1595
+ return validateCreateFormEventAudienceRequest(raw);
1596
+ case 11:
1597
+ return validateCreateMessageOaEventAudienceRequest(raw);
1598
+ case 14:
1599
+ return validateCreateMessagePersonalEventAudienceRequest(raw);
1600
+ default: {
1601
+ const errors = [];
1602
+ const name = typeof raw.name === "string" ? raw.name.trim() : "";
1603
+ if (!name) {
1604
+ errors.push("T\xEAn t\u1EADp \u0111\u1ED1i t\u01B0\u1EE3ng ('name') l\xE0 b\u1EAFt bu\u1ED9c.");
1605
+ } else if (name.length > 100) {
1606
+ errors.push(`T\xEAn t\u1EADp \u0111\u1ED1i t\u01B0\u1EE3ng kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 100 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${name.length} k\xFD t\u1EF1).`);
1607
+ }
1608
+ if (!Number.isInteger(caType) || caType <= 0) {
1609
+ errors.push(`Lo\u1EA1i \u0111\u1ED1i t\u01B0\u1EE3ng t\xF9y ch\u1EC9nh ('caType') kh\xF4ng h\u1EE3p l\u1EC7: ${raw.caType}.`);
1610
+ }
1611
+ if (!raw.targeting || typeof raw.targeting !== "object") {
1612
+ errors.push("C\u1EA5u h\xECnh nh\u1EAFm m\u1EE5c ti\xEAu ('targeting') l\xE0 b\u1EAFt bu\u1ED9c.");
1613
+ }
1614
+ return {
1615
+ isValid: errors.length === 0,
1616
+ errors,
1617
+ data: errors.length === 0 ? raw : void 0
1618
+ };
1619
+ }
1620
+ }
1621
+ }
1538
1622
  var ZaloAudiencesValidator = {
1623
+ createCustomAudience: validateCreateCustomAudienceRequest,
1539
1624
  createSavedAudience: validateCreateSavedAudienceRequest,
1540
1625
  createPhoneAudience: validateCreatePhoneAudienceRequest,
1541
1626
  createLookalikeAudience: validateCreateLookalikeAudienceRequest,
1542
1627
  createFormEventAudience: validateCreateFormEventAudienceRequest,
1543
1628
  createMessageOaEventAudience: validateCreateMessageOaEventAudienceRequest,
1544
1629
  createMessagePersonalEventAudience: validateCreateMessagePersonalEventAudienceRequest,
1545
- estimateAudience: validateEstimateAudienceRequest
1630
+ estimateAudience: validateEstimateAudienceRequest,
1631
+ uploadPhoneList: validateUploadCustomAudiencePhoneListRequest,
1632
+ validateUploadPhoneList: validateUploadCustomAudiencePhoneListRequest,
1633
+ validateUploadCustomAudiencePhoneList: validateUploadCustomAudiencePhoneListRequest
1546
1634
  };
1547
1635
 
1548
1636
  // src/dtos/ads.dto.ts
@@ -2361,12 +2449,78 @@ function validateDuplicateAdParams(params) {
2361
2449
  warnings
2362
2450
  };
2363
2451
  }
2452
+ function validateCropCoordinates(input) {
2453
+ const errors = [];
2454
+ const warnings = [];
2455
+ if (!input || typeof input !== "object") {
2456
+ return {
2457
+ isValid: false,
2458
+ errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u c\u1EAFt/t\u1EA3i \u1EA3nh qu\u1EA3ng c\xE1o ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."],
2459
+ warnings
2460
+ };
2461
+ }
2462
+ const raw = input;
2463
+ const file = raw.File ?? raw.file;
2464
+ if (!file) {
2465
+ errors.push("Tr\u01B0\u1EDDng t\u1EC7p \u1EA3nh ('File') l\xE0 b\u1EAFt bu\u1ED9c.");
2466
+ } else if (typeof file === "string" && !/^(https?:\/\/|data:image\/)/i.test(file.trim())) {
2467
+ errors.push("\u0110\u01B0\u1EDDng d\u1EABn t\u1EC7p \u1EA3nh ('File') ph\u1EA3i l\xE0 URL HTTP/HTTPS ho\u1EB7c data URL h\u1EE3p l\u1EC7.");
2468
+ }
2469
+ const x = raw.x !== void 0 ? Number(raw.x) : 0;
2470
+ const y = raw.y !== void 0 ? Number(raw.y) : 0;
2471
+ const width = raw.width !== void 0 ? Number(raw.width) : 0;
2472
+ const height = raw.height !== void 0 ? Number(raw.height) : 0;
2473
+ const scale = raw.scale !== void 0 ? Number(raw.scale) : 1;
2474
+ if (isNaN(x) || x < 0) {
2475
+ errors.push(`T\u1ECDa \u0111\u1ED9 x kh\xF4ng h\u1EE3p l\u1EC7: '${raw.x}'. Ph\u1EA3i l\xE0 s\u1ED1 kh\xF4ng \xE2m (>= 0).`);
2476
+ }
2477
+ if (isNaN(y) || y < 0) {
2478
+ errors.push(`T\u1ECDa \u0111\u1ED9 y kh\xF4ng h\u1EE3p l\u1EC7: '${raw.y}'. Ph\u1EA3i l\xE0 s\u1ED1 kh\xF4ng \xE2m (>= 0).`);
2479
+ }
2480
+ if (isNaN(width) || width < 0) {
2481
+ errors.push(`Chi\u1EC1u r\u1ED9ng khung c\u1EAFt ('width') kh\xF4ng h\u1EE3p l\u1EC7: '${raw.width}'. Ph\u1EA3i l\xE0 s\u1ED1 kh\xF4ng \xE2m.`);
2482
+ }
2483
+ if (isNaN(height) || height < 0) {
2484
+ errors.push(`Chi\u1EC1u cao khung c\u1EAFt ('height') kh\xF4ng h\u1EE3p l\u1EC7: '${raw.height}'. Ph\u1EA3i l\xE0 s\u1ED1 kh\xF4ng \xE2m.`);
2485
+ }
2486
+ if (isNaN(scale) || scale <= 0) {
2487
+ errors.push(`T\u1EF7 l\u1EC7 co d\xE3n ('scale') kh\xF4ng h\u1EE3p l\u1EC7: '${raw.scale}'. Ph\u1EA3i l\xE0 s\u1ED1 d\u01B0\u01A1ng (> 0).`);
2488
+ }
2489
+ if (width > 0 && height === 0 || height > 0 && width === 0) {
2490
+ errors.push("Khi \u0111\xE3 ch\u1EC9 \u0111\u1ECBnh c\u1EAFt \u1EA3nh, c\u1EA3 'width' v\xE0 'height' \u0111\u1EC1u ph\u1EA3i l\u1EDBn h\u01A1n 0.");
2491
+ }
2492
+ if (width > 0 && height > 0) {
2493
+ const ratio = width / height;
2494
+ const isLandscape = Math.abs(ratio - 1.92) < 0.2 || Math.abs(ratio - 1.91) < 0.2 || Math.abs(ratio - 1.78) < 0.2;
2495
+ const isSquare = Math.abs(ratio - 1) < 0.05;
2496
+ const isVertical = Math.abs(ratio - 0.5625) < 0.1;
2497
+ if (!isLandscape && !isSquare && !isVertical) {
2498
+ warnings.push(`T\u1EF7 l\u1EC7 khung c\u1EAFt (${width}x${height} ~ ${ratio.toFixed(2)}:1) kh\xE1c c\xE1c t\u1EF7 l\u1EC7 chu\u1EA9n c\u1EE7a Zalo Ads (16:9 / 1.92:1 ngang, 1:1 vu\xF4ng ho\u1EB7c 9:16 d\u1ECDc). H\xE3y ki\u1EC3m tra hi\u1EC3n th\u1ECB th\u1EF1c t\u1EBF.`);
2499
+ }
2500
+ }
2501
+ const cleanData = {
2502
+ File: file,
2503
+ x,
2504
+ y,
2505
+ width,
2506
+ height,
2507
+ scale
2508
+ };
2509
+ return {
2510
+ isValid: errors.length === 0,
2511
+ errors,
2512
+ warnings,
2513
+ data: errors.length === 0 ? cleanData : void 0
2514
+ };
2515
+ }
2364
2516
  var ZaloCampaignsValidator = {
2365
2517
  createCampaign: validateCreateCampaignPayload,
2366
2518
  updateAd: validateUpdateAdPayload,
2367
2519
  renameCampaign: validateRenameCampaignParams,
2368
2520
  changeStatus: validateChangeCampaignStatusParams,
2369
- duplicateAd: validateDuplicateAdParams
2521
+ duplicateAd: validateDuplicateAdParams,
2522
+ validateCropCoordinates,
2523
+ validateUploadCropAdImage: validateCropCoordinates
2370
2524
  };
2371
2525
 
2372
2526
  // src/services/campaigns.service.ts
@@ -3204,6 +3358,18 @@ var OP_ZaloAdsListAgencyCustomersWithBudget = {
3204
3358
  "cookieFields": [],
3205
3359
  "bodyFields": []
3206
3360
  };
3361
+ var OP_ZaloAdsGetApiBaAgencyEmployees = {
3362
+ "operationId": "ZaloAds_getApiBaAgencyEmployees",
3363
+ "method": "GET",
3364
+ "endpoint": "/api/ba/agency/employees",
3365
+ "baseUrl": "https://ads.zalo.me",
3366
+ "binaryFields": [],
3367
+ "pathFields": [],
3368
+ "queryFields": [],
3369
+ "headerFields": [],
3370
+ "cookieFields": [],
3371
+ "bodyFields": []
3372
+ };
3207
3373
  var OP_ZaloAdsGetApiNotifiesHeader = {
3208
3374
  "operationId": "ZaloAds_getApiNotifiesHeader",
3209
3375
  "method": "GET",
@@ -3253,6 +3419,9 @@ var ZaloAccountService = class {
3253
3419
  };
3254
3420
  return this.client.requestWithoutBody(OP_ZaloAdsListAgencyCustomersWithBudget, this.client.toTransportInput(OP_ZaloAdsListAgencyCustomersWithBudget, normalized), options);
3255
3421
  }
3422
+ getApiBaAgencyEmployees(request = {}, options) {
3423
+ return this.client.requestWithoutBody(OP_ZaloAdsGetApiBaAgencyEmployees, this.client.toTransportInput(OP_ZaloAdsGetApiBaAgencyEmployees, request), options);
3424
+ }
3256
3425
  getApiNotifiesHeader(request = {}, options) {
3257
3426
  return this.client.requestWithoutBody(OP_ZaloAdsGetApiNotifiesHeader, this.client.toTransportInput(OP_ZaloAdsGetApiNotifiesHeader, request), options);
3258
3427
  }
@@ -3275,6 +3444,10 @@ var ZaloAccountService = class {
3275
3444
  getBaAccountAllGrantedMembers(...args) {
3276
3445
  return this.getApiBaAccountAllgrantedmembers(...args);
3277
3446
  }
3447
+ /** Danh sách nhân viên trực thuộc Agency */
3448
+ getBaAgencyEmployees(...args) {
3449
+ return this.getApiBaAgencyEmployees(...args);
3450
+ }
3278
3451
  /** Thông báo trên thanh tiêu đề */
3279
3452
  getNotifiesHeader(...args) {
3280
3453
  return this.getApiNotifiesHeader(...args);
@@ -5016,6 +5189,12 @@ var ZaloAdsService = class extends ZaloCampaignsService {
5016
5189
  listAgencyCustomersWithBudget(request = { limit: 15, offset: 0, joinDateAsc: true }, options) {
5017
5190
  return this.account.listAgencyCustomersWithBudget(request, options);
5018
5191
  }
5192
+ getApiBaAgencyEmployees(request = {}, options) {
5193
+ return this.account.getApiBaAgencyEmployees(request, options);
5194
+ }
5195
+ getBaAgencyEmployees(...args) {
5196
+ return this.account.getBaAgencyEmployees(...args);
5197
+ }
5019
5198
  getApiNotifiesHeader(request = {}, options) {
5020
5199
  return this.account.getApiNotifiesHeader(request, options);
5021
5200
  }
@@ -5518,10 +5697,60 @@ function validateListFormLeadsRequest(input) {
5518
5697
  } : void 0
5519
5698
  };
5520
5699
  }
5700
+ function validateToggleLeadNotificationRequest(input) {
5701
+ const errors = [];
5702
+ if (!input || typeof input !== "object") {
5703
+ return {
5704
+ isValid: false,
5705
+ errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u b\u1EADt/t\u1EAFt th\xF4ng b\xE1o lead ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
5706
+ };
5707
+ }
5708
+ const raw = input;
5709
+ const formId = typeof raw.formId === "string" ? raw.formId.trim() : raw.formId ? String(raw.formId).trim() : "";
5710
+ if (!formId) {
5711
+ errors.push("M\xE3 bi\u1EC3u m\u1EABu ('formId') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
5712
+ }
5713
+ return {
5714
+ isValid: errors.length === 0,
5715
+ errors,
5716
+ data: errors.length === 0 ? { formId } : void 0
5717
+ };
5718
+ }
5719
+ function validateUpdateLeadNotificationIntervalRequest(input) {
5720
+ const errors = [];
5721
+ if (!input || typeof input !== "object") {
5722
+ return {
5723
+ isValid: false,
5724
+ errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u c\u1EADp nh\u1EADt chu k\u1EF3 th\xF4ng b\xE1o lead ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
5725
+ };
5726
+ }
5727
+ const raw = input;
5728
+ const oaId = typeof raw.oaId === "string" ? raw.oaId.trim() : raw.oaId ? String(raw.oaId).trim() : "";
5729
+ const formId = typeof raw.formId === "string" ? raw.formId.trim() : raw.formId ? String(raw.formId).trim() : "";
5730
+ if (!oaId) {
5731
+ errors.push("M\xE3 Official Account ('oaId') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
5732
+ }
5733
+ if (!formId) {
5734
+ errors.push("M\xE3 bi\u1EC3u m\u1EABu ('formId') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
5735
+ }
5736
+ const interval = Number(raw.interval);
5737
+ if (isNaN(interval) || ![0, 1, 6].includes(interval)) {
5738
+ errors.push(`Chu k\u1EF3 th\xF4ng b\xE1o lead ('interval') '${raw.interval}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn thu\u1ED9c [0, 1, 6] (0: Ngay l\u1EADp t\u1EE9c khi c\xF3 lead / INSTANT, 1 ho\u1EB7c 6: T\u1ED5ng h\u1EE3p theo ng\xE0y / DAILY).`);
5739
+ }
5740
+ return {
5741
+ isValid: errors.length === 0,
5742
+ errors,
5743
+ data: errors.length === 0 ? { oaId, formId, interval } : void 0
5744
+ };
5745
+ }
5521
5746
  var ZaloFormsValidator = {
5522
5747
  createForm: validateCreateFormRequest,
5523
5748
  listFormsByOfficialAccount: validateListFormsByOfficialAccountRequest,
5524
- listFormLeads: validateListFormLeadsRequest
5749
+ listFormLeads: validateListFormLeadsRequest,
5750
+ enableLeadNotification: validateToggleLeadNotificationRequest,
5751
+ disableLeadNotification: validateToggleLeadNotificationRequest,
5752
+ updateLeadNotificationInterval: validateUpdateLeadNotificationIntervalRequest,
5753
+ validateLeadNotificationInterval: validateUpdateLeadNotificationIntervalRequest
5525
5754
  };
5526
5755
 
5527
5756
  // src/services/forms.service.ts
@@ -6229,6 +6458,53 @@ function validateUpsertInstantPageFormRequest(input) {
6229
6458
  data: errors.length === 0 ? data : void 0
6230
6459
  };
6231
6460
  }
6461
+ function validateUpdateInstantPageSharesRequest(input) {
6462
+ const errors = [];
6463
+ if (!input || typeof input !== "object") {
6464
+ return {
6465
+ isValid: false,
6466
+ errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u c\u1EADp nh\u1EADt quy\u1EC1n chia s\u1EBB Instant Page ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
6467
+ };
6468
+ }
6469
+ const obj = input;
6470
+ if (!isPositiveInteger2(obj.instantPageId)) {
6471
+ errors.push("Tr\u01B0\u1EDDng 'instantPageId' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
6472
+ }
6473
+ if (!Array.isArray(obj.shares) || obj.shares.length === 0) {
6474
+ errors.push("Tr\u01B0\u1EDDng 'shares' l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i ch\u1EE9a \xEDt nh\u1EA5t m\u1ED9t ng\u01B0\u1EDDi d\xF9ng \u0111\u01B0\u1EE3c ph\xE2n quy\u1EC1n (minItems: 1).");
6475
+ } else {
6476
+ const validPermissions = [1, 2, 3, 4];
6477
+ const seenUserIds = /* @__PURE__ */ new Set();
6478
+ obj.shares.forEach((item, idx) => {
6479
+ if (!item || typeof item !== "object") {
6480
+ errors.push(`Ph\u1EA7n t\u1EED th\u1EE9 ${idx + 1} trong danh s\xE1ch 'shares' ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng.`);
6481
+ return;
6482
+ }
6483
+ const share = item;
6484
+ const userId = Number(share.userId);
6485
+ if (!Number.isInteger(userId) || userId <= 0) {
6486
+ errors.push(`Ph\u1EA7n t\u1EED th\u1EE9 ${idx + 1}: Tr\u01B0\u1EDDng 'userId' ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng \u0111\u1ECBnh danh Zalo (hi\u1EC7n t\u1EA1i: ${share.userId}).`);
6487
+ } else if (seenUserIds.has(userId)) {
6488
+ errors.push(`Ph\u1EA7n t\u1EED th\u1EE9 ${idx + 1}: ID ng\u01B0\u1EDDi d\xF9ng '${userId}' b\u1ECB tr\xF9ng l\u1EB7p trong danh s\xE1ch ph\xE2n quy\u1EC1n.`);
6489
+ } else {
6490
+ seenUserIds.add(userId);
6491
+ }
6492
+ const permission = Number(share.permission);
6493
+ if (!validPermissions.includes(permission)) {
6494
+ errors.push(`Ph\u1EA7n t\u1EED th\u1EE9 ${idx + 1}: Quy\u1EC1n 'permission' kh\xF4ng h\u1EE3p l\u1EC7: ${share.permission}. Ph\u1EA3i thu\u1ED9c [1, 2, 3, 4] (1: ADMIN, 2: UPDATE_PAGE, 3: DOWNLOAD_INFO, 4: READ_ONLY).`);
6495
+ }
6496
+ });
6497
+ }
6498
+ const cleanData = {
6499
+ instantPageId: toPositiveInteger2(obj.instantPageId),
6500
+ shares: obj.shares || []
6501
+ };
6502
+ return {
6503
+ isValid: errors.length === 0,
6504
+ errors,
6505
+ data: errors.length === 0 ? cleanData : void 0
6506
+ };
6507
+ }
6232
6508
  var ZaloInstantPagesValidator = {
6233
6509
  validateCreateInstantPage: validateCreateInstantPageRequest,
6234
6510
  validateCloneInstantPage: validateCloneInstantPageRequest,
@@ -6237,6 +6513,8 @@ var ZaloInstantPagesValidator = {
6237
6513
  validateListInstantPageEditHistory: validateListInstantPageEditHistoryRequest,
6238
6514
  validateListInstantPageFormRecords: validateListInstantPageFormRecordsRequest,
6239
6515
  validateListInstantPageShares: validateListInstantPageSharesRequest,
6516
+ validateUpdateInstantPageShares: validateUpdateInstantPageSharesRequest,
6517
+ validateUpdateShares: validateUpdateInstantPageSharesRequest,
6240
6518
  validateListInstantPageUsers: validateListInstantPageUsersRequest,
6241
6519
  validateListMiniPageTemplates: validateListMiniPageTemplatesRequest,
6242
6520
  validateSearchInstantPages: validateSearchInstantPagesRequest,
@@ -7326,6 +7604,461 @@ var ZaloConversionsValidator = class {
7326
7604
  };
7327
7605
  }
7328
7606
  };
7607
+
7608
+ // src/validators/profile-ads.validator.ts
7609
+ var ZALO_PROFILE_ADS_SUB_CATEGORIES = {
7610
+ 10043: "B\u1EA5t \u0111\u1ED9ng s\u1EA3n",
7611
+ 10018: "C\xF4ng ngh\u1EC7 & Thi\u1EBFt b\u1ECB",
7612
+ 10097: "D\u1ECBch v\u1EE5 ti\u1EC7n \xEDch",
7613
+ 10020: "Du l\u1ECBch & L\u01B0u tr\xFA",
7614
+ 10021: "Gi\xE1o d\u1EE5c & \u0110\xE0o t\u1EA1o",
7615
+ 10024: "Mua s\u1EAFm & B\xE1n l\u1EBB",
7616
+ 10019: "M\u1EF9 ph\u1EA9m & L\xE0m \u0111\u1EB9p",
7617
+ 10014: "Nh\xE0 h\xE0ng & Qu\xE1n",
7618
+ 10094: "\xD4 t\xF4 & Xe m\xE1y",
7619
+ 10098: "S\u1EA3n xu\u1EA5t & Ch\u1EBF t\u1EA1o",
7620
+ 10044: "T\xE0i ch\xEDnh & Ng\xE2n h\xE0ng",
7621
+ 10099: "Thi\u1EBFt k\u1EBF & Thi c\xF4ng",
7622
+ 10017: "Th\u1EDDi trang & May m\u1EB7c",
7623
+ 10023: "Th\u1EF1c ph\u1EA9m & \u0110\u1ED3 u\u1ED1ng",
7624
+ 10016: "Truy\u1EC1n th\xF4ng & Gi\u1EA3i tr\xED",
7625
+ 10092: "Truy\u1EC1n th\xF4ng n\u1ED9i b\u1ED9",
7626
+ 10101: "Tuy\u1EC3n d\u1EE5ng & Vi\u1EC7c l\xE0m",
7627
+ 10100: "T\u01B0 v\u1EA5n & Qu\u1EA3n l\xFD",
7628
+ 10095: "V\u1EADn t\u1EA3i",
7629
+ 10093: "Vi\u1EC5n th\xF4ng",
7630
+ 10022: "Y t\u1EBF & D\u01B0\u1EE3c ph\u1EA9m",
7631
+ 10025: "D\u1ECBch v\u1EE5 kh\xE1c"
7632
+ };
7633
+ var ZALO_PROFILE_ADS_PROVINCES = {
7634
+ 1: "Th\xE0nh ph\u1ED1 H\xE0 N\u1ED9i",
7635
+ 4: "T\u1EC9nh Cao B\u1EB1ng",
7636
+ 8: "T\u1EC9nh Tuy\xEAn Quang",
7637
+ 11: "T\u1EC9nh \u0110i\u1EC7n Bi\xEAn",
7638
+ 12: "T\u1EC9nh Lai Ch\xE2u",
7639
+ 14: "T\u1EC9nh S\u01A1n La",
7640
+ 15: "T\u1EC9nh L\xE0o Cai",
7641
+ 19: "T\u1EC9nh Th\xE1i Nguy\xEAn",
7642
+ 20: "T\u1EC9nh L\u1EA1ng S\u01A1n",
7643
+ 22: "T\u1EC9nh Qu\u1EA3ng Ninh",
7644
+ 24: "T\u1EC9nh B\u1EAFc Ninh",
7645
+ 25: "T\u1EC9nh Ph\xFA Th\u1ECD",
7646
+ 31: "Th\xE0nh ph\u1ED1 H\u1EA3i Ph\xF2ng",
7647
+ 33: "T\u1EC9nh H\u01B0ng Y\xEAn",
7648
+ 37: "T\u1EC9nh Ninh B\xECnh",
7649
+ 38: "T\u1EC9nh Thanh H\xF3a",
7650
+ 40: "T\u1EC9nh Ngh\u1EC7 An",
7651
+ 42: "T\u1EC9nh H\xE0 T\u0129nh",
7652
+ 44: "T\u1EC9nh Qu\u1EA3ng Tr\u1ECB",
7653
+ 46: "Th\xE0nh ph\u1ED1 Hu\u1EBF",
7654
+ 48: "Th\xE0nh ph\u1ED1 \u0110\xE0 N\u1EB5ng",
7655
+ 51: "T\u1EC9nh Qu\u1EA3ng Ng\xE3i",
7656
+ 52: "T\u1EC9nh Gia Lai",
7657
+ 56: "T\u1EC9nh Kh\xE1nh H\xF2a",
7658
+ 66: "T\u1EC9nh \u0110\u1EAFk L\u1EAFk",
7659
+ 68: "T\u1EC9nh L\xE2m \u0110\u1ED3ng",
7660
+ 75: "T\u1EC9nh \u0110\u1ED3ng Nai",
7661
+ 79: "Th\xE0nh ph\u1ED1 H\u1ED3 Ch\xED Minh",
7662
+ 80: "T\u1EC9nh T\xE2y Ninh",
7663
+ 82: "T\u1EC9nh \u0110\u1ED3ng Th\xE1p",
7664
+ 86: "T\u1EC9nh V\u0129nh Long",
7665
+ 91: "T\u1EC9nh An Giang",
7666
+ 92: "Th\xE0nh ph\u1ED1 C\u1EA7n Th\u01A1",
7667
+ 96: "T\u1EC9nh C\xE0 Mau"
7668
+ };
7669
+ var VIETNAM_PHONE_REGEX = /^(84|0)(3[2-9]|5[2689]|7[06-9]|8[1-9]|9[0-9])[0-9]{7}$/;
7670
+ function isValidUrl2(val) {
7671
+ return /^(https?:\/\/|data:image\/)/i.test(val);
7672
+ }
7673
+ function validateCreateOaPageRequest(input) {
7674
+ const errors = [];
7675
+ if (!input || typeof input !== "object") {
7676
+ return {
7677
+ isValid: false,
7678
+ errors: ["D\u1EEF li\u1EC7u kh\u1EDFi t\u1EA1o Zalo Official Account ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng (object)."]
7679
+ };
7680
+ }
7681
+ const raw = input;
7682
+ const oaName = typeof raw.oaName === "string" ? raw.oaName.trim() : "";
7683
+ if (!oaName) {
7684
+ errors.push("T\xEAn trang Official Account ('oaName') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
7685
+ } else if (oaName.length < 2 || oaName.length > 40) {
7686
+ errors.push(`T\xEAn trang Official Account ph\u1EA3i t\u1EEB 2 \u0111\u1EBFn 40 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${oaName.length} k\xFD t\u1EF1).`);
7687
+ } else {
7688
+ if (oaName.length > 5 && oaName === oaName.toUpperCase() && /[A-Z]/.test(oaName)) {
7689
+ errors.push("T\xEAn trang Official Account kh\xF4ng \u0111\u01B0\u1EE3c vi\u1EBFt in hoa to\xE0n b\u1ED9 c\xE1c t\u1EEB. Vui l\xF2ng vi\u1EBFt theo ng\u1EEF ph\xE1p ti\u1EBFng Vi\u1EC7t chu\u1EA9n.");
7690
+ }
7691
+ const forbiddenKeywords = ["s\u1ED1 1", "nh\u1EA5t vi\u1EC7t nam", "cam k\u1EBFt 100%", "tr\u1ECB d\u1EE9t \u0111i\u1EC3m"];
7692
+ for (const kw of forbiddenKeywords) {
7693
+ if (oaName.toLowerCase().includes(kw)) {
7694
+ errors.push(`T\xEAn trang Official Account ch\u1EE9a t\u1EEB ng\u1EEF cam k\u1EBFt/ph\xF4 tr\u01B0\u01A1ng kh\xF4ng h\u1EE3p l\u1EC7: '${kw}'.`);
7695
+ }
7696
+ }
7697
+ }
7698
+ const description = typeof raw.description === "string" ? raw.description.trim() : "";
7699
+ if (!description) {
7700
+ errors.push("Th\xF4ng tin m\xF4 t\u1EA3 ho\u1EA1t \u0111\u1ED9ng ('description') l\xE0 b\u1EAFt bu\u1ED9c.");
7701
+ } else if (description.length < 20 || description.length > 500) {
7702
+ errors.push(`Th\xF4ng tin m\xF4 t\u1EA3 ho\u1EA1t \u0111\u1ED9ng ph\u1EA3i t\u1EEB 20 \u0111\u1EBFn 500 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${description.length} k\xFD t\u1EF1).`);
7703
+ }
7704
+ const contactName = typeof raw.contactName === "string" ? raw.contactName.trim() : "";
7705
+ if (!contactName) {
7706
+ errors.push("H\u1ECD v\xE0 t\xEAn ng\u01B0\u1EDDi li\xEAn h\u1EC7 ('contactName') l\xE0 b\u1EAFt bu\u1ED9c.");
7707
+ } else if (contactName.split(/\s+/).length < 2) {
7708
+ errors.push("H\u1ECD v\xE0 t\xEAn ng\u01B0\u1EDDi li\xEAn h\u1EC7 ph\u1EA3i c\xF3 \xEDt nh\u1EA5t 2 t\u1EEB (h\u1ECD v\xE0 t\xEAn).");
7709
+ }
7710
+ const contactPhone = typeof raw.contactPhone === "string" ? raw.contactPhone.trim() : String(raw.contactPhone || "").trim();
7711
+ if (!contactPhone) {
7712
+ errors.push("S\u1ED1 \u0111i\u1EC7n tho\u1EA1i li\xEAn h\u1EC7 ('contactPhone') l\xE0 b\u1EAFt bu\u1ED9c.");
7713
+ } else {
7714
+ const cleanPhone = contactPhone.replace(/\s+/g, "");
7715
+ if (!VIETNAM_PHONE_REGEX.test(cleanPhone)) {
7716
+ errors.push(`S\u1ED1 \u0111i\u1EC7n tho\u1EA1i li\xEAn h\u1EC7 '${contactPhone}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i l\xE0 s\u1ED1 di \u0111\u1ED9ng Vi\u1EC7t Nam 10 ch\u1EEF s\u1ED1 (v\xED d\u1EE5: 0901234567 ho\u1EB7c 84901234567).`);
7717
+ }
7718
+ }
7719
+ const subCatId = Number(raw.subCategoryId);
7720
+ if (!subCatId || !ZALO_PROFILE_ADS_SUB_CATEGORIES[subCatId]) {
7721
+ errors.push(
7722
+ `M\xE3 danh m\u1EE5c ho\u1EA1t \u0111\u1ED9ng ('subCategoryId') '${raw.subCategoryId}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i thu\u1ED9c 22 m\xE3 danh m\u1EE5c chu\u1EA9n tr\xEAn Zalo Ads Profile (v\xED d\u1EE5: 10018: C\xF4ng ngh\u1EC7 & Thi\u1EBFt b\u1ECB, 10043: B\u1EA5t \u0111\u1ED9ng s\u1EA3n, 10024: Mua s\u1EAFm & B\xE1n l\u1EBB).`
7723
+ );
7724
+ }
7725
+ const provinceId = Number(raw.province);
7726
+ if (!provinceId || !ZALO_PROFILE_ADS_PROVINCES[provinceId]) {
7727
+ errors.push(
7728
+ `M\xE3 T\u1EC9nh/Th\xE0nh ph\u1ED1 ('province') '${raw.province}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i thu\u1ED9c 34 m\xE3 h\xE0nh ch\xEDnh chu\u1EA9n tr\xEAn Zalo Ads Profile (v\xED d\u1EE5: 1: H\xE0 N\u1ED9i, 79: TP.HCM, 48: \u0110\xE0 N\u1EB5ng).`
7729
+ );
7730
+ }
7731
+ const district = Number(raw.district);
7732
+ if (!district || !Number.isInteger(district) || district <= 0) {
7733
+ errors.push("M\xE3 Ph\u01B0\u1EDDng/X\xE3 ('district') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
7734
+ }
7735
+ const address = typeof raw.address === "string" ? raw.address.trim() : "";
7736
+ if (!address || address.length < 5) {
7737
+ errors.push("\u0110\u1ECBa ch\u1EC9 ho\u1EA1t \u0111\u1ED9ng chi ti\u1EBFt ('address') ph\u1EA3i c\xF3 \u0111\u1ED9 d\xE0i t\u1ED1i thi\u1EC3u 5 k\xFD t\u1EF1.");
7738
+ }
7739
+ const avatarId = typeof raw.avatarId === "string" ? raw.avatarId.trim() : "";
7740
+ if (!avatarId) {
7741
+ errors.push("M\xE3 \u0111\u1ECBnh danh \u1EA3nh \u0111\u1EA1i di\u1EC7n ('avatarId') l\xE0 b\u1EAFt bu\u1ED9c. H\xE3y t\u1EA3i \u1EA3nh qua API uploadOaAvatar tr\u01B0\u1EDBc.");
7742
+ }
7743
+ const coverId = typeof raw.coverId === "string" ? raw.coverId.trim() : "";
7744
+ if (!coverId) {
7745
+ errors.push("M\xE3 \u0111\u1ECBnh danh \u1EA3nh b\xECa ('coverId') l\xE0 b\u1EAFt bu\u1ED9c. H\xE3y t\u1EA3i \u1EA3nh qua API uploadOaCover tr\u01B0\u1EDBc.");
7746
+ }
7747
+ const cleanData = {
7748
+ option: "createpage",
7749
+ typeId: raw.typeId !== void 0 ? Number(raw.typeId) : 2,
7750
+ typeName: typeof raw.typeName === "string" ? raw.typeName : "store",
7751
+ tier: raw.tier !== void 0 ? Number(raw.tier) : 0,
7752
+ categoryId: raw.categoryId !== void 0 ? Number(raw.categoryId) : 10003,
7753
+ subCategoryId: subCatId,
7754
+ oaName,
7755
+ description,
7756
+ contactName,
7757
+ contactPhone,
7758
+ avatarId,
7759
+ coverId,
7760
+ province: provinceId,
7761
+ district,
7762
+ address,
7763
+ agreeTerm: raw.agreeTerm !== void 0 ? Boolean(raw.agreeTerm) : true,
7764
+ ...typeof raw["crsf-token"] === "string" ? { "crsf-token": raw["crsf-token"] } : {}
7765
+ };
7766
+ return {
7767
+ isValid: errors.length === 0,
7768
+ errors,
7769
+ data: errors.length === 0 ? cleanData : void 0
7770
+ };
7771
+ }
7772
+ function validateUploadMediaRequest(input, options) {
7773
+ const errors = [];
7774
+ if (!input || typeof input !== "object") {
7775
+ return {
7776
+ isValid: false,
7777
+ errors: ["D\u1EEF li\u1EC7u y\xEAu c\u1EA7u t\u1EA3i \u1EA3nh l\xEAn ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
7778
+ };
7779
+ }
7780
+ const raw = input;
7781
+ const fileField = options.mediaType === "avatar" ? raw["avatar-file"] ?? raw.file ?? raw.File : raw["cover-file"] ?? raw.file ?? raw.File;
7782
+ if (!fileField) {
7783
+ errors.push(`Tr\u01B0\u1EDDng t\u1EC7p \u1EA3nh ('${options.mediaType === "avatar" ? "avatar-file" : "cover-file"}') l\xE0 b\u1EAFt bu\u1ED9c.`);
7784
+ return { isValid: false, errors };
7785
+ }
7786
+ if (typeof fileField === "string") {
7787
+ const trimmed = fileField.trim();
7788
+ if (!trimmed) {
7789
+ errors.push("\u0110\u01B0\u1EDDng d\u1EABn t\u1EC7p \u1EA3nh kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
7790
+ } else if (!isValidUrl2(trimmed)) {
7791
+ errors.push(`\u0110\u01B0\u1EDDng d\u1EABn t\u1EC7p '${trimmed}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i l\xE0 URL HTTP/HTTPS c\xF4ng khai ho\u1EB7c data URL.`);
7792
+ }
7793
+ }
7794
+ const maxBytes = options.maxSizeBytes || 15 * 1024 * 1024;
7795
+ if (typeof raw.sizeBytes === "number" && raw.sizeBytes > maxBytes) {
7796
+ const sizeMb = (raw.sizeBytes / (1024 * 1024)).toFixed(2);
7797
+ errors.push(`Dung l\u01B0\u1EE3ng \u1EA3nh v\u01B0\u1EE3t qu\xE1 gi\u1EDBi h\u1EA1n t\u1ED1i \u0111a 15MB (dung l\u01B0\u1EE3ng: ${sizeMb}MB).`);
7798
+ }
7799
+ const minW = options.minWidth || (options.mediaType === "avatar" ? 150 : 320);
7800
+ const minH = options.minHeight || (options.mediaType === "avatar" ? 150 : 180);
7801
+ if (typeof raw.width === "number" && raw.width < minW) {
7802
+ errors.push(`Chi\u1EC1u r\u1ED9ng \u1EA3nh t\u1ED1i thi\u1EC3u ${minW}px (hi\u1EC7n t\u1EA1i: ${raw.width}px).`);
7803
+ }
7804
+ if (typeof raw.height === "number" && raw.height < minH) {
7805
+ errors.push(`Chi\u1EC1u cao \u1EA3nh t\u1ED1i thi\u1EC3u ${minH}px (hi\u1EC7n t\u1EA1i: ${raw.height}px).`);
7806
+ }
7807
+ return {
7808
+ isValid: errors.length === 0,
7809
+ errors,
7810
+ data: errors.length === 0 ? {
7811
+ file: fileField,
7812
+ isNew: typeof raw["is-new"] === "string" ? raw["is-new"] : "true",
7813
+ option: typeof raw.option === "string" ? raw.option : "update"
7814
+ } : void 0
7815
+ };
7816
+ }
7817
+ var ZaloProfileAdsValidator = {
7818
+ validateCreateOaPage: validateCreateOaPageRequest,
7819
+ validateUploadMedia: validateUploadMediaRequest,
7820
+ validateUploadAvatar: (input) => validateUploadMediaRequest(input, { mediaType: "avatar", minWidth: 150, minHeight: 150 }),
7821
+ validateUploadCover: (input) => validateUploadMediaRequest(input, { mediaType: "cover", minWidth: 320, minHeight: 180 })
7822
+ };
7823
+
7824
+ // src/validators/reports.validator.ts
7825
+ var MAX_REPORT_RANGE_SECONDS = 90 * 86400;
7826
+ var MAX_REPORT_RANGE_MS = MAX_REPORT_RANGE_SECONDS * 1e3;
7827
+ function validateUpsertCustomReportRequest(input) {
7828
+ const errors = [];
7829
+ if (!input || typeof input !== "object") {
7830
+ return {
7831
+ isValid: false,
7832
+ errors: ["D\u1EEF li\u1EC7u c\u1EA5u h\xECnh b\xE1o c\xE1o t\xF9y ch\u1EC9nh ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
7833
+ };
7834
+ }
7835
+ const raw = input;
7836
+ let id = 0;
7837
+ if (raw.id !== void 0 && raw.id !== null) {
7838
+ const parsedId = Number(raw.id);
7839
+ if (!Number.isInteger(parsedId) || parsedId < 0) {
7840
+ errors.push("Tr\u01B0\u1EDDng 'id' ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn kh\xF4ng \xE2m (0 khi t\u1EA1o m\u1EDBi, > 0 khi c\u1EADp nh\u1EADt).");
7841
+ } else {
7842
+ id = parsedId;
7843
+ }
7844
+ }
7845
+ const name = typeof raw.name === "string" ? raw.name.trim() : "";
7846
+ if (!name) {
7847
+ errors.push("T\xEAn b\xE1o c\xE1o t\xF9y ch\u1EC9nh ('name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
7848
+ } else if (name.length > 100) {
7849
+ errors.push(`T\xEAn b\xE1o c\xE1o t\xF9y ch\u1EC9nh kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 100 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${name.length} k\xFD t\u1EF1).`);
7850
+ }
7851
+ const settings = [];
7852
+ if (!Array.isArray(raw.settings) || raw.settings.length === 0) {
7853
+ errors.push("Danh s\xE1ch ch\u1EC9 s\u1ED1 c\u1ED9t ('settings') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i c\xF3 \xEDt nh\u1EA5t 1 ch\u1EC9 s\u1ED1.");
7854
+ } else {
7855
+ for (const item of raw.settings) {
7856
+ const colId = Number(item);
7857
+ if (!Number.isInteger(colId) || colId <= 0) {
7858
+ errors.push(`M\xE3 ch\u1EC9 s\u1ED1 c\u1ED9t '${item}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng.`);
7859
+ } else {
7860
+ if (!settings.includes(colId)) {
7861
+ settings.push(colId);
7862
+ }
7863
+ }
7864
+ }
7865
+ }
7866
+ const isDefault = Boolean(raw.isDefault);
7867
+ const cleanData = {
7868
+ id,
7869
+ name,
7870
+ settings,
7871
+ isDefault
7872
+ };
7873
+ return {
7874
+ isValid: errors.length === 0,
7875
+ errors,
7876
+ data: errors.length === 0 ? cleanData : void 0
7877
+ };
7878
+ }
7879
+ function validateDateRangeReportRequest(input) {
7880
+ const errors = [];
7881
+ if (!input || typeof input !== "object") {
7882
+ return {
7883
+ isValid: false,
7884
+ errors: ["Tham s\u1ED1 truy v\u1EA5n kho\u1EA3ng th\u1EDDi gian b\xE1o c\xE1o ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
7885
+ };
7886
+ }
7887
+ const raw = input;
7888
+ const rawStart = raw.startDate ?? raw.from;
7889
+ const rawEnd = raw.endDate ?? raw.to;
7890
+ if (rawStart === void 0 || rawStart === null) {
7891
+ errors.push("M\u1ED1c th\u1EDDi gian b\u1EAFt \u0111\u1EA7u ('startDate' ho\u1EB7c 'from') l\xE0 b\u1EAFt bu\u1ED9c.");
7892
+ }
7893
+ if (rawEnd === void 0 || rawEnd === null) {
7894
+ errors.push("M\u1ED1c th\u1EDDi gian k\u1EBFt th\xFAc ('endDate' ho\u1EB7c 'to') l\xE0 b\u1EAFt bu\u1ED9c.");
7895
+ }
7896
+ if (errors.length > 0) {
7897
+ return { isValid: false, errors };
7898
+ }
7899
+ const startNum = Number(rawStart);
7900
+ const endNum = Number(rawEnd);
7901
+ if (isNaN(startNum) || startNum <= 0) {
7902
+ errors.push(`M\u1ED1c th\u1EDDi gian b\u1EAFt \u0111\u1EA7u '${rawStart}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i l\xE0 Unix timestamp d\u01B0\u01A1ng.`);
7903
+ }
7904
+ if (isNaN(endNum) || endNum <= 0) {
7905
+ errors.push(`M\u1ED1c th\u1EDDi gian k\u1EBFt th\xFAc '${rawEnd}' kh\xF4ng h\u1EE3p l\u1EC7. Ph\u1EA3i l\xE0 Unix timestamp d\u01B0\u01A1ng.`);
7906
+ }
7907
+ if (errors.length > 0) {
7908
+ return { isValid: false, errors };
7909
+ }
7910
+ const isMs = startNum > 1e10 || endNum > 1e10;
7911
+ const maxRange = isMs ? MAX_REPORT_RANGE_MS : MAX_REPORT_RANGE_SECONDS;
7912
+ if (endNum < startNum) {
7913
+ errors.push("M\u1ED1c th\u1EDDi gian k\u1EBFt th\xFAc ph\u1EA3i l\u1EDBn h\u01A1n ho\u1EB7c b\u1EB1ng m\u1ED1c th\u1EDDi gian b\u1EAFt \u0111\u1EA7u.");
7914
+ } else {
7915
+ const diff = endNum - startNum;
7916
+ if (diff > maxRange) {
7917
+ const days = isMs ? Math.round(diff / (86400 * 1e3)) : Math.round(diff / 86400);
7918
+ errors.push(`Kho\u1EA3ng th\u1EDDi gian truy v\u1EA5n b\xE1o c\xE1o kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 90 ng\xE0y theo ch\xEDnh s\xE1ch Zalo Ads (kho\u1EA3ng th\u1EDDi gian hi\u1EC7n t\u1EA1i: ${days} ng\xE0y).`);
7919
+ }
7920
+ }
7921
+ let campaignId;
7922
+ if (raw.campaignId !== void 0 && raw.campaignId !== null) {
7923
+ const parsedCampId = Number(raw.campaignId);
7924
+ if (!Number.isInteger(parsedCampId) || parsedCampId <= 0) {
7925
+ errors.push("M\xE3 chi\u1EBFn d\u1ECBch ('campaignId') ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0).");
7926
+ } else {
7927
+ campaignId = parsedCampId;
7928
+ }
7929
+ }
7930
+ const cleanData = {
7931
+ startDate: startNum,
7932
+ endDate: endNum,
7933
+ isMilliseconds: isMs,
7934
+ ...campaignId !== void 0 ? { campaignId } : {}
7935
+ };
7936
+ return {
7937
+ isValid: errors.length === 0,
7938
+ errors,
7939
+ data: errors.length === 0 ? cleanData : void 0
7940
+ };
7941
+ }
7942
+ var ZaloReportsValidator = {
7943
+ validateUpsertCustomReport: validateUpsertCustomReportRequest,
7944
+ validateDateRangeReport: validateDateRangeReportRequest
7945
+ };
7946
+
7947
+ // src/validators/media.validator.ts
7948
+ function isValidUrl3(val) {
7949
+ if (typeof val !== "string") return false;
7950
+ return /^https?:\/\/.+/i.test(val.trim());
7951
+ }
7952
+ function validateSaveMediaRequest(input) {
7953
+ const errors = [];
7954
+ if (!input) {
7955
+ return {
7956
+ isValid: false,
7957
+ errors: ["D\u1EEF li\u1EC7u l\u01B0u Media ('saveMedia') kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng."]
7958
+ };
7959
+ }
7960
+ let targetObj = input;
7961
+ if (typeof input === "string") {
7962
+ try {
7963
+ targetObj = JSON.parse(input);
7964
+ } catch {
7965
+ return {
7966
+ isValid: false,
7967
+ errors: ["Chu\u1ED7i JSON d\u1EEF li\u1EC7u Media ('data') kh\xF4ng \u0111\xFAng \u0111\u1ECBnh d\u1EA1ng."]
7968
+ };
7969
+ }
7970
+ }
7971
+ if (!targetObj || typeof targetObj !== "object") {
7972
+ return {
7973
+ isValid: false,
7974
+ errors: ["D\u1EEF li\u1EC7u Media ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng."]
7975
+ };
7976
+ }
7977
+ const rawObj = targetObj;
7978
+ let raw = rawObj;
7979
+ if (rawObj.data && typeof rawObj.data === "object") {
7980
+ raw = rawObj.data;
7981
+ } else if (typeof rawObj.data === "string") {
7982
+ try {
7983
+ raw = JSON.parse(rawObj.data);
7984
+ } catch {
7985
+ return {
7986
+ isValid: false,
7987
+ errors: ["Chu\u1ED7i JSON trong tr\u01B0\u1EDDng 'data' kh\xF4ng \u0111\xFAng \u0111\u1ECBnh d\u1EA1ng."]
7988
+ };
7989
+ }
7990
+ }
7991
+ const name = typeof raw.Name === "string" ? raw.Name.trim() : typeof raw.name === "string" ? raw.name.trim() : "";
7992
+ if (!name) {
7993
+ errors.push("T\xEAn t\u1EC7p media ('Name') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 kh\xF4ng \u0111\u01B0\u1EE3c \u0111\u1EC3 tr\u1ED1ng.");
7994
+ } else if (name.length > 255) {
7995
+ errors.push(`T\xEAn t\u1EC7p media kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 255 k\xFD t\u1EF1 (hi\u1EC7n t\u1EA1i: ${name.length} k\xFD t\u1EF1).`);
7996
+ }
7997
+ const typeVal = raw.Type !== void 0 ? Number(raw.Type) : raw.type !== void 0 ? Number(raw.type) : NaN;
7998
+ if (typeVal !== 1 && typeVal !== 2) {
7999
+ errors.push(`Lo\u1EA1i media ('Type') kh\xF4ng h\u1EE3p l\u1EC7: '${raw.Type ?? raw.type}'. Ch\u1EC9 h\u1ED7 tr\u1EE3 1 (\u1EA2nh) ho\u1EB7c 2 (Video).`);
8000
+ }
8001
+ const rawSettings = raw.Settings ?? raw.settings;
8002
+ if (!rawSettings || typeof rawSettings !== "object") {
8003
+ errors.push("C\u1EA5u h\xECnh t\u1EC7p media ('Settings') l\xE0 b\u1EAFt bu\u1ED9c.");
8004
+ return { isValid: false, errors };
8005
+ }
8006
+ const url = typeof rawSettings.Url === "string" ? rawSettings.Url.trim() : typeof rawSettings.url === "string" ? rawSettings.url.trim() : "";
8007
+ if (!url) {
8008
+ errors.push("\u0110\u01B0\u1EDDng d\u1EABn t\u1EC7p media ('Settings.Url') l\xE0 b\u1EAFt bu\u1ED9c.");
8009
+ } else if (!isValidUrl3(url)) {
8010
+ errors.push(`\u0110\u01B0\u1EDDng d\u1EABn t\u1EC7p media ('Settings.Url') kh\xF4ng h\u1EE3p l\u1EC7: '${url}'. Ph\u1EA3i l\xE0 URL HTTP ho\u1EB7c HTTPS b\u1EAFt \u0111\u1EA7u b\u1EB1ng http:// ho\u1EB7c https://.`);
8011
+ }
8012
+ const width = Number(rawSettings.Width ?? rawSettings.width);
8013
+ if (!Number.isInteger(width) || width <= 0) {
8014
+ errors.push(`Chi\u1EC1u r\u1ED9ng t\u1EC7p media ('Settings.Width') ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0). Hi\u1EC7n t\u1EA1i: ${rawSettings.Width ?? rawSettings.width}`);
8015
+ }
8016
+ const height = Number(rawSettings.Height ?? rawSettings.height);
8017
+ if (!Number.isInteger(height) || height <= 0) {
8018
+ errors.push(`Chi\u1EC1u cao t\u1EC7p media ('Settings.Height') ph\u1EA3i l\xE0 s\u1ED1 nguy\xEAn d\u01B0\u01A1ng (> 0). Hi\u1EC7n t\u1EA1i: ${rawSettings.Height ?? rawSettings.height}`);
8019
+ }
8020
+ let duration;
8021
+ let thumbUrl;
8022
+ if (typeVal === 2) {
8023
+ const dur = Number(rawSettings.Duration ?? rawSettings.duration);
8024
+ if (!isNaN(dur) && dur > 0) {
8025
+ if (dur > 600) {
8026
+ errors.push(`Th\u1EDDi l\u01B0\u1EE3ng video ('Settings.Duration') kh\xF4ng \u0111\u01B0\u1EE3c v\u01B0\u1EE3t qu\xE1 600 gi\xE2y (hi\u1EC7n t\u1EA1i: ${dur}s).`);
8027
+ } else {
8028
+ duration = dur;
8029
+ }
8030
+ } else {
8031
+ errors.push("V\u1EDBi lo\u1EA1i media Video (Type = 2), th\u1EDDi l\u01B0\u1EE3ng video ('Settings.Duration') l\xE0 b\u1EAFt bu\u1ED9c v\xE0 ph\u1EA3i l\xE0 s\u1ED1 d\u01B0\u01A1ng (> 0).");
8032
+ }
8033
+ const thumb = typeof rawSettings.ThumbUrl === "string" ? rawSettings.ThumbUrl.trim() : typeof rawSettings.thumbUrl === "string" ? rawSettings.thumbUrl.trim() : "";
8034
+ if (thumb) {
8035
+ if (!isValidUrl3(thumb)) {
8036
+ errors.push(`\u1EA2nh thu nh\u1ECF c\u1EE7a video ('Settings.ThumbUrl') kh\xF4ng h\u1EE3p l\u1EC7: '${thumb}'. Ph\u1EA3i l\xE0 URL HTTP/HTTPS.`);
8037
+ } else {
8038
+ thumbUrl = thumb;
8039
+ }
8040
+ }
8041
+ }
8042
+ const cleanData = {
8043
+ Name: name,
8044
+ Type: typeVal,
8045
+ Settings: {
8046
+ Url: url,
8047
+ Width: width,
8048
+ Height: height,
8049
+ ...duration !== void 0 ? { Duration: duration } : {},
8050
+ ...thumbUrl !== void 0 ? { ThumbUrl: thumbUrl } : {}
8051
+ }
8052
+ };
8053
+ return {
8054
+ isValid: errors.length === 0,
8055
+ errors,
8056
+ data: errors.length === 0 ? cleanData : void 0
8057
+ };
8058
+ }
8059
+ var ZaloMediaValidator = {
8060
+ validateSaveMedia: validateSaveMediaRequest
8061
+ };
7329
8062
  export {
7330
8063
  ALLOWED_CTAS_PER_AD_TYPE,
7331
8064
  ALL_ZALO_ADS_DOMAINS,
@@ -7337,12 +8070,17 @@ export {
7337
8070
  AutomatedRuleTimeRangeEnum,
7338
8071
  ConversionLabelEnum,
7339
8072
  ConversionUrlTypeEnum,
8073
+ MAX_REPORT_RANGE_MS,
8074
+ MAX_REPORT_RANGE_SECONDS,
7340
8075
  MemoryZaloSessionStore,
7341
8076
  RedisZaloSessionStore,
7342
8077
  TieredZaloSessionStore,
7343
8078
  VALID_AD_TYPES,
7344
8079
  VALID_CAMPAIGN_TYPES,
8080
+ VIETNAM_PHONE_REGEX,
7345
8081
  ZALO_NEW_REGION_PROVINCE_CODES,
8082
+ ZALO_PROFILE_ADS_PROVINCES,
8083
+ ZALO_PROFILE_ADS_SUB_CATEGORIES,
7346
8084
  ZALO_PROVINCE_MERGE_MAPPING,
7347
8085
  ZALO_REGION_PROVINCE_CODES,
7348
8086
  ZaloAccountService,
@@ -7396,8 +8134,11 @@ export {
7396
8134
  ZaloInstantPagesService,
7397
8135
  ZaloInstantPagesValidator,
7398
8136
  ZaloMediaService,
8137
+ ZaloMediaValidator,
7399
8138
  ZaloProfileAdsService,
8139
+ ZaloProfileAdsValidator,
7400
8140
  ZaloReportsService,
8141
+ ZaloReportsValidator,
7401
8142
  ZaloSdkError,
7402
8143
  ZaloSdkHttpClient,
7403
8144
  ZaloWidgetApiService,
@@ -7411,6 +8152,7 @@ export {
7411
8152
  validateChangeCampaignStatusParams,
7412
8153
  validateCloneInstantPageRequest,
7413
8154
  validateCreateCampaignPayload,
8155
+ validateCreateCustomAudienceRequest,
7414
8156
  validateCreateFlowRequest,
7415
8157
  validateCreateFormEventAudienceRequest,
7416
8158
  validateCreateFormRequest,
@@ -7418,8 +8160,11 @@ export {
7418
8160
  validateCreateLookalikeAudienceRequest,
7419
8161
  validateCreateMessageOaEventAudienceRequest,
7420
8162
  validateCreateMessagePersonalEventAudienceRequest,
8163
+ validateCreateOaPageRequest,
7421
8164
  validateCreatePhoneAudienceRequest,
7422
8165
  validateCreateSavedAudienceRequest,
8166
+ validateCropCoordinates,
8167
+ validateDateRangeReportRequest,
7423
8168
  validateDuplicateAdParams,
7424
8169
  validateEstimateAudienceRequest,
7425
8170
  validateGetInstantPageDetailRequest,
@@ -7435,10 +8180,17 @@ export {
7435
8180
  validateListMiniPageTemplatesRequest,
7436
8181
  validateListOfficialAccountsRequest,
7437
8182
  validateRenameCampaignParams,
8183
+ validateSaveMediaRequest,
7438
8184
  validateSearchInstantPagesRequest,
8185
+ validateToggleLeadNotificationRequest,
7439
8186
  validateUpdateAdPayload,
7440
8187
  validateUpdateFlowRequest,
7441
8188
  validateUpdateInstantPageRequest,
8189
+ validateUpdateInstantPageSharesRequest,
8190
+ validateUpdateLeadNotificationIntervalRequest,
8191
+ validateUploadCustomAudiencePhoneListRequest,
8192
+ validateUploadMediaRequest,
8193
+ validateUpsertCustomReportRequest,
7442
8194
  validateUpsertInstantPageFormRequest
7443
8195
  };
7444
8196
  //# sourceMappingURL=index.mjs.map