@bprotsyk/aso-core 2.1.142 → 2.1.181

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.
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TraffleKeitaroService = exports.updateStreamsForApp = exports.ITraffleTrafficType = void 0;
6
+ exports.TraffleKeitaroService = exports.updateCampaignNamesToNewPattern = exports.updateStreamsForApp = exports.ITraffleTrafficType = void 0;
7
7
  const http_1 = __importDefault(require("./http"));
8
8
  const app_1 = require("../../../app/app");
9
9
  const openai_1 = require("../../../network/openai/openai");
@@ -290,6 +290,24 @@ async function checkAndUpdateCampaignParameters(existingCampaign, app, platform)
290
290
  return await updateCampaignWithAppParams(existingCampaign, app, platform);
291
291
  }
292
292
  console.log("Parameters are up to date, no update needed");
293
+ // Always add postback even if no parameter update is needed
294
+ try {
295
+ console.log(`[Traffle] Adding postback to campaign ${existingCampaign.id} (no parameter update needed)`);
296
+ const postbackUrl = `https://traffle-tech.com/lander/appsflyer-s2s/index.php?status={status}&bundle_id={sub_id_16}&advertising_id={sub_id_17}&appsflyer_device_id={sub_id_18}&appsflyer_dev_key={sub_id_19}`;
297
+ await http_1.default.put(`/campaigns/${existingCampaign.id}`, {
298
+ postbacks: [{
299
+ id: 0,
300
+ campaign_id: existingCampaign.id,
301
+ method: "GET",
302
+ statuses: ["lead", "sale", "rejected", "rebill"],
303
+ url: postbackUrl
304
+ }]
305
+ });
306
+ console.log(`[Traffle] Postback added to campaign ${existingCampaign.id}`);
307
+ }
308
+ catch (error) {
309
+ console.error(`[Traffle] Failed to add postback to campaign ${existingCampaign.id}:`, error);
310
+ }
293
311
  return false;
294
312
  }
295
313
  return false;
@@ -465,6 +483,7 @@ async function updateAppWithCampaignParams(existingCampaign, app, platform) {
465
483
  }
466
484
  }
467
485
  async function cloneTraffleCampaign(app, platform, addDefaultStreams) {
486
+ console.log(`[Traffle] cloneTraffleCampaign called for app ${app.id}, platform ${platform}, addDefaultStreams: ${addDefaultStreams}`);
468
487
  const ORIGINAL_CLONE_CAMPAIGN_ID = 1925;
469
488
  const appsflyerAvailability = app.platforms[platform].appsflyerParams?.apiToken ? "[AF]" : "";
470
489
  let name = `[${app.id}] [${app.bundle}] ${app.name} [Volodymyr Vinnik] [El Trafico] [Android] ${appsflyerAvailability} ${app.domainParams.name}`;
@@ -593,6 +612,24 @@ async function cloneTraffleCampaign(app, platform, addDefaultStreams) {
593
612
  }
594
613
  }
595
614
  }
615
+ // Add postback to existing campaign
616
+ try {
617
+ console.log(`[Traffle] Adding postback to existing campaign ${existingCampaign.id}`);
618
+ const postbackUrl = `https://traffle-tech.com/lander/appsflyer-s2s/index.php?status={status}&bundle_id={sub_id_16}&advertising_id={sub_id_17}&appsflyer_device_id={sub_id_18}&appsflyer_dev_key={sub_id_19}`;
619
+ await http_1.default.put(`/campaigns/${existingCampaign.id}`, {
620
+ postbacks: [{
621
+ id: 0,
622
+ campaign_id: existingCampaign.id,
623
+ method: "GET",
624
+ statuses: ["lead", "sale", "rejected", "rebill"],
625
+ url: postbackUrl
626
+ }]
627
+ });
628
+ console.log(`[Traffle] Postback added to campaign ${existingCampaign.id}`);
629
+ }
630
+ catch (error) {
631
+ console.error(`[Traffle] Failed to add postback to campaign ${existingCampaign.id}:`, error);
632
+ }
596
633
  console.log(existingCampaign);
