adapty 0.1.0 → 0.1.2

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,6 +3,7 @@ import open from 'open';
3
3
  import { ApiClient } from '../../lib/api-client.js';
4
4
  import { buildUserAgent } from '../../lib/client-from-config.js';
5
5
  import { readConfig, writeConfig } from '../../lib/config.js';
6
+ import { ApiError } from '../../lib/errors.js';
6
7
  function sleep(ms) {
7
8
  return new Promise((resolve) => {
8
9
  setTimeout(resolve, ms);
@@ -35,7 +36,7 @@ export default class AuthLogin extends Command {
35
36
  // browser open failed silently — URL already printed
36
37
  }
37
38
  this.log('Waiting for authorization...');
38
- let interval = device.interval * 1000;
39
+ let interval = Math.max((device.interval || 5) * 1000, 5000);
39
40
  const deadline = Date.now() + device.expires_in * 1000;
40
41
  let consecutiveErrors = 0;
41
42
  // Handle Ctrl+C
@@ -55,6 +56,27 @@ export default class AuthLogin extends Command {
55
56
  });
56
57
  }
57
58
  catch (error) {
59
+ if (error instanceof ApiError) {
60
+ switch (error.errorCode) {
61
+ case 'authorization_pending': {
62
+ continue;
63
+ }
64
+ case 'slow_down': {
65
+ interval += 5000;
66
+ continue;
67
+ }
68
+ case 'access_denied': {
69
+ this.error('Authorization denied.', { exit: 1 });
70
+ break;
71
+ }
72
+ case 'expired_token': {
73
+ this.error('Code expired. Run `adapty auth login` again.', { exit: 1 });
74
+ break;
75
+ }
76
+ default:
77
+ // unexpected API error — fall through to network error handling
78
+ }
79
+ }
58
80
  consecutiveErrors++;
59
81
  if (consecutiveErrors >= 10) {
60
82
  this.error('Too many consecutive network errors. Check your connection and try again.', { exit: 1 });
@@ -65,28 +87,6 @@ export default class AuthLogin extends Command {
65
87
  continue;
66
88
  }
67
89
  consecutiveErrors = 0;
68
- if ('error' in result) {
69
- switch (result.error) {
70
- case 'access_denied': {
71
- this.error('Authorization denied.', { exit: 1 });
72
- break;
73
- }
74
- case 'authorization_pending': {
75
- continue;
76
- }
77
- case 'slow_down': {
78
- interval += 5000;
79
- continue;
80
- }
81
- case 'expired_token': {
82
- this.error('Code expired. Run `adapty auth login` again.', { exit: 1 });
83
- break; // unreachable but satisfies linter
84
- }
85
- default: {
86
- this.error(`Unexpected error: ${result.error}`, { exit: 1 });
87
- }
88
- }
89
- }
90
90
  if ('access_token' in result) {
91
91
  await writeConfig({
92
92
  access_token: result.access_token,
@@ -1,5 +1,8 @@
1
1
  import { ApiError, NetworkError, parseApiError } from './errors.js';
2
2
  const DEFAULT_API_URL = 'https://api.adapty.io/api/v1/developer';
3
+ function ensureTrailingSlash(path) {
4
+ return path.endsWith('/') ? path : `${path}/`;
5
+ }
3
6
  export class ApiClient {
4
7
  baseUrl;
5
8
  token;
@@ -13,7 +16,7 @@ export class ApiClient {
13
16
  this.userAgent = opts.userAgent ?? 'adapty-cli';
14
17
  }
15
18
  async get(path, params) {
16
- let url = `${this.baseUrl}${path}`;
19
+ let url = `${this.baseUrl}${ensureTrailingSlash(path)}`;
17
20
  if (params) {
18
21
  const qs = new URLSearchParams(params);
19
22
  url += `?${qs.toString()}`;
@@ -21,13 +24,13 @@ export class ApiClient {
21
24
  return this.request(url, { method: 'GET' });
22
25
  }
23
26
  async post(path, body) {
24
- return this.request(`${this.baseUrl}${path}`, {
27
+ return this.request(`${this.baseUrl}${ensureTrailingSlash(path)}`, {
25
28
  body: body ? JSON.stringify(body) : undefined,
26
29
  method: 'POST',
27
30
  });
28
31
  }
29
32
  async put(path, body) {
30
- return this.request(`${this.baseUrl}${path}`, {
33
+ return this.request(`${this.baseUrl}${ensureTrailingSlash(path)}`, {
31
34
  body: body ? JSON.stringify(body) : undefined,
32
35
  method: 'PUT',
33
36
  });
@@ -765,12 +765,12 @@
765
765
  "update.js"
766
766
  ]
767
767
  },
768
- "placements:create": {
768
+ "products:create": {
769
769
  "aliases": [],
770
770
  "args": {},
771
- "description": "Create a placement with a paywall",
771
+ "description": "Create a product with vendor products per platform",
772
772
  "examples": [
773
- "<%= config.bin %> placements create --app UUID --name \"Default\" --developer-id default --paywall-id UUID"
773
+ "<%= config.bin %> products create --app UUID --name \"Monthly\" --access-level-id UUID --period monthly --ios-product-id com.example.monthly"
774
774
  ],
775
775
  "flags": {
776
776
  "json": {
@@ -788,25 +788,46 @@
788
788
  "multiple": false,
789
789
  "type": "option"
790
790
  },
791
- "developer-id": {
792
- "description": "Developer ID for the placement",
793
- "name": "developer-id",
791
+ "access-level-id": {
792
+ "description": "Access level ID (UUID)",
793
+ "name": "access-level-id",
794
794
  "required": true,
795
795
  "hasDynamicHelp": false,
796
796
  "multiple": false,
797
797
  "type": "option"
798
798
  },
799
+ "android-base-plan-id": {
800
+ "description": "Android base plan ID",
801
+ "name": "android-base-plan-id",
802
+ "hasDynamicHelp": false,
803
+ "multiple": false,
804
+ "type": "option"
805
+ },
806
+ "android-product-id": {
807
+ "description": "Android product ID",
808
+ "name": "android-product-id",
809
+ "hasDynamicHelp": false,
810
+ "multiple": false,
811
+ "type": "option"
812
+ },
813
+ "ios-product-id": {
814
+ "description": "iOS product ID",
815
+ "name": "ios-product-id",
816
+ "hasDynamicHelp": false,
817
+ "multiple": false,
818
+ "type": "option"
819
+ },
799
820
  "name": {
800
- "description": "Placement name",
821
+ "description": "Product name",
801
822
  "name": "name",
802
823
  "required": true,
803
824
  "hasDynamicHelp": false,
804
825
  "multiple": false,
805
826
  "type": "option"
806
827
  },
807
- "paywall-id": {
808
- "description": "Paywall ID (UUID)",
809
- "name": "paywall-id",
828
+ "period": {
829
+ "description": "Subscription period (weekly, monthly, 2_months, 3_months, 6_months, yearly, lifetime)",
830
+ "name": "period",
810
831
  "required": true,
811
832
  "hasDynamicHelp": false,
812
833
  "multiple": false,
@@ -815,7 +836,7 @@
815
836
  },
816
837
  "hasDynamicHelp": false,
817
838
  "hiddenAliases": [],
818
- "id": "placements:create",
839
+ "id": "products:create",
819
840
  "pluginAlias": "adapty",
820
841
  "pluginName": "adapty",
821
842
  "pluginType": "core",
@@ -825,22 +846,22 @@
825
846
  "relativePath": [
826
847
  "dist",
827
848
  "commands",
828
- "placements",
849
+ "products",
829
850
  "create.js"
830
851
  ]
831
852
  },
832
- "placements:get": {
853
+ "products:get": {
833
854
  "aliases": [],
834
855
  "args": {
835
- "placement_id": {
836
- "description": "Placement ID (UUID)",
837
- "name": "placement_id",
856
+ "product_id": {
857
+ "description": "Product ID (UUID)",
858
+ "name": "product_id",
838
859
  "required": true
839
860
  }
840
861
  },
841
- "description": "Get placement details",
862
+ "description": "Get product details",
842
863
  "examples": [
843
- "<%= config.bin %> placements get --app UUID 550e8400-e29b-41d4-a716-446655440000"
864
+ "<%= config.bin %> products get --app UUID 550e8400-e29b-41d4-a716-446655440000"
844
865
  ],
845
866
  "flags": {
846
867
  "json": {
@@ -861,7 +882,7 @@
861
882
  },
862
883
  "hasDynamicHelp": false,
863
884
  "hiddenAliases": [],
864
- "id": "placements:get",
885
+ "id": "products:get",
865
886
  "pluginAlias": "adapty",
866
887
  "pluginName": "adapty",
867
888
  "pluginType": "core",
@@ -871,16 +892,16 @@
871
892
  "relativePath": [
872
893
  "dist",
873
894
  "commands",
874
- "placements",
895
+ "products",
875
896
  "get.js"
876
897
  ]
877
898
  },
878
- "placements:list": {
899
+ "products:list": {
879
900
  "aliases": [],
880
901
  "args": {},
881
- "description": "List placements for an app",
902
+ "description": "List products for an app",
882
903
  "examples": [
883
- "<%= config.bin %> placements list --app 550e8400-..."
904
+ "<%= config.bin %> products list --app 550e8400-..."
884
905
  ],
885
906
  "flags": {
886
907
  "json": {
@@ -917,7 +938,7 @@
917
938
  },
918
939
  "hasDynamicHelp": false,
919
940
  "hiddenAliases": [],
920
- "id": "placements:list",
941
+ "id": "products:list",
921
942
  "pluginAlias": "adapty",
922
943
  "pluginName": "adapty",
923
944
  "pluginType": "core",
@@ -927,22 +948,22 @@
927
948
  "relativePath": [
928
949
  "dist",
929
950
  "commands",
930
- "placements",
951
+ "products",
931
952
  "list.js"
932
953
  ]
933
954
  },
934
- "placements:update": {
955
+ "products:update": {
935
956
  "aliases": [],
936
957
  "args": {
937
- "placement_id": {
938
- "description": "Placement ID (UUID)",
939
- "name": "placement_id",
958
+ "product_id": {
959
+ "description": "Product ID (UUID)",
960
+ "name": "product_id",
940
961
  "required": true
941
962
  }
942
963
  },
943
- "description": "Update a placement",
964
+ "description": "Update a product",
944
965
  "examples": [
945
- "<%= config.bin %> placements update --app UUID 550e8400-... --name \"Default\" --developer-id default --paywall-id UUID"
966
+ "<%= config.bin %> products update --app UUID 550e8400-... --name \"Monthly\" --access-level-id UUID --period monthly --ios-product-id com.example.monthly"
946
967
  ],
947
968
  "flags": {
948
969
  "json": {
@@ -960,25 +981,46 @@
960
981
  "multiple": false,
961
982
  "type": "option"
962
983
  },
963
- "developer-id": {
964
- "description": "Developer ID for the placement",
965
- "name": "developer-id",
984
+ "access-level-id": {
985
+ "description": "Access level ID (UUID)",
986
+ "name": "access-level-id",
966
987
  "required": true,
967
988
  "hasDynamicHelp": false,
968
989
  "multiple": false,
969
990
  "type": "option"
970
991
  },
992
+ "android-base-plan-id": {
993
+ "description": "Android base plan ID",
994
+ "name": "android-base-plan-id",
995
+ "hasDynamicHelp": false,
996
+ "multiple": false,
997
+ "type": "option"
998
+ },
999
+ "android-product-id": {
1000
+ "description": "Android product ID",
1001
+ "name": "android-product-id",
1002
+ "hasDynamicHelp": false,
1003
+ "multiple": false,
1004
+ "type": "option"
1005
+ },
1006
+ "ios-product-id": {
1007
+ "description": "iOS product ID",
1008
+ "name": "ios-product-id",
1009
+ "hasDynamicHelp": false,
1010
+ "multiple": false,
1011
+ "type": "option"
1012
+ },
971
1013
  "name": {
972
- "description": "Placement name",
1014
+ "description": "Product name",
973
1015
  "name": "name",
974
1016
  "required": true,
975
1017
  "hasDynamicHelp": false,
976
1018
  "multiple": false,
977
1019
  "type": "option"
978
1020
  },
979
- "paywall-id": {
980
- "description": "Paywall ID (UUID)",
981
- "name": "paywall-id",
1021
+ "period": {
1022
+ "description": "Subscription period (weekly, monthly, 2_months, 3_months, 6_months, yearly, lifetime)",
1023
+ "name": "period",
982
1024
  "required": true,
983
1025
  "hasDynamicHelp": false,
984
1026
  "multiple": false,
@@ -987,7 +1029,7 @@
987
1029
  },
988
1030
  "hasDynamicHelp": false,
989
1031
  "hiddenAliases": [],
990
- "id": "placements:update",
1032
+ "id": "products:update",
991
1033
  "pluginAlias": "adapty",
992
1034
  "pluginName": "adapty",
993
1035
  "pluginType": "core",
@@ -997,16 +1039,16 @@
997
1039
  "relativePath": [
998
1040
  "dist",
999
1041
  "commands",
1000
- "placements",
1042
+ "products",
1001
1043
  "update.js"
1002
1044
  ]
1003
1045
  },
1004
- "products:create": {
1046
+ "placements:create": {
1005
1047
  "aliases": [],
1006
1048
  "args": {},
1007
- "description": "Create a product with vendor products per platform",
1049
+ "description": "Create a placement with a paywall",
1008
1050
  "examples": [
1009
- "<%= config.bin %> products create --app UUID --name \"Monthly\" --access-level-id UUID --period monthly --ios-product-id com.example.monthly"
1051
+ "<%= config.bin %> placements create --app UUID --name \"Default\" --developer-id default --paywall-id UUID"
1010
1052
  ],
1011
1053
  "flags": {
1012
1054
  "json": {
@@ -1024,46 +1066,25 @@
1024
1066
  "multiple": false,
1025
1067
  "type": "option"
1026
1068
  },
1027
- "access-level-id": {
1028
- "description": "Access level ID (UUID)",
1029
- "name": "access-level-id",
1069
+ "developer-id": {
1070
+ "description": "Developer ID for the placement",
1071
+ "name": "developer-id",
1030
1072
  "required": true,
1031
1073
  "hasDynamicHelp": false,
1032
1074
  "multiple": false,
1033
1075
  "type": "option"
1034
1076
  },
1035
- "android-base-plan-id": {
1036
- "description": "Android base plan ID",
1037
- "name": "android-base-plan-id",
1038
- "hasDynamicHelp": false,
1039
- "multiple": false,
1040
- "type": "option"
1041
- },
1042
- "android-product-id": {
1043
- "description": "Android product ID",
1044
- "name": "android-product-id",
1045
- "hasDynamicHelp": false,
1046
- "multiple": false,
1047
- "type": "option"
1048
- },
1049
- "ios-product-id": {
1050
- "description": "iOS product ID",
1051
- "name": "ios-product-id",
1052
- "hasDynamicHelp": false,
1053
- "multiple": false,
1054
- "type": "option"
1055
- },
1056
1077
  "name": {
1057
- "description": "Product name",
1078
+ "description": "Placement name",
1058
1079
  "name": "name",
1059
1080
  "required": true,
1060
1081
  "hasDynamicHelp": false,
1061
1082
  "multiple": false,
1062
1083
  "type": "option"
1063
1084
  },
1064
- "period": {
1065
- "description": "Subscription period (weekly, monthly, 2_months, 3_months, 6_months, yearly, lifetime)",
1066
- "name": "period",
1085
+ "paywall-id": {
1086
+ "description": "Paywall ID (UUID)",
1087
+ "name": "paywall-id",
1067
1088
  "required": true,
1068
1089
  "hasDynamicHelp": false,
1069
1090
  "multiple": false,
@@ -1072,7 +1093,7 @@
1072
1093
  },
1073
1094
  "hasDynamicHelp": false,
1074
1095
  "hiddenAliases": [],
1075
- "id": "products:create",
1096
+ "id": "placements:create",
1076
1097
  "pluginAlias": "adapty",
1077
1098
  "pluginName": "adapty",
1078
1099
  "pluginType": "core",
@@ -1082,22 +1103,22 @@
1082
1103
  "relativePath": [
1083
1104
  "dist",
1084
1105
  "commands",
1085
- "products",
1106
+ "placements",
1086
1107
  "create.js"
1087
1108
  ]
1088
1109
  },
1089
- "products:get": {
1110
+ "placements:get": {
1090
1111
  "aliases": [],
1091
1112
  "args": {
1092
- "product_id": {
1093
- "description": "Product ID (UUID)",
1094
- "name": "product_id",
1113
+ "placement_id": {
1114
+ "description": "Placement ID (UUID)",
1115
+ "name": "placement_id",
1095
1116
  "required": true
1096
1117
  }
1097
1118
  },
1098
- "description": "Get product details",
1119
+ "description": "Get placement details",
1099
1120
  "examples": [
1100
- "<%= config.bin %> products get --app UUID 550e8400-e29b-41d4-a716-446655440000"
1121
+ "<%= config.bin %> placements get --app UUID 550e8400-e29b-41d4-a716-446655440000"
1101
1122
  ],
1102
1123
  "flags": {
1103
1124
  "json": {
@@ -1118,7 +1139,7 @@
1118
1139
  },
1119
1140
  "hasDynamicHelp": false,
1120
1141
  "hiddenAliases": [],
1121
- "id": "products:get",
1142
+ "id": "placements:get",
1122
1143
  "pluginAlias": "adapty",
1123
1144
  "pluginName": "adapty",
1124
1145
  "pluginType": "core",
@@ -1128,16 +1149,16 @@
1128
1149
  "relativePath": [
1129
1150
  "dist",
1130
1151
  "commands",
1131
- "products",
1152
+ "placements",
1132
1153
  "get.js"
1133
1154
  ]
1134
1155
  },
1135
- "products:list": {
1156
+ "placements:list": {
1136
1157
  "aliases": [],
1137
1158
  "args": {},
1138
- "description": "List products for an app",
1159
+ "description": "List placements for an app",
1139
1160
  "examples": [
1140
- "<%= config.bin %> products list --app 550e8400-..."
1161
+ "<%= config.bin %> placements list --app 550e8400-..."
1141
1162
  ],
1142
1163
  "flags": {
1143
1164
  "json": {
@@ -1174,7 +1195,7 @@
1174
1195
  },
1175
1196
  "hasDynamicHelp": false,
1176
1197
  "hiddenAliases": [],
1177
- "id": "products:list",
1198
+ "id": "placements:list",
1178
1199
  "pluginAlias": "adapty",
1179
1200
  "pluginName": "adapty",
1180
1201
  "pluginType": "core",
@@ -1184,22 +1205,22 @@
1184
1205
  "relativePath": [
1185
1206
  "dist",
1186
1207
  "commands",
1187
- "products",
1208
+ "placements",
1188
1209
  "list.js"
1189
1210
  ]
1190
1211
  },
1191
- "products:update": {
1212
+ "placements:update": {
1192
1213
  "aliases": [],
1193
1214
  "args": {
1194
- "product_id": {
1195
- "description": "Product ID (UUID)",
1196
- "name": "product_id",
1215
+ "placement_id": {
1216
+ "description": "Placement ID (UUID)",
1217
+ "name": "placement_id",
1197
1218
  "required": true
1198
1219
  }
1199
1220
  },
1200
- "description": "Update a product",
1221
+ "description": "Update a placement",
1201
1222
  "examples": [
1202
- "<%= config.bin %> products update --app UUID 550e8400-... --name \"Monthly\" --access-level-id UUID --period monthly --ios-product-id com.example.monthly"
1223
+ "<%= config.bin %> placements update --app UUID 550e8400-... --name \"Default\" --developer-id default --paywall-id UUID"
1203
1224
  ],
1204
1225
  "flags": {
1205
1226
  "json": {
@@ -1217,46 +1238,25 @@
1217
1238
  "multiple": false,
1218
1239
  "type": "option"
1219
1240
  },
1220
- "access-level-id": {
1221
- "description": "Access level ID (UUID)",
1222
- "name": "access-level-id",
1241
+ "developer-id": {
1242
+ "description": "Developer ID for the placement",
1243
+ "name": "developer-id",
1223
1244
  "required": true,
1224
1245
  "hasDynamicHelp": false,
1225
1246
  "multiple": false,
1226
1247
  "type": "option"
1227
1248
  },
1228
- "android-base-plan-id": {
1229
- "description": "Android base plan ID",
1230
- "name": "android-base-plan-id",
1231
- "hasDynamicHelp": false,
1232
- "multiple": false,
1233
- "type": "option"
1234
- },
1235
- "android-product-id": {
1236
- "description": "Android product ID",
1237
- "name": "android-product-id",
1238
- "hasDynamicHelp": false,
1239
- "multiple": false,
1240
- "type": "option"
1241
- },
1242
- "ios-product-id": {
1243
- "description": "iOS product ID",
1244
- "name": "ios-product-id",
1245
- "hasDynamicHelp": false,
1246
- "multiple": false,
1247
- "type": "option"
1248
- },
1249
1249
  "name": {
1250
- "description": "Product name",
1250
+ "description": "Placement name",
1251
1251
  "name": "name",
1252
1252
  "required": true,
1253
1253
  "hasDynamicHelp": false,
1254
1254
  "multiple": false,
1255
1255
  "type": "option"
1256
1256
  },
1257
- "period": {
1258
- "description": "Subscription period (weekly, monthly, 2_months, 3_months, 6_months, yearly, lifetime)",
1259
- "name": "period",
1257
+ "paywall-id": {
1258
+ "description": "Paywall ID (UUID)",
1259
+ "name": "paywall-id",
1260
1260
  "required": true,
1261
1261
  "hasDynamicHelp": false,
1262
1262
  "multiple": false,
@@ -1265,7 +1265,7 @@
1265
1265
  },
1266
1266
  "hasDynamicHelp": false,
1267
1267
  "hiddenAliases": [],
1268
- "id": "products:update",
1268
+ "id": "placements:update",
1269
1269
  "pluginAlias": "adapty",
1270
1270
  "pluginName": "adapty",
1271
1271
  "pluginType": "core",
@@ -1275,10 +1275,10 @@
1275
1275
  "relativePath": [
1276
1276
  "dist",
1277
1277
  "commands",
1278
- "products",
1278
+ "placements",
1279
1279
  "update.js"
1280
1280
  ]
1281
1281
  }
1282
1282
  },
1283
- "version": "0.1.0"
1283
+ "version": "0.1.2"
1284
1284
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "adapty",
3
3
  "description": "Adapty command line interface",
4
- "version": "0.1.0",
4
+ "version": "0.1.2",
5
5
  "author": "Adapty team <support@adapty.io>",
6
6
  "bin": {
7
7
  "adapty": "./bin/run.js"