@onereach/billing-shared 31.17.0 → 31.17.1-beta.13420.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.
Files changed (71) hide show
  1. package/dist/cjs/billing-boundaries/index.js +49 -0
  2. package/dist/cjs/billing-boundaries/index.js.map +1 -0
  3. package/dist/cjs/billing-boundaries/types.js +3 -0
  4. package/dist/cjs/billing-boundaries/types.js.map +1 -0
  5. package/dist/cjs/index.js +2 -0
  6. package/dist/cjs/index.js.map +1 -1
  7. package/dist/cjs/usage-granularity/constants.js +7 -0
  8. package/dist/cjs/usage-granularity/constants.js.map +1 -0
  9. package/dist/cjs/usage-granularity/index.js +23 -0
  10. package/dist/cjs/usage-granularity/index.js.map +1 -0
  11. package/dist/cjs/usage-granularity/metric-policy.js +45 -0
  12. package/dist/cjs/usage-granularity/metric-policy.js.map +1 -0
  13. package/dist/cjs/usage-granularity/reporting.types.js +3 -0
  14. package/dist/cjs/usage-granularity/reporting.types.js.map +1 -0
  15. package/dist/cjs/usage-granularity/source-event-policy.js +48 -0
  16. package/dist/cjs/usage-granularity/source-event-policy.js.map +1 -0
  17. package/dist/cjs/usage-granularity/types.js +3 -0
  18. package/dist/cjs/usage-granularity/types.js.map +1 -0
  19. package/dist/cjs/usage-granularity/usage-granularity.js +67 -0
  20. package/dist/cjs/usage-granularity/usage-granularity.js.map +1 -0
  21. package/dist/esm/billing-boundaries/index.js +42 -0
  22. package/dist/esm/billing-boundaries/index.js.map +1 -0
  23. package/dist/esm/billing-boundaries/types.js +2 -0
  24. package/dist/esm/billing-boundaries/types.js.map +1 -0
  25. package/dist/esm/index.js +2 -0
  26. package/dist/esm/index.js.map +1 -1
  27. package/dist/esm/usage-granularity/constants.js +4 -0
  28. package/dist/esm/usage-granularity/constants.js.map +1 -0
  29. package/dist/esm/usage-granularity/index.js +7 -0
  30. package/dist/esm/usage-granularity/index.js.map +1 -0
  31. package/dist/esm/usage-granularity/metric-policy.js +40 -0
  32. package/dist/esm/usage-granularity/metric-policy.js.map +1 -0
  33. package/dist/esm/usage-granularity/reporting.types.js +2 -0
  34. package/dist/esm/usage-granularity/reporting.types.js.map +1 -0
  35. package/dist/esm/usage-granularity/source-event-policy.js +43 -0
  36. package/dist/esm/usage-granularity/source-event-policy.js.map +1 -0
  37. package/dist/esm/usage-granularity/types.js +2 -0
  38. package/dist/esm/usage-granularity/types.js.map +1 -0
  39. package/dist/esm/usage-granularity/usage-granularity.js +60 -0
  40. package/dist/esm/usage-granularity/usage-granularity.js.map +1 -0
  41. package/dist/types/billing-boundaries/index.d.ts +6 -0
  42. package/dist/types/billing-boundaries/index.d.ts.map +1 -0
  43. package/dist/types/billing-boundaries/types.d.ts +9 -0
  44. package/dist/types/billing-boundaries/types.d.ts.map +1 -0
  45. package/dist/types/index.d.ts +2 -0
  46. package/dist/types/index.d.ts.map +1 -1
  47. package/dist/types/usage-granularity/constants.d.ts +4 -0
  48. package/dist/types/usage-granularity/constants.d.ts.map +1 -0
  49. package/dist/types/usage-granularity/index.d.ts +7 -0
  50. package/dist/types/usage-granularity/index.d.ts.map +1 -0
  51. package/dist/types/usage-granularity/metric-policy.d.ts +4 -0
  52. package/dist/types/usage-granularity/metric-policy.d.ts.map +1 -0
  53. package/dist/types/usage-granularity/reporting.types.d.ts +14 -0
  54. package/dist/types/usage-granularity/reporting.types.d.ts.map +1 -0
  55. package/dist/types/usage-granularity/source-event-policy.d.ts +7 -0
  56. package/dist/types/usage-granularity/source-event-policy.d.ts.map +1 -0
  57. package/dist/types/usage-granularity/types.d.ts +8 -0
  58. package/dist/types/usage-granularity/types.d.ts.map +1 -0
  59. package/dist/types/usage-granularity/usage-granularity.d.ts +7 -0
  60. package/dist/types/usage-granularity/usage-granularity.d.ts.map +1 -0
  61. package/package.json +1 -1
  62. package/src/billing-boundaries/index.ts +52 -0
  63. package/src/billing-boundaries/types.ts +9 -0
  64. package/src/index.ts +2 -0
  65. package/src/usage-granularity/constants.ts +5 -0
  66. package/src/usage-granularity/index.ts +6 -0
  67. package/src/usage-granularity/metric-policy.ts +41 -0
  68. package/src/usage-granularity/reporting.types.ts +15 -0
  69. package/src/usage-granularity/source-event-policy.ts +45 -0
  70. package/src/usage-granularity/types.ts +9 -0
  71. package/src/usage-granularity/usage-granularity.ts +72 -0
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isUtcMidnight = isUtcMidnight;
4
+ exports.isUtcInclusiveDateEnd = isUtcInclusiveDateEnd;
5
+ exports.toExclusiveUtcDateEnd = toExclusiveUtcDateEnd;
6
+ exports.getUtcBillingDateIssues = getUtcBillingDateIssues;
7
+ var UTC_DAY_MS = 24 * 60 * 60 * 1000;
8
+ function isUtcMidnight(value) {
9
+ return value instanceof Date && Number.isFinite(value.getTime()) && value.getTime() % UTC_DAY_MS === 0;
10
+ }
11
+ function isUtcInclusiveDateEnd(value) {
12
+ if (!(value instanceof Date) || !Number.isFinite(value.getTime()))
13
+ return false;
14
+ var time = value.getTime();
15
+ return (isUtcMidnight(value) || (time + 1) % UTC_DAY_MS === 0)
16
+ && Number.isFinite(new Date(Math.floor(time / UTC_DAY_MS) * UTC_DAY_MS + UTC_DAY_MS).getTime());
17
+ }
18
+ function toExclusiveUtcDateEnd(value) {
19
+ if (!isUtcInclusiveDateEnd(value)) {
20
+ throw new RangeError('Billing end date must be a UTC calendar date or UTC end of day');
21
+ }
22
+ return new Date(Math.floor(value.getTime() / UTC_DAY_MS) * UTC_DAY_MS + UTC_DAY_MS);
23
+ }
24
+ function getUtcBillingDateIssues(startDate, endDate, options) {
25
+ if (options === void 0) { options = {}; }
26
+ var issues = [];
27
+ var prefix = options.pathPrefix ? "".concat(options.pathPrefix, ".") : '';
28
+ if (!isUtcMidnight(startDate)) {
29
+ issues.push({
30
+ path: "".concat(prefix, "startDate"),
31
+ constraints: { utcMidnight: 'Start date must be a valid date at midnight UTC' },
32
+ });
33
+ }
34
+ var openEnd = options.allowOpenEnd && (endDate === null || endDate === undefined);
35
+ if (!openEnd && !isUtcInclusiveDateEnd(endDate)) {
36
+ issues.push({
37
+ path: "".concat(prefix, "endDate"),
38
+ constraints: { utcCalendarEnd: 'End date must be a valid UTC calendar date at midnight or 23:59:59.999 UTC (inclusive)' },
39
+ });
40
+ }
41
+ if (isUtcMidnight(startDate) && isUtcInclusiveDateEnd(endDate) && toExclusiveUtcDateEnd(endDate) <= startDate) {
42
+ issues.push({
43
+ path: "".concat(prefix, "endDate"),
44
+ constraints: { minDate: 'End date must not be before the start date' },
45
+ });
46
+ }
47
+ return issues;
48
+ }
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/billing-boundaries/index.ts"],"names":[],"mappings":";;AAIA,sCAEC;AAGD,sDAKC;AAGD,sDAKC;AAED,0DA2BC;AAjDD,IAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEvC,SAAgB,aAAa,CAAC,KAAc;IAC1C,OAAO,KAAK,YAAY,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,GAAG,UAAU,KAAK,CAAC,CAAC;AACzG,CAAC;AAGD,SAAgB,qBAAqB,CAAC,KAAc;IAClD,IAAI,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAChF,IAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7B,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC;WACzD,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AACpG,CAAC;AAGD,SAAgB,qBAAqB,CAAC,KAAW;IAC/C,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,UAAU,CAAC,gEAAgE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC;AACtF,CAAC;AAED,SAAgB,uBAAuB,CACrC,SAAkB,EAClB,OAAgB,EAChB,OAA0C;IAA1C,wBAAA,EAAA,YAA0C;IAE1C,IAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,IAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,UAAG,OAAO,CAAC,UAAU,MAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,UAAG,MAAM,cAAW;YAC1B,WAAW,EAAE,EAAE,WAAW,EAAE,iDAAiD,EAAE;SAChF,CAAC,CAAC;IACL,CAAC;IACD,IAAM,OAAO,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC;IACpF,IAAI,CAAC,OAAO,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,UAAG,MAAM,YAAS;YACxB,WAAW,EAAE,EAAE,cAAc,EAAE,wFAAwF,EAAE;SAC1H,CAAC,CAAC;IACL,CAAC;IACD,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,qBAAqB,CAAC,OAAO,CAAC,IAAI,qBAAqB,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;QAC9G,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,UAAG,MAAM,YAAS;YACxB,WAAW,EAAE,EAAE,OAAO,EAAE,4CAA4C,EAAE;SACvE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/billing-boundaries/types.ts"],"names":[],"mappings":""}
package/dist/cjs/index.js CHANGED
@@ -18,4 +18,6 @@ __exportStar(require("./enums"), exports);
18
18
  __exportStar(require("./constants"), exports);