597
634
  return existingCampaign;
598
635
  }
@@ -720,6 +757,24 @@ async function cloneTraffleCampaign(app, platform, addDefaultStreams) {
720
757
  await createStreamWithoutIds(stream, newCampaign.id);
721
758
  }
722
759
  const updatedCampaign = await getCampaignById(newCampaign.id);
760
+ // Add postback to new campaign
761
+ try {
762
+ console.log(`[Traffle] Adding postback to new campaign ${updatedCampaign.id}`);
763
+ const postbackUrl = `https://traffle-tech.com/lander/appsflyer-s2s/index.php?status={status}&bundle_id={sub_id_16}&advertising_id={sub_id_17}&appsflyer_device_id={sub_id_18}&appsflyer_dev_key={sub_id_19}`;
764
+ await http_1.default.put(`/campaigns/${updatedCampaign.id}`, {
765
+ postbacks: [{
766
+ id: 0,
767
+ campaign_id: updatedCampaign.id,
768
+ method: "GET",
769
+ statuses: ["lead", "sale", "rejected", "rebill"],
770
+ url: postbackUrl
771
+ }]
772
+ });
773
+ console.log(`[Traffle] Postback added to campaign ${updatedCampaign.id}`);
774
+ }
775
+ catch (error) {
776
+ console.error(`[Traffle] Failed to add postback to campaign ${updatedCampaign.id}:`, error);
777
+ }
723
778
  return updatedCampaign;
724
779
  }
725
780
  async function findCampaignForAppPlatform(app, platform) {
@@ -840,6 +895,183 @@ async function updateStreamsForApp(app, platform) {
840
895
  }
841
896
  }
842
897
  exports.updateStreamsForApp = updateStreamsForApp;
