@schematichq/schematic-react 1.5.0 → 1.7.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/README.md +80 -2
- package/dist/schematic-react.cjs.js +1633 -54
- package/dist/schematic-react.d.ts +851 -4
- package/dist/schematic-react.esm.js +1633 -54
- package/package.json +27 -31
|
@@ -30,23 +30,38 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
BillingDataProvider: () => BillingDataProvider,
|
|
34
|
+
BillingProvider: () => BillingProvider,
|
|
35
|
+
DEFAULT_INVOICE_QUERY: () => DEFAULT_INVOICE_QUERY,
|
|
36
|
+
INVOICE_PAGE_SIZE: () => INVOICE_PAGE_SIZE,
|
|
37
|
+
InvoiceStatus: () => InvoiceStatus,
|
|
33
38
|
RuleType: () => RuleType,
|
|
34
39
|
Schematic: () => Schematic,
|
|
40
|
+
SchematicI18nContext: () => SchematicI18nContext,
|
|
41
|
+
SchematicI18nProvider: () => SchematicI18nProvider,
|
|
35
42
|
SchematicProvider: () => SchematicProvider,
|
|
36
43
|
TrialStatus: () => TrialStatus,
|
|
37
44
|
UsagePeriod: () => UsagePeriod,
|
|
45
|
+
normalizeInvoiceQuery: () => normalizeInvoiceQuery2,
|
|
46
|
+
useBillingDataSource: () => useBillingDataSource,
|
|
47
|
+
useInvalidateBillingData: () => useInvalidateBillingData,
|
|
48
|
+
useInvoices: () => useInvoices,
|
|
38
49
|
useSchematic: () => useSchematic,
|
|
39
50
|
useSchematicContext: () => useSchematicContext,
|
|
40
51
|
useSchematicCreditBalance: () => useSchematicCreditBalance,
|
|
41
52
|
useSchematicEntitlement: () => useSchematicEntitlement,
|
|
42
53
|
useSchematicEvents: () => useSchematicEvents,
|
|
43
54
|
useSchematicFlag: () => useSchematicFlag,
|
|
55
|
+
useSchematicI18n: () => useSchematicI18n,
|
|
44
56
|
useSchematicIsPending: () => useSchematicIsPending,
|
|
45
|
-
|
|
57
|
+
useSchematicLocale: () => useSchematicLocale,
|
|
58
|
+
useSchematicPlan: () => useSchematicPlan,
|
|
59
|
+
useSchematicStrings: () => useSchematicStrings,
|
|
60
|
+
useSchematicTranslate: () => useSchematicTranslate
|
|
46
61
|
});
|
|
47
62
|
module.exports = __toCommonJS(index_exports);
|
|
48
63
|
|
|
49
|
-
// node_modules/@schematichq/schematic-js/dist/schematic.esm.js
|
|
64
|
+
// node_modules/.pnpm/@schematichq+schematic-js@1.8.0/node_modules/@schematichq/schematic-js/dist/schematic.esm.js
|
|
50
65
|
var __create2 = Object.create;
|
|
51
66
|
var __defProp2 = Object.defineProperty;
|
|
52
67
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
@@ -60,6 +75,10 @@ var __commonJS = (cb, mod) => function __require() {
|
|
|
60
75
|
throw mod = 0, e;
|
|
61
76
|
}
|
|
62
77
|
};
|
|
78
|
+
var __export2 = (target, all) => {
|
|
79
|
+
for (var name in all)
|
|
80
|
+
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
81
|
+
};
|
|
63
82
|
var __copyProps2 = (to, from, except, desc) => {
|
|
64
83
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
65
84
|
for (let key of __getOwnPropNames2(from))
|
|
@@ -77,7 +96,7 @@ var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__
|
|
|
77
96
|
mod
|
|
78
97
|
));
|
|
79
98
|
var require_browser_polyfill = __commonJS({
|
|
80
|
-
"node_modules/cross-fetch/dist/browser-polyfill.js"(exports) {
|
|
99
|
+
"node_modules/.pnpm/cross-fetch@4.1.0/node_modules/cross-fetch/dist/browser-polyfill.js"(exports) {
|
|
81
100
|
(function(self2) {
|
|
82
101
|
var irrelevant = (function(exports2) {
|
|
83
102
|
var g = typeof globalThis !== "undefined" && globalThis || typeof self2 !== "undefined" && self2 || // eslint-disable-next-line no-undef
|
|
@@ -661,6 +680,18 @@ function MetricPeriodMonthResetFromJSON(json) {
|
|
|
661
680
|
function MetricPeriodMonthResetFromJSONTyped(json, ignoreDiscriminator) {
|
|
662
681
|
return json;
|
|
663
682
|
}
|
|
683
|
+
function WarningTierFromJSON(json) {
|
|
684
|
+
return WarningTierFromJSONTyped(json, false);
|
|
685
|
+
}
|
|
686
|
+
function WarningTierFromJSONTyped(json, ignoreDiscriminator) {
|
|
687
|
+
if (json == null) {
|
|
688
|
+
return json;
|
|
689
|
+
}
|
|
690
|
+
return {
|
|
691
|
+
key: json["key"],
|
|
692
|
+
value: json["value"]
|
|
693
|
+
};
|
|
694
|
+
}
|
|
664
695
|
function MetricPeriodFromJSON(json) {
|
|
665
696
|
return MetricPeriodFromJSONTyped(json, false);
|
|
666
697
|
}
|
|
@@ -692,7 +723,8 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
692
723
|
monthReset: json["month_reset"] == null ? void 0 : MetricPeriodMonthResetFromJSON(json["month_reset"]),
|
|
693
724
|
softLimit: json["soft_limit"] == null ? void 0 : json["soft_limit"],
|
|
694
725
|
usage: json["usage"] == null ? void 0 : json["usage"],
|
|
695
|
-
valueType: EntitlementValueTypeFromJSON(json["value_type"])
|
|
726
|
+
valueType: EntitlementValueTypeFromJSON(json["value_type"]),
|
|
727
|
+
warningTiers: json["warning_tiers"] == null ? void 0 : json["warning_tiers"].map(WarningTierFromJSON)
|
|
696
728
|
};
|
|
697
729
|
}
|
|
698
730
|
function RuleTypeFromJSON(json) {
|
|
@@ -1062,6 +1094,7 @@ function EventBodyFlagCheckToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
1062
1094
|
error: value["error"],
|
|
1063
1095
|
flag_id: value["flagId"],
|
|
1064
1096
|
flag_key: value["flagKey"],
|
|
1097
|
+
preflight: value["preflight"],
|
|
1065
1098
|
reason: value["reason"],
|
|
1066
1099
|
req_company: value["reqCompany"],
|
|
1067
1100
|
req_user: value["reqUser"],
|
|
@@ -1133,7 +1166,8 @@ var CheckFlagReturnFromJSON = (json) => {
|
|
|
1133
1166
|
ruleType: ruleType == null ? void 0 : ruleType,
|
|
1134
1167
|
softLimit: entitlement?.softLimit == null ? void 0 : entitlement.softLimit,
|
|
1135
1168
|
userId: userId == null ? void 0 : userId,
|
|
1136
|
-
value
|
|
1169
|
+
value,
|
|
1170
|
+
warningTiers: entitlement?.warningTiers == null ? void 0 : entitlement.warningTiers
|
|
1137
1171
|
};
|
|
1138
1172
|
};
|
|
1139
1173
|
var CheckPlanReturnFromJSON = (json) => {
|
|
@@ -1160,7 +1194,7 @@ var CreditBalancesFromJSON = (json) => {
|
|
|
1160
1194
|
}
|
|
1161
1195
|
return balances;
|
|
1162
1196
|
};
|
|
1163
|
-
var cacheVersion = "
|
|
1197
|
+
var cacheVersion = "7b920cf4";
|
|
1164
1198
|
function contextString(context) {
|
|
1165
1199
|
const sortedContext = Object.keys(context).reduce((acc, key) => {
|
|
1166
1200
|
const sortedKeys = Object.keys(
|
|
@@ -1175,16 +1209,695 @@ function contextString(context) {
|
|
|
1175
1209
|
}, {});
|
|
1176
1210
|
return JSON.stringify(sortedContext);
|
|
1177
1211
|
}
|
|
1178
|
-
var version = "1.
|
|
1212
|
+
var version = "1.8.0";
|
|
1213
|
+
var models_exports = {};
|
|
1214
|
+
__export2(models_exports, {
|
|
1215
|
+
ApiErrorFromJSON: () => ApiErrorFromJSON,
|
|
1216
|
+
ApiErrorFromJSONTyped: () => ApiErrorFromJSONTyped,
|
|
1217
|
+
ApiErrorToJSON: () => ApiErrorToJSON,
|
|
1218
|
+
ApiErrorToJSONTyped: () => ApiErrorToJSONTyped,
|
|
1219
|
+
CompanyDiscountResponseDataFromJSON: () => CompanyDiscountResponseDataFromJSON,
|
|
1220
|
+
CompanyDiscountResponseDataFromJSONTyped: () => CompanyDiscountResponseDataFromJSONTyped,
|
|
1221
|
+
CompanyDiscountResponseDataToJSON: () => CompanyDiscountResponseDataToJSON,
|
|
1222
|
+
CompanyDiscountResponseDataToJSONTyped: () => CompanyDiscountResponseDataToJSONTyped,
|
|
1223
|
+
CompanyInvoiceResponseDataFromJSON: () => CompanyInvoiceResponseDataFromJSON,
|
|
1224
|
+
CompanyInvoiceResponseDataFromJSONTyped: () => CompanyInvoiceResponseDataFromJSONTyped,
|
|
1225
|
+
CompanyInvoiceResponseDataToJSON: () => CompanyInvoiceResponseDataToJSON,
|
|
1226
|
+
CompanyInvoiceResponseDataToJSONTyped: () => CompanyInvoiceResponseDataToJSONTyped,
|
|
1227
|
+
CompanyInvoicesResponseDataFromJSON: () => CompanyInvoicesResponseDataFromJSON,
|
|
1228
|
+
CompanyInvoicesResponseDataFromJSONTyped: () => CompanyInvoicesResponseDataFromJSONTyped,
|
|
1229
|
+
CompanyInvoicesResponseDataToJSON: () => CompanyInvoicesResponseDataToJSON,
|
|
1230
|
+
CompanyInvoicesResponseDataToJSONTyped: () => CompanyInvoicesResponseDataToJSONTyped,
|
|
1231
|
+
CompanyUpcomingInvoiceResponseDataFromJSON: () => CompanyUpcomingInvoiceResponseDataFromJSON,
|
|
1232
|
+
CompanyUpcomingInvoiceResponseDataFromJSONTyped: () => CompanyUpcomingInvoiceResponseDataFromJSONTyped,
|
|
1233
|
+
CompanyUpcomingInvoiceResponseDataToJSON: () => CompanyUpcomingInvoiceResponseDataToJSON,
|
|
1234
|
+
CompanyUpcomingInvoiceResponseDataToJSONTyped: () => CompanyUpcomingInvoiceResponseDataToJSONTyped,
|
|
1235
|
+
GetCompanyInvoicesParamsFromJSON: () => GetCompanyInvoicesParamsFromJSON,
|
|
1236
|
+
GetCompanyInvoicesParamsFromJSONTyped: () => GetCompanyInvoicesParamsFromJSONTyped,
|
|
1237
|
+
GetCompanyInvoicesParamsToJSON: () => GetCompanyInvoicesParamsToJSON,
|
|
1238
|
+
GetCompanyInvoicesParamsToJSONTyped: () => GetCompanyInvoicesParamsToJSONTyped,
|
|
1239
|
+
GetCompanyInvoicesResponseFromJSON: () => GetCompanyInvoicesResponseFromJSON,
|
|
1240
|
+
GetCompanyInvoicesResponseFromJSONTyped: () => GetCompanyInvoicesResponseFromJSONTyped,
|
|
1241
|
+
GetCompanyInvoicesResponseToJSON: () => GetCompanyInvoicesResponseToJSON,
|
|
1242
|
+
GetCompanyInvoicesResponseToJSONTyped: () => GetCompanyInvoicesResponseToJSONTyped,
|
|
1243
|
+
GetCompanyUpcomingInvoiceResponseFromJSON: () => GetCompanyUpcomingInvoiceResponseFromJSON,
|
|
1244
|
+
GetCompanyUpcomingInvoiceResponseFromJSONTyped: () => GetCompanyUpcomingInvoiceResponseFromJSONTyped,
|
|
1245
|
+
GetCompanyUpcomingInvoiceResponseToJSON: () => GetCompanyUpcomingInvoiceResponseToJSON,
|
|
1246
|
+
GetCompanyUpcomingInvoiceResponseToJSONTyped: () => GetCompanyUpcomingInvoiceResponseToJSONTyped,
|
|
1247
|
+
InvoiceStatus: () => InvoiceStatus,
|
|
1248
|
+
InvoiceStatusFromJSON: () => InvoiceStatusFromJSON,
|
|
1249
|
+
InvoiceStatusFromJSONTyped: () => InvoiceStatusFromJSONTyped,
|
|
1250
|
+
InvoiceStatusToJSON: () => InvoiceStatusToJSON,
|
|
1251
|
+
InvoiceStatusToJSONTyped: () => InvoiceStatusToJSONTyped,
|
|
1252
|
+
instanceOfApiError: () => instanceOfApiError,
|
|
1253
|
+
instanceOfCompanyDiscountResponseData: () => instanceOfCompanyDiscountResponseData,
|
|
1254
|
+
instanceOfCompanyInvoiceResponseData: () => instanceOfCompanyInvoiceResponseData,
|
|
1255
|
+
instanceOfCompanyInvoicesResponseData: () => instanceOfCompanyInvoicesResponseData,
|
|
1256
|
+
instanceOfCompanyUpcomingInvoiceResponseData: () => instanceOfCompanyUpcomingInvoiceResponseData,
|
|
1257
|
+
instanceOfGetCompanyInvoicesParams: () => instanceOfGetCompanyInvoicesParams,
|
|
1258
|
+
instanceOfGetCompanyInvoicesResponse: () => instanceOfGetCompanyInvoicesResponse,
|
|
1259
|
+
instanceOfGetCompanyUpcomingInvoiceResponse: () => instanceOfGetCompanyUpcomingInvoiceResponse,
|
|
1260
|
+
instanceOfInvoiceStatus: () => instanceOfInvoiceStatus
|
|
1261
|
+
});
|
|
1262
|
+
function instanceOfApiError(value) {
|
|
1263
|
+
if (!("error" in value) || value["error"] === void 0) return false;
|
|
1264
|
+
return true;
|
|
1265
|
+
}
|
|
1266
|
+
function ApiErrorFromJSON(json) {
|
|
1267
|
+
return ApiErrorFromJSONTyped(json, false);
|
|
1268
|
+
}
|
|
1269
|
+
function ApiErrorFromJSONTyped(json, ignoreDiscriminator) {
|
|
1270
|
+
if (json == null) {
|
|
1271
|
+
return json;
|
|
1272
|
+
}
|
|
1273
|
+
return {
|
|
1274
|
+
error: json["error"]
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
function ApiErrorToJSON(json) {
|
|
1278
|
+
return ApiErrorToJSONTyped(json, false);
|
|
1279
|
+
}
|
|
1280
|
+
function ApiErrorToJSONTyped(value, ignoreDiscriminator = false) {
|
|
1281
|
+
if (value == null) {
|
|
1282
|
+
return value;
|
|
1283
|
+
}
|
|
1284
|
+
return {
|
|
1285
|
+
error: value["error"]
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
function instanceOfCompanyDiscountResponseData(value) {
|
|
1289
|
+
if (!("couponName" in value) || value["couponName"] === void 0)
|
|
1290
|
+
return false;
|
|
1291
|
+
if (!("duration" in value) || value["duration"] === void 0) return false;
|
|
1292
|
+
return true;
|
|
1293
|
+
}
|
|
1294
|
+
function CompanyDiscountResponseDataFromJSON(json) {
|
|
1295
|
+
return CompanyDiscountResponseDataFromJSONTyped(json, false);
|
|
1296
|
+
}
|
|
1297
|
+
function CompanyDiscountResponseDataFromJSONTyped(json, ignoreDiscriminator) {
|
|
1298
|
+
if (json == null) {
|
|
1299
|
+
return json;
|
|
1300
|
+
}
|
|
1301
|
+
return {
|
|
1302
|
+
amountOff: json["amount_off"] == null ? void 0 : json["amount_off"],
|
|
1303
|
+
couponName: json["coupon_name"],
|
|
1304
|
+
currency: json["currency"] == null ? void 0 : json["currency"],
|
|
1305
|
+
customerFacingCode: json["customer_facing_code"] == null ? void 0 : json["customer_facing_code"],
|
|
1306
|
+
duration: json["duration"],
|
|
1307
|
+
durationInMonths: json["duration_in_months"] == null ? void 0 : json["duration_in_months"],
|
|
1308
|
+
percentOff: json["percent_off"] == null ? void 0 : json["percent_off"]
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
function CompanyDiscountResponseDataToJSON(json) {
|
|
1312
|
+
return CompanyDiscountResponseDataToJSONTyped(json, false);
|
|
1313
|
+
}
|
|
1314
|
+
function CompanyDiscountResponseDataToJSONTyped(value, ignoreDiscriminator = false) {
|
|
1315
|
+
if (value == null) {
|
|
1316
|
+
return value;
|
|
1317
|
+
}
|
|
1318
|
+
return {
|
|
1319
|
+
amount_off: value["amountOff"],
|
|
1320
|
+
coupon_name: value["couponName"],
|
|
1321
|
+
currency: value["currency"],
|
|
1322
|
+
customer_facing_code: value["customerFacingCode"],
|
|
1323
|
+
duration: value["duration"],
|
|
1324
|
+
duration_in_months: value["durationInMonths"],
|
|
1325
|
+
percent_off: value["percentOff"]
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
var InvoiceStatus = {
|
|
1329
|
+
Draft: "draft",
|
|
1330
|
+
Open: "open",
|
|
1331
|
+
Paid: "paid",
|
|
1332
|
+
Uncollectible: "uncollectible",
|
|
1333
|
+
Void: "void"
|
|
1334
|
+
};
|
|
1335
|
+
function instanceOfInvoiceStatus(value) {
|
|
1336
|
+
for (const key in InvoiceStatus) {
|
|
1337
|
+
if (Object.prototype.hasOwnProperty.call(InvoiceStatus, key)) {
|
|
1338
|
+
if (InvoiceStatus[key] === value) {
|
|
1339
|
+
return true;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
return false;
|
|
1344
|
+
}
|
|
1345
|
+
function InvoiceStatusFromJSON(json) {
|
|
1346
|
+
return InvoiceStatusFromJSONTyped(json, false);
|
|
1347
|
+
}
|
|
1348
|
+
function InvoiceStatusFromJSONTyped(json, ignoreDiscriminator) {
|
|
1349
|
+
return json;
|
|
1350
|
+
}
|
|
1351
|
+
function InvoiceStatusToJSON(value) {
|
|
1352
|
+
return value;
|
|
1353
|
+
}
|
|
1354
|
+
function InvoiceStatusToJSONTyped(value, ignoreDiscriminator) {
|
|
1355
|
+
return value;
|
|
1356
|
+
}
|
|
1357
|
+
function instanceOfCompanyInvoiceResponseData(value) {
|
|
1358
|
+
if (!("amountDue" in value) || value["amountDue"] === void 0) return false;
|
|
1359
|
+
if (!("createdAt" in value) || value["createdAt"] === void 0) return false;
|
|
1360
|
+
if (!("currency" in value) || value["currency"] === void 0) return false;
|
|
1361
|
+
if (!("id" in value) || value["id"] === void 0) return false;
|
|
1362
|
+
return true;
|
|
1363
|
+
}
|
|
1364
|
+
function CompanyInvoiceResponseDataFromJSON(json) {
|
|
1365
|
+
return CompanyInvoiceResponseDataFromJSONTyped(json, false);
|
|
1366
|
+
}
|
|
1367
|
+
function CompanyInvoiceResponseDataFromJSONTyped(json, ignoreDiscriminator) {
|
|
1368
|
+
if (json == null) {
|
|
1369
|
+
return json;
|
|
1370
|
+
}
|
|
1371
|
+
return {
|
|
1372
|
+
amountDue: json["amount_due"],
|
|
1373
|
+
createdAt: new Date(json["created_at"]),
|
|
1374
|
+
currency: json["currency"],
|
|
1375
|
+
dueDate: json["due_date"] == null ? void 0 : new Date(json["due_date"]),
|
|
1376
|
+
id: json["id"],
|
|
1377
|
+
status: json["status"] == null ? void 0 : InvoiceStatusFromJSON(json["status"]),
|
|
1378
|
+
url: json["url"] == null ? void 0 : json["url"]
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
function CompanyInvoiceResponseDataToJSON(json) {
|
|
1382
|
+
return CompanyInvoiceResponseDataToJSONTyped(json, false);
|
|
1383
|
+
}
|
|
1384
|
+
function CompanyInvoiceResponseDataToJSONTyped(value, ignoreDiscriminator = false) {
|
|
1385
|
+
if (value == null) {
|
|
1386
|
+
return value;
|
|
1387
|
+
}
|
|
1388
|
+
return {
|
|
1389
|
+
amount_due: value["amountDue"],
|
|
1390
|
+
created_at: value["createdAt"].toISOString(),
|
|
1391
|
+
currency: value["currency"],
|
|
1392
|
+
due_date: value["dueDate"] == null ? void 0 : value["dueDate"].toISOString(),
|
|
1393
|
+
id: value["id"],
|
|
1394
|
+
status: InvoiceStatusToJSON(value["status"]),
|
|
1395
|
+
url: value["url"]
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1398
|
+
function instanceOfCompanyInvoicesResponseData(value) {
|
|
1399
|
+
if (!("count" in value) || value["count"] === void 0) return false;
|
|
1400
|
+
if (!("invoices" in value) || value["invoices"] === void 0) return false;
|
|
1401
|
+
return true;
|
|
1402
|
+
}
|
|
1403
|
+
function CompanyInvoicesResponseDataFromJSON(json) {
|
|
1404
|
+
return CompanyInvoicesResponseDataFromJSONTyped(json, false);
|
|
1405
|
+
}
|
|
1406
|
+
function CompanyInvoicesResponseDataFromJSONTyped(json, ignoreDiscriminator) {
|
|
1407
|
+
if (json == null) {
|
|
1408
|
+
return json;
|
|
1409
|
+
}
|
|
1410
|
+
return {
|
|
1411
|
+
count: json["count"],
|
|
1412
|
+
invoices: json["invoices"].map(
|
|
1413
|
+
CompanyInvoiceResponseDataFromJSON
|
|
1414
|
+
)
|
|
1415
|
+
};
|
|
1416
|
+
}
|
|
1417
|
+
function CompanyInvoicesResponseDataToJSON(json) {
|
|
1418
|
+
return CompanyInvoicesResponseDataToJSONTyped(json, false);
|
|
1419
|
+
}
|
|
1420
|
+
function CompanyInvoicesResponseDataToJSONTyped(value, ignoreDiscriminator = false) {
|
|
1421
|
+
if (value == null) {
|
|
1422
|
+
return value;
|
|
1423
|
+
}
|
|
1424
|
+
return {
|
|
1425
|
+
count: value["count"],
|
|
1426
|
+
invoices: value["invoices"].map(
|
|
1427
|
+
CompanyInvoiceResponseDataToJSON
|
|
1428
|
+
)
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
function instanceOfCompanyUpcomingInvoiceResponseData(value) {
|
|
1432
|
+
if (!("amountDue" in value) || value["amountDue"] === void 0) return false;
|
|
1433
|
+
if (!("currency" in value) || value["currency"] === void 0) return false;
|
|
1434
|
+
if (!("customerBalanceApplied" in value) || value["customerBalanceApplied"] === void 0)
|
|
1435
|
+
return false;
|
|
1436
|
+
if (!("customerBalanceRemaining" in value) || value["customerBalanceRemaining"] === void 0)
|
|
1437
|
+
return false;
|
|
1438
|
+
if (!("discounts" in value) || value["discounts"] === void 0) return false;
|
|
1439
|
+
if (!("subtotal" in value) || value["subtotal"] === void 0) return false;
|
|
1440
|
+
return true;
|
|
1441
|
+
}
|
|
1442
|
+
function CompanyUpcomingInvoiceResponseDataFromJSON(json) {
|
|
1443
|
+
return CompanyUpcomingInvoiceResponseDataFromJSONTyped(json, false);
|
|
1444
|
+
}
|
|
1445
|
+
function CompanyUpcomingInvoiceResponseDataFromJSONTyped(json, ignoreDiscriminator) {
|
|
1446
|
+
if (json == null) {
|
|
1447
|
+
return json;
|
|
1448
|
+
}
|
|
1449
|
+
return {
|
|
1450
|
+
amountDue: json["amount_due"],
|
|
1451
|
+
currency: json["currency"],
|
|
1452
|
+
customerBalanceApplied: json["customer_balance_applied"],
|
|
1453
|
+
customerBalanceRemaining: json["customer_balance_remaining"],
|
|
1454
|
+
discounts: json["discounts"].map(
|
|
1455
|
+
CompanyDiscountResponseDataFromJSON
|
|
1456
|
+
),
|
|
1457
|
+
dueDate: json["due_date"] == null ? void 0 : new Date(json["due_date"]),
|
|
1458
|
+
subtotal: json["subtotal"]
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
function CompanyUpcomingInvoiceResponseDataToJSON(json) {
|
|
1462
|
+
return CompanyUpcomingInvoiceResponseDataToJSONTyped(json, false);
|
|
1463
|
+
}
|
|
1464
|
+
function CompanyUpcomingInvoiceResponseDataToJSONTyped(value, ignoreDiscriminator = false) {
|
|
1465
|
+
if (value == null) {
|
|
1466
|
+
return value;
|
|
1467
|
+
}
|
|
1468
|
+
return {
|
|
1469
|
+
amount_due: value["amountDue"],
|
|
1470
|
+
currency: value["currency"],
|
|
1471
|
+
customer_balance_applied: value["customerBalanceApplied"],
|
|
1472
|
+
customer_balance_remaining: value["customerBalanceRemaining"],
|
|
1473
|
+
discounts: value["discounts"].map(
|
|
1474
|
+
CompanyDiscountResponseDataToJSON
|
|
1475
|
+
),
|
|
1476
|
+
due_date: value["dueDate"] == null ? void 0 : value["dueDate"].toISOString(),
|
|
1477
|
+
subtotal: value["subtotal"]
|
|
1478
|
+
};
|
|
1479
|
+
}
|
|
1480
|
+
function instanceOfGetCompanyInvoicesParams(value) {
|
|
1481
|
+
return true;
|
|
1482
|
+
}
|
|
1483
|
+
function GetCompanyInvoicesParamsFromJSON(json) {
|
|
1484
|
+
return GetCompanyInvoicesParamsFromJSONTyped(json, false);
|
|
1485
|
+
}
|
|
1486
|
+
function GetCompanyInvoicesParamsFromJSONTyped(json, ignoreDiscriminator) {
|
|
1487
|
+
if (json == null) {
|
|
1488
|
+
return json;
|
|
1489
|
+
}
|
|
1490
|
+
return {
|
|
1491
|
+
includePending: json["include_pending"] == null ? void 0 : json["include_pending"],
|
|
1492
|
+
limit: json["limit"] == null ? void 0 : json["limit"],
|
|
1493
|
+
offset: json["offset"] == null ? void 0 : json["offset"]
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
function GetCompanyInvoicesParamsToJSON(json) {
|
|
1497
|
+
return GetCompanyInvoicesParamsToJSONTyped(json, false);
|
|
1498
|
+
}
|
|
1499
|
+
function GetCompanyInvoicesParamsToJSONTyped(value, ignoreDiscriminator = false) {
|
|
1500
|
+
if (value == null) {
|
|
1501
|
+
return value;
|
|
1502
|
+
}
|
|
1503
|
+
return {
|
|
1504
|
+
include_pending: value["includePending"],
|
|
1505
|
+
limit: value["limit"],
|
|
1506
|
+
offset: value["offset"]
|
|
1507
|
+
};
|
|
1508
|
+
}
|
|
1509
|
+
function instanceOfGetCompanyInvoicesResponse(value) {
|
|
1510
|
+
if (!("data" in value) || value["data"] === void 0) return false;
|
|
1511
|
+
if (!("params" in value) || value["params"] === void 0) return false;
|
|
1512
|
+
return true;
|
|
1513
|
+
}
|
|
1514
|
+
function GetCompanyInvoicesResponseFromJSON(json) {
|
|
1515
|
+
return GetCompanyInvoicesResponseFromJSONTyped(json, false);
|
|
1516
|
+
}
|
|
1517
|
+
function GetCompanyInvoicesResponseFromJSONTyped(json, ignoreDiscriminator) {
|
|
1518
|
+
if (json == null) {
|
|
1519
|
+
return json;
|
|
1520
|
+
}
|
|
1521
|
+
return {
|
|
1522
|
+
data: CompanyInvoicesResponseDataFromJSON(json["data"]),
|
|
1523
|
+
params: GetCompanyInvoicesParamsFromJSON(json["params"])
|
|
1524
|
+
};
|
|
1525
|
+
}
|
|
1526
|
+
function GetCompanyInvoicesResponseToJSON(json) {
|
|
1527
|
+
return GetCompanyInvoicesResponseToJSONTyped(json, false);
|
|
1528
|
+
}
|
|
1529
|
+
function GetCompanyInvoicesResponseToJSONTyped(value, ignoreDiscriminator = false) {
|
|
1530
|
+
if (value == null) {
|
|
1531
|
+
return value;
|
|
1532
|
+
}
|
|
1533
|
+
return {
|
|
1534
|
+
data: CompanyInvoicesResponseDataToJSON(value["data"]),
|
|
1535
|
+
params: GetCompanyInvoicesParamsToJSON(value["params"])
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
function instanceOfGetCompanyUpcomingInvoiceResponse(value) {
|
|
1539
|
+
if (!("data" in value) || value["data"] === void 0) return false;
|
|
1540
|
+
if (!("params" in value) || value["params"] === void 0) return false;
|
|
1541
|
+
return true;
|
|
1542
|
+
}
|
|
1543
|
+
function GetCompanyUpcomingInvoiceResponseFromJSON(json) {
|
|
1544
|
+
return GetCompanyUpcomingInvoiceResponseFromJSONTyped(json, false);
|
|
1545
|
+
}
|
|
1546
|
+
function GetCompanyUpcomingInvoiceResponseFromJSONTyped(json, ignoreDiscriminator) {
|
|
1547
|
+
if (json == null) {
|
|
1548
|
+
return json;
|
|
1549
|
+
}
|
|
1550
|
+
return {
|
|
1551
|
+
data: CompanyUpcomingInvoiceResponseDataFromJSON(json["data"]),
|
|
1552
|
+
params: json["params"]
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
function GetCompanyUpcomingInvoiceResponseToJSON(json) {
|
|
1556
|
+
return GetCompanyUpcomingInvoiceResponseToJSONTyped(json, false);
|
|
1557
|
+
}
|
|
1558
|
+
function GetCompanyUpcomingInvoiceResponseToJSONTyped(value, ignoreDiscriminator = false) {
|
|
1559
|
+
if (value == null) {
|
|
1560
|
+
return value;
|
|
1561
|
+
}
|
|
1562
|
+
return {
|
|
1563
|
+
data: CompanyUpcomingInvoiceResponseDataToJSON(value["data"]),
|
|
1564
|
+
params: value["params"]
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
var DEFAULT_INVOICE_QUERY = {};
|
|
1568
|
+
function normalizeInvoiceQuery(query) {
|
|
1569
|
+
const { includePending, ...rest } = query;
|
|
1570
|
+
return includePending === true ? { ...rest, includePending: true } : rest;
|
|
1571
|
+
}
|
|
1572
|
+
var SchematicApiError = class extends Error {
|
|
1573
|
+
constructor(status, path, body) {
|
|
1574
|
+
super(
|
|
1575
|
+
typeof body === "object" && body !== null && "error" in body ? String(body.error) : `Request to ${path} failed with status ${status}`
|
|
1576
|
+
);
|
|
1577
|
+
this.status = status;
|
|
1578
|
+
this.path = path;
|
|
1579
|
+
this.body = body;
|
|
1580
|
+
this.name = "SchematicApiError";
|
|
1581
|
+
}
|
|
1582
|
+
status;
|
|
1583
|
+
path;
|
|
1584
|
+
body;
|
|
1585
|
+
};
|
|
1586
|
+
var DEFAULT_API_URL = "https://api.schematichq.com";
|
|
1587
|
+
var TOKEN_CACHE_SIZE = 10;
|
|
1588
|
+
function sessionKey(session) {
|
|
1589
|
+
return JSON.stringify([session.company, session.user ?? null]);
|
|
1590
|
+
}
|
|
1591
|
+
var SchematicSession = class {
|
|
1592
|
+
_apiUrl;
|
|
1593
|
+
_headers;
|
|
1594
|
+
_fetch;
|
|
1595
|
+
_session;
|
|
1596
|
+
_tokens = /* @__PURE__ */ new Map();
|
|
1597
|
+
_resolving = /* @__PURE__ */ new Map();
|
|
1598
|
+
/**
|
|
1599
|
+
* Bumped when the session's identity changes, and only then — the object
|
|
1600
|
+
* itself is replaced on every render. Anything asking "is this still the
|
|
1601
|
+
* session I started under?" counts generations rather than comparing.
|
|
1602
|
+
*/
|
|
1603
|
+
_generation = 0;
|
|
1604
|
+
_listeners = /* @__PURE__ */ new Set();
|
|
1605
|
+
constructor(options = {}) {
|
|
1606
|
+
this._session = options.session;
|
|
1607
|
+
this._apiUrl = (options.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, "");
|
|
1608
|
+
this._headers = options.additionalHeaders ?? {};
|
|
1609
|
+
this._fetch = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
1610
|
+
}
|
|
1611
|
+
get key() {
|
|
1612
|
+
return this._session === null || this._session === void 0 ? void 0 : sessionKey(this._session);
|
|
1613
|
+
}
|
|
1614
|
+
get status() {
|
|
1615
|
+
if (this._session === void 0) {
|
|
1616
|
+
return "pending";
|
|
1617
|
+
}
|
|
1618
|
+
return this._session === null ? "ended" : "active";
|
|
1619
|
+
}
|
|
1620
|
+
/** Only a statement that changes which pair is read counts as a change. */
|
|
1621
|
+
set(session) {
|
|
1622
|
+
if (session === void 0) {
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
const previous = this._session;
|
|
1626
|
+
this._session = session;
|
|
1627
|
+
if (session === null) {
|
|
1628
|
+
if (previous === null) {
|
|
1629
|
+
return;
|
|
1630
|
+
}
|
|
1631
|
+
this._tokens.clear();
|
|
1632
|
+
this._resolving.clear();
|
|
1633
|
+
this._generation += 1;
|
|
1634
|
+
this._emit({ type: "ended" });
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
if (previous !== null && previous !== void 0) {
|
|
1638
|
+
if (previous.company === session.company && (previous.user ?? null) === (session.user ?? null)) {
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
this._generation += 1;
|
|
1642
|
+
this._emit({ type: "changed" });
|
|
1643
|
+
return;
|
|
1644
|
+
}
|
|
1645
|
+
this._generation += 1;
|
|
1646
|
+
this._emit({ type: "started" });
|
|
1647
|
+
}
|
|
1648
|
+
onChange(listener) {
|
|
1649
|
+
this._listeners.add(listener);
|
|
1650
|
+
return () => {
|
|
1651
|
+
this._listeners.delete(listener);
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
_emit(event) {
|
|
1655
|
+
for (const listener of this._listeners) {
|
|
1656
|
+
listener(event);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
_cached(key) {
|
|
1660
|
+
const cached = this._tokens.get(key);
|
|
1661
|
+
if (cached === void 0) {
|
|
1662
|
+
return void 0;
|
|
1663
|
+
}
|
|
1664
|
+
if (cached.expiresAt !== void 0 && cached.expiresAt.getTime() <= Date.now()) {
|
|
1665
|
+
this._tokens.delete(key);
|
|
1666
|
+
return void 0;
|
|
1667
|
+
}
|
|
1668
|
+
this._tokens.delete(key);
|
|
1669
|
+
this._tokens.set(key, cached);
|
|
1670
|
+
return cached;
|
|
1671
|
+
}
|
|
1672
|
+
_cache(key, resolved) {
|
|
1673
|
+
this._tokens.delete(key);
|
|
1674
|
+
this._tokens.set(key, resolved);
|
|
1675
|
+
while (this._tokens.size > TOKEN_CACHE_SIZE) {
|
|
1676
|
+
const oldest = this._tokens.keys().next();
|
|
1677
|
+
if (oldest.done === true) {
|
|
1678
|
+
break;
|
|
1679
|
+
}
|
|
1680
|
+
this._tokens.delete(oldest.value);
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* The credential for a session, minted if this one is not held. `force`
|
|
1685
|
+
* retires what is held first: the caller is a request the API has just
|
|
1686
|
+
* rejected.
|
|
1687
|
+
*/
|
|
1688
|
+
resolveToken(session, force) {
|
|
1689
|
+
const { token } = session;
|
|
1690
|
+
if (typeof token === "string") {
|
|
1691
|
+
return Promise.resolve(token);
|
|
1692
|
+
}
|
|
1693
|
+
const key = sessionKey(session);
|
|
1694
|
+
if (!force) {
|
|
1695
|
+
const cached = this._cached(key);
|
|
1696
|
+
if (cached !== void 0) {
|
|
1697
|
+
return Promise.resolve(cached.token);
|
|
1698
|
+
}
|
|
1699
|
+
} else {
|
|
1700
|
+
this._tokens.delete(key);
|
|
1701
|
+
}
|
|
1702
|
+
const inflight = this._resolving.get(key);
|
|
1703
|
+
if (inflight !== void 0 && inflight.sessionGeneration === this._generation && (!force || inflight.forced)) {
|
|
1704
|
+
return inflight.promise;
|
|
1705
|
+
}
|
|
1706
|
+
const provider = token;
|
|
1707
|
+
const sessionGeneration = this._generation;
|
|
1708
|
+
const owns = () => this._resolving.get(key)?.promise === promise;
|
|
1709
|
+
const promise = Promise.resolve().then(() => provider()).then((result) => {
|
|
1710
|
+
const { resolved, stamped } = asResolvedToken(result, session);
|
|
1711
|
+
if (owns() && (this._generation === sessionGeneration || stamped)) {
|
|
1712
|
+
this._cache(key, resolved);
|
|
1713
|
+
}
|
|
1714
|
+
return resolved.token;
|
|
1715
|
+
}).finally(() => {
|
|
1716
|
+
if (owns()) {
|
|
1717
|
+
this._resolving.delete(key);
|
|
1718
|
+
}
|
|
1719
|
+
});
|
|
1720
|
+
this._resolving.set(key, { promise, forced: force, sessionGeneration });
|
|
1721
|
+
return promise;
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Sends a request under the active session's credential, refreshing once
|
|
1725
|
+
* and retrying if the API rejects it. Rejects rather than answering when
|
|
1726
|
+
* the session changes while the request is in flight: the rows would
|
|
1727
|
+
* otherwise come back as the answer to a question asked for another pair.
|
|
1728
|
+
*/
|
|
1729
|
+
async request(path, options = {}) {
|
|
1730
|
+
const { method = "GET", body } = options;
|
|
1731
|
+
const send = async (credential2) => this._fetch(`${this._apiUrl}${path}`, {
|
|
1732
|
+
method,
|
|
1733
|
+
headers: {
|
|
1734
|
+
"Accept": "application/json",
|
|
1735
|
+
...body === void 0 ? {} : { "Content-Type": "application/json" },
|
|
1736
|
+
...this._headers,
|
|
1737
|
+
"X-Schematic-Api-Key": credential2
|
|
1738
|
+
},
|
|
1739
|
+
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
1740
|
+
});
|
|
1741
|
+
const session = this._session;
|
|
1742
|
+
if (session === null) {
|
|
1743
|
+
throw new Error("There is no session to read data for.");
|
|
1744
|
+
}
|
|
1745
|
+
if (session === void 0) {
|
|
1746
|
+
throw new Error("A session is required to read data.");
|
|
1747
|
+
}
|
|
1748
|
+
const provider = session.token;
|
|
1749
|
+
const generation = this._generation;
|
|
1750
|
+
const stillOurs = async (response2) => {
|
|
1751
|
+
if (this._generation === generation) {
|
|
1752
|
+
return;
|
|
1753
|
+
}
|
|
1754
|
+
if (response2 !== void 0) {
|
|
1755
|
+
await discardBody(response2);
|
|
1756
|
+
}
|
|
1757
|
+
throw new Error("The session changed while this request was in flight.");
|
|
1758
|
+
};
|
|
1759
|
+
const credential = await this.resolveToken(session, false);
|
|
1760
|
+
if (this._generation !== generation) {
|
|
1761
|
+
throw new Error("The session changed before this request was sent.");
|
|
1762
|
+
}
|
|
1763
|
+
let response = await send(credential);
|
|
1764
|
+
await stillOurs(response);
|
|
1765
|
+
if (response.status === 401 && typeof provider === "function" && this._generation === generation) {
|
|
1766
|
+
const status = response.status;
|
|
1767
|
+
const rejected = await readBody(response);
|
|
1768
|
+
let retried = false;
|
|
1769
|
+
const current = this._session;
|
|
1770
|
+
if (this._generation === generation && current !== null && current !== void 0) {
|
|
1771
|
+
const refreshed = await this.resolveToken(current, true);
|
|
1772
|
+
if (this._generation === generation) {
|
|
1773
|
+
response = await send(refreshed);
|
|
1774
|
+
await stillOurs(response);
|
|
1775
|
+
retried = true;
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
if (!retried) {
|
|
1779
|
+
throw new SchematicApiError(status, path, rejected);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
if (options.noContentOn?.includes(response.status) === true) {
|
|
1783
|
+
await discardBody(response);
|
|
1784
|
+
await stillOurs();
|
|
1785
|
+
return void 0;
|
|
1786
|
+
}
|
|
1787
|
+
const parsed = await readBody(response);
|
|
1788
|
+
await stillOurs();
|
|
1789
|
+
if (!response.ok) {
|
|
1790
|
+
throw new SchematicApiError(response.status, path, parsed);
|
|
1791
|
+
}
|
|
1792
|
+
return parsed;
|
|
1793
|
+
}
|
|
1794
|
+
};
|
|
1795
|
+
function asResolvedToken(result, session) {
|
|
1796
|
+
if (typeof result === "string") {
|
|
1797
|
+
return { resolved: { token: result }, stamped: false };
|
|
1798
|
+
}
|
|
1799
|
+
const token = result?.token;
|
|
1800
|
+
if (typeof token !== "string" || token === "") {
|
|
1801
|
+
throw new Error("The access token provider did not return a token.");
|
|
1802
|
+
}
|
|
1803
|
+
if (result.company !== void 0 && result.company !== session.company || result.user !== void 0 && session.user !== void 0 && result.user !== session.user) {
|
|
1804
|
+
throw new Error(
|
|
1805
|
+
"The access token provider returned a token for a different session."
|
|
1806
|
+
);
|
|
1807
|
+
}
|
|
1808
|
+
const stamped = result.company !== void 0 && (session.user === void 0 || result.user !== void 0);
|
|
1809
|
+
return { resolved: { token, expiresAt: asDate(result.expiresAt) }, stamped };
|
|
1810
|
+
}
|
|
1811
|
+
function asDate(value) {
|
|
1812
|
+
if (value === void 0 || value === null) {
|
|
1813
|
+
return void 0;
|
|
1814
|
+
}
|
|
1815
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
1816
|
+
return Number.isNaN(date.getTime()) ? void 0 : date;
|
|
1817
|
+
}
|
|
1818
|
+
async function discardBody(response) {
|
|
1819
|
+
try {
|
|
1820
|
+
await response.body?.cancel();
|
|
1821
|
+
} catch {
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
async function readBody(response) {
|
|
1825
|
+
const text = await response.text();
|
|
1826
|
+
if (text === "") {
|
|
1827
|
+
return null;
|
|
1828
|
+
}
|
|
1829
|
+
try {
|
|
1830
|
+
return JSON.parse(text);
|
|
1831
|
+
} catch {
|
|
1832
|
+
return text;
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
var INVOICE_PAGE_SIZE = 12;
|
|
1836
|
+
var INVOICE_MAX_PAGE_SIZE = 250;
|
|
1837
|
+
var SchematicBillingClient = class {
|
|
1838
|
+
/**
|
|
1839
|
+
* Public so a second client over the same surface can be constructed on
|
|
1840
|
+
* this one rather than minting tokens of its own.
|
|
1841
|
+
*/
|
|
1842
|
+
session;
|
|
1843
|
+
constructor(options = {}) {
|
|
1844
|
+
this.session = options instanceof SchematicSession ? options : new SchematicSession(options);
|
|
1845
|
+
}
|
|
1846
|
+
get sessionKey() {
|
|
1847
|
+
return this.session.key;
|
|
1848
|
+
}
|
|
1849
|
+
get sessionStatus() {
|
|
1850
|
+
return this.session.status;
|
|
1851
|
+
}
|
|
1852
|
+
setSession(session) {
|
|
1853
|
+
this.session.set(session);
|
|
1854
|
+
}
|
|
1855
|
+
onSessionChange(listener) {
|
|
1856
|
+
return this.session.onChange(listener);
|
|
1857
|
+
}
|
|
1858
|
+
fetchInvoices(params) {
|
|
1859
|
+
const query = new URLSearchParams({
|
|
1860
|
+
limit: String(Math.min(params.limit, INVOICE_MAX_PAGE_SIZE)),
|
|
1861
|
+
offset: String(params.offset)
|
|
1862
|
+
});
|
|
1863
|
+
if (params.includePending !== void 0) {
|
|
1864
|
+
query.set("include_pending", String(params.includePending));
|
|
1865
|
+
}
|
|
1866
|
+
const path = `/company/invoices?${query}`;
|
|
1867
|
+
return this.session.request(path).then((body) => {
|
|
1868
|
+
if (body === null || typeof body !== "object" || !("data" in body)) {
|
|
1869
|
+
throw new Error(`Malformed response from ${path}`);
|
|
1870
|
+
}
|
|
1871
|
+
const data = body.data;
|
|
1872
|
+
if (data == null || data.invoices == null) {
|
|
1873
|
+
return { invoices: [], count: 0 };
|
|
1874
|
+
}
|
|
1875
|
+
const decoded = GetCompanyInvoicesResponseFromJSON(body).data;
|
|
1876
|
+
return { invoices: decoded.invoices, count: decoded.count };
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
fetchUpcomingInvoice() {
|
|
1880
|
+
const path = "/company/upcoming-invoice";
|
|
1881
|
+
return this.session.request(path, { noContentOn: [204] }).then((body) => {
|
|
1882
|
+
if (body === void 0) {
|
|
1883
|
+
return null;
|
|
1884
|
+
}
|
|
1885
|
+
if (body === null || typeof body !== "object" || !("data" in body)) {
|
|
1886
|
+
throw new Error(`Malformed response from ${path}`);
|
|
1887
|
+
}
|
|
1888
|
+
return GetCompanyUpcomingInvoiceResponseFromJSON(body).data;
|
|
1889
|
+
});
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1179
1892
|
var anonymousIdKey = "schematicId";
|
|
1180
1893
|
var flagStateCachePrefix = "schematicCache";
|
|
1181
1894
|
var flagStateCacheMaxContexts = 10;
|
|
1182
1895
|
var flagStateCacheDefaultMaxAgeMs = 7 * 24 * 60 * 60 * 1e3;
|
|
1183
1896
|
var emptyCreditBalances = Object.freeze({});
|
|
1184
1897
|
var Schematic = class {
|
|
1185
|
-
|
|
1898
|
+
_additionalHeaders = {};
|
|
1186
1899
|
apiKey;
|
|
1187
|
-
|
|
1900
|
+
_apiUrl = "https://api.schematichq.com";
|
|
1188
1901
|
conn = null;
|
|
1189
1902
|
context = {};
|
|
1190
1903
|
debugEnabled = false;
|
|
@@ -1264,7 +1977,7 @@ var Schematic = class {
|
|
|
1264
1977
|
if (this.offlineEnabled) {
|
|
1265
1978
|
this.setIsPending(false);
|
|
1266
1979
|
}
|
|
1267
|
-
this.
|
|
1980
|
+
this._additionalHeaders = {
|
|
1268
1981
|
"X-Schematic-Client-Version": `schematic-js@${version}`,
|
|
1269
1982
|
...options?.additionalHeaders ?? {}
|
|
1270
1983
|
};
|
|
@@ -1280,7 +1993,7 @@ var Schematic = class {
|
|
|
1280
1993
|
}
|
|
1281
1994
|
this.hydrateFlagStateFromCache();
|
|
1282
1995
|
if (options?.apiUrl !== void 0) {
|
|
1283
|
-
this.
|
|
1996
|
+
this._apiUrl = options.apiUrl;
|
|
1284
1997
|
}
|
|
1285
1998
|
if (options?.eventUrl !== void 0) {
|
|
1286
1999
|
this.eventUrl = options.eventUrl;
|
|
@@ -1345,6 +2058,12 @@ var Schematic = class {
|
|
|
1345
2058
|
this.debug("Initialized with debug mode enabled");
|
|
1346
2059
|
}
|
|
1347
2060
|
}
|
|
2061
|
+
get apiUrl() {
|
|
2062
|
+
return this._apiUrl;
|
|
2063
|
+
}
|
|
2064
|
+
get additionalHeaders() {
|
|
2065
|
+
return { ...this._additionalHeaders };
|
|
2066
|
+
}
|
|
1348
2067
|
/**
|
|
1349
2068
|
* Resolve fallback value according to priority order:
|
|
1350
2069
|
* 1. Callsite fallback value (if provided)
|
|
@@ -1430,11 +2149,11 @@ var Schematic = class {
|
|
|
1430
2149
|
return resolvedFallbackResult.value;
|
|
1431
2150
|
}
|
|
1432
2151
|
if (!this.useWebSocket) {
|
|
1433
|
-
const requestUrl = `${this.
|
|
2152
|
+
const requestUrl = `${this._apiUrl}/flags/${key}/check`;
|
|
1434
2153
|
return fetch(requestUrl, {
|
|
1435
2154
|
method: "POST",
|
|
1436
2155
|
headers: {
|
|
1437
|
-
...this.
|
|
2156
|
+
...this._additionalHeaders ?? {},
|
|
1438
2157
|
"Content-Type": "application/json;charset=UTF-8",
|
|
1439
2158
|
"X-Schematic-Api-Key": this.apiKey
|
|
1440
2159
|
},
|
|
@@ -1637,12 +2356,12 @@ var Schematic = class {
|
|
|
1637
2356
|
this.debug(`checkFlags offline result: returning empty object`);
|
|
1638
2357
|
return {};
|
|
1639
2358
|
}
|
|
1640
|
-
const requestUrl = `${this.
|
|
2359
|
+
const requestUrl = `${this._apiUrl}/flags/check`;
|
|
1641
2360
|
const requestBody = JSON.stringify(context);
|
|
1642
2361
|
return fetch(requestUrl, {
|
|
1643
2362
|
method: "POST",
|
|
1644
2363
|
headers: {
|
|
1645
|
-
...this.
|
|
2364
|
+
...this._additionalHeaders ?? {},
|
|
1646
2365
|
"Content-Type": "application/json;charset=UTF-8",
|
|
1647
2366
|
"X-Schematic-Api-Key": this.apiKey
|
|
1648
2367
|
},
|
|
@@ -2189,7 +2908,7 @@ var Schematic = class {
|
|
|
2189
2908
|
const response = await fetch(captureUrl, {
|
|
2190
2909
|
method: "POST",
|
|
2191
2910
|
headers: {
|
|
2192
|
-
...this.
|
|
2911
|
+
...this._additionalHeaders ?? {},
|
|
2193
2912
|
"Content-Type": "application/json;charset=UTF-8"
|
|
2194
2913
|
},
|
|
2195
2914
|
body: payload
|
|
@@ -2685,7 +3404,7 @@ var Schematic = class {
|
|
|
2685
3404
|
}
|
|
2686
3405
|
});
|
|
2687
3406
|
this.currentWebSocket = socket;
|
|
2688
|
-
const clientVersion = this.
|
|
3407
|
+
const clientVersion = this._additionalHeaders["X-Schematic-Client-Version"] ?? `schematic-js@${version}`;
|
|
2689
3408
|
const messagePayload = {
|
|
2690
3409
|
apiKey: this.apiKey,
|
|
2691
3410
|
clientVersion,
|
|
@@ -2919,23 +3638,853 @@ var notifyCreditBalanceListener = (listener, value) => {
|
|
|
2919
3638
|
};
|
|
2920
3639
|
|
|
2921
3640
|
// src/context/schematic.tsx
|
|
2922
|
-
var
|
|
3641
|
+
var import_react5 = __toESM(require("react"));
|
|
3642
|
+
|
|
3643
|
+
// src/billing/contract/index.ts
|
|
3644
|
+
function normalizeInvoiceQuery2(query) {
|
|
3645
|
+
return normalizeInvoiceQuery(query).includePending === true ? { includePending: true } : {};
|
|
3646
|
+
}
|
|
3647
|
+
|
|
3648
|
+
// src/billing/store.ts
|
|
3649
|
+
var Resource = class {
|
|
3650
|
+
constructor(_fetcher, initial, _readiness = () => "ready") {
|
|
3651
|
+
this._fetcher = _fetcher;
|
|
3652
|
+
this._readiness = _readiness;
|
|
3653
|
+
this._loaded = initial !== void 0;
|
|
3654
|
+
this._snapshot = {
|
|
3655
|
+
data: initial,
|
|
3656
|
+
error: void 0,
|
|
3657
|
+
isPending: initial === void 0
|
|
3658
|
+
};
|
|
3659
|
+
}
|
|
3660
|
+
_fetcher;
|
|
3661
|
+
_readiness;
|
|
3662
|
+
_snapshot;
|
|
3663
|
+
_listeners = /* @__PURE__ */ new Set();
|
|
3664
|
+
_inflight;
|
|
3665
|
+
_extending;
|
|
3666
|
+
/** A refetch asked for mid-load; runs once that load lands. */
|
|
3667
|
+
_queued;
|
|
3668
|
+
_generation = 0;
|
|
3669
|
+
_loaded = false;
|
|
3670
|
+
get snapshot() {
|
|
3671
|
+
return this._snapshot;
|
|
3672
|
+
}
|
|
3673
|
+
get subscriberCount() {
|
|
3674
|
+
return this._listeners.size;
|
|
3675
|
+
}
|
|
3676
|
+
getSnapshot = () => this._snapshot;
|
|
3677
|
+
subscribe = (listener) => {
|
|
3678
|
+
this._listeners.add(listener);
|
|
3679
|
+
if (!this._loaded && this._inflight === void 0 && this._snapshot.error === void 0) {
|
|
3680
|
+
void this.load();
|
|
3681
|
+
}
|
|
3682
|
+
return () => {
|
|
3683
|
+
this._listeners.delete(listener);
|
|
3684
|
+
};
|
|
3685
|
+
};
|
|
3686
|
+
load() {
|
|
3687
|
+
if (this._inflight !== void 0) {
|
|
3688
|
+
return this._inflight;
|
|
3689
|
+
}
|
|
3690
|
+
const readiness = this._readiness();
|
|
3691
|
+
if (readiness !== "ready") {
|
|
3692
|
+
if (readiness === "never" && this._snapshot.isPending) {
|
|
3693
|
+
this._set({ ...this._snapshot, isPending: false });
|
|
3694
|
+
}
|
|
3695
|
+
return Promise.resolve();
|
|
3696
|
+
}
|
|
3697
|
+
const generation = ++this._generation;
|
|
3698
|
+
this._set({ ...this._snapshot, error: void 0, isPending: true });
|
|
3699
|
+
const run = Promise.resolve().then(() => this._fetcher()).then(
|
|
3700
|
+
(data) => {
|
|
3701
|
+
if (generation !== this._generation) return;
|
|
3702
|
+
this._loaded = true;
|
|
3703
|
+
this._set({ data, error: void 0, isPending: false });
|
|
3704
|
+
},
|
|
3705
|
+
(cause) => {
|
|
3706
|
+
if (generation !== this._generation) return;
|
|
3707
|
+
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
3708
|
+
this._set({ ...this._snapshot, error, isPending: false });
|
|
3709
|
+
}
|
|
3710
|
+
).finally(() => {
|
|
3711
|
+
if (generation === this._generation) {
|
|
3712
|
+
this._inflight = void 0;
|
|
3713
|
+
}
|
|
3714
|
+
});
|
|
3715
|
+
this._inflight = run;
|
|
3716
|
+
return run;
|
|
3717
|
+
}
|
|
3718
|
+
/**
|
|
3719
|
+
* Reloads; `data` holds its current value until the response lands. Asked
|
|
3720
|
+
* for mid-load, it runs again after: that request was built before
|
|
3721
|
+
* whatever prompted this one. Refetches queued on one load share the
|
|
3722
|
+
* re-run; a reset, seed, or clear in the meantime supersedes it.
|
|
3723
|
+
*/
|
|
3724
|
+
refetch() {
|
|
3725
|
+
if (this._inflight === void 0) {
|
|
3726
|
+
return this.load();
|
|
3727
|
+
}
|
|
3728
|
+
if (this._queued === void 0) {
|
|
3729
|
+
const generation = this._generation;
|
|
3730
|
+
const queued = this._inflight.then(() => {
|
|
3731
|
+
if (this._queued === queued) {
|
|
3732
|
+
this._queued = void 0;
|
|
3733
|
+
}
|
|
3734
|
+
if (generation !== this._generation) {
|
|
3735
|
+
return;
|
|
3736
|
+
}
|
|
3737
|
+
return this.load();
|
|
3738
|
+
});
|
|
3739
|
+
this._queued = queued;
|
|
3740
|
+
}
|
|
3741
|
+
return this._queued;
|
|
3742
|
+
}
|
|
3743
|
+
/**
|
|
3744
|
+
* Pages: `fetcher` receives the current data and returns what replaces it.
|
|
3745
|
+
* Never rejects — a caller that wants the failure reads `snapshot.error`,
|
|
3746
|
+
* and `data` keeps what was already fetched.
|
|
3747
|
+
*
|
|
3748
|
+
* A load already in flight wins: it is about to refresh the window this
|
|
3749
|
+
* would have appended to.
|
|
3750
|
+
*/
|
|
3751
|
+
extend(fetcher) {
|
|
3752
|
+
const current = this._snapshot.data;
|
|
3753
|
+
if (current === void 0) {
|
|
3754
|
+
return Promise.resolve();
|
|
3755
|
+
}
|
|
3756
|
+
if (this._readiness() !== "ready") {
|
|
3757
|
+
return Promise.resolve();
|
|
3758
|
+
}
|
|
3759
|
+
if (this._extending !== void 0) {
|
|
3760
|
+
return this._extending;
|
|
3761
|
+
}
|
|
3762
|
+
if (this._inflight !== void 0) {
|
|
3763
|
+
return this._inflight;
|
|
3764
|
+
}
|
|
3765
|
+
const generation = ++this._generation;
|
|
3766
|
+
this._set({ ...this._snapshot, error: void 0, isPending: true });
|
|
3767
|
+
const run = Promise.resolve().then(() => fetcher(current)).then(
|
|
3768
|
+
(data) => {
|
|
3769
|
+
if (generation !== this._generation) return;
|
|
3770
|
+
this._set({ data, error: void 0, isPending: false });
|
|
3771
|
+
},
|
|
3772
|
+
(cause) => {
|
|
3773
|
+
if (generation !== this._generation) return;
|
|
3774
|
+
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
3775
|
+
this._set({ ...this._snapshot, error, isPending: false });
|
|
3776
|
+
}
|
|
3777
|
+
).finally(() => {
|
|
3778
|
+
if (this._extending === run) {
|
|
3779
|
+
this._extending = void 0;
|
|
3780
|
+
}
|
|
3781
|
+
});
|
|
3782
|
+
this._extending = run;
|
|
3783
|
+
return run;
|
|
3784
|
+
}
|
|
3785
|
+
seed(data) {
|
|
3786
|
+
this._generation++;
|
|
3787
|
+
this._inflight = void 0;
|
|
3788
|
+
this._extending = void 0;
|
|
3789
|
+
this._queued = void 0;
|
|
3790
|
+
this._loaded = true;
|
|
3791
|
+
this._set({ data, error: void 0, isPending: false });
|
|
3792
|
+
}
|
|
3793
|
+
update(fn) {
|
|
3794
|
+
if (this._snapshot.data === void 0) return;
|
|
3795
|
+
this._generation++;
|
|
3796
|
+
this._inflight = void 0;
|
|
3797
|
+
this._extending = void 0;
|
|
3798
|
+
this._queued = void 0;
|
|
3799
|
+
this._set({ ...this._snapshot, data: fn(this._snapshot.data) });
|
|
3800
|
+
}
|
|
3801
|
+
/**
|
|
3802
|
+
* Forgets everything and stays empty — no data, no error, not pending.
|
|
3803
|
+
* What a resource holds when there is no session to hold it for: a session
|
|
3804
|
+
* ending is not a failure and must not surface as one.
|
|
3805
|
+
*/
|
|
3806
|
+
clear() {
|
|
3807
|
+
this._generation++;
|
|
3808
|
+
this._inflight = void 0;
|
|
3809
|
+
this._extending = void 0;
|
|
3810
|
+
this._queued = void 0;
|
|
3811
|
+
this._loaded = false;
|
|
3812
|
+
this._set({ data: void 0, error: void 0, isPending: false });
|
|
3813
|
+
}
|
|
3814
|
+
/** Forgets everything; reloads immediately if anyone is subscribed. */
|
|
3815
|
+
reset() {
|
|
3816
|
+
this._generation++;
|
|
3817
|
+
this._inflight = void 0;
|
|
3818
|
+
this._extending = void 0;
|
|
3819
|
+
this._queued = void 0;
|
|
3820
|
+
this._loaded = false;
|
|
3821
|
+
const readiness = this._readiness();
|
|
3822
|
+
const willLoad = this._listeners.size > 0 && readiness === "ready";
|
|
3823
|
+
this._set({
|
|
3824
|
+
data: void 0,
|
|
3825
|
+
error: void 0,
|
|
3826
|
+
isPending: willLoad || readiness === "waiting"
|
|
3827
|
+
});
|
|
3828
|
+
if (willLoad) {
|
|
3829
|
+
void this.load();
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
_set(next) {
|
|
3833
|
+
this._snapshot = next;
|
|
3834
|
+
for (const listener of this._listeners) {
|
|
3835
|
+
listener();
|
|
3836
|
+
}
|
|
3837
|
+
}
|
|
3838
|
+
};
|
|
3839
|
+
function hashKey(params) {
|
|
3840
|
+
return JSON.stringify(canonical(params));
|
|
3841
|
+
}
|
|
3842
|
+
function canonical(value) {
|
|
3843
|
+
if (Array.isArray(value)) {
|
|
3844
|
+
return value.map(canonical);
|
|
3845
|
+
}
|
|
3846
|
+
if (value instanceof Date) {
|
|
3847
|
+
const time = value.getTime();
|
|
3848
|
+
return Number.isNaN(time) ? "Invalid Date" : value.toISOString();
|
|
3849
|
+
}
|
|
3850
|
+
if (value !== null && typeof value === "object") {
|
|
3851
|
+
const out = {};
|
|
3852
|
+
for (const key of Object.keys(value).sort()) {
|
|
3853
|
+
const v = value[key];
|
|
3854
|
+
if (v !== void 0) {
|
|
3855
|
+
out[key] = canonical(v);
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
return out;
|
|
3859
|
+
}
|
|
3860
|
+
return value ?? null;
|
|
3861
|
+
}
|
|
3862
|
+
var DEFAULT_EVICTION = { maxIdle: 4 };
|
|
3863
|
+
var KeyedResource = class {
|
|
3864
|
+
constructor(_fetcher, options = {}) {
|
|
3865
|
+
this._fetcher = _fetcher;
|
|
3866
|
+
this._readiness = options.readiness ?? (() => "ready");
|
|
3867
|
+
this._hash = options.hash ?? hashKey;
|
|
3868
|
+
this._eviction = {
|
|
3869
|
+
maxIdle: options.eviction?.maxIdle ?? DEFAULT_EVICTION.maxIdle
|
|
3870
|
+
};
|
|
3871
|
+
}
|
|
3872
|
+
_fetcher;
|
|
3873
|
+
_entries = /* @__PURE__ */ new Map();
|
|
3874
|
+
_hash;
|
|
3875
|
+
_eviction;
|
|
3876
|
+
_readiness;
|
|
3877
|
+
hash(params) {
|
|
3878
|
+
return this._hash(params);
|
|
3879
|
+
}
|
|
3880
|
+
get size() {
|
|
3881
|
+
return this._entries.size;
|
|
3882
|
+
}
|
|
3883
|
+
entries() {
|
|
3884
|
+
return Array.from(this._entries, ([key, e]) => ({ key, ...e }));
|
|
3885
|
+
}
|
|
3886
|
+
get(params) {
|
|
3887
|
+
const key = this._hash(params);
|
|
3888
|
+
const existing = this._entries.get(key);
|
|
3889
|
+
if (existing !== void 0) {
|
|
3890
|
+
this._entries.delete(key);
|
|
3891
|
+
this._entries.set(key, existing);
|
|
3892
|
+
return existing.resource;
|
|
3893
|
+
}
|
|
3894
|
+
const resource = new Resource(
|
|
3895
|
+
() => this._fetcher(params, resource.snapshot.data),
|
|
3896
|
+
void 0,
|
|
3897
|
+
this._readiness
|
|
3898
|
+
);
|
|
3899
|
+
this._entries.set(key, { params, resource });
|
|
3900
|
+
return resource;
|
|
3901
|
+
}
|
|
3902
|
+
has(params) {
|
|
3903
|
+
return this._entries.has(this._hash(params));
|
|
3904
|
+
}
|
|
3905
|
+
subscribe(params, listener) {
|
|
3906
|
+
const resource = this.get(params);
|
|
3907
|
+
const unsubscribe = resource.subscribe(listener);
|
|
3908
|
+
return () => {
|
|
3909
|
+
unsubscribe();
|
|
3910
|
+
this._evict();
|
|
3911
|
+
};
|
|
3912
|
+
}
|
|
3913
|
+
seed(params, data) {
|
|
3914
|
+
this.get(params).seed(data);
|
|
3915
|
+
}
|
|
3916
|
+
evict(params) {
|
|
3917
|
+
return this._entries.delete(this._hash(params));
|
|
3918
|
+
}
|
|
3919
|
+
resetAll() {
|
|
3920
|
+
for (const [key, { resource }] of Array.from(this._entries)) {
|
|
3921
|
+
if (resource.subscriberCount === 0) {
|
|
3922
|
+
this._entries.delete(key);
|
|
3923
|
+
} else {
|
|
3924
|
+
resource.reset();
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
resumeAll() {
|
|
3929
|
+
for (const { resource } of this._entries.values()) {
|
|
3930
|
+
if (resource.subscriberCount === 0) {
|
|
3931
|
+
continue;
|
|
3932
|
+
}
|
|
3933
|
+
const { data, error } = resource.snapshot;
|
|
3934
|
+
if (data === void 0 || error !== void 0) {
|
|
3935
|
+
void resource.load();
|
|
3936
|
+
}
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
clearAll() {
|
|
3940
|
+
for (const [key, { resource }] of Array.from(this._entries)) {
|
|
3941
|
+
if (resource.subscriberCount === 0) {
|
|
3942
|
+
this._entries.delete(key);
|
|
3943
|
+
} else {
|
|
3944
|
+
resource.clear();
|
|
3945
|
+
}
|
|
3946
|
+
}
|
|
3947
|
+
}
|
|
3948
|
+
invalidateAll() {
|
|
3949
|
+
for (const { resource } of this._entries.values()) {
|
|
3950
|
+
if (resource.snapshot.data !== void 0) {
|
|
3951
|
+
void resource.refetch();
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
_evict() {
|
|
3956
|
+
const idle = Array.from(this._entries).filter(
|
|
3957
|
+
([, e]) => e.resource.subscriberCount === 0
|
|
3958
|
+
);
|
|
3959
|
+
let excess = idle.length - this._eviction.maxIdle;
|
|
3960
|
+
for (const [key] of idle) {
|
|
3961
|
+
if (excess <= 0) break;
|
|
3962
|
+
this._entries.delete(key);
|
|
3963
|
+
excess -= 1;
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
};
|
|
3967
|
+
|
|
3968
|
+
// src/billing/client.ts
|
|
3969
|
+
function claimOf(client) {
|
|
3970
|
+
return { status: client.sessionStatus, key: client.sessionKey };
|
|
3971
|
+
}
|
|
3972
|
+
function claimFrom(session) {
|
|
3973
|
+
if (session === void 0) {
|
|
3974
|
+
return void 0;
|
|
3975
|
+
}
|
|
3976
|
+
return session === null ? { status: "ended", key: void 0 } : { status: "active", key: sessionKey(session) };
|
|
3977
|
+
}
|
|
3978
|
+
function judgeSeed(seedKey, claim) {
|
|
3979
|
+
if (claim.status === "ended") {
|
|
3980
|
+
return "drop";
|
|
3981
|
+
}
|
|
3982
|
+
if (seedKey === void 0) {
|
|
3983
|
+
return "adopt";
|
|
3984
|
+
}
|
|
3985
|
+
if (claim.status === "pending") {
|
|
3986
|
+
return "hold";
|
|
3987
|
+
}
|
|
3988
|
+
return seedKey === claim.key ? "adopt" : "drop";
|
|
3989
|
+
}
|
|
3990
|
+
var READINESS = {
|
|
3991
|
+
pending: "waiting",
|
|
3992
|
+
active: "ready",
|
|
3993
|
+
ended: "never"
|
|
3994
|
+
};
|
|
3995
|
+
var BillingStore = class {
|
|
3996
|
+
constructor(_client, initialData = {}, options = {}) {
|
|
3997
|
+
this._client = _client;
|
|
3998
|
+
this._pageSize = options.pageSize ?? INVOICE_PAGE_SIZE;
|
|
3999
|
+
this.invoices = new KeyedResource(
|
|
4000
|
+
(query, current) => this._reloadWindow(
|
|
4001
|
+
query,
|
|
4002
|
+
Math.max(this._pageSize, current?.invoices.length ?? 0)
|
|
4003
|
+
),
|
|
4004
|
+
// Waiting until connected; then a session still pending stays
|
|
4005
|
+
// pending, and one that has ended settles empty rather than recording
|
|
4006
|
+
// the client's refusal as an error.
|
|
4007
|
+
{
|
|
4008
|
+
readiness: () => this._connected ? READINESS[this._client.sessionStatus] : "waiting"
|
|
4009
|
+
}
|
|
4010
|
+
);
|
|
4011
|
+
if (initialData.invoices !== void 0) {
|
|
4012
|
+
this._held = {
|
|
4013
|
+
// Normalized the way the hook normalizes, or the caller asking for
|
|
4014
|
+
// it fetches the same page again.
|
|
4015
|
+
params: normalizeInvoiceQuery2(
|
|
4016
|
+
initialData.params?.invoices ?? DEFAULT_INVOICE_QUERY
|
|
4017
|
+
),
|
|
4018
|
+
data: initialData.invoices,
|
|
4019
|
+
key: initialData.sessionKey
|
|
4020
|
+
};
|
|
4021
|
+
this._settleSeed(claimFrom(options.session) ?? claimOf(this._client));
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
_client;
|
|
4025
|
+
invoices;
|
|
4026
|
+
_pageSize;
|
|
4027
|
+
_unsubscribe;
|
|
4028
|
+
_connected = false;
|
|
4029
|
+
_seeded = false;
|
|
4030
|
+
/** The session that prefetch was for, where it said. */
|
|
4031
|
+
_seedKey;
|
|
4032
|
+
/** A stamped prefetch waiting for a session to check it against. */
|
|
4033
|
+
_held;
|
|
4034
|
+
/**
|
|
4035
|
+
* Not done in the constructor: the provider arms it from an effect, and
|
|
4036
|
+
* React runs an effect, its cleanup, then the effect again under
|
|
4037
|
+
* StrictMode. A subscription made once at construction is torn down by
|
|
4038
|
+
* that cleanup and never comes back, leaving the store deaf to every
|
|
4039
|
+
* session change for the rest of the page.
|
|
4040
|
+
*
|
|
4041
|
+
* Also what opens the store: subscribers who arrived first have been
|
|
4042
|
+
* waiting, and this is the moment the session is known to be installed.
|
|
4043
|
+
*/
|
|
4044
|
+
connect() {
|
|
4045
|
+
this._unsubscribe?.();
|
|
4046
|
+
const unsubscribe = this._client.onSessionChange?.((event) => {
|
|
4047
|
+
if (event.type === "ended") {
|
|
4048
|
+
this._held = void 0;
|
|
4049
|
+
this._seeded = false;
|
|
4050
|
+
this.clearAll();
|
|
4051
|
+
} else if (event.type === "changed") {
|
|
4052
|
+
this._held = void 0;
|
|
4053
|
+
this._seeded = false;
|
|
4054
|
+
this.resetAll();
|
|
4055
|
+
} else {
|
|
4056
|
+
this._onStarted();
|
|
4057
|
+
}
|
|
4058
|
+
});
|
|
4059
|
+
this._unsubscribe = unsubscribe;
|
|
4060
|
+
if (!this._connected) {
|
|
4061
|
+
this._connected = true;
|
|
4062
|
+
this._settleSeed(claimOf(this._client));
|
|
4063
|
+
this.resumeAll();
|
|
4064
|
+
}
|
|
4065
|
+
return () => {
|
|
4066
|
+
unsubscribe?.();
|
|
4067
|
+
if (this._unsubscribe === unsubscribe) {
|
|
4068
|
+
this._unsubscribe = void 0;
|
|
4069
|
+
}
|
|
4070
|
+
};
|
|
4071
|
+
}
|
|
4072
|
+
_onStarted() {
|
|
4073
|
+
const claim = claimOf(this._client);
|
|
4074
|
+
this._settleSeed(claim);
|
|
4075
|
+
if (this._seeded && judgeSeed(this._seedKey, claim) !== "adopt") {
|
|
4076
|
+
this._seeded = false;
|
|
4077
|
+
this.resetAll();
|
|
4078
|
+
return;
|
|
4079
|
+
}
|
|
4080
|
+
this._seeded = false;
|
|
4081
|
+
this.resumeAll();
|
|
4082
|
+
}
|
|
4083
|
+
/** Adopts, keeps holding, or drops the prefetch, by what `claim` says. */
|
|
4084
|
+
_settleSeed(claim) {
|
|
4085
|
+
const held = this._held;
|
|
4086
|
+
if (held === void 0) {
|
|
4087
|
+
return;
|
|
4088
|
+
}
|
|
4089
|
+
const verdict = judgeSeed(held.key, claim);
|
|
4090
|
+
if (verdict === "hold") {
|
|
4091
|
+
return;
|
|
4092
|
+
}
|
|
4093
|
+
this._held = void 0;
|
|
4094
|
+
if (verdict === "adopt") {
|
|
4095
|
+
this.invoices.seed(held.params, held.data);
|
|
4096
|
+
this._seedKey = held.key;
|
|
4097
|
+
this._seeded = true;
|
|
4098
|
+
}
|
|
4099
|
+
}
|
|
4100
|
+
resource(name) {
|
|
4101
|
+
return this[name];
|
|
4102
|
+
}
|
|
4103
|
+
/** Forgets every resource; subscribed ones reload, idle ones are dropped. */
|
|
4104
|
+
resetAll() {
|
|
4105
|
+
for (const name of RESOURCE_NAMES) {
|
|
4106
|
+
this[name].resetAll();
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
4109
|
+
/** Forgets every resource and leaves them empty; nothing reloads. */
|
|
4110
|
+
clearAll() {
|
|
4111
|
+
for (const name of RESOURCE_NAMES) {
|
|
4112
|
+
this[name].clearAll();
|
|
4113
|
+
}
|
|
4114
|
+
}
|
|
4115
|
+
/** Loads every resource that is subscribed and has nothing yet. */
|
|
4116
|
+
resumeAll() {
|
|
4117
|
+
for (const name of RESOURCE_NAMES) {
|
|
4118
|
+
this[name].resumeAll();
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
/** Reloads every resource that has been loaded, keeping its current data. */
|
|
4122
|
+
invalidateAll() {
|
|
4123
|
+
for (const name of RESOURCE_NAMES) {
|
|
4124
|
+
this[name].invalidateAll();
|
|
4125
|
+
}
|
|
4126
|
+
}
|
|
4127
|
+
/**
|
|
4128
|
+
* Appends the next page to the invoices list for `query`, when there is
|
|
4129
|
+
* one. A failure records the error on the resource and keeps the rows
|
|
4130
|
+
* already fetched; the returned promise never rejects.
|
|
4131
|
+
*/
|
|
4132
|
+
loadMoreInvoices(query = DEFAULT_INVOICE_QUERY) {
|
|
4133
|
+
const resource = this.invoices.get(normalizeInvoiceQuery2(query));
|
|
4134
|
+
if (resource.snapshot.data?.hasMore !== true) {
|
|
4135
|
+
return Promise.resolve();
|
|
4136
|
+
}
|
|
4137
|
+
return resource.extend(async (current) => {
|
|
4138
|
+
const page = await this._fetchInvoices(
|
|
4139
|
+
normalizeInvoiceQuery2(query),
|
|
4140
|
+
current.invoices.length,
|
|
4141
|
+
this._pageSize
|
|
4142
|
+
);
|
|
4143
|
+
const invoices = [...current.invoices, ...page.invoices];
|
|
4144
|
+
return {
|
|
4145
|
+
invoices,
|
|
4146
|
+
count: page.count,
|
|
4147
|
+
// From the count the page came back with, not the one the list was
|
|
4148
|
+
// built on: an invoice finalized between the two requests changes
|
|
4149
|
+
// what is left to load. An empty page ends the list whatever the
|
|
4150
|
+
// count says — the rows and the count are two queries, and a count
|
|
4151
|
+
// that outruns the rows would otherwise leave `hasMore` true for
|
|
4152
|
+
// good, with every further page fetching nothing.
|
|
4153
|
+
hasMore: page.invoices.length > 0 && invoices.length < page.count
|
|
4154
|
+
};
|
|
4155
|
+
});
|
|
4156
|
+
}
|
|
4157
|
+
dispose() {
|
|
4158
|
+
this._unsubscribe?.();
|
|
4159
|
+
}
|
|
4160
|
+
/**
|
|
4161
|
+
* Re-reads the window already loaded, in as many requests as the API's
|
|
4162
|
+
* page cap needs. A window paged past that cap still comes back whole:
|
|
4163
|
+
* asking for it in one request would be a 400, and asking for only the
|
|
4164
|
+
* first page would drop the rest.
|
|
4165
|
+
*/
|
|
4166
|
+
async _reloadWindow(query, window2) {
|
|
4167
|
+
const invoices = [];
|
|
4168
|
+
let count = 0;
|
|
4169
|
+
while (invoices.length < window2) {
|
|
4170
|
+
const page = await this._fetchInvoices(
|
|
4171
|
+
query,
|
|
4172
|
+
invoices.length,
|
|
4173
|
+
Math.min(INVOICE_MAX_PAGE_SIZE, window2 - invoices.length)
|
|
4174
|
+
);
|
|
4175
|
+
count = page.count;
|
|
4176
|
+
invoices.push(...page.invoices);
|
|
4177
|
+
if (page.invoices.length === 0 || invoices.length >= count) {
|
|
4178
|
+
break;
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
return {
|
|
4182
|
+
invoices,
|
|
4183
|
+
count,
|
|
4184
|
+
hasMore: invoices.length > 0 && invoices.length < count
|
|
4185
|
+
};
|
|
4186
|
+
}
|
|
4187
|
+
/**
|
|
4188
|
+
* Returns what the server said and nothing more: whether there is more to
|
|
4189
|
+
* load depends on the whole window, which only the caller assembling it
|
|
4190
|
+
* knows — `_reloadWindow` across its requests, and `loadMoreInvoices`
|
|
4191
|
+
* across the rows already loaded.
|
|
4192
|
+
*/
|
|
4193
|
+
_fetchInvoices(query, offset, limit) {
|
|
4194
|
+
return this._client.fetchInvoices({ ...query, limit, offset });
|
|
4195
|
+
}
|
|
4196
|
+
};
|
|
4197
|
+
var RESOURCE_NAMES = ["invoices"];
|
|
4198
|
+
|
|
4199
|
+
// src/billing/context.tsx
|
|
4200
|
+
var import_react2 = require("react");
|
|
4201
|
+
|
|
4202
|
+
// src/i18n/context.tsx
|
|
4203
|
+
var import_react = require("react");
|
|
4204
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
4205
|
+
var EMPTY = Object.freeze({});
|
|
4206
|
+
var SchematicI18nContext = (0, import_react.createContext)(EMPTY);
|
|
4207
|
+
function SchematicI18nProvider({
|
|
4208
|
+
children,
|
|
4209
|
+
locale,
|
|
4210
|
+
onMissingString,
|
|
4211
|
+
strings,
|
|
4212
|
+
translate
|
|
4213
|
+
}) {
|
|
4214
|
+
const parent = (0, import_react.useContext)(SchematicI18nContext);
|
|
4215
|
+
const value = (0, import_react.useMemo)(
|
|
4216
|
+
() => ({
|
|
4217
|
+
locale: locale ?? parent.locale,
|
|
4218
|
+
translate: translate ?? parent.translate,
|
|
4219
|
+
strings: strings === void 0 ? parent.strings : { ...parent.strings, ...strings },
|
|
4220
|
+
onMissingString: onMissingString ?? parent.onMissingString
|
|
4221
|
+
}),
|
|
4222
|
+
[locale, onMissingString, parent, strings, translate]
|
|
4223
|
+
);
|
|
4224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SchematicI18nContext.Provider, { value, children });
|
|
4225
|
+
}
|
|
4226
|
+
function useSchematicI18n() {
|
|
4227
|
+
return (0, import_react.useContext)(SchematicI18nContext);
|
|
4228
|
+
}
|
|
4229
|
+
function useSchematicLocale() {
|
|
4230
|
+
return (0, import_react.useContext)(SchematicI18nContext).locale;
|
|
4231
|
+
}
|
|
4232
|
+
function useSchematicTranslate() {
|
|
4233
|
+
return (0, import_react.useContext)(SchematicI18nContext).translate;
|
|
4234
|
+
}
|
|
4235
|
+
function useSchematicStrings() {
|
|
4236
|
+
return (0, import_react.useContext)(SchematicI18nContext).strings;
|
|
4237
|
+
}
|
|
4238
|
+
|
|
4239
|
+
// src/billing/context.tsx
|
|
4240
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
4241
|
+
var BillingDataContext = (0, import_react2.createContext)(
|
|
4242
|
+
void 0
|
|
4243
|
+
);
|
|
4244
|
+
var MISSING_BILLING_SOURCE_MESSAGE = "Schematic billing hooks need a SchematicProvider with a session, billingClient, or initialData, or a BillingDataProvider.";
|
|
4245
|
+
var missingSourceError = new Error(MISSING_BILLING_SOURCE_MESSAGE);
|
|
4246
|
+
var missingHandle = {
|
|
4247
|
+
data: void 0,
|
|
4248
|
+
error: missingSourceError,
|
|
4249
|
+
isPending: false,
|
|
4250
|
+
refetch: () => {
|
|
4251
|
+
}
|
|
4252
|
+
};
|
|
4253
|
+
var missingBillingSource = {
|
|
4254
|
+
subscribe: () => () => {
|
|
4255
|
+
},
|
|
4256
|
+
handle: () => missingHandle,
|
|
4257
|
+
loadMoreInvoices: () => Promise.resolve(),
|
|
4258
|
+
invalidateAll: () => {
|
|
4259
|
+
}
|
|
4260
|
+
};
|
|
4261
|
+
function useBillingDataSource() {
|
|
4262
|
+
return (0, import_react2.useContext)(BillingDataContext) ?? missingBillingSource;
|
|
4263
|
+
}
|
|
4264
|
+
function BillingDataProvider({
|
|
4265
|
+
children,
|
|
4266
|
+
data,
|
|
4267
|
+
locale,
|
|
4268
|
+
onLoadMoreInvoices,
|
|
4269
|
+
onMissingString,
|
|
4270
|
+
onRefetch,
|
|
4271
|
+
status,
|
|
4272
|
+
strings,
|
|
4273
|
+
translate
|
|
4274
|
+
}) {
|
|
4275
|
+
const source = (0, import_react2.useMemo)(() => {
|
|
4276
|
+
const handles = /* @__PURE__ */ new Map();
|
|
4277
|
+
return {
|
|
4278
|
+
subscribe: () => () => {
|
|
4279
|
+
},
|
|
4280
|
+
handle: (name) => {
|
|
4281
|
+
const cached = handles.get(name);
|
|
4282
|
+
if (cached !== void 0) {
|
|
4283
|
+
return cached;
|
|
4284
|
+
}
|
|
4285
|
+
const value = data[name];
|
|
4286
|
+
const override = status?.[name];
|
|
4287
|
+
const handle = {
|
|
4288
|
+
data: value,
|
|
4289
|
+
error: override?.error,
|
|
4290
|
+
isPending: override?.isPending ?? value === void 0,
|
|
4291
|
+
refetch: () => onRefetch?.(name)
|
|
4292
|
+
};
|
|
4293
|
+
handles.set(name, handle);
|
|
4294
|
+
return handle;
|
|
4295
|
+
},
|
|
4296
|
+
loadMoreInvoices: (query) => {
|
|
4297
|
+
onLoadMoreInvoices?.(query);
|
|
4298
|
+
return Promise.resolve();
|
|
4299
|
+
},
|
|
4300
|
+
invalidateAll: () => {
|
|
4301
|
+
}
|
|
4302
|
+
};
|
|
4303
|
+
}, [data, onLoadMoreInvoices, onRefetch, status]);
|
|
4304
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BillingDataContext.Provider, { value: source, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4305
|
+
SchematicI18nProvider,
|
|
4306
|
+
{
|
|
4307
|
+
locale,
|
|
4308
|
+
strings,
|
|
4309
|
+
translate,
|
|
4310
|
+
onMissingString,
|
|
4311
|
+
children
|
|
4312
|
+
}
|
|
4313
|
+
) });
|
|
4314
|
+
}
|
|
4315
|
+
|
|
4316
|
+
// src/billing/hooks.ts
|
|
4317
|
+
var import_react3 = require("react");
|
|
4318
|
+
function useStableParams(params) {
|
|
4319
|
+
const key = hashKey(params);
|
|
4320
|
+
const ref = (0, import_react3.useRef)({ key, params });
|
|
4321
|
+
if (ref.current.key !== key) {
|
|
4322
|
+
ref.current = { key, params };
|
|
4323
|
+
}
|
|
4324
|
+
return ref.current.params;
|
|
4325
|
+
}
|
|
4326
|
+
function useBillingResource(name, params) {
|
|
4327
|
+
const source = useBillingDataSource();
|
|
4328
|
+
const subscribe = (0, import_react3.useCallback)(
|
|
4329
|
+
(listener) => source.subscribe(name, params, listener),
|
|
4330
|
+
[name, params, source]
|
|
4331
|
+
);
|
|
4332
|
+
const getSnapshot = (0, import_react3.useCallback)(
|
|
4333
|
+
() => source.handle(name, params),
|
|
4334
|
+
[name, params, source]
|
|
4335
|
+
);
|
|
4336
|
+
return (0, import_react3.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
4337
|
+
}
|
|
4338
|
+
function useInvoices(query = DEFAULT_INVOICE_QUERY) {
|
|
4339
|
+
const source = useBillingDataSource();
|
|
4340
|
+
const params = useStableParams(normalizeInvoiceQuery2(query));
|
|
4341
|
+
const handle = useBillingResource("invoices", params);
|
|
4342
|
+
const loadMore = (0, import_react3.useCallback)(
|
|
4343
|
+
() => source.loadMoreInvoices(params),
|
|
4344
|
+
[params, source]
|
|
4345
|
+
);
|
|
4346
|
+
return (0, import_react3.useMemo)(() => ({ ...handle, loadMore }), [handle, loadMore]);
|
|
4347
|
+
}
|
|
4348
|
+
function useInvalidateBillingData() {
|
|
4349
|
+
return useBillingDataSource().invalidateAll;
|
|
4350
|
+
}
|
|
4351
|
+
|
|
4352
|
+
// src/billing/provider.tsx
|
|
4353
|
+
var import_react4 = require("react");
|
|
4354
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
4355
|
+
var SESSION_REPLACED_MESSAGE = "BillingProvider is moving its billingClient from one session to another. A client holds one session: if another provider shares this client, each will keep installing its own and show the other's data. Give each provider its own client.";
|
|
4356
|
+
function BillingProvider({
|
|
4357
|
+
billingClient,
|
|
4358
|
+
children,
|
|
4359
|
+
initialData,
|
|
4360
|
+
locale,
|
|
4361
|
+
onMissingString,
|
|
4362
|
+
session,
|
|
4363
|
+
strings,
|
|
4364
|
+
translate
|
|
4365
|
+
}) {
|
|
4366
|
+
const initialRef = (0, import_react4.useRef)(initialData);
|
|
4367
|
+
const install = () => {
|
|
4368
|
+
billingClient?.setSession?.(session);
|
|
4369
|
+
};
|
|
4370
|
+
(0, import_react4.useEffect)(() => {
|
|
4371
|
+
const claim = billingClient?.sessionKey;
|
|
4372
|
+
if (claim !== void 0 && session !== null && session !== void 0 && claim !== sessionKey(session)) {
|
|
4373
|
+
console.warn(SESSION_REPLACED_MESSAGE);
|
|
4374
|
+
}
|
|
4375
|
+
}, []);
|
|
4376
|
+
(0, import_react4.useEffect)(install);
|
|
4377
|
+
const seedSpent = (0, import_react4.useRef)(false);
|
|
4378
|
+
const store = (0, import_react4.useMemo)(
|
|
4379
|
+
() => billingClient === void 0 ? void 0 : new BillingStore(
|
|
4380
|
+
billingClient,
|
|
4381
|
+
seedSpent.current ? void 0 : initialRef.current,
|
|
4382
|
+
{
|
|
4383
|
+
// What `install` is about to say, so a stamped prefetch is
|
|
4384
|
+
// judged now rather than after the effect.
|
|
4385
|
+
session
|
|
4386
|
+
}
|
|
4387
|
+
),
|
|
4388
|
+
// `session` is read only when the store is built: the client learns
|
|
4389
|
+
// later sessions through `install`, and the store through the client.
|
|
4390
|
+
[billingClient]
|
|
4391
|
+
);
|
|
4392
|
+
(0, import_react4.useEffect)(() => {
|
|
4393
|
+
if (store !== void 0) {
|
|
4394
|
+
seedSpent.current = true;
|
|
4395
|
+
}
|
|
4396
|
+
}, [store]);
|
|
4397
|
+
(0, import_react4.useEffect)(() => store?.connect(), [store]);
|
|
4398
|
+
const source = (0, import_react4.useMemo)(() => {
|
|
4399
|
+
if (store === void 0) {
|
|
4400
|
+
return initialRef.current === void 0 ? void 0 : staticSource(initialRef.current);
|
|
4401
|
+
}
|
|
4402
|
+
const handles = /* @__PURE__ */ new WeakMap();
|
|
4403
|
+
const handle = (name, params) => {
|
|
4404
|
+
const resource = store.resource(name).get(params);
|
|
4405
|
+
const snapshot = resource.getSnapshot();
|
|
4406
|
+
const cached = handles.get(resource);
|
|
4407
|
+
if (cached !== void 0 && cached.snapshot === snapshot) {
|
|
4408
|
+
return cached.handle;
|
|
4409
|
+
}
|
|
4410
|
+
const next = {
|
|
4411
|
+
...snapshot,
|
|
4412
|
+
refetch: () => void resource.refetch()
|
|
4413
|
+
};
|
|
4414
|
+
handles.set(resource, { snapshot, handle: next });
|
|
4415
|
+
return next;
|
|
4416
|
+
};
|
|
4417
|
+
return {
|
|
4418
|
+
subscribe: (name, params, listener) => store.resource(name).subscribe(params, listener),
|
|
4419
|
+
handle,
|
|
4420
|
+
loadMoreInvoices: (query) => store.loadMoreInvoices(query),
|
|
4421
|
+
invalidateAll: () => store.invalidateAll()
|
|
4422
|
+
};
|
|
4423
|
+
}, [store]);
|
|
4424
|
+
const localized = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4425
|
+
SchematicI18nProvider,
|
|
4426
|
+
{
|
|
4427
|
+
locale,
|
|
4428
|
+
strings,
|
|
4429
|
+
translate,
|
|
4430
|
+
onMissingString,
|
|
4431
|
+
children
|
|
4432
|
+
}
|
|
4433
|
+
);
|
|
4434
|
+
if (source === void 0) {
|
|
4435
|
+
return localized;
|
|
4436
|
+
}
|
|
4437
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BillingDataContext.Provider, { value: source, children: localized });
|
|
4438
|
+
}
|
|
4439
|
+
function staticSource(data) {
|
|
4440
|
+
const handles = /* @__PURE__ */ new Map();
|
|
4441
|
+
return {
|
|
4442
|
+
subscribe: () => () => {
|
|
4443
|
+
},
|
|
4444
|
+
handle: (name) => {
|
|
4445
|
+
const cached = handles.get(name);
|
|
4446
|
+
if (cached !== void 0) {
|
|
4447
|
+
return cached;
|
|
4448
|
+
}
|
|
4449
|
+
const value = data[name];
|
|
4450
|
+
const next = {
|
|
4451
|
+
data: value,
|
|
4452
|
+
error: void 0,
|
|
4453
|
+
isPending: value === void 0,
|
|
4454
|
+
refetch: () => {
|
|
4455
|
+
}
|
|
4456
|
+
};
|
|
4457
|
+
handles.set(name, next);
|
|
4458
|
+
return next;
|
|
4459
|
+
},
|
|
4460
|
+
loadMoreInvoices: () => Promise.resolve(),
|
|
4461
|
+
invalidateAll: () => {
|
|
4462
|
+
}
|
|
4463
|
+
};
|
|
4464
|
+
}
|
|
2923
4465
|
|
|
2924
4466
|
// src/version.ts
|
|
2925
|
-
var version2 = "1.
|
|
4467
|
+
var version2 = "1.7.0";
|
|
2926
4468
|
|
|
2927
4469
|
// src/context/schematic.tsx
|
|
2928
|
-
var
|
|
2929
|
-
var SchematicContext = (0,
|
|
4470
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
4471
|
+
var SchematicContext = (0, import_react5.createContext)(
|
|
2930
4472
|
null
|
|
2931
4473
|
);
|
|
2932
4474
|
var SchematicProvider = ({
|
|
4475
|
+
session,
|
|
4476
|
+
billingClient,
|
|
2933
4477
|
children,
|
|
2934
4478
|
client: providedClient,
|
|
4479
|
+
initialData,
|
|
4480
|
+
locale,
|
|
4481
|
+
onMissingString,
|
|
2935
4482
|
publishableKey,
|
|
4483
|
+
strings,
|
|
4484
|
+
translate,
|
|
2936
4485
|
...clientOpts
|
|
2937
4486
|
}) => {
|
|
2938
|
-
const initialOptsRef = (0,
|
|
4487
|
+
const initialOptsRef = (0, import_react5.useRef)({
|
|
2939
4488
|
publishableKey,
|
|
2940
4489
|
useWebSocket: true,
|
|
2941
4490
|
additionalHeaders: {
|
|
@@ -2943,7 +4492,7 @@ var SchematicProvider = ({
|
|
|
2943
4492
|
},
|
|
2944
4493
|
...clientOpts
|
|
2945
4494
|
});
|
|
2946
|
-
const client = (0,
|
|
4495
|
+
const client = (0, import_react5.useMemo)(() => {
|
|
2947
4496
|
if (providedClient) {
|
|
2948
4497
|
return providedClient;
|
|
2949
4498
|
}
|
|
@@ -2951,7 +4500,7 @@ var SchematicProvider = ({
|
|
|
2951
4500
|
...initialOptsRef.current
|
|
2952
4501
|
});
|
|
2953
4502
|
}, [providedClient]);
|
|
2954
|
-
(0,
|
|
4503
|
+
(0, import_react5.useEffect)(() => {
|
|
2955
4504
|
return () => {
|
|
2956
4505
|
if (!providedClient) {
|
|
2957
4506
|
client.cleanup().catch((error) => {
|
|
@@ -2960,16 +4509,46 @@ var SchematicProvider = ({
|
|
|
2960
4509
|
}
|
|
2961
4510
|
};
|
|
2962
4511
|
}, [client, providedClient]);
|
|
2963
|
-
const contextValue = (0,
|
|
4512
|
+
const contextValue = (0, import_react5.useMemo)(
|
|
2964
4513
|
() => ({
|
|
2965
4514
|
client
|
|
2966
4515
|
}),
|
|
2967
4516
|
[client]
|
|
2968
4517
|
);
|
|
2969
|
-
|
|
4518
|
+
const { apiUrl, additionalHeaders } = initialOptsRef.current;
|
|
4519
|
+
const providedApiUrl = providedClient?.apiUrl;
|
|
4520
|
+
const resolvedBillingClient = (0, import_react5.useMemo)(
|
|
4521
|
+
() => billingClient ?? new SchematicBillingClient({
|
|
4522
|
+
session,
|
|
4523
|
+
apiUrl: apiUrl ?? providedApiUrl,
|
|
4524
|
+
// Read as they stand when a client is built: headers do not change
|
|
4525
|
+
// where the token goes, so they are no reason to build one.
|
|
4526
|
+
additionalHeaders: {
|
|
4527
|
+
...providedClient?.additionalHeaders,
|
|
4528
|
+
...additionalHeaders
|
|
4529
|
+
}
|
|
4530
|
+
}),
|
|
4531
|
+
// `session` is deliberately absent: `BillingProvider` forwards it through
|
|
4532
|
+
// `setSession`, so a token change resets the billing resources without
|
|
4533
|
+
// rebuilding the client.
|
|
4534
|
+
[additionalHeaders, apiUrl, billingClient, providedApiUrl]
|
|
4535
|
+
);
|
|
4536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SchematicContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4537
|
+
BillingProvider,
|
|
4538
|
+
{
|
|
4539
|
+
billingClient: resolvedBillingClient,
|
|
4540
|
+
initialData,
|
|
4541
|
+
locale,
|
|
4542
|
+
session,
|
|
4543
|
+
strings,
|
|
4544
|
+
translate,
|
|
4545
|
+
onMissingString,
|
|
4546
|
+
children
|
|
4547
|
+
}
|
|
4548
|
+
) });
|
|
2970
4549
|
};
|
|
2971
4550
|
var useSchematic = () => {
|
|
2972
|
-
const context =
|
|
4551
|
+
const context = import_react5.default.useContext(SchematicContext);
|
|
2973
4552
|
if (context === null) {
|
|
2974
4553
|
throw new Error("useSchematic must be used within a SchematicProvider");
|
|
2975
4554
|
}
|
|
@@ -2977,11 +4556,11 @@ var useSchematic = () => {
|
|
|
2977
4556
|
};
|
|
2978
4557
|
|
|
2979
4558
|
// src/hooks/schematic.ts
|
|
2980
|
-
var
|
|
4559
|
+
var import_react6 = require("react");
|
|
2981
4560
|
var useSchematicClient = (opts) => {
|
|
2982
4561
|
const schematic = useSchematic();
|
|
2983
4562
|
const { client } = opts ?? {};
|
|
2984
|
-
return (0,
|
|
4563
|
+
return (0, import_react6.useMemo)(() => {
|
|
2985
4564
|
if (client) {
|
|
2986
4565
|
return client;
|
|
2987
4566
|
}
|
|
@@ -2990,7 +4569,7 @@ var useSchematicClient = (opts) => {
|
|
|
2990
4569
|
};
|
|
2991
4570
|
var useSchematicContext = (opts) => {
|
|
2992
4571
|
const client = useSchematicClient(opts);
|
|
2993
|
-
return (0,
|
|
4572
|
+
return (0, import_react6.useMemo)(
|
|
2994
4573
|
() => ({
|
|
2995
4574
|
setContext: client.setContext.bind(client)
|
|
2996
4575
|
}),
|
|
@@ -2999,33 +4578,33 @@ var useSchematicContext = (opts) => {
|
|
|
2999
4578
|
};
|
|
3000
4579
|
var useSchematicEvents = (opts) => {
|
|
3001
4580
|
const client = useSchematicClient(opts);
|
|
3002
|
-
const track = (0,
|
|
4581
|
+
const track = (0, import_react6.useCallback)(
|
|
3003
4582
|
(...args) => client.track(...args),
|
|
3004
4583
|
[client]
|
|
3005
4584
|
);
|
|
3006
|
-
const identify = (0,
|
|
4585
|
+
const identify = (0, import_react6.useCallback)(
|
|
3007
4586
|
(...args) => client.identify(...args),
|
|
3008
4587
|
[client]
|
|
3009
4588
|
);
|
|
3010
|
-
return (0,
|
|
4589
|
+
return (0, import_react6.useMemo)(() => ({ track, identify }), [track, identify]);
|
|
3011
4590
|
};
|
|
3012
4591
|
var useSchematicFlag = (key, opts) => {
|
|
3013
4592
|
const client = useSchematicClient(opts);
|
|
3014
4593
|
const fallback = opts?.fallback ?? false;
|
|
3015
|
-
const subscribe = (0,
|
|
4594
|
+
const subscribe = (0, import_react6.useCallback)(
|
|
3016
4595
|
(callback) => client.addFlagValueListener(key, callback),
|
|
3017
4596
|
[client, key]
|
|
3018
4597
|
);
|
|
3019
|
-
const getSnapshot = (0,
|
|
4598
|
+
const getSnapshot = (0, import_react6.useCallback)(() => {
|
|
3020
4599
|
const value = client.getFlagValue(key);
|
|
3021
4600
|
return typeof value === "undefined" ? fallback : value;
|
|
3022
4601
|
}, [client, key, fallback]);
|
|
3023
|
-
return (0,
|
|
4602
|
+
return (0, import_react6.useSyncExternalStore)(subscribe, getSnapshot, () => fallback);
|
|
3024
4603
|
};
|
|
3025
4604
|
var useSchematicEntitlement = (key, opts) => {
|
|
3026
4605
|
const client = useSchematicClient(opts);
|
|
3027
4606
|
const fallback = opts?.fallback ?? false;
|
|
3028
|
-
const fallbackCheck = (0,
|
|
4607
|
+
const fallbackCheck = (0, import_react6.useMemo)(
|
|
3029
4608
|
() => ({
|
|
3030
4609
|
flag: key,
|
|
3031
4610
|
reason: "Fallback",
|
|
@@ -3033,20 +4612,20 @@ var useSchematicEntitlement = (key, opts) => {
|
|
|
3033
4612
|
}),
|
|
3034
4613
|
[key, fallback]
|
|
3035
4614
|
);
|
|
3036
|
-
const subscribe = (0,
|
|
4615
|
+
const subscribe = (0, import_react6.useCallback)(
|
|
3037
4616
|
(callback) => client.addFlagCheckListener(key, callback),
|
|
3038
4617
|
[client, key]
|
|
3039
4618
|
);
|
|
3040
|
-
const getSnapshot = (0,
|
|
4619
|
+
const getSnapshot = (0, import_react6.useCallback)(() => {
|
|
3041
4620
|
const check = client.getFlagCheck(key);
|
|
3042
4621
|
return check ?? fallbackCheck;
|
|
3043
4622
|
}, [client, key, fallbackCheck]);
|
|
3044
|
-
return (0,
|
|
4623
|
+
return (0, import_react6.useSyncExternalStore)(subscribe, getSnapshot, () => fallbackCheck);
|
|
3045
4624
|
};
|
|
3046
4625
|
var useSchematicPlan = (opts) => {
|
|
3047
4626
|
const client = useSchematicClient(opts);
|
|
3048
4627
|
const fallback = opts?.fallback;
|
|
3049
|
-
const fallbackPlan = (0,
|
|
4628
|
+
const fallbackPlan = (0, import_react6.useMemo)(
|
|
3050
4629
|
() => fallback,
|
|
3051
4630
|
[
|
|
3052
4631
|
fallback?.id,
|
|
@@ -3055,37 +4634,37 @@ var useSchematicPlan = (opts) => {
|
|
|
3055
4634
|
fallback?.trialStatus
|
|
3056
4635
|
]
|
|
3057
4636
|
);
|
|
3058
|
-
const subscribe = (0,
|
|
4637
|
+
const subscribe = (0, import_react6.useCallback)(
|
|
3059
4638
|
(callback) => client.addPlanListener(callback),
|
|
3060
4639
|
[client]
|
|
3061
4640
|
);
|
|
3062
|
-
const getSnapshot = (0,
|
|
4641
|
+
const getSnapshot = (0, import_react6.useCallback)(() => {
|
|
3063
4642
|
const plan = client.getPlan();
|
|
3064
4643
|
return plan ?? fallbackPlan;
|
|
3065
4644
|
}, [client, fallbackPlan]);
|
|
3066
|
-
return (0,
|
|
4645
|
+
return (0, import_react6.useSyncExternalStore)(subscribe, getSnapshot, () => fallbackPlan);
|
|
3067
4646
|
};
|
|
3068
4647
|
var useSchematicCreditBalance = (creditId, opts) => {
|
|
3069
4648
|
const client = useSchematicClient(opts);
|
|
3070
|
-
const subscribe = (0,
|
|
4649
|
+
const subscribe = (0, import_react6.useCallback)(
|
|
3071
4650
|
(callback) => client.addCreditBalanceListener(callback),
|
|
3072
4651
|
[client]
|
|
3073
4652
|
);
|
|
3074
|
-
const getSnapshot = (0,
|
|
3075
|
-
() => client.getCreditBalance(creditId),
|
|
4653
|
+
const getSnapshot = (0, import_react6.useCallback)(
|
|
4654
|
+
() => creditId === void 0 ? void 0 : client.getCreditBalance(creditId),
|
|
3076
4655
|
[client, creditId]
|
|
3077
4656
|
);
|
|
3078
|
-
const balance = (0,
|
|
3079
|
-
const isPendingSubscribe = (0,
|
|
4657
|
+
const balance = (0, import_react6.useSyncExternalStore)(subscribe, getSnapshot, () => void 0);
|
|
4658
|
+
const isPendingSubscribe = (0, import_react6.useCallback)(
|
|
3080
4659
|
(callback) => client.addIsPendingListener(callback),
|
|
3081
4660
|
[client]
|
|
3082
4661
|
);
|
|
3083
|
-
const isPending = (0,
|
|
4662
|
+
const isPending = (0, import_react6.useSyncExternalStore)(
|
|
3084
4663
|
isPendingSubscribe,
|
|
3085
4664
|
() => client.getIsPending(),
|
|
3086
4665
|
() => true
|
|
3087
4666
|
);
|
|
3088
|
-
return (0,
|
|
4667
|
+
return (0, import_react6.useMemo)(
|
|
3089
4668
|
() => ({
|
|
3090
4669
|
balance: balance?.settled ?? 0,
|
|
3091
4670
|
isLoading: balance === void 0 && isPending
|
|
@@ -3095,12 +4674,12 @@ var useSchematicCreditBalance = (creditId, opts) => {
|
|
|
3095
4674
|
};
|
|
3096
4675
|
var useSchematicIsPending = (opts) => {
|
|
3097
4676
|
const client = useSchematicClient(opts);
|
|
3098
|
-
const subscribe = (0,
|
|
4677
|
+
const subscribe = (0, import_react6.useCallback)(
|
|
3099
4678
|
(callback) => client.addIsPendingListener(callback),
|
|
3100
4679
|
[client]
|
|
3101
4680
|
);
|
|
3102
|
-
const getSnapshot = (0,
|
|
3103
|
-
return (0,
|
|
4681
|
+
const getSnapshot = (0, import_react6.useCallback)(() => client.getIsPending(), [client]);
|
|
4682
|
+
return (0, import_react6.useSyncExternalStore)(subscribe, getSnapshot, () => true);
|
|
3104
4683
|
};
|
|
3105
4684
|
/*! Bundled license information:
|
|
3106
4685
|
|