19
19
  __exportStar(require("./types"), exports);
20
20
  __exportStar(require("./utils"), exports);
21
+ __exportStar(require("./usage-granularity"), exports);
22
+ __exportStar(require("./billing-boundaries"), exports);
21
23
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,8CAA4B;AAC5B,0CAAwB;AACxB,0CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,8CAA4B;AAC5B,0CAAwB;AACxB,0CAAwB;AACxB,sDAAoC;AACpC,uDAAqC"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.USAGE_HOUR_MS = exports.DEFAULT_USAGE_GRANULARITY_HOURS = exports.USAGE_GRANULARITY_HOURS = void 0;
4
+ exports.USAGE_GRANULARITY_HOURS = [1, 2, 3, 4, 6, 8, 12, 24];
5
+ exports.DEFAULT_USAGE_GRANULARITY_HOURS = 1;
6
+ exports.USAGE_HOUR_MS = 3600000;
7
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/usage-granularity/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,uBAAuB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAU,CAAC;AAE9D,QAAA,+BAA+B,GAAG,CAAC,CAAC;AAEpC,QAAA,aAAa,GAAG,OAAO,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./constants"), exports);
18
+ __exportStar(require("./types"), exports);
19
+ __exportStar(require("./usage-granularity"), exports);
20
+ __exportStar(require("./source-event-policy"), exports);
21
+ __exportStar(require("./reporting.types"), exports);
22
+ __exportStar(require("./metric-policy"), exports);
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/usage-granularity/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,0CAAwB;AACxB,sDAAoC;AACpC,wDAAsC;AACtC,oDAAkC;AAClC,kDAAgC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.supportsCoarseUsageCollection = supportsCoarseUsageCollection;
5
+ exports.assertUsageCollectionMetric = assertUsageCollectionMetric;
6
+ var category_namespace_1 = require("../enums/category-namespace");
7
+ var customer_usage_1 = require("../enums/customer-usage");
8
+ var COARSE_EVENTS = (_a = {},
9
+ _a[customer_usage_1.DataSourceProvider.AZURE] = [
10
+ category_namespace_1.CategoryNamespace.PROCESSING_FLOW,
11
+ category_namespace_1.CategoryNamespace.PROCESSING_VOICE,
12
+ category_namespace_1.CategoryNamespace.EXECUTABLE_GENERAL,
13
+ category_namespace_1.CategoryNamespace.EXECUTABLE_PORT_IN_IDENTIFIER,
14
+ category_namespace_1.CategoryNamespace.LOOKUP,
15
+ category_namespace_1.CategoryNamespace.TELEPHONY_VOICE,
16
+ category_namespace_1.CategoryNamespace.MESSAGING_TEXT,
17
+ category_namespace_1.CategoryNamespace.CONVERSATIONS_WAP,
18
+ category_namespace_1.CategoryNamespace.CARRIER_FEE,
19
+ category_namespace_1.CategoryNamespace.USER,
20
+ category_namespace_1.CategoryNamespace.IDENTIFIER,
21
+ category_namespace_1.CategoryNamespace.STORAGE_GENERAL,
22
+ category_namespace_1.CategoryNamespace.STORAGE_WEAVIATE,
23
+ ],
24
+ _a[customer_usage_1.DataSourceProvider.DRUID] = [
25
+ category_namespace_1.CategoryNamespace.EXECUTABLE_LLM,
26
+ category_namespace_1.CategoryNamespace.EXECUTABLE_GENERAL,
27
+ category_namespace_1.CategoryNamespace.STORAGE_WEAVIATE,
28
+ category_namespace_1.CategoryNamespace.LOOKUP,
29
+ category_namespace_1.CategoryNamespace.TELEPHONY_VOICE,
30
+ category_namespace_1.CategoryNamespace.PROCESSING_VOICE,
31
+ category_namespace_1.CategoryNamespace.CARRIER_FEE,
32
+ category_namespace_1.CategoryNamespace.MESSAGING_TEXT,
33
+ ],
34
+ _a);
35
+ function supportsCoarseUsageCollection(provider, eventType) {
36
+ if (provider !== customer_usage_1.DataSourceProvider.AZURE && provider !== customer_usage_1.DataSourceProvider.DRUID)
37
+ return false;
38
+ return COARSE_EVENTS[provider].includes(eventType);
39
+ }
40
+ function assertUsageCollectionMetric(provider, eventType, hours) {
41
+ if (hours > 1 && !supportsCoarseUsageCollection(provider, eventType)) {
42
+ throw new Error("Coarse collection is not verified for ".concat(provider, "/").concat(eventType, "; use 1h granularity"));
43
+ }
44
+ }
45
+ //# sourceMappingURL=metric-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-policy.js","sourceRoot":"","sources":["../../../src/usage-granularity/metric-policy.ts"],"names":[],"mappings":";;;AA+BA,sEAGC;AAED,kEAIC;AAxCD,kEAAgE;AAChE,0DAA6D;AAE7D,IAAM,aAAa;IACjB,GAAC,mCAAkB,CAAC,KAAK,IAAG;QAC1B,sCAAiB,CAAC,eAAe;QACjC,sCAAiB,CAAC,gBAAgB;QAClC,sCAAiB,CAAC,kBAAkB;QACpC,sCAAiB,CAAC,6BAA6B;QAC/C,sCAAiB,CAAC,MAAM;QACxB,sCAAiB,CAAC,eAAe;QACjC,sCAAiB,CAAC,cAAc;QAChC,sCAAiB,CAAC,iBAAiB;QACnC,sCAAiB,CAAC,WAAW;QAC7B,sCAAiB,CAAC,IAAI;QACtB,sCAAiB,CAAC,UAAU;QAC5B,sCAAiB,CAAC,eAAe;QACjC,sCAAiB,CAAC,gBAAgB;KACnC;IACD,GAAC,mCAAkB,CAAC,KAAK,IAAG;QAC1B,sCAAiB,CAAC,cAAc;QAChC,sCAAiB,CAAC,kBAAkB;QACpC,sCAAiB,CAAC,gBAAgB;QAClC,sCAAiB,CAAC,MAAM;QACxB,sCAAiB,CAAC,eAAe;QACjC,sCAAiB,CAAC,gBAAgB;QAClC,sCAAiB,CAAC,WAAW;QAC7B,sCAAiB,CAAC,cAAc;KACjC;OACF,CAAC;AAEF,SAAgB,6BAA6B,CAAC,QAAgB,EAAE,SAA4B;IAC1F,IAAI,QAAQ,KAAK,mCAAkB,CAAC,KAAK,IAAI,QAAQ,KAAK,mCAAkB,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACjG,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AACrD,CAAC;AAED,SAAgB,2BAA2B,CAAC,QAAgB,EAAE,SAA4B,EAAE,KAAa;IACvG,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,gDAAyC,QAAQ,cAAI,SAAS,yBAAsB,CAAC,CAAC;IACxG,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=reporting.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporting.types.js","sourceRoot":"","sources":["../../../src/usage-granularity/reporting.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.DB_EVENT_TYPE_MAP = void 0;
5
+ exports.getDruidEventTypes = getDruidEventTypes;
6
+ var category_namespace_1 = require("../enums/category-namespace");
7
+ var customer_usage_1 = require("../enums/customer-usage");
8
+ exports.DB_EVENT_TYPE_MAP = (_a = {},
9
+ _a[customer_usage_1.DataSourceProvider.AZURE] = [
10
+ category_namespace_1.CategoryNamespace.PROCESSING_FLOW,
11
+ category_namespace_1.CategoryNamespace.PROCESSING_VOICE,
12
+ category_namespace_1.CategoryNamespace.EXECUTABLE_GENERAL,
13
+ category_namespace_1.CategoryNamespace.EXECUTABLE_PORT_IN_IDENTIFIER,
14
+ category_namespace_1.CategoryNamespace.LOOKUP,
15
+ category_namespace_1.CategoryNamespace.TELEPHONY_VOICE,
16
+ category_namespace_1.CategoryNamespace.MESSAGING_TEXT,
17
+ category_namespace_1.CategoryNamespace.CONVERSATIONS_WAP,
18
+ category_namespace_1.CategoryNamespace.CARRIER_FEE,
19
+ category_namespace_1.CategoryNamespace.STORAGE_GENERAL,
20
+ category_namespace_1.CategoryNamespace.STORAGE_WEAVIATE,
21
+ category_namespace_1.CategoryNamespace.IDENTIFIER,
22
+ category_namespace_1.CategoryNamespace.USER,
23
+ category_namespace_1.CategoryNamespace.PRODUCT,
24
+ ],
25
+ _a[customer_usage_1.DataSourceProvider.DRUID] = [
26
+ category_namespace_1.CategoryNamespace.EXECUTABLE_LLM,
27
+ category_namespace_1.CategoryNamespace.EXECUTABLE_GENERAL,
28
+ category_namespace_1.CategoryNamespace.STORAGE_WEAVIATE,
29
+ category_namespace_1.CategoryNamespace.LOOKUP,
30
+ category_namespace_1.CategoryNamespace.TELEPHONY_VOICE,
31
+ category_namespace_1.CategoryNamespace.PROCESSING_VOICE,
32
+ category_namespace_1.CategoryNamespace.CARRIER_FEE,
33
+ category_namespace_1.CategoryNamespace.MESSAGING_TEXT,
34
+ category_namespace_1.CategoryNamespace.PRODUCT,
35
+ ],
36
+ _a);
37
+ var CATEGORY_NAMESPACES = new Set(Object.values(category_namespace_1.CategoryNamespace));
38
+ function getDruidEventTypes(metadata) {
39
+ if (!Array.isArray(metadata === null || metadata === void 0 ? void 0 : metadata.tables))
40
+ return [];
41
+ var eventTypes = metadata.tables.flatMap(function (table) {
42
+ if (typeof table !== 'object' || table === null || !('eventTypes' in table))
43
+ return [];
44
+ return Array.isArray(table.eventTypes) ? table.eventTypes : [];
45
+ });
46
+ return Array.from(new Set(eventTypes.filter(function (eventType) { return (typeof eventType === 'string' && CATEGORY_NAMESPACES.has(eventType)); })));
47
+ }
48
+ //# sourceMappingURL=source-event-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-event-policy.js","sourceRoot":"","sources":["../../../src/usage-granularity/source-event-policy.ts"],"names":[],"mappings":";;;;AAmCA,gDASC;AA5CD,kEAAgE;AAChE,0DAA6D;AAEhD,QAAA,iBAAiB;IAC5B,GAAC,mCAAkB,CAAC,KAAK,IAAG;QAC1B,sCAAiB,CAAC,eAAe;QACjC,sCAAiB,CAAC,gBAAgB;QAClC,sCAAiB,CAAC,kBAAkB;QACpC,sCAAiB,CAAC,6BAA6B;QAC/C,sCAAiB,CAAC,MAAM;QACxB,sCAAiB,CAAC,eAAe;QACjC,sCAAiB,CAAC,cAAc;QAChC,sCAAiB,CAAC,iBAAiB;QACnC,sCAAiB,CAAC,WAAW;QAC7B,sCAAiB,CAAC,eAAe;QACjC,sCAAiB,CAAC,gBAAgB;QAClC,sCAAiB,CAAC,UAAU;QAC5B,sCAAiB,CAAC,IAAI;QACtB,sCAAiB,CAAC,OAAO;KAC1B;IACD,GAAC,mCAAkB,CAAC,KAAK,IAAG;QAC1B,sCAAiB,CAAC,cAAc;QAChC,sCAAiB,CAAC,kBAAkB;QACpC,sCAAiB,CAAC,gBAAgB;QAClC,sCAAiB,CAAC,MAAM;QACxB,sCAAiB,CAAC,eAAe;QACjC,sCAAiB,CAAC,gBAAgB;QAClC,sCAAiB,CAAC,WAAW;QAC7B,sCAAiB,CAAC,cAAc;QAChC,sCAAiB,CAAC,OAAO;KAC1B;QACD;AAEF,IAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,MAAM,CAAC,sCAAiB,CAAC,CAAC,CAAC;AAE9E,SAAgB,kBAAkB,CAAC,QAAkC;IACnE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,IAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,UAAA,KAAK;QAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,YAAY,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACvF,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,UAAC,SAAS,IAAqC,OAAA,CACzF,OAAO,SAAS,KAAK,QAAQ,IAAI,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CACpE,EAF0F,CAE1F,CAAC,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/usage-granularity/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isUsageGranularityHours = isUsageGranularityHours;
4
+ exports.getCompatibleUsageGranularity = getCompatibleUsageGranularity;
5
+ exports.getUsageSlotStart = getUsageSlotStart;
6
+ exports.resolveUsageGranularity = resolveUsageGranularity;
7
+ exports.scheduleUsageGranularity = scheduleUsageGranularity;
8
+ var constants_1 = require("./constants");
9
+ function isUsageGranularityHours(value) {
10
+ return typeof value === 'number' && constants_1.USAGE_GRANULARITY_HOURS.some(function (hours) { return hours === value; });
11
+ }
12
+ function getCompatibleUsageGranularity(hours) {
13
+ var compatible = constants_1.USAGE_GRANULARITY_HOURS.find(function (candidate) { return hours.every(function (value) { return candidate % value === 0; }); });
14
+ if (compatible === undefined)
15
+ throw new Error('No compatible usage granularity');
16
+ return compatible;
17
+ }
18
+ function getUsageSlotStart(date, hours) {
19
+ var time = date.getTime();
20
+ if (!Number.isFinite(time) || !isUsageGranularityHours(hours)) {
21
+ throw new Error('Invalid usage slot date or granularity');
22
+ }
23
+ var duration = hours * constants_1.USAGE_HOUR_MS;
24
+ return new Date(Math.floor(time / duration) * duration);
25
+ }
26
+ function resolveUsageGranularity(state, now) {
27
+ if (!Number.isFinite(now.getTime()))
28
+ throw new Error('Invalid usage granularity date');
29
+ if (state.pendingGranularityHours !== null &&
30
+ state.granularityEffectiveAt !== null &&
31
+ new Date(state.granularityEffectiveAt).getTime() <= now.getTime()) {
32
+ return {
33
+ granularityHours: state.pendingGranularityHours,
34
+ pendingGranularityHours: null,
35
+ granularityEffectiveAt: null,
36
+ };
37
+ }
38
+ return {
39
+ granularityHours: state.granularityHours,
40
+ pendingGranularityHours: state.pendingGranularityHours,
41
+ granularityEffectiveAt: state.granularityEffectiveAt,
42
+ };
43
+ }
44
+ function scheduleUsageGranularity(state, requested, now) {
45
+ var current = resolveUsageGranularity(state, now);
46
+ if (requested === undefined)
47
+ return current;
48
+ if (!isUsageGranularityHours(requested))
49
+ throw new Error('Invalid usage granularity');
50
+ if (requested === current.granularityHours) {
51
+ return {
52
+ granularityHours: requested,
53
+ pendingGranularityHours: null,
54
+ granularityEffectiveAt: null,
55
+ };
56
+ }
57
+ if (requested === current.pendingGranularityHours)
58
+ return current;
59
+ var sharedHours = getCompatibleUsageGranularity([current.granularityHours, requested]);
60
+ var boundary = getUsageSlotStart(now, sharedHours);
61
+ return {
62
+ granularityHours: current.granularityHours,
63
+ pendingGranularityHours: requested,
64
+ granularityEffectiveAt: new Date(boundary.getTime() + sharedHours * constants_1.USAGE_HOUR_MS),
65
+ };
66
+ }
67
+ //# sourceMappingURL=usage-granularity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-granularity.js","sourceRoot":"","sources":["../../../src/usage-granularity/usage-granularity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ const UTC_DAY_MS = 24 * 60 * 60 * 1000;
2
+ export function isUtcMidnight(value) {
3
+ return value instanceof Date && Number.isFinite(value.getTime()) && value.getTime() % UTC_DAY_MS === 0;
4
+ }
5
+ export function isUtcInclusiveDateEnd(value) {
6
+ if (!(value instanceof Date) || !Number.isFinite(value.getTime()))
7
+ return false;
8
+ const time = value.getTime();
9
+ return (isUtcMidnight(value) || (time + 1) % UTC_DAY_MS === 0)
10
+ && Number.isFinite(new Date(Math.floor(time / UTC_DAY_MS) * UTC_DAY_MS + UTC_DAY_MS).getTime());
11
+ }
12
+ export function toExclusiveUtcDateEnd(value) {
13
+ if (!isUtcInclusiveDateEnd(value)) {
14
+ throw new RangeError('Billing end date must be a UTC calendar date or UTC end of day');
15
+ }
16
+ return new Date(Math.floor(value.getTime() / UTC_DAY_MS) * UTC_DAY_MS + UTC_DAY_MS);
17
+ }
18
+ export function getUtcBillingDateIssues(startDate, endDate, options = {}) {
19
+ const issues = [];
20
+ const prefix = options.pathPrefix ? `${options.pathPrefix}.` : '';
21
+ if (!isUtcMidnight(startDate)) {
22
+ issues.push({
23
+ path: `${prefix}startDate`,
24
+ constraints: { utcMidnight: 'Start date must be a valid date at midnight UTC' },
25
+ });
26
+ }
27
+ const openEnd = options.allowOpenEnd && (endDate === null || endDate === undefined);
28
+ if (!openEnd && !isUtcInclusiveDateEnd(endDate)) {
29
+ issues.push({
30
+ path: `${prefix}endDate`,
31
+ constraints: { utcCalendarEnd: 'End date must be a valid UTC calendar date at midnight or 23:59:59.999 UTC (inclusive)' },
32
+ });
33
+ }
34
+ if (isUtcMidnight(startDate) && isUtcInclusiveDateEnd(endDate) && toExclusiveUtcDateEnd(endDate) <= startDate) {
35
+ issues.push({
36
+ path: `${prefix}endDate`,
37
+ constraints: { minDate: 'End date must not be before the start date' },
38
+ });
39
+ }
40
+ return issues;
41
+ }
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/billing-boundaries/index.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEvC,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,KAAK,YAAY,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,GAAG,UAAU,KAAK,CAAC,CAAC;AACzG,CAAC;AAGD,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAChF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7B,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC;WACzD,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AACpG,CAAC;AAGD,MAAM,UAAU,qBAAqB,CAAC,KAAW;IAC/C,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,UAAU,CAAC,gEAAgE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,SAAkB,EAClB,OAAgB,EAChB,UAAwC,EAAE;IAE1C,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,GAAG,MAAM,WAAW;YAC1B,WAAW,EAAE,EAAE,WAAW,EAAE,iDAAiD,EAAE;SAChF,CAAC,CAAC;IACL,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC;IACpF,IAAI,CAAC,OAAO,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,GAAG,MAAM,SAAS;YACxB,WAAW,EAAE,EAAE,cAAc,EAAE,wFAAwF,EAAE;SAC1H,CAAC,CAAC;IACL,CAAC;IACD,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,qBAAqB,CAAC,OAAO,CAAC,IAAI,qBAAqB,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;QAC9G,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,GAAG,MAAM,SAAS;YACxB,WAAW,EAAE,EAAE,OAAO,EAAE,4CAA4C,EAAE;SACvE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/billing-boundaries/types.ts"],"names":[],"mappings":""}
package/dist/esm/index.js CHANGED
@@ -2,4 +2,6 @@ export * from './enums';
2
2
  export * from './constants';