898
+ async function findCampaignsWithOldNamingPattern() {
899
+ try {
900
+ const allCampaigns = await getAllCampaigns();
901
+ // Pattern: [id] app_name [bundle] [platform] domain.com (flexible - ID is optional)
902
+ // We want to find campaigns that DON'T have [Volodymyr Vinnik] in them
903
+ const oldPatternCampaigns = allCampaigns.filter(campaign => {
904
+ const name = campaign.name;
905
+ // Check if it matches the old pattern: BAN_prefix [id] app_name [bundle] [platform] domain (flexible)
906
+ const oldPattern = /^(BAN[_\w.]*\s+)?(\[(\d+)\]\s+)?([^[]+)\s+\[([^\]]+)\]\s+\[([^\]]+)\]\s+(.+)$/;
907
+ const match = name.match(oldPattern);
908
+ if (!match)
909
+ return false;
910
+ // Check if it doesn't already have [Volodymyr Vinnik]
911
+ return !name.includes('[Volodymyr Vinnik]');
912
+ });
913
+ console.log(`Found ${oldPatternCampaigns.length} campaigns with old naming pattern`);
914
+ return oldPatternCampaigns;
915
+ }
916
+ catch (error) {
917
+ console.error("Error finding campaigns with old naming pattern:", error);
918
+ return [];
919
+ }
920
+ }
921
+ async function updateCampaignNameToNewPattern(campaign, requireConfirmation = false) {
922
+ try {
923
+ const name = campaign.name;
924
+ // Parse the old pattern: BAN_prefix [id] app_name [bundle] [platform] domain (flexible - BAN and ID are optional)
925
+ const oldPattern = /^(BAN[_\w.]*\s+)?(\[(\d+)\]\s+)?([^[]+)\s+\[([^\]]+)\]\s+\[([^\]]+)\]\s+(.+)$/;
926
+ const match = name.match(oldPattern);
927
+ if (!match) {
928
+ console.log(`Campaign ${campaign.id} doesn't match old pattern: ${name}`);
929
+ return false;
930
+ }
931
+ const [, banPrefix, , idFromName, appName, bundle, platform, domain] = match;
932
+ // Create new name based on what exists in original name
933
+ let newName;
934
+ if (banPrefix && idFromName) {
935
+ // Original had BAN and ID: BAN_prefix [id] [bundle] app_name [Volodymyr Vinnik] [El Trafico] [platform] domain
936
+ newName = `${banPrefix.trim()} [${idFromName}] [${bundle}] ${appName.trim()} [Volodymyr Vinnik] [El Trafico] [${platform}] ${domain}`;
937
+ }
938
+ else if (banPrefix && !idFromName) {
939
+ // Original had BAN but no ID: BAN_prefix [bundle] app_name [Volodymyr Vinnik] [El Trafico] [platform] domain
940
+ newName = `${banPrefix.trim()} [${bundle}] ${appName.trim()} [Volodymyr Vinnik] [El Trafico] [${platform}] ${domain}`;
941
+ }
942
+ else if (!banPrefix && idFromName) {
943
+ // Original had ID but no BAN: [id] [bundle] app_name [Volodymyr Vinnik] [El Trafico] [platform] domain
944
+ newName = `[${idFromName}] [${bundle}] ${appName.trim()} [Volodymyr Vinnik] [El Trafico] [${platform}] ${domain}`;
945
+ }
946
+ else {
947
+ // Original had neither BAN nor ID: [bundle] app_name [Volodymyr Vinnik] [El Trafico] [platform] domain
948
+ newName = `[${bundle}] ${appName.trim()} [Volodymyr Vinnik] [El Trafico] [${platform}] ${domain}`;
949
+ }
950
+ if (requireConfirmation) {
951
+ console.log(`\nCampaign ${campaign.id}:`);
952
+ console.log(`OLD: "${name}"`);
953
+ console.log(`NEW: "${newName}"`);
954
+ console.log(`\nDo you want to update this campaign? (y/n/s to skip all remaining):`);
955
+ const confirmed = await confirmUpdate();
956
+ if (!confirmed) {
957
+ console.log(`Skipped campaign ${campaign.id}`);
958
+ return false;
959
+ }
960
+ }
961
+ // Update the campaign
962
+ await http_1.default.put(`/campaigns/${campaign.id}`, { name: newName });
963
+ console.log(`Updated campaign ${campaign.id}: "${name}" → "${newName}"`);
964
+ return true;
965
+ }
966
+ catch (error) {
967
+ console.error(`Failed to update campaign ${campaign.id}:`, error);
968
+ return false;
969
+ }
970
+ }
971
+ // Helper function to handle user confirmation
972
+ async function confirmUpdate() {
973
+ const readline = require('readline');
974
+ const rl = readline.createInterface({
975
+ input: process.stdin,
976
+ output: process.stdout
977
+ });
978
+ return new Promise((resolve) => {
979
+ rl.question('', (answer) => {
980
+ rl.close();
981
+ const lowerAnswer = answer.toLowerCase().trim();
982
+ if (lowerAnswer === 's') {
983
+ // Skip all remaining
984
+ console.log("Skipping all remaining updates...");
985
+ process.exit(0);
986
+ }
987
+ resolve(lowerAnswer === 'y' || lowerAnswer === 'yes');
988
+ });
989
+ });
990
+ }
991
+ async function updateCampaignNamesToNewPattern(requireConfirmation = false) {
992
+ try {
993
+ console.log("Starting campaign name update process...");
994
+ const oldPatternCampaigns = await findCampaignsWithOldNamingPattern();
995
+ if (oldPatternCampaigns.length === 0) {
996
+ console.log("No campaigns found with old naming pattern");
997
+ return { updated: 0, failed: 0 };
998
+ }
999
+ console.log(`Found ${oldPatternCampaigns.length} campaigns to potentially update`);
1000
+ if (requireConfirmation) {
1001
+ console.log("Interactive mode: You will be asked to confirm each update");
1002
+ }
1003
+ let updated = 0;
1004
+ let failed = 0;
1005
+ for (const campaign of oldPatternCampaigns) {
1006
+ const success = await updateCampaignNameToNewPattern(campaign, requireConfirmation);
1007
+ if (success) {
1008
+ updated++;
1009
+ }
1010
+ else {
1011
+ failed++;
1012
+ }
1013
+ }
1014
+ console.log(`Campaign name update completed: ${updated} updated, ${failed} failed`);
1015
+ return { updated, failed };
1016
+ }
1017
+ catch (error) {
1018
+ console.error("Failed to update campaign names:", error);
1019
+ return { updated: 0, failed: 0 };
1020
+ }
1021
+ }
1022
+ exports.updateCampaignNamesToNewPattern = updateCampaignNamesToNewPattern;
1023
+ async function ensurePostbacksForCampaign(campaignId, appId, bundle) {
1024
+ try {
1025
+ console.log(`[Traffle] Starting ensurePostbacksForCampaign for campaign ${campaignId}, app ${appId}, bundle ${bundle}`);
1026
+ const postbackUrl = `https://traffle-tech.com/lander/appsflyer-s2s/index.php?status={status}&bundle_id={sub_id_16}&advertising_id={sub_id_17}&appsflyer_device_id={sub_id_18}&appsflyer_dev_key={sub_id_19}`;
1027
+ // Check if postback already exists
1028
+ console.log(`[Traffle] Getting existing postbacks for campaign ${campaignId}`);
1029
+ const existingPostbacks = await getCampaignPostbacks(campaignId);
1030
+ console.log(`[Traffle] Existing postbacks:`, existingPostbacks);
1031
+ const postbackExists = existingPostbacks?.some(postback => postback.url === postbackUrl &&
1032
+ postback.method === "GET" &&
1033
+ postback.statuses?.includes("lead"));
1034
+ if (postbackExists) {
1035
+ console.log(`[Traffle] AppsFlyer postback already exists for Traffle campaign ${campaignId}, skipping`);
1036
+ return;
1037
+ }
1038
+ const postbackData = {
1039
+ id: 0,
1040
+ campaign_id: campaignId,
1041
+ method: "GET",
1042
+ statuses: ["lead", "sale", "rejected", "rebill"],
1043
+ url: postbackUrl
1044
+ };
1045
+ console.log(`[Traffle] Adding AppsFlyer postback to Traffle campaign ${campaignId}:`, postbackData);
1046
+ // Use Traffle API to add postback via campaign update
1047
+ console.log(`[Traffle] Making PUT request to /campaigns/${campaignId} with postbacks:`, [postbackData]);
1048
+ const response = await http_1.default.put(`/campaigns/${campaignId}`, {
1049
+ postbacks: [postbackData]
1050
+ });
1051
+ console.log(`[Traffle] Postback creation response:`, response.status, response.data?.postbacks);
1052
+ if (response.status === 200) {
1053
+ console.log(`[Traffle] Successfully added AppsFlyer postback to Traffle campaign ${campaignId}`);
1054
+ }
1055
+ }
1056
+ catch (error) {
1057
+ console.error(`Failed to add AppsFlyer postback to Traffle campaign ${campaignId}:`, error);
1058
+ }
1059
+ }
1060
+ async function getCampaignPostbacks(campaignId) {
1061
+ try {
1062
+ console.log(`[Traffle] Getting postbacks for campaign ${campaignId}`);
1063
+ const response = await http_1.default.get(`/campaigns/${campaignId}`);
1064
+ console.log(`[Traffle] Campaign ${campaignId} response:`, response.status, response.data?.postbacks);
1065
+ if (response.status === 200 && response.data) {
1066
+ return response.data.postbacks || [];
1067
+ }
1068
+ return null;
1069
+ }
1070
+ catch (error) {
1071
+ console.error(`[Traffle] Failed to get postbacks for Traffle campaign ${campaignId}:`, error);
1072
+ return null;
1073
+ }
1074
+ }
843
1075
  exports.TraffleKeitaroService = {
844
- addOffersToTraffleKeitaro, getTraffleOffersGroups, getTraffleAffiliateNetworks, createGroup, deleteOfferById, getAllOffers, updateOfferLinkById, cloneTraffleCampaign, TrafleKeitaroParameters, updateStreamsForApp
1076
+ addOffersToTraffleKeitaro, getTraffleOffersGroups, getTraffleAffiliateNetworks, createGroup, deleteOfferById, getAllOffers, getAllCampaigns, updateOfferLinkById, cloneTraffleCampaign, TrafleKeitaroParameters, updateStreamsForApp, updateCampaignNamesToNewPattern
845
1077
  };