3
3
  export * from './types';
4
4
  export * from './utils';
5
+ export * from './usage-granularity';
6
+ export * from './billing-boundaries';
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export const USAGE_GRANULARITY_HOURS = [1, 2, 3, 4, 6, 8, 12, 24];
2
+ export const DEFAULT_USAGE_GRANULARITY_HOURS = 1;
3
+ export const USAGE_HOUR_MS = 3600000;
4
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/usage-granularity/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAU,CAAC;AAE3E,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './constants';
2
+ export * from './types';
3
+ export * from './usage-granularity';
4
+ export * from './source-event-policy';
5
+ export * from './reporting.types';
6
+ export * from './metric-policy';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/usage-granularity/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { CategoryNamespace } from '../enums/category-namespace';
2
+ import { DataSourceProvider } from '../enums/customer-usage';
3
+ const COARSE_EVENTS = {
4
+ [DataSourceProvider.AZURE]: [
5
+ CategoryNamespace.PROCESSING_FLOW,
6
+ CategoryNamespace.PROCESSING_VOICE,
7
+ CategoryNamespace.EXECUTABLE_GENERAL,
8
+ CategoryNamespace.EXECUTABLE_PORT_IN_IDENTIFIER,
9
+ CategoryNamespace.LOOKUP,
10
+ CategoryNamespace.TELEPHONY_VOICE,
11
+ CategoryNamespace.MESSAGING_TEXT,
12
+ CategoryNamespace.CONVERSATIONS_WAP,
13
+ CategoryNamespace.CARRIER_FEE,
14
+ CategoryNamespace.USER,
15
+ CategoryNamespace.IDENTIFIER,
16
+ CategoryNamespace.STORAGE_GENERAL,
17
+ CategoryNamespace.STORAGE_WEAVIATE,
18
+ ],
19
+ [DataSourceProvider.DRUID]: [
20
+ CategoryNamespace.EXECUTABLE_LLM,
21
+ CategoryNamespace.EXECUTABLE_GENERAL,
22
+ CategoryNamespace.STORAGE_WEAVIATE,
23
+ CategoryNamespace.LOOKUP,
24
+ CategoryNamespace.TELEPHONY_VOICE,
25
+ CategoryNamespace.PROCESSING_VOICE,
26
+ CategoryNamespace.CARRIER_FEE,
27
+ CategoryNamespace.MESSAGING_TEXT,
28
+ ],
29
+ };
30
+ export function supportsCoarseUsageCollection(provider, eventType) {
31
+ if (provider !== DataSourceProvider.AZURE && provider !== DataSourceProvider.DRUID)
32
+ return false;
33
+ return COARSE_EVENTS[provider].includes(eventType);
34
+ }
35
+ export function assertUsageCollectionMetric(provider, eventType, hours) {
36
+ if (hours > 1 && !supportsCoarseUsageCollection(provider, eventType)) {
37
+ throw new Error(`Coarse collection is not verified for ${provider}/${eventType}; use 1h granularity`);
38
+ }
39
+ }
40
+ //# sourceMappingURL=metric-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-policy.js","sourceRoot":"","sources":["../../../src/usage-granularity/metric-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,aAAa,GAA8F;IAC/G,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE;QAC1B,iBAAiB,CAAC,eAAe;QACjC,iBAAiB,CAAC,gBAAgB;QAClC,iBAAiB,CAAC,kBAAkB;QACpC,iBAAiB,CAAC,6BAA6B;QAC/C,iBAAiB,CAAC,MAAM;QACxB,iBAAiB,CAAC,eAAe;QACjC,iBAAiB,CAAC,cAAc;QAChC,iBAAiB,CAAC,iBAAiB;QACnC,iBAAiB,CAAC,WAAW;QAC7B,iBAAiB,CAAC,IAAI;QACtB,iBAAiB,CAAC,UAAU;QAC5B,iBAAiB,CAAC,eAAe;QACjC,iBAAiB,CAAC,gBAAgB;KACnC;IACD,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE;QAC1B,iBAAiB,CAAC,cAAc;QAChC,iBAAiB,CAAC,kBAAkB;QACpC,iBAAiB,CAAC,gBAAgB;QAClC,iBAAiB,CAAC,MAAM;QACxB,iBAAiB,CAAC,eAAe;QACjC,iBAAiB,CAAC,gBAAgB;QAClC,iBAAiB,CAAC,WAAW;QAC7B,iBAAiB,CAAC,cAAc;KACjC;CACF,CAAC;AAEF,MAAM,UAAU,6BAA6B,CAAC,QAAgB,EAAE,SAA4B;IAC1F,IAAI,QAAQ,KAAK,kBAAkB,CAAC,KAAK,IAAI,QAAQ,KAAK,kBAAkB,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACjG,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,QAAgB,EAAE,SAA4B,EAAE,KAAa;IACvG,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,yCAAyC,QAAQ,IAAI,SAAS,sBAAsB,CAAC,CAAC;IACxG,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reporting.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporting.types.js","sourceRoot":"","sources":["../../../src/usage-granularity/reporting.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { CategoryNamespace } from '../enums/category-namespace';
2
+ import { DataSourceProvider } from '../enums/customer-usage';
3
+ export const DB_EVENT_TYPE_MAP = {
4
+ [DataSourceProvider.AZURE]: [
5
+ CategoryNamespace.PROCESSING_FLOW,
6
+ CategoryNamespace.PROCESSING_VOICE,
7
+ CategoryNamespace.EXECUTABLE_GENERAL,
8
+ CategoryNamespace.EXECUTABLE_PORT_IN_IDENTIFIER,
9
+ CategoryNamespace.LOOKUP,
10
+ CategoryNamespace.TELEPHONY_VOICE,
11
+ CategoryNamespace.MESSAGING_TEXT,
12
+ CategoryNamespace.CONVERSATIONS_WAP,
13
+ CategoryNamespace.CARRIER_FEE,
14
+ CategoryNamespace.STORAGE_GENERAL,
15
+ CategoryNamespace.STORAGE_WEAVIATE,
16
+ CategoryNamespace.IDENTIFIER,
17
+ CategoryNamespace.USER,
18
+ CategoryNamespace.PRODUCT,
19
+ ],
20
+ [DataSourceProvider.DRUID]: [
21
+ CategoryNamespace.EXECUTABLE_LLM,
22
+ CategoryNamespace.EXECUTABLE_GENERAL,
23
+ CategoryNamespace.STORAGE_WEAVIATE,
24
+ CategoryNamespace.LOOKUP,
25
+ CategoryNamespace.TELEPHONY_VOICE,
26
+ CategoryNamespace.PROCESSING_VOICE,
27
+ CategoryNamespace.CARRIER_FEE,
28
+ CategoryNamespace.MESSAGING_TEXT,
29
+ CategoryNamespace.PRODUCT,
30
+ ],
31
+ };
32
+ const CATEGORY_NAMESPACES = new Set(Object.values(CategoryNamespace));
33
+ export function getDruidEventTypes(metadata) {
34
+ if (!Array.isArray(metadata === null || metadata === void 0 ? void 0 : metadata.tables))
35
+ return [];
36
+ const eventTypes = metadata.tables.flatMap(table => {
37
+ if (typeof table !== 'object' || table === null || !('eventTypes' in table))
38
+ return [];
39
+ return Array.isArray(table.eventTypes) ? table.eventTypes : [];
40
+ });
41
+ return Array.from(new Set(eventTypes.filter((eventType) => (typeof eventType === 'string' && CATEGORY_NAMESPACES.has(eventType)))));
42
+ }
43
+ //# sourceMappingURL=source-event-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-event-policy.js","sourceRoot":"","sources":["../../../src/usage-granularity/source-event-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE;QAC1B,iBAAiB,CAAC,eAAe;QACjC,iBAAiB,CAAC,gBAAgB;QAClC,iBAAiB,CAAC,kBAAkB;QACpC,iBAAiB,CAAC,6BAA6B;QAC/C,iBAAiB,CAAC,MAAM;QACxB,iBAAiB,CAAC,eAAe;QACjC,iBAAiB,CAAC,cAAc;QAChC,iBAAiB,CAAC,iBAAiB;QACnC,iBAAiB,CAAC,WAAW;QAC7B,iBAAiB,CAAC,eAAe;QACjC,iBAAiB,CAAC,gBAAgB;QAClC,iBAAiB,CAAC,UAAU;QAC5B,iBAAiB,CAAC,IAAI;QACtB,iBAAiB,CAAC,OAAO;KAC1B;IACD,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE;QAC1B,iBAAiB,CAAC,cAAc;QAChC,iBAAiB,CAAC,kBAAkB;QACpC,iBAAiB,CAAC,gBAAgB;QAClC,iBAAiB,CAAC,MAAM;QACxB,iBAAiB,CAAC,eAAe;QACjC,iBAAiB,CAAC,gBAAgB;QAClC,iBAAiB,CAAC,WAAW;QAC7B,iBAAiB,CAAC,cAAc;QAChC,iBAAiB,CAAC,OAAO;KAC1B;CACF,CAAC;AAEF,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAE9E,MAAM,UAAU,kBAAkB,CAAC,QAAkC;IACnE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,YAAY,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACvF,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAkC,EAAE,CAAC,CACzF,OAAO,SAAS,KAAK,QAAQ,IAAI,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CACpE,CAAC,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/usage-granularity/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,60 @@
1
+ import { USAGE_GRANULARITY_HOURS, USAGE_HOUR_MS } from './constants';
2
+ export function isUsageGranularityHours(value) {
3
+ return typeof value === 'number' && USAGE_GRANULARITY_HOURS.some(hours => hours === value);
4
+ }
5
+ export function getCompatibleUsageGranularity(hours) {
6
+ const compatible = USAGE_GRANULARITY_HOURS.find(candidate => hours.every(value => candidate % value === 0));
7
+ if (compatible === undefined)
8
+ throw new Error('No compatible usage granularity');
9
+ return compatible;
10
+ }
11
+ export function getUsageSlotStart(date, hours) {
12
+ const time = date.getTime();
13
+ if (!Number.isFinite(time) || !isUsageGranularityHours(hours)) {
14
+ throw new Error('Invalid usage slot date or granularity');
15
+ }
16
+ const duration = hours * USAGE_HOUR_MS;
17
+ return new Date(Math.floor(time / duration) * duration);
18
+ }
19
+ export function resolveUsageGranularity(state, now) {
20
+ if (!Number.isFinite(now.getTime()))
21
+ throw new Error('Invalid usage granularity date');
22
+ if (state.pendingGranularityHours !== null &&
23
+ state.granularityEffectiveAt !== null &&
24
+ new Date(state.granularityEffectiveAt).getTime() <= now.getTime()) {
25
+ return {
26
+ granularityHours: state.pendingGranularityHours,
27
+ pendingGranularityHours: null,
28
+ granularityEffectiveAt: null,
29
+ };
30
+ }
31
+ return {
32
+ granularityHours: state.granularityHours,
33
+ pendingGranularityHours: state.pendingGranularityHours,
34
+ granularityEffectiveAt: state.granularityEffectiveAt,
35
+ };
36
+ }
37
+ export function scheduleUsageGranularity(state, requested, now) {
38
+ const current = resolveUsageGranularity(state, now);
39
+ if (requested === undefined)
40
+ return current;
41
+ if (!isUsageGranularityHours(requested))
42
+ throw new Error('Invalid usage granularity');
43
+ if (requested === current.granularityHours) {
44
+ return {
45
+ granularityHours: requested,
46
+ pendingGranularityHours: null,
47
+ granularityEffectiveAt: null,
48
+ };
49
+ }
50
+ if (requested === current.pendingGranularityHours)
51
+ return current;
52
+ const sharedHours = getCompatibleUsageGranularity([current.granularityHours, requested]);
53
+ const boundary = getUsageSlotStart(now, sharedHours);
54
+ return {
55
+ granularityHours: current.granularityHours,
56
+ pendingGranularityHours: requested,
57
+ granularityEffectiveAt: new Date(boundary.getTime() + sharedHours * USAGE_HOUR_MS),
58
+ };
59
+ }
60
+ //# sourceMappingURL=usage-granularity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-granularity.js","sourceRoot":"","sources":["../../../src/usage-granularity/usage-granularity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { BillingDateIssue, BillingDateValidationOptions } from './types';
2
+ export declare function isUtcMidnight(value: unknown): value is Date;
3
+ export declare function isUtcInclusiveDateEnd(value: unknown): value is Date;
4
+ export declare function toExclusiveUtcDateEnd(value: Date): Date;
5
+ export declare function getUtcBillingDateIssues(startDate: unknown, endDate: unknown, options?: BillingDateValidationOptions): BillingDateIssue[];
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/billing-boundaries/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAI9E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAE3D;AAGD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAKnE;AAGD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAKvD;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,4BAAiC,GACzC,gBAAgB,EAAE,CAuBpB"}
@@ -0,0 +1,9 @@
1
+ export interface BillingDateIssue {
2
+ path: string;
3
+ constraints: Record<string, string>;
4
+ }
5
+ export interface BillingDateValidationOptions {
6
+ allowOpenEnd?: boolean;
7
+ pathPrefix?: string;
8
+ }
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/billing-boundaries/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,4BAA4B;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -2,4 +2,6 @@ export * from './enums';
2
2
  export * from './constants';
3
3
  export * from './types';
4
4
  export * from './utils';
5
+ export * from './usage-granularity';
6
+ export * from './billing-boundaries';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const USAGE_GRANULARITY_HOURS: readonly [1, 2, 3, 4, 6, 8, 12, 24];
2
+ export declare const DEFAULT_USAGE_GRANULARITY_HOURS = 1;
3
+ export declare const USAGE_HOUR_MS = 3600000;
4
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/usage-granularity/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,qCAAsC,CAAC;AAE3E,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAEjD,eAAO,MAAM,aAAa,UAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './constants';
2
+ export * from './types';
3
+ export * from './usage-granularity';
4
+ export * from './source-event-policy';
5
+ export * from './reporting.types';
6
+ export * from './metric-policy';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/usage-granularity/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { CategoryNamespace } from '../enums/category-namespace';
2
+ export declare function supportsCoarseUsageCollection(provider: string, eventType: CategoryNamespace): boolean;
3
+ export declare function assertUsageCollectionMetric(provider: string, eventType: CategoryNamespace, hours: number): void;
4
+ //# sourceMappingURL=metric-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metric-policy.d.ts","sourceRoot":"","sources":["../../../src/usage-granularity/metric-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AA+BhE,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAGrG;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAI/G"}
@@ -0,0 +1,14 @@
1
+ import type { UsageGranularityHours } from './types';
2
+ export type UsageResolutionAdjustment = 'granularityExpanded' | 'rangeExpanded' | 'unknownCoverage' | 'providerOverlapExcluded';
3
+ export interface UsageResolutionMetadata {
4
+ requestedGranularityHours: UsageGranularityHours;
5
+ effectiveGranularityHours: UsageGranularityHours;
6
+ requestedDateFrom: string;
7
+ requestedDateTo: string;
8
+ effectiveDateFrom: string;
9
+ effectiveDateTo: string;
10
+ adjustments: UsageResolutionAdjustment[];
11
+ coverageStatus: 'known' | 'partial' | 'unknown';
12
+ coverageVersion: string;
13
+ }
14
+ //# sourceMappingURL=reporting.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporting.types.d.ts","sourceRoot":"","sources":["../../../src/usage-granularity/reporting.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,MAAM,yBAAyB,GAAG,qBAAqB,GAAG,eAAe,GAAG,iBAAiB,GAAG,yBAAyB,CAAC;AAEhI,MAAM,WAAW,uBAAuB;IACtC,yBAAyB,EAAE,qBAAqB,CAAC;IACjD,yBAAyB,EAAE,qBAAqB,CAAC;IACjD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,yBAAyB,EAAE,CAAC;IACzC,cAAc,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAChD,eAAe,EAAE,MAAM,CAAC;CACzB"}
@@ -0,0 +1,7 @@
1
+ import { CategoryNamespace } from '../enums/category-namespace';
2
+ export declare const DB_EVENT_TYPE_MAP: {
3
+ azure: CategoryNamespace[];
4
+ druid: CategoryNamespace[];
5
+ };
6
+ export declare function getDruidEventTypes(metadata?: Record<string, unknown>): CategoryNamespace[];
7
+ //# sourceMappingURL=source-event-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-event-policy.d.ts","sourceRoot":"","sources":["../../../src/usage-granularity/source-event-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE,eAAO,MAAM,iBAAiB;;;CA4B7B,CAAC;AAIF,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,EAAE,CAS1F"}
@@ -0,0 +1,8 @@
1
+ import type { USAGE_GRANULARITY_HOURS } from './constants';
2
+ export type UsageGranularityHours = typeof USAGE_GRANULARITY_HOURS[number];
3
+ export type UsageGranularityState = {
4
+ granularityHours: UsageGranularityHours;
5
+ pendingGranularityHours: UsageGranularityHours | null;
6
+ granularityEffectiveAt: Date | null;
7
+ };
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/usage-granularity/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG,OAAO,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAE3E,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,uBAAuB,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACtD,sBAAsB,EAAE,IAAI,GAAG,IAAI,CAAC;CACrC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { UsageGranularityHours, UsageGranularityState } from './types';
2
+ export declare function isUsageGranularityHours(value: unknown): value is UsageGranularityHours;
3
+ export declare function getCompatibleUsageGranularity(hours: readonly UsageGranularityHours[]): UsageGranularityHours;
4
+ export declare function getUsageSlotStart(date: Date, hours: UsageGranularityHours): Date;
5
+ export declare function resolveUsageGranularity(state: UsageGranularityState, now: Date): UsageGranularityState;
6
+ export declare function scheduleUsageGranularity(state: UsageGranularityState, requested: UsageGranularityHours | undefined, now: Date): UsageGranularityState;
7
+ //# sourceMappingURL=usage-granularity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-granularity.d.ts","sourceRoot":"","sources":["../../../src/usage-granularity/usage-granularity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE5E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAEtF;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,SAAS,qBAAqB,EAAE,GACtC,qBAAqB,CAIvB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,qBAAqB,GAAG,IAAI,CAOhF;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,IAAI,GACR,qBAAqB,CAkBvB;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,qBAAqB,EAC5B,SAAS,EAAE,qBAAqB,GAAG,SAAS,EAC5C,GAAG,EAAE,IAAI,GACR,qBAAqB,CAoBvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onereach/billing-shared",
3
- "version": "31.17.0",
3
+ "version": "31.17.1-beta.13420.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -0,0 +1,52 @@
1
+ import type { BillingDateIssue, BillingDateValidationOptions } from './types';
2
+
3
+ const UTC_DAY_MS = 24 * 60 * 60 * 1000;
4
+
5
+ export function isUtcMidnight(value: unknown): value is Date {
6
+ return value instanceof Date && Number.isFinite(value.getTime()) && value.getTime() % UTC_DAY_MS === 0;
7
+ }
8
+
9
+ /** Inclusive calendar ends accept the API's date-only and UTC end-of-day conventions. */
10
+ export function isUtcInclusiveDateEnd(value: unknown): value is Date {
11
+ if (!(value instanceof Date) || !Number.isFinite(value.getTime())) return false;
12
+ const time = value.getTime();
13
+ return (isUtcMidnight(value) || (time + 1) % UTC_DAY_MS === 0)
14
+ && Number.isFinite(new Date(Math.floor(time / UTC_DAY_MS) * UTC_DAY_MS + UTC_DAY_MS).getTime());
15
+ }
16
+
17
+ /** Convert an inclusive UTC calendar end to the next midnight, without changing stored dates. */
18
+ export function toExclusiveUtcDateEnd(value: Date): Date {
19
+ if (!isUtcInclusiveDateEnd(value)) {
20
+ throw new RangeError('Billing end date must be a UTC calendar date or UTC end of day');
21
+ }
22
+ return new Date(Math.floor(value.getTime() / UTC_DAY_MS) * UTC_DAY_MS + UTC_DAY_MS);
23
+ }
24
+
25
+ export function getUtcBillingDateIssues(
26
+ startDate: unknown,
27
+ endDate: unknown,
28
+ options: BillingDateValidationOptions = {},
29
+ ): BillingDateIssue[] {
30
+ const issues: BillingDateIssue[] = [];
31
+ const prefix = options.pathPrefix ? `${options.pathPrefix}.` : '';
32
+ if (!isUtcMidnight(startDate)) {
33
+ issues.push({
34
+ path: `${prefix}startDate`,
35
+ constraints: { utcMidnight: 'Start date must be a valid date at midnight UTC' },
36
+ });
37
+ }
38
+ const openEnd = options.allowOpenEnd && (endDate === null || endDate === undefined);
39
+ if (!openEnd && !isUtcInclusiveDateEnd(endDate)) {
40
+ issues.push({
41
+ path: `${prefix}endDate`,
42
+ constraints: { utcCalendarEnd: 'End date must be a valid UTC calendar date at midnight or 23:59:59.999 UTC (inclusive)' },
43
+ });
44
+ }
45
+ if (isUtcMidnight(startDate) && isUtcInclusiveDateEnd(endDate) && toExclusiveUtcDateEnd(endDate) <= startDate) {
46
+ issues.push({
47
+ path: `${prefix}endDate`,
48
+ constraints: { minDate: 'End date must not be before the start date' },
49
+ });
50
+ }
51
+ return issues;
52
+ }
@@ -0,0 +1,9 @@
1
+ export interface BillingDateIssue {
2
+ path: string;
3
+ constraints: Record<string, string>;
4
+ }
5
+
6
+ export interface BillingDateValidationOptions {
7
+ allowOpenEnd?: boolean;
8
+ pathPrefix?: string;
9
+ }
package/src/index.ts CHANGED
@@ -2,3 +2,5 @@ export * from './enums';
2
2
  export * from './constants';