@@ -0,0 +1,31 @@
1
+ export interface WPConversion {
2
+ status: string;
3
+ regDate: Date;
4
+ qualDate: Date;
5
+ approveOrRejectDate: Date;
6
+ project: string;
7
+ offerName: string;
8
+ sum: number;
9
+ currency: string;
10
+ geo: string;
11
+ subId?: string;
12
+ clickId: string;
13
+ }
14
+ export interface ConversionComparison {
15
+ wpConversions: WPConversion[];
16
+ keitaroConversions: any[];
17
+ matches: {
18
+ wp: WPConversion;
19
+ keitaro: any;
20
+ }[];
21
+ mismatches: {
22
+ onlyInWP: WPConversion[];
23
+ onlyInKeitaro: any[];
24
+ };
25
+ rejected: {
26
+ wp: WPConversion[];
27
+ keitaro: any[];
28
+ };
29
+ }
30
+ export declare function parseWPConversions(filePath: string): Promise<WPConversion[]>;
31
+ export declare function compareConversions(wpFilePath: string, keitaroConversions: any[]): Promise<ConversionComparison>;
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.compareConversions = exports.parseWPConversions = void 0;
27
+ const sync_1 = require("csv-parse/sync");
28
+ const fs = __importStar(require("fs"));
29
+ function parseDate(dateStr) {
30
+ const [month, day, year] = dateStr.split('/').map(num => parseInt(num));
31
+ return new Date(2000 + year, month - 1, day);
32
+ }
33
+ async function parseWPConversions(filePath) {
34
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
35
+ const records = (0, sync_1.parse)(fileContent, {
36
+ delimiter: ';',
37
+ columns: true,
38
+ skip_empty_lines: true
39
+ });
40
+ return records.map((record) => ({
41
+ status: record.Status,
42
+ regDate: parseDate(record.RegDate),
43
+ qualDate: parseDate(record.QualDate),
44
+ approveOrRejectDate: parseDate(record.Approve_or_Reject_Date),
45
+ project: record.Project,
46
+ offerName: record.Offer_Name,
47
+ sum: parseFloat(record.Sum),
48
+ currency: record.Currency,
49
+ geo: record.Geo,
50
+ subId: record.Sub_ID || undefined,
51
+ clickId: record.Click_ID
52
+ }));
53
+ }
54
+ exports.parseWPConversions = parseWPConversions;
55
+ async function compareConversions(wpFilePath, keitaroConversions) {
56
+ const wpConversions = await parseWPConversions(wpFilePath);
57
+ const matches = [];
58
+ const onlyInWP = [];
59
+ const onlyInKeitaro = [];
60
+ const rejectedWP = [];
61
+ const rejectedKeitaro = [];
62
+ // Create a map of Keitaro conversions by their sub_id to match with WP's Click_ID
63
+ const keitaroMap = new Map(keitaroConversions.map(conv => [conv.sub_id, conv]));
64
+ // First, find matches and conversions only in WP
65
+ for (const wpConv of wpConversions) {
66
+ // Skip rejected conversions
67
+ if (wpConv.status === 'Удержан') {
68
+ rejectedWP.push(wpConv);
69
+ continue;
70
+ }
71
+ const keitaroMatch = keitaroMap.get(wpConv.clickId);
72
+ if (keitaroMatch) {
73
+ matches.push({ wp: wpConv, keitaro: keitaroMatch });
74
+ keitaroMap.delete(wpConv.clickId);
75
+ }
76
+ else {
77
+ onlyInWP.push(wpConv);
78
+ }
79
+ }
80
+ // Remaining conversions in keitaroMap are only in Keitaro
81
+ // We need to check their status before adding them to onlyInKeitaro
82
+ for (const [_, conv] of keitaroMap) {
83
+ if (conv.status === 'rejected') {
84
+ rejectedKeitaro.push(conv);
85
+ }
86
+ else {
87
+ onlyInKeitaro.push(conv);
88
+ }
89
+ }
90
+ return {
91
+ wpConversions: wpConversions.filter(conv => conv.status !== 'Удержан'),
92
+ keitaroConversions: keitaroConversions.filter(conv => conv.status !== 'rejected'),
93
+ matches,
94
+ mismatches: {
95
+ onlyInWP,
96
+ onlyInKeitaro
97
+ },
98
+ rejected: {
99
+ wp: rejectedWP,
100
+ keitaro: rejectedKeitaro
101
+ }
102
+ };
103
+ }
104
+ exports.compareConversions = compareConversions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bprotsyk/aso-core",
3
- "version": "2.1.142",
3
+ "version": "2.1.181",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "scripts": {
package/src/app/app.ts CHANGED
@@ -4,6 +4,15 @@ import mongoose, { Document, Model, model, PipelineStage, Schema, UpdateQuery, U
4
4
  import { AlternativeFullscreen } from "app/app-integration";
5
5
  const util = require("util")
6
6
 
7
+ export interface IAppsflyerPostback {
8
+ campaign_id: number
9
+ id: number
10
+ method: "GET" | "POST"
11
+ statuses: string[]
12
+ url: string
13
+ notes?: string
14
+ }
15
+
7
16
  export interface IApp extends Document {
8
17
  id: number
9
18
  enabled: boolean,
@@ -42,6 +51,7 @@ export interface IApp extends Document {
42
51
  ech?: boolean,
43
52
  imageFormat: EImageFormat
44
53
  policyPath: string
54
+ postbacks?: IAppsflyerPostback[]
45
55
  }
46
56
 
47
57
  export enum EImageFormat {
@@ -390,7 +400,34 @@ export const AppSchema = new Schema({
390
400
  policyPath: {
391
401
  type: String,
392
402
  default: "none"
393
- }
403
+ },
404
+ postbacks: [{
405
+ campaign_id: {
406
+ type: Number,
407
+ required: true
408
+ },
409
+ id: {
410
+ type: Number,
411
+ required: true
412
+ },
413
+ method: {
414
+ type: String,
415
+ enum: ["GET", "POST"],
416
+ required: true
417
+ },
418
+ statuses: [{
419
+ type: String,
420
+ required: true
421
+ }],
422
+ url: {
423
+ type: String,
424
+ required: true
425
+ },
426
+ notes: {
427
+ type: String,
428
+ required: false
429
+ }
430
+ }]
394
431
  })
395
432
 
396
433
 
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ export { IOffer, IPartner, IOfferType } from "./offers/offer"
4
4
  export { IOffersSection, OffersSectionSchema, DefaultSectionId } from "./offers/section"
5
5
  export { IAppOffersSection, ISectionsList, SectionsListSchema, IOfferState } from "./offers/list"
6
6
 
7
- export { IAdjustEventIds, IntegrationVersion, IApp, AppSchema, PlugType, IAppKeitaroData, IExternalParams, IPlatformParams, EPlatform, AppStatus, IPublicationHistory, IRemovalInfo, EDirectType } from "./app/app"
7
+ export { IAdjustEventIds, IntegrationVersion, IApp, AppSchema, PlugType, IAppKeitaroData, IExternalParams, IPlatformParams, EPlatform, AppStatus, IPublicationHistory, IRemovalInfo, EDirectType, IAppsflyerPostback } from "./app/app"
8
8
  export { IAppListItem } from "./app/app-list-item"
9
9
  export { AppType } from "./app/app-type"
10
10
  export { AlternativeLayoutType, AlternativeSourceType, AlternativeLogicType, AlternativeNetworkTool, AlternativeStorageType, AlternativeNavigation, AlternativeOnBackPressed, AlternativeOnActivityResult, IAppIntegration as IFlashIntegration } from "./app/app-integration"