3
3
  export * from './types';
4
4
  export * from './utils';
5
+ export * from './usage-granularity';
6
+ export * from './billing-boundaries';
@@ -0,0 +1,5 @@
1
+ export const USAGE_GRANULARITY_HOURS = [1, 2, 3, 4, 6, 8, 12, 24] as const;
2
+
3
+ export const DEFAULT_USAGE_GRANULARITY_HOURS = 1;
4
+
5
+ export const USAGE_HOUR_MS = 3600000;
@@ -0,0 +1,6 @@
1
+ export * from './constants';
2
+ export * from './types';
3
+ export * from './usage-granularity';
4
+ export * from './source-event-policy';
5
+ export * from './reporting.types';
6
+ export * from './metric-policy';
@@ -0,0 +1,41 @@
1
+ import { CategoryNamespace } from '../enums/category-namespace';
2
+ import { DataSourceProvider } from '../enums/customer-usage';
3
+
4
+ const COARSE_EVENTS: Record<DataSourceProvider.AZURE | DataSourceProvider.DRUID, readonly CategoryNamespace[]> = {
5
+ [DataSourceProvider.AZURE]: [
6
+ CategoryNamespace.PROCESSING_FLOW,
7
+ CategoryNamespace.PROCESSING_VOICE,
8
+ CategoryNamespace.EXECUTABLE_GENERAL,
9
+ CategoryNamespace.EXECUTABLE_PORT_IN_IDENTIFIER,
10
+ CategoryNamespace.LOOKUP,
11
+ CategoryNamespace.TELEPHONY_VOICE,
12
+ CategoryNamespace.MESSAGING_TEXT,
13
+ CategoryNamespace.CONVERSATIONS_WAP,
14
+ CategoryNamespace.CARRIER_FEE,
15
+ CategoryNamespace.USER,
16
+ CategoryNamespace.IDENTIFIER,
17
+ CategoryNamespace.STORAGE_GENERAL,
18
+ CategoryNamespace.STORAGE_WEAVIATE,
19
+ ],
20
+ [DataSourceProvider.DRUID]: [
21
+ CategoryNamespace.EXECUTABLE_LLM,
22
+ CategoryNamespace.EXECUTABLE_GENERAL,
23
+ CategoryNamespace.STORAGE_WEAVIATE,
24
+ CategoryNamespace.LOOKUP,
25
+ CategoryNamespace.TELEPHONY_VOICE,
26
+ CategoryNamespace.PROCESSING_VOICE,
27
+ CategoryNamespace.CARRIER_FEE,
28
+ CategoryNamespace.MESSAGING_TEXT,
29
+ ],
30
+ };
31
+
32
+ export function supportsCoarseUsageCollection(provider: string, eventType: CategoryNamespace): boolean {
33
+ if (provider !== DataSourceProvider.AZURE && provider !== DataSourceProvider.DRUID) return false;
34
+ return COARSE_EVENTS[provider].includes(eventType);
35
+ }
36
+
37
+ export function assertUsageCollectionMetric(provider: string, eventType: CategoryNamespace, hours: number): void {
38
+ if (hours > 1 && !supportsCoarseUsageCollection(provider, eventType)) {
39
+ throw new Error(`Coarse collection is not verified for ${provider}/${eventType}; use 1h granularity`);
40
+ }
41
+ }
@@ -0,0 +1,15 @@
1
+ import type { UsageGranularityHours } from './types';
2
+
3
+ export type UsageResolutionAdjustment = 'granularityExpanded' | 'rangeExpanded' | 'unknownCoverage' | 'providerOverlapExcluded';
4
+
5
+ export interface UsageResolutionMetadata {
6
+ requestedGranularityHours: UsageGranularityHours;
7
+ effectiveGranularityHours: UsageGranularityHours;
8
+ requestedDateFrom: string;
9
+ requestedDateTo: string;
10
+ effectiveDateFrom: string;
11
+ effectiveDateTo: string;
12
+ adjustments: UsageResolutionAdjustment[];
13
+ coverageStatus: 'known' | 'partial' | 'unknown';
14
+ coverageVersion: string;
15
+ }
@@ -0,0 +1,45 @@
1
+ import { CategoryNamespace } from '../enums/category-namespace';
2
+ import { DataSourceProvider } from '../enums/customer-usage';
3
+
4
+ export const DB_EVENT_TYPE_MAP = {
5
+ [DataSourceProvider.AZURE]: [
6
+ CategoryNamespace.PROCESSING_FLOW,
7
+ CategoryNamespace.PROCESSING_VOICE,
8
+ CategoryNamespace.EXECUTABLE_GENERAL,
9
+ CategoryNamespace.EXECUTABLE_PORT_IN_IDENTIFIER,
10
+ CategoryNamespace.LOOKUP,
11
+ CategoryNamespace.TELEPHONY_VOICE,
12
+ CategoryNamespace.MESSAGING_TEXT,
13
+ CategoryNamespace.CONVERSATIONS_WAP,
14
+ CategoryNamespace.CARRIER_FEE,
15
+ CategoryNamespace.STORAGE_GENERAL,
16
+ CategoryNamespace.STORAGE_WEAVIATE,
17
+ CategoryNamespace.IDENTIFIER,
18
+ CategoryNamespace.USER,
19
+ CategoryNamespace.PRODUCT,
20
+ ],
21
+ [DataSourceProvider.DRUID]: [
22
+ CategoryNamespace.EXECUTABLE_LLM,
23
+ CategoryNamespace.EXECUTABLE_GENERAL,
24
+ CategoryNamespace.STORAGE_WEAVIATE,
25
+ CategoryNamespace.LOOKUP,
26
+ CategoryNamespace.TELEPHONY_VOICE,
27
+ CategoryNamespace.PROCESSING_VOICE,
28
+ CategoryNamespace.CARRIER_FEE,
29
+ CategoryNamespace.MESSAGING_TEXT,
30
+ CategoryNamespace.PRODUCT,
31
+ ],
32
+ };
33
+
34
+ const CATEGORY_NAMESPACES = new Set<string>(Object.values(CategoryNamespace));
35
+
36
+ export function getDruidEventTypes(metadata?: Record<string, unknown>): CategoryNamespace[] {
37
+ if (!Array.isArray(metadata?.tables)) return [];
38
+ const eventTypes = metadata.tables.flatMap(table => {
39
+ if (typeof table !== 'object' || table === null || !('eventTypes' in table)) return [];
40
+ return Array.isArray(table.eventTypes) ? table.eventTypes : [];
41
+ });
42
+ return Array.from(new Set(eventTypes.filter((eventType): eventType is CategoryNamespace => (
43
+ typeof eventType === 'string' && CATEGORY_NAMESPACES.has(eventType)
44
+ ))));
45
+ }
@@ -0,0 +1,9 @@
1
+ import type { USAGE_GRANULARITY_HOURS } from './constants';
2
+
3
+ export type UsageGranularityHours = typeof USAGE_GRANULARITY_HOURS[number];
4
+
5
+ export type UsageGranularityState = {
6
+ granularityHours: UsageGranularityHours;
7
+ pendingGranularityHours: UsageGranularityHours | null;
8
+ granularityEffectiveAt: Date | null;
9
+ };
@@ -0,0 +1,72 @@
1
+ import { USAGE_GRANULARITY_HOURS, USAGE_HOUR_MS } from './constants';
2
+ import type { UsageGranularityHours, UsageGranularityState } from './types';
3
+
4
+ export function isUsageGranularityHours(value: unknown): value is UsageGranularityHours {
5
+ return typeof value === 'number' && USAGE_GRANULARITY_HOURS.some(hours => hours === value);
6
+ }
7
+
8
+ export function getCompatibleUsageGranularity(
9
+ hours: readonly UsageGranularityHours[],
10
+ ): UsageGranularityHours {
11
+ const compatible = USAGE_GRANULARITY_HOURS.find(candidate => hours.every(value => candidate % value === 0));
12
+ if (compatible === undefined) throw new Error('No compatible usage granularity');
13
+ return compatible;
14
+ }
15
+
16
+ export function getUsageSlotStart(date: Date, hours: UsageGranularityHours): Date {
17
+ const time = date.getTime();
18
+ if (!Number.isFinite(time) || !isUsageGranularityHours(hours)) {
19
+ throw new Error('Invalid usage slot date or granularity');
20
+ }
21
+ const duration = hours * USAGE_HOUR_MS;
22
+ return new Date(Math.floor(time / duration) * duration);
23
+ }
24
+
25
+ export function resolveUsageGranularity(
26
+ state: UsageGranularityState,
27
+ now: Date,
28
+ ): UsageGranularityState {
29
+ if (!Number.isFinite(now.getTime())) throw new Error('Invalid usage granularity date');
30
+ if (
31
+ state.pendingGranularityHours !== null &&
32
+ state.granularityEffectiveAt !== null &&
33
+ new Date(state.granularityEffectiveAt).getTime() <= now.getTime()
34
+ ) {
35
+ return {
36
+ granularityHours: state.pendingGranularityHours,
37
+ pendingGranularityHours: null,
38
+ granularityEffectiveAt: null,
39
+ };
40
+ }
41
+ return {
42
+ granularityHours: state.granularityHours,
43
+ pendingGranularityHours: state.pendingGranularityHours,
44
+ granularityEffectiveAt: state.granularityEffectiveAt,
45
+ };
46
+ }
47
+
48
+ export function scheduleUsageGranularity(
49
+ state: UsageGranularityState,
50
+ requested: UsageGranularityHours | undefined,
51
+ now: Date,
52
+ ): UsageGranularityState {
53
+ const current = resolveUsageGranularity(state, now);
54
+ if (requested === undefined) return current;
55
+ if (!isUsageGranularityHours(requested)) throw new Error('Invalid usage granularity');
56
+ if (requested === current.granularityHours) {
57
+ return {
58
+ granularityHours: requested,
59
+ pendingGranularityHours: null,
60
+ granularityEffectiveAt: null,
61
+ };
62
+ }
63
+ if (requested === current.pendingGranularityHours) return current;
64
+
65
+ const sharedHours = getCompatibleUsageGranularity([current.granularityHours, requested]);
66
+ const boundary = getUsageSlotStart(now, sharedHours);
67
+ return {
68
+ granularityHours: current.granularityHours,
69
+ pendingGranularityHours: requested,
70
+ granularityEffectiveAt: new Date(boundary.getTime() + sharedHours * USAGE_HOUR_MS),
71
+ };
72
+ }