@qpqjs/core 0.6.3 → 0.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.
Files changed (77) hide show
  1. package/lib/commonjs/actions/ai/getAiUsageAmountMicroUsd.d.ts +9 -0
  2. package/lib/commonjs/actions/ai/getAiUsageAmountMicroUsd.js +21 -0
  3. package/lib/commonjs/actions/ai/getAiUsageAmountMicroUsd.js.map +1 -0
  4. package/lib/commonjs/actions/ai/index.d.ts +1 -0
  5. package/lib/commonjs/actions/ai/index.js +1 -0
  6. package/lib/commonjs/actions/ai/index.js.map +1 -1
  7. package/lib/commonjs/actions/ai/sumAiStreamUsage.d.ts +1 -1
  8. package/lib/commonjs/actions/ai/sumAiStreamUsage.js +11 -2
  9. package/lib/commonjs/actions/ai/sumAiStreamUsage.js.map +1 -1
  10. package/lib/commonjs/actions/ai/types/AiModelTokenRates.d.ts +4 -0
  11. package/lib/commonjs/actions/ai/types/AiModelTokenRates.js +3 -0
  12. package/lib/commonjs/actions/ai/types/AiModelTokenRates.js.map +1 -0
  13. package/lib/commonjs/actions/ai/types/AiStreamUsage.d.ts +6 -1
  14. package/lib/commonjs/actions/ai/types/AiStreamUsage.js.map +1 -1
  15. package/lib/commonjs/actions/ai/types/AiTokenRates.d.ts +14 -0
  16. package/lib/commonjs/actions/ai/types/AiTokenRates.js +3 -0
  17. package/lib/commonjs/actions/ai/types/AiTokenRates.js.map +1 -0
  18. package/lib/commonjs/actions/ai/types/index.d.ts +2 -0
  19. package/lib/commonjs/actions/ai/types/index.js +2 -0
  20. package/lib/commonjs/actions/ai/types/index.js.map +1 -1
  21. package/lib/commonjs/types/QpqIsoDateTime.d.ts +11 -0
  22. package/lib/commonjs/types/QpqIsoDateTime.js +4 -0
  23. package/lib/commonjs/types/QpqIsoDateTime.js.map +1 -1
  24. package/lib/commonjs/utils/dateTime/addCalendarMonths.d.ts +6 -0
  25. package/lib/commonjs/utils/dateTime/addCalendarMonths.js +20 -0
  26. package/lib/commonjs/utils/dateTime/addCalendarMonths.js.map +1 -0
  27. package/lib/commonjs/utils/dateTime/getUtcOffsetMinutes.d.ts +7 -0
  28. package/lib/commonjs/utils/dateTime/getUtcOffsetMinutes.js +23 -0
  29. package/lib/commonjs/utils/dateTime/getUtcOffsetMinutes.js.map +1 -0
  30. package/lib/commonjs/utils/dateTime/getWeekdayFromMonday.d.ts +2 -0
  31. package/lib/commonjs/utils/dateTime/getWeekdayFromMonday.js +7 -0
  32. package/lib/commonjs/utils/dateTime/getWeekdayFromMonday.js.map +1 -0
  33. package/lib/commonjs/utils/dateTime/index.d.ts +4 -0
  34. package/lib/commonjs/utils/dateTime/index.js +4 -0
  35. package/lib/commonjs/utils/dateTime/index.js.map +1 -1
  36. package/lib/commonjs/utils/dateTime/isQpqIsoDateTime.d.ts +3 -0
  37. package/lib/commonjs/utils/dateTime/isQpqIsoDateTime.js +8 -0
  38. package/lib/commonjs/utils/dateTime/isQpqIsoDateTime.js.map +1 -0
  39. package/lib/esm/actions/ai/getAiUsageAmountMicroUsd.d.ts +9 -0
  40. package/lib/esm/actions/ai/getAiUsageAmountMicroUsd.js +16 -0
  41. package/lib/esm/actions/ai/getAiUsageAmountMicroUsd.js.map +1 -0
  42. package/lib/esm/actions/ai/index.d.ts +1 -0
  43. package/lib/esm/actions/ai/index.js +1 -0
  44. package/lib/esm/actions/ai/index.js.map +1 -1
  45. package/lib/esm/actions/ai/sumAiStreamUsage.d.ts +1 -1
  46. package/lib/esm/actions/ai/sumAiStreamUsage.js +11 -2
  47. package/lib/esm/actions/ai/sumAiStreamUsage.js.map +1 -1
  48. package/lib/esm/actions/ai/types/AiModelTokenRates.d.ts +4 -0
  49. package/lib/esm/actions/ai/types/AiModelTokenRates.js +2 -0
  50. package/lib/esm/actions/ai/types/AiModelTokenRates.js.map +1 -0
  51. package/lib/esm/actions/ai/types/AiStreamUsage.d.ts +6 -1
  52. package/lib/esm/actions/ai/types/AiStreamUsage.js.map +1 -1
  53. package/lib/esm/actions/ai/types/AiTokenRates.d.ts +14 -0
  54. package/lib/esm/actions/ai/types/AiTokenRates.js +2 -0
  55. package/lib/esm/actions/ai/types/AiTokenRates.js.map +1 -0
  56. package/lib/esm/actions/ai/types/index.d.ts +2 -0
  57. package/lib/esm/actions/ai/types/index.js +2 -0
  58. package/lib/esm/actions/ai/types/index.js.map +1 -1
  59. package/lib/esm/types/QpqIsoDateTime.d.ts +11 -0
  60. package/lib/esm/types/QpqIsoDateTime.js +4 -0
  61. package/lib/esm/types/QpqIsoDateTime.js.map +1 -1
  62. package/lib/esm/utils/dateTime/addCalendarMonths.d.ts +6 -0
  63. package/lib/esm/utils/dateTime/addCalendarMonths.js +16 -0
  64. package/lib/esm/utils/dateTime/addCalendarMonths.js.map +1 -0
  65. package/lib/esm/utils/dateTime/getUtcOffsetMinutes.d.ts +7 -0
  66. package/lib/esm/utils/dateTime/getUtcOffsetMinutes.js +19 -0
  67. package/lib/esm/utils/dateTime/getUtcOffsetMinutes.js.map +1 -0
  68. package/lib/esm/utils/dateTime/getWeekdayFromMonday.d.ts +2 -0
  69. package/lib/esm/utils/dateTime/getWeekdayFromMonday.js +3 -0
  70. package/lib/esm/utils/dateTime/getWeekdayFromMonday.js.map +1 -0
  71. package/lib/esm/utils/dateTime/index.d.ts +4 -0
  72. package/lib/esm/utils/dateTime/index.js +4 -0
  73. package/lib/esm/utils/dateTime/index.js.map +1 -1
  74. package/lib/esm/utils/dateTime/isQpqIsoDateTime.d.ts +3 -0
  75. package/lib/esm/utils/dateTime/isQpqIsoDateTime.js +4 -0
  76. package/lib/esm/utils/dateTime/isQpqIsoDateTime.js.map +1 -0
  77. package/package.json +3 -3
@@ -0,0 +1,9 @@
1
+ import { AiStreamUsage } from './types/AiStreamUsage';
2
+ import { AiTokenRates } from './types/AiTokenRates';
3
+ import { AiCacheTtl } from './AiCacheTtl';
4
+ /**
5
+ * What a call's tokens come to at `rates`, in millionths of a US dollar, rounded to a whole number
6
+ * so totals add up exactly. Cache writes are priced at the five minute rate only when every write
7
+ * lived for five minutes (`cacheTtl` FiveMinutes); otherwise at the hour rate, the dearer one.
8
+ */
9
+ export declare const getAiUsageAmountMicroUsd: (usage: AiStreamUsage, rates: AiTokenRates, cacheTtl?: AiCacheTtl) => number;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAiUsageAmountMicroUsd = void 0;
4
+ const AiCacheTtl_1 = require("./AiCacheTtl");
5
+ /**
6
+ * What a call's tokens come to at `rates`, in millionths of a US dollar, rounded to a whole number
7
+ * so totals add up exactly. Cache writes are priced at the five minute rate only when every write
8
+ * lived for five minutes (`cacheTtl` FiveMinutes); otherwise at the hour rate, the dearer one.
9
+ */
10
+ const getAiUsageAmountMicroUsd = (usage, rates, cacheTtl) => {
11
+ var _a, _b, _c, _d, _e, _f;
12
+ const cacheReadTokens = (_a = usage.cacheReadInputTokens) !== null && _a !== void 0 ? _a : 0;
13
+ const cacheWriteTokens = (_b = usage.cacheWriteInputTokens) !== null && _b !== void 0 ? _b : 0;
14
+ // `inputTokens` is the total of the three input kinds, so only the uncached part is priced as input.
15
+ const noCacheTokens = (_c = usage.noCacheInputTokens) !== null && _c !== void 0 ? _c : Math.max(0, ((_d = usage.inputTokens) !== null && _d !== void 0 ? _d : 0) - cacheReadTokens - cacheWriteTokens);
16
+ const cacheWriteRate = cacheTtl === AiCacheTtl_1.AiCacheTtl.FiveMinutes ? rates.cacheWriteFiveMinutes : ((_e = rates.cacheWriteOneHour) !== null && _e !== void 0 ? _e : rates.cacheWriteFiveMinutes);
17
+ // A rate per million tokens times a token count is already millionths of a dollar.
18
+ return Math.round(noCacheTokens * rates.input + cacheReadTokens * rates.cacheRead + cacheWriteTokens * cacheWriteRate + ((_f = usage.outputTokens) !== null && _f !== void 0 ? _f : 0) * rates.output);
19
+ };
20
+ exports.getAiUsageAmountMicroUsd = getAiUsageAmountMicroUsd;
21
+ //# sourceMappingURL=getAiUsageAmountMicroUsd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getAiUsageAmountMicroUsd.js","sourceRoot":"","sources":["../../../../src/actions/ai/getAiUsageAmountMicroUsd.ts"],"names":[],"mappings":";;;AAEA,6CAA0C;AAE1C;;;;GAIG;AACI,MAAM,wBAAwB,GAAG,CAAC,KAAoB,EAAE,KAAmB,EAAE,QAAqB,EAAU,EAAE;;IACnH,MAAM,eAAe,GAAG,MAAA,KAAK,CAAC,oBAAoB,mCAAI,CAAC,CAAC;IACxD,MAAM,gBAAgB,GAAG,MAAA,KAAK,CAAC,qBAAqB,mCAAI,CAAC,CAAC;IAE1D,qGAAqG;IACrG,MAAM,aAAa,GAAG,MAAA,KAAK,CAAC,kBAAkB,mCAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAA,KAAK,CAAC,WAAW,mCAAI,CAAC,CAAC,GAAG,eAAe,GAAG,gBAAgB,CAAC,CAAC;IAE7H,MAAM,cAAc,GAAG,QAAQ,KAAK,uBAAU,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,MAAA,KAAK,CAAC,iBAAiB,mCAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAEpJ,mFAAmF;IACnF,OAAO,IAAI,CAAC,KAAK,CACf,aAAa,GAAG,KAAK,CAAC,KAAK,GAAG,eAAe,GAAG,KAAK,CAAC,SAAS,GAAG,gBAAgB,GAAG,cAAc,GAAG,CAAC,MAAA,KAAK,CAAC,YAAY,mCAAI,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAC/I,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,wBAAwB,4BAanC","sourcesContent":["import { AiStreamUsage } from './types/AiStreamUsage';\nimport { AiTokenRates } from './types/AiTokenRates';\nimport { AiCacheTtl } from './AiCacheTtl';\n\n/**\n * What a call's tokens come to at `rates`, in millionths of a US dollar, rounded to a whole number\n * so totals add up exactly. Cache writes are priced at the five minute rate only when every write\n * lived for five minutes (`cacheTtl` FiveMinutes); otherwise at the hour rate, the dearer one.\n */\nexport const getAiUsageAmountMicroUsd = (usage: AiStreamUsage, rates: AiTokenRates, cacheTtl?: AiCacheTtl): number => {\n const cacheReadTokens = usage.cacheReadInputTokens ?? 0;\n const cacheWriteTokens = usage.cacheWriteInputTokens ?? 0;\n\n // `inputTokens` is the total of the three input kinds, so only the uncached part is priced as input.\n const noCacheTokens = usage.noCacheInputTokens ?? Math.max(0, (usage.inputTokens ?? 0) - cacheReadTokens - cacheWriteTokens);\n\n const cacheWriteRate = cacheTtl === AiCacheTtl.FiveMinutes ? rates.cacheWriteFiveMinutes : (rates.cacheWriteOneHour ?? rates.cacheWriteFiveMinutes);\n\n // A rate per million tokens times a token count is already millionths of a dollar.\n return Math.round(\n noCacheTokens * rates.input + cacheReadTokens * rates.cacheRead + cacheWriteTokens * cacheWriteRate + (usage.outputTokens ?? 0) * rates.output,\n );\n};\n"]}
@@ -10,5 +10,6 @@ export * from './AiReasoningEffort';
10
10
  export * from './askAiGetModelRegions';
11
11
  export * from './askAiPrompt';
12
12
  export * from './askAiPromptStream';
13
+ export * from './getAiUsageAmountMicroUsd';
13
14
  export * from './sumAiStreamUsage';
14
15
  export * from './types';
@@ -26,6 +26,7 @@ __exportStar(require("./AiReasoningEffort"), exports);
26
26
  __exportStar(require("./askAiGetModelRegions"), exports);
27
27
  __exportStar(require("./askAiPrompt"), exports);
28
28
  __exportStar(require("./askAiPromptStream"), exports);
29
+ __exportStar(require("./getAiUsageAmountMicroUsd"), exports);
29
30
  __exportStar(require("./sumAiStreamUsage"), exports);
30
31
  __exportStar(require("./types"), exports);
31
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/actions/ai/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,+CAA6B;AAC7B,iDAA+B;AAC/B,iDAA+B;AAC/B,8CAA4B;AAC5B,4CAA0B;AAC1B,qDAAmC;AACnC,sDAAoC;AACpC,sDAAoC;AACpC,yDAAuC;AACvC,gDAA8B;AAC9B,sDAAoC;AACpC,qDAAmC;AACnC,0CAAwB","sourcesContent":["export * from './AiActionType';\nexport * from './AiCacheTtl';\nexport * from './AiDataRegion';\nexport * from './AiJsonSchema';\nexport * from './AiMessage';\nexport * from './AiModel';\nexport * from './AiModelRegionMap';\nexport * from './AiReasoningConfig';\nexport * from './AiReasoningEffort';\nexport * from './askAiGetModelRegions';\nexport * from './askAiPrompt';\nexport * from './askAiPromptStream';\nexport * from './sumAiStreamUsage';\nexport * from './types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/actions/ai/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,+CAA6B;AAC7B,iDAA+B;AAC/B,iDAA+B;AAC/B,8CAA4B;AAC5B,4CAA0B;AAC1B,qDAAmC;AACnC,sDAAoC;AACpC,sDAAoC;AACpC,yDAAuC;AACvC,gDAA8B;AAC9B,sDAAoC;AACpC,6DAA2C;AAC3C,qDAAmC;AACnC,0CAAwB","sourcesContent":["export * from './AiActionType';\nexport * from './AiCacheTtl';\nexport * from './AiDataRegion';\nexport * from './AiJsonSchema';\nexport * from './AiMessage';\nexport * from './AiModel';\nexport * from './AiModelRegionMap';\nexport * from './AiReasoningConfig';\nexport * from './AiReasoningEffort';\nexport * from './askAiGetModelRegions';\nexport * from './askAiPrompt';\nexport * from './askAiPromptStream';\nexport * from './getAiUsageAmountMicroUsd';\nexport * from './sumAiStreamUsage';\nexport * from './types';\n"]}
@@ -1,6 +1,6 @@
1
1
  import { AiStreamUsage } from './types/AiStreamUsage';
2
2
  /**
3
- * Adds token usages together field by field, for a chat's cost or a turn that spanned several
3
+ * Adds token usages (and their costs and charges) together field by field, for a chat's cost or a turn that spanned several
4
4
  * executions. A field no usage reported stays undefined rather than becoming zero.
5
5
  */
6
6
  export declare const sumAiStreamUsage: (usages: readonly AiStreamUsage[]) => AiStreamUsage;
@@ -1,9 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sumAiStreamUsage = void 0;
4
- const USAGE_FIELDS = ['inputTokens', 'outputTokens', 'totalTokens', 'cacheReadInputTokens', 'cacheWriteInputTokens', 'noCacheInputTokens'];
4
+ const USAGE_FIELDS = [
5
+ 'inputTokens',
6
+ 'outputTokens',
7
+ 'totalTokens',
8
+ 'cacheReadInputTokens',
9
+ 'cacheWriteInputTokens',
10
+ 'noCacheInputTokens',
11
+ 'costMicroUsd',
12
+ 'chargeMicroUsd',
13
+ ];
5
14
  /**
6
- * Adds token usages together field by field, for a chat's cost or a turn that spanned several
15
+ * Adds token usages (and their costs and charges) together field by field, for a chat's cost or a turn that spanned several
7
16
  * executions. A field no usage reported stays undefined rather than becoming zero.
8
17
  */
9
18
  const sumAiStreamUsage = (usages) => USAGE_FIELDS.reduce((sum, field) => {
@@ -1 +1 @@
1
- {"version":3,"file":"sumAiStreamUsage.js","sourceRoot":"","sources":["../../../../src/actions/ai/sumAiStreamUsage.ts"],"names":[],"mappings":";;;AAEA,MAAM,YAAY,GAAG,CAAC,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,oBAAoB,CAAU,CAAC;AAEpJ;;;GAGG;AACI,MAAM,gBAAgB,GAAG,CAAC,MAAgC,EAAiB,EAAE,CAClF,YAAY,CAAC,MAAM,CAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAE7G,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,iCAAM,GAAG,KAAE,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,IAAG,CAAC,CAAC,GAAG,CAAC;AAC9G,CAAC,EAAE,EAAE,CAAC,CAAC;AALI,QAAA,gBAAgB,oBAKpB","sourcesContent":["import { AiStreamUsage } from './types/AiStreamUsage';\n\nconst USAGE_FIELDS = ['inputTokens', 'outputTokens', 'totalTokens', 'cacheReadInputTokens', 'cacheWriteInputTokens', 'noCacheInputTokens'] as const;\n\n/**\n * Adds token usages together field by field, for a chat's cost or a turn that spanned several\n * executions. A field no usage reported stays undefined rather than becoming zero.\n */\nexport const sumAiStreamUsage = (usages: readonly AiStreamUsage[]): AiStreamUsage =>\n USAGE_FIELDS.reduce<AiStreamUsage>((sum, field) => {\n const reported = usages.map((usage) => usage[field]).filter((value): value is number => value !== undefined);\n\n return reported.length > 0 ? { ...sum, [field]: reported.reduce((total, value) => total + value, 0) } : sum;\n }, {});\n"]}
1
+ {"version":3,"file":"sumAiStreamUsage.js","sourceRoot":"","sources":["../../../../src/actions/ai/sumAiStreamUsage.ts"],"names":[],"mappings":";;;AAEA,MAAM,YAAY,GAAG;IACnB,aAAa;IACb,cAAc;IACd,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,oBAAoB;IACpB,cAAc;IACd,gBAAgB;CACR,CAAC;AAEX;;;GAGG;AACI,MAAM,gBAAgB,GAAG,CAAC,MAAgC,EAAiB,EAAE,CAClF,YAAY,CAAC,MAAM,CAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAE7G,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,iCAAM,GAAG,KAAE,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,IAAG,CAAC,CAAC,GAAG,CAAC;AAC9G,CAAC,EAAE,EAAE,CAAC,CAAC;AALI,QAAA,gBAAgB,oBAKpB","sourcesContent":["import { AiStreamUsage } from './types/AiStreamUsage';\n\nconst USAGE_FIELDS = [\n 'inputTokens',\n 'outputTokens',\n 'totalTokens',\n 'cacheReadInputTokens',\n 'cacheWriteInputTokens',\n 'noCacheInputTokens',\n 'costMicroUsd',\n 'chargeMicroUsd',\n] as const;\n\n/**\n * Adds token usages (and their costs and charges) together field by field, for a chat's cost or a turn that spanned several\n * executions. A field no usage reported stays undefined rather than becoming zero.\n */\nexport const sumAiStreamUsage = (usages: readonly AiStreamUsage[]): AiStreamUsage =>\n USAGE_FIELDS.reduce<AiStreamUsage>((sum, field) => {\n const reported = usages.map((usage) => usage[field]).filter((value): value is number => value !== undefined);\n\n return reported.length > 0 ? { ...sum, [field]: reported.reduce((total, value) => total + value, 0) } : sum;\n }, {});\n"]}
@@ -0,0 +1,4 @@
1
+ import { AiModel } from '../AiModel';
2
+ import { AiTokenRates } from './AiTokenRates';
3
+ /** Token rates for each model that has them, in US dollars per million tokens. */
4
+ export type AiModelTokenRates = Partial<Record<AiModel, AiTokenRates>>;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=AiModelTokenRates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiModelTokenRates.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/AiModelTokenRates.ts"],"names":[],"mappings":"","sourcesContent":["import { AiModel } from '../AiModel';\nimport { AiTokenRates } from './AiTokenRates';\n\n/** Token rates for each model that has them, in US dollars per million tokens. */\nexport type AiModelTokenRates = Partial<Record<AiModel, AiTokenRates>>;\n"]}
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Token usage reported by the model.
2
+ * Token usage reported by the model, what it cost when the platform knows its prices, and what it
3
+ * is charged at when an app bills for it.
3
4
  *
4
5
  * Each field may be undefined if the underlying provider doesn't report it.
5
6
  * `totalTokens` is the sum of input + output (plus any reasoning tokens, when applicable).
@@ -17,4 +18,8 @@ export type AiStreamUsage = {
17
18
  cacheWriteInputTokens?: number;
18
19
  /** Prompt tokens neither read from nor written to the cache. */
19
20
  noCacheInputTokens?: number;
21
+ /** What the call cost at the platform's list price, in millionths of a US dollar. Set only by a platform that knows its prices. */
22
+ costMicroUsd?: number;
23
+ /** What the call is charged at an app's own rates, in millionths of a US dollar. Set by the app that bills for it, never by a platform. */
24
+ chargeMicroUsd?: number;
20
25
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AiStreamUsage.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/AiStreamUsage.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Token usage reported by the model.\n *\n * Each field may be undefined if the underlying provider doesn't report it.\n * `totalTokens` is the sum of input + output (plus any reasoning tokens, when applicable).\n */\nexport type AiStreamUsage = {\n /** Prompt tokens consumed. */\n inputTokens?: number;\n /** Completion tokens produced. */\n outputTokens?: number;\n /** Total tokens, typically `inputTokens + outputTokens` (+ reasoning, when applicable). */\n totalTokens?: number;\n /** Prompt tokens served from the prompt cache. */\n cacheReadInputTokens?: number;\n /** Prompt tokens written to the prompt cache by this request. */\n cacheWriteInputTokens?: number;\n /** Prompt tokens neither read from nor written to the cache. */\n noCacheInputTokens?: number;\n};\n"]}
1
+ {"version":3,"file":"AiStreamUsage.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/AiStreamUsage.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Token usage reported by the model, what it cost when the platform knows its prices, and what it\n * is charged at when an app bills for it.\n *\n * Each field may be undefined if the underlying provider doesn't report it.\n * `totalTokens` is the sum of input + output (plus any reasoning tokens, when applicable).\n */\nexport type AiStreamUsage = {\n /** Prompt tokens consumed. */\n inputTokens?: number;\n /** Completion tokens produced. */\n outputTokens?: number;\n /** Total tokens, typically `inputTokens + outputTokens` (+ reasoning, when applicable). */\n totalTokens?: number;\n /** Prompt tokens served from the prompt cache. */\n cacheReadInputTokens?: number;\n /** Prompt tokens written to the prompt cache by this request. */\n cacheWriteInputTokens?: number;\n /** Prompt tokens neither read from nor written to the cache. */\n noCacheInputTokens?: number;\n /** What the call cost at the platform's list price, in millionths of a US dollar. Set only by a platform that knows its prices. */\n costMicroUsd?: number;\n /** What the call is charged at an app's own rates, in millionths of a US dollar. Set by the app that bills for it, never by a platform. */\n chargeMicroUsd?: number;\n};\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * What a model's tokens are priced at, in US dollars per million tokens: a platform's list price,
3
+ * or an app's own rates for what it charges.
4
+ */
5
+ export type AiTokenRates = {
6
+ /** Prompt tokens neither read from nor written to the cache. */
7
+ input: number;
8
+ output: number;
9
+ cacheRead: number;
10
+ /** A cache write that lives for five minutes. */
11
+ cacheWriteFiveMinutes: number;
12
+ /** A cache write that lives for an hour. Absent for a model that only caches for five minutes. */
13
+ cacheWriteOneHour?: number;
14
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=AiTokenRates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiTokenRates.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/AiTokenRates.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * What a model's tokens are priced at, in US dollars per million tokens: a platform's list price,\n * or an app's own rates for what it charges.\n */\nexport type AiTokenRates = {\n /** Prompt tokens neither read from nor written to the cache. */\n input: number;\n output: number;\n cacheRead: number;\n /** A cache write that lives for five minutes. */\n cacheWriteFiveMinutes: number;\n /** A cache write that lives for an hour. Absent for a model that only caches for five minutes. */\n cacheWriteOneHour?: number;\n};\n"]}
@@ -1,3 +1,4 @@
1
+ export * from './AiModelTokenRates';
1
2
  export * from './AiStreamAbort';
2
3
  export * from './AiStreamCustom';
3
4
  export * from './AiStreamError';
@@ -30,3 +31,4 @@ export * from './AiStreamToolInputStart';
30
31
  export * from './AiStreamToolOutputDenied';
31
32
  export * from './AiStreamToolResult';
32
33
  export * from './AiStreamUsage';
34
+ export * from './AiTokenRates';
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./AiModelTokenRates"), exports);
17
18
  __exportStar(require("./AiStreamAbort"), exports);
18
19
  __exportStar(require("./AiStreamCustom"), exports);
19
20
  __exportStar(require("./AiStreamError"), exports);
@@ -46,4 +47,5 @@ __exportStar(require("./AiStreamToolInputStart"), exports);
46
47
  __exportStar(require("./AiStreamToolOutputDenied"), exports);
47
48
  __exportStar(require("./AiStreamToolResult"), exports);
48
49
  __exportStar(require("./AiStreamUsage"), exports);
50
+ __exportStar(require("./AiTokenRates"), exports);
49
51
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kDAAgC;AAChC,mDAAiC;AACjC,kDAAgC;AAChC,iDAA+B;AAC/B,qDAAmC;AACnC,mDAAiC;AACjC,yDAAuC;AACvC,uDAAqC;AACrC,iDAA+B;AAC/B,qDAAmC;AACnC,gDAA8B;AAC9B,2DAAyC;AACzC,yDAAuC;AACvC,8DAA4C;AAC5C,2DAAyC;AACzC,mDAAiC;AACjC,uDAAqC;AACrC,kDAAgC;AAChC,sDAAoC;AACpC,sDAAoC;AACpC,oDAAkC;AAClC,sDAAoC;AACpC,gEAA8C;AAC9C,iEAA+C;AAC/C,qDAAmC;AACnC,sDAAoC;AACpC,2DAAyC;AACzC,yDAAuC;AACvC,2DAAyC;AACzC,6DAA2C;AAC3C,uDAAqC;AACrC,kDAAgC","sourcesContent":["export * from './AiStreamAbort';\nexport * from './AiStreamCustom';\nexport * from './AiStreamError';\nexport * from './AiStreamFile';\nexport * from './AiStreamFilePart';\nexport * from './AiStreamFinish';\nexport * from './AiStreamFinishReason';\nexport * from './AiStreamFinishStep';\nexport * from './AiStreamPart';\nexport * from './AiStreamPartType';\nexport * from './AiStreamRaw';\nexport * from './AiStreamReasoningDelta';\nexport * from './AiStreamReasoningEnd';\nexport * from './AiStreamReasoningFilePart';\nexport * from './AiStreamReasoningStart';\nexport * from './AiStreamSource';\nexport * from './AiStreamSourcePart';\nexport * from './AiStreamStart';\nexport * from './AiStreamStartStep';\nexport * from './AiStreamTextDelta';\nexport * from './AiStreamTextEnd';\nexport * from './AiStreamTextStart';\nexport * from './AiStreamToolApprovalRequest';\nexport * from './AiStreamToolApprovalResponse';\nexport * from './AiStreamToolCall';\nexport * from './AiStreamToolError';\nexport * from './AiStreamToolInputDelta';\nexport * from './AiStreamToolInputEnd';\nexport * from './AiStreamToolInputStart';\nexport * from './AiStreamToolOutputDenied';\nexport * from './AiStreamToolResult';\nexport * from './AiStreamUsage';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,kDAAgC;AAChC,mDAAiC;AACjC,kDAAgC;AAChC,iDAA+B;AAC/B,qDAAmC;AACnC,mDAAiC;AACjC,yDAAuC;AACvC,uDAAqC;AACrC,iDAA+B;AAC/B,qDAAmC;AACnC,gDAA8B;AAC9B,2DAAyC;AACzC,yDAAuC;AACvC,8DAA4C;AAC5C,2DAAyC;AACzC,mDAAiC;AACjC,uDAAqC;AACrC,kDAAgC;AAChC,sDAAoC;AACpC,sDAAoC;AACpC,oDAAkC;AAClC,sDAAoC;AACpC,gEAA8C;AAC9C,iEAA+C;AAC/C,qDAAmC;AACnC,sDAAoC;AACpC,2DAAyC;AACzC,yDAAuC;AACvC,2DAAyC;AACzC,6DAA2C;AAC3C,uDAAqC;AACrC,kDAAgC;AAChC,iDAA+B","sourcesContent":["export * from './AiModelTokenRates';\nexport * from './AiStreamAbort';\nexport * from './AiStreamCustom';\nexport * from './AiStreamError';\nexport * from './AiStreamFile';\nexport * from './AiStreamFilePart';\nexport * from './AiStreamFinish';\nexport * from './AiStreamFinishReason';\nexport * from './AiStreamFinishStep';\nexport * from './AiStreamPart';\nexport * from './AiStreamPartType';\nexport * from './AiStreamRaw';\nexport * from './AiStreamReasoningDelta';\nexport * from './AiStreamReasoningEnd';\nexport * from './AiStreamReasoningFilePart';\nexport * from './AiStreamReasoningStart';\nexport * from './AiStreamSource';\nexport * from './AiStreamSourcePart';\nexport * from './AiStreamStart';\nexport * from './AiStreamStartStep';\nexport * from './AiStreamTextDelta';\nexport * from './AiStreamTextEnd';\nexport * from './AiStreamTextStart';\nexport * from './AiStreamToolApprovalRequest';\nexport * from './AiStreamToolApprovalResponse';\nexport * from './AiStreamToolCall';\nexport * from './AiStreamToolError';\nexport * from './AiStreamToolInputDelta';\nexport * from './AiStreamToolInputEnd';\nexport * from './AiStreamToolInputStart';\nexport * from './AiStreamToolOutputDenied';\nexport * from './AiStreamToolResult';\nexport * from './AiStreamUsage';\nexport * from './AiTokenRates';\n"]}
@@ -1,9 +1,16 @@
1
+ /** The four-digit year of an ISO 8601 date, such as `2026`. */
1
2
  export type TYear = `${number}${number}${number}${number}`;
3
+ /** The two-digit month of an ISO 8601 date, `01` to `12`. */
2
4
  export type TMonth = `${number}${number}`;
5
+ /** The two-digit day of the month of an ISO 8601 date, `01` to `31`. */
3
6
  export type TDay = `${number}${number}`;
7
+ /** The two-digit hour of an ISO 8601 time on a 24-hour clock, `00` to `23`; also the hours of a UtcOffset. */
4
8
  export type THours = `${number}${number}`;
9
+ /** The two-digit minute of an ISO 8601 time, `00` to `59`; also the minutes of a UtcOffset. */
5
10
  export type TMinutes = `${number}${number}`;
11
+ /** The two-digit second of an ISO 8601 time, `00` to `59`. */
6
12
  export type TSeconds = `${number}${number}`;
13
+ /** The three-digit millisecond of an ISO 8601 time, `000` to `999`. */
7
14
  export type TMilliseconds = `${number}${number}${number}`;
8
15
  /**
9
16
  * Represent a string like `2021-01-08`
@@ -21,3 +28,7 @@ export type TDateISOTime = `${THours}:${TMinutes}:${TSeconds}.${TMilliseconds}`;
21
28
  * "Expression produces a union type that is too complex to represent. ts(2590)
22
29
  */
23
30
  export type QpqIsoDateTime = `${TDateISODate}T${TDateISOTime}Z`;
31
+ /**
32
+ * A fixed offset from UTC as `±HH:MM` ('+10:00', '+09:30', '-03:30'). Fixed: it never follows daylight saving.
33
+ */
34
+ export type UtcOffset = `${'+' | '-'}${THours}:${TMinutes}`;
@@ -1,5 +1,9 @@
1
1
  "use strict";
2
+ /* eslint-disable qpq/one-export-per-file */
2
3
  // Template-literal typing for ISO-8601 timestamps
3
4
  // (from https://gist.github.com/MrChocolatine/367fb2a35d02f6175cc8ccb3d3a20054)
5
+ //
6
+ // Each `${number}` placeholder accepts any numeric text, so these types catch a missing part, a separator in the wrong
7
+ // place or letters, never an out-of-range value: '99' is a TMonth and '1.5' a THours. Check values at runtime.
4
8
  Object.defineProperty(exports, "__esModule", { value: true });
5
9
  //# sourceMappingURL=QpqIsoDateTime.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"QpqIsoDateTime.js","sourceRoot":"","sources":["../../../src/types/QpqIsoDateTime.ts"],"names":[],"mappings":";AAAA,kDAAkD;AAClD,gFAAgF","sourcesContent":["// Template-literal typing for ISO-8601 timestamps\n// (from https://gist.github.com/MrChocolatine/367fb2a35d02f6175cc8ccb3d3a20054)\n\nexport type TYear = `${number}${number}${number}${number}`;\nexport type TMonth = `${number}${number}`;\nexport type TDay = `${number}${number}`;\nexport type THours = `${number}${number}`;\nexport type TMinutes = `${number}${number}`;\nexport type TSeconds = `${number}${number}`;\nexport type TMilliseconds = `${number}${number}${number}`;\n\n/**\n * Represent a string like `2021-01-08`\n */\nexport type TDateISODate = `${TYear}-${TMonth}-${TDay}`;\n\n/**\n * Represent a string like `14:42:34.678`\n */\nexport type TDateISOTime = `${THours}:${TMinutes}:${TSeconds}.${TMilliseconds}`;\n\n/**\n * Represent a string like `2021-01-08T14:42:34.678Z` (format: ISO 8601).\n *\n * It is not possible to type more precisely (list every possible values for months, hours etc) as\n * it would result in a warning from TypeScript:\n * \"Expression produces a union type that is too complex to represent. ts(2590)\n */\nexport type QpqIsoDateTime = `${TDateISODate}T${TDateISOTime}Z`;\n"]}
1
+ {"version":3,"file":"QpqIsoDateTime.js","sourceRoot":"","sources":["../../../src/types/QpqIsoDateTime.ts"],"names":[],"mappings":";AAAA,4CAA4C;AAC5C,kDAAkD;AAClD,gFAAgF;AAChF,EAAE;AACF,uHAAuH;AACvH,+GAA+G","sourcesContent":["/* eslint-disable qpq/one-export-per-file */\n// Template-literal typing for ISO-8601 timestamps\n// (from https://gist.github.com/MrChocolatine/367fb2a35d02f6175cc8ccb3d3a20054)\n//\n// Each `${number}` placeholder accepts any numeric text, so these types catch a missing part, a separator in the wrong\n// place or letters, never an out-of-range value: '99' is a TMonth and '1.5' a THours. Check values at runtime.\n\n/** The four-digit year of an ISO 8601 date, such as `2026`. */\nexport type TYear = `${number}${number}${number}${number}`;\n\n/** The two-digit month of an ISO 8601 date, `01` to `12`. */\nexport type TMonth = `${number}${number}`;\n\n/** The two-digit day of the month of an ISO 8601 date, `01` to `31`. */\nexport type TDay = `${number}${number}`;\n\n/** The two-digit hour of an ISO 8601 time on a 24-hour clock, `00` to `23`; also the hours of a UtcOffset. */\nexport type THours = `${number}${number}`;\n\n/** The two-digit minute of an ISO 8601 time, `00` to `59`; also the minutes of a UtcOffset. */\nexport type TMinutes = `${number}${number}`;\n\n/** The two-digit second of an ISO 8601 time, `00` to `59`. */\nexport type TSeconds = `${number}${number}`;\n\n/** The three-digit millisecond of an ISO 8601 time, `000` to `999`. */\nexport type TMilliseconds = `${number}${number}${number}`;\n\n/**\n * Represent a string like `2021-01-08`\n */\nexport type TDateISODate = `${TYear}-${TMonth}-${TDay}`;\n\n/**\n * Represent a string like `14:42:34.678`\n */\nexport type TDateISOTime = `${THours}:${TMinutes}:${TSeconds}.${TMilliseconds}`;\n\n/**\n * Represent a string like `2021-01-08T14:42:34.678Z` (format: ISO 8601).\n *\n * It is not possible to type more precisely (list every possible values for months, hours etc) as\n * it would result in a warning from TypeScript:\n * \"Expression produces a union type that is too complex to represent. ts(2590)\n */\nexport type QpqIsoDateTime = `${TDateISODate}T${TDateISOTime}Z`;\n\n/**\n * A fixed offset from UTC as `±HH:MM` ('+10:00', '+09:30', '-03:30'). Fixed: it never follows daylight saving.\n */\nexport type UtcOffset = `${'+' | '-'}${THours}:${TMinutes}`;\n"]}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The calendar day (`YYYY-MM-DD`) some whole months after `day` (negative for before), the day of the month kept where the
3
+ * target month has it and clamped to its last day where not: 31 March less a month is 28 or 29 February. Unlike
4
+ * addMonthsToTDateIso, which lets a short month overflow into the next (31 March less a month is 3 March).
5
+ */
6
+ export declare const addCalendarMonths: (day: string, months: number) => string;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addCalendarMonths = void 0;
4
+ /**
5
+ * The calendar day (`YYYY-MM-DD`) some whole months after `day` (negative for before), the day of the month kept where the
6
+ * target month has it and clamped to its last day where not: 31 March less a month is 28 or 29 February. Unlike
7
+ * addMonthsToTDateIso, which lets a short month overflow into the next (31 March less a month is 3 March).
8
+ */
9
+ const addCalendarMonths = (day, months) => {
10
+ const [year = 0, month = 1, date = 1] = day.split('-').map(Number);
11
+ const index = year * 12 + (month - 1) + months;
12
+ const targetYear = Math.floor(index / 12);
13
+ const targetMonth = index - targetYear * 12 + 1;
14
+ // Day 0 of the month after is the last day of this one.
15
+ const lastDate = new Date(Date.UTC(targetYear, targetMonth, 0)).getUTCDate();
16
+ const pad = (value) => String(value).padStart(2, '0');
17
+ return `${String(targetYear).padStart(4, '0')}-${pad(targetMonth)}-${pad(Math.min(date, lastDate))}`;
18
+ };
19
+ exports.addCalendarMonths = addCalendarMonths;
20
+ //# sourceMappingURL=addCalendarMonths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addCalendarMonths.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/addCalendarMonths.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACI,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAE,MAAc,EAAU,EAAE;IACvE,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,KAAK,GAAG,UAAU,GAAG,EAAE,GAAG,CAAC,CAAC;IAChD,wDAAwD;IACxD,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IAC7E,MAAM,GAAG,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAEtE,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;AACvG,CAAC,CAAC;AAVW,QAAA,iBAAiB,qBAU5B","sourcesContent":["/**\n * The calendar day (`YYYY-MM-DD`) some whole months after `day` (negative for before), the day of the month kept where the\n * target month has it and clamped to its last day where not: 31 March less a month is 28 or 29 February. Unlike\n * addMonthsToTDateIso, which lets a short month overflow into the next (31 March less a month is 3 March).\n */\nexport const addCalendarMonths = (day: string, months: number): string => {\n const [year = 0, month = 1, date = 1] = day.split('-').map(Number);\n const index = year * 12 + (month - 1) + months;\n const targetYear = Math.floor(index / 12);\n const targetMonth = index - targetYear * 12 + 1;\n // Day 0 of the month after is the last day of this one.\n const lastDate = new Date(Date.UTC(targetYear, targetMonth, 0)).getUTCDate();\n const pad = (value: number): string => String(value).padStart(2, '0');\n\n return `${String(targetYear).padStart(4, '0')}-${pad(targetMonth)}-${pad(Math.min(date, lastDate))}`;\n};\n"]}
@@ -0,0 +1,7 @@
1
+ import { Nullable } from '../../types/Nullable';
2
+ import { UtcOffset } from '../../types/QpqIsoDateTime';
3
+ /**
4
+ * The minutes an offset adds to UTC ('+09:30' is 570), or null when it is not a real one. The UtcOffset type only checks
5
+ * the shape (`'+99:00'` compiles), so the range and the quarter hours are checked here.
6
+ */
7
+ export declare const getUtcOffsetMinutes: (utcOffset: UtcOffset) => Nullable<number>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUtcOffsetMinutes = void 0;
4
+ // Every offset in use lies from -12:00 to +14:00, in whole quarter hours (Nepal is +05:45).
5
+ const MIN_OFFSET_MINUTES = -12 * 60;
6
+ const MAX_OFFSET_MINUTES = 14 * 60;
7
+ const OFFSET_PATTERN = /^([+-])(\d{2}):(\d{2})$/;
8
+ /**
9
+ * The minutes an offset adds to UTC ('+09:30' is 570), or null when it is not a real one. The UtcOffset type only checks
10
+ * the shape (`'+99:00'` compiles), so the range and the quarter hours are checked here.
11
+ */
12
+ const getUtcOffsetMinutes = (utcOffset) => {
13
+ const match = OFFSET_PATTERN.exec(utcOffset);
14
+ if (!match) {
15
+ return null;
16
+ }
17
+ const [, sign, hours = '', minutes = ''] = match;
18
+ const total = (Number(hours) * 60 + Number(minutes)) * (sign === '-' ? -1 : 1);
19
+ const isQuarterHour = Number(minutes) % 15 === 0 && Number(minutes) < 60;
20
+ return isQuarterHour && total >= MIN_OFFSET_MINUTES && total <= MAX_OFFSET_MINUTES ? total : null;
21
+ };
22
+ exports.getUtcOffsetMinutes = getUtcOffsetMinutes;
23
+ //# sourceMappingURL=getUtcOffsetMinutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getUtcOffsetMinutes.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/getUtcOffsetMinutes.ts"],"names":[],"mappings":";;;AAGA,4FAA4F;AAC5F,MAAM,kBAAkB,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;AACpC,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,CAAC;AACnC,MAAM,cAAc,GAAG,yBAAyB,CAAC;AAEjD;;;GAGG;AACI,MAAM,mBAAmB,GAAG,CAAC,SAAoB,EAAoB,EAAE;IAC5E,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEzE,OAAO,aAAa,IAAI,KAAK,IAAI,kBAAkB,IAAI,KAAK,IAAI,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACpG,CAAC,CAAC;AAZW,QAAA,mBAAmB,uBAY9B","sourcesContent":["import { Nullable } from '../../types/Nullable';\nimport { UtcOffset } from '../../types/QpqIsoDateTime';\n\n// Every offset in use lies from -12:00 to +14:00, in whole quarter hours (Nepal is +05:45).\nconst MIN_OFFSET_MINUTES = -12 * 60;\nconst MAX_OFFSET_MINUTES = 14 * 60;\nconst OFFSET_PATTERN = /^([+-])(\\d{2}):(\\d{2})$/;\n\n/**\n * The minutes an offset adds to UTC ('+09:30' is 570), or null when it is not a real one. The UtcOffset type only checks\n * the shape (`'+99:00'` compiles), so the range and the quarter hours are checked here.\n */\nexport const getUtcOffsetMinutes = (utcOffset: UtcOffset): Nullable<number> => {\n const match = OFFSET_PATTERN.exec(utcOffset);\n\n if (!match) {\n return null;\n }\n\n const [, sign, hours = '', minutes = ''] = match;\n const total = (Number(hours) * 60 + Number(minutes)) * (sign === '-' ? -1 : 1);\n const isQuarterHour = Number(minutes) % 15 === 0 && Number(minutes) < 60;\n\n return isQuarterHour && total >= MIN_OFFSET_MINUTES && total <= MAX_OFFSET_MINUTES ? total : null;\n};\n"]}
@@ -0,0 +1,2 @@
1
+ /** The weekday of a calendar day (`YYYY-MM-DD`), 0 for Monday to 6 for Sunday. A civil date's weekday needs no zone. */
2
+ export declare const getWeekdayFromMonday: (day: string) => number;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getWeekdayFromMonday = void 0;
4
+ /** The weekday of a calendar day (`YYYY-MM-DD`), 0 for Monday to 6 for Sunday. A civil date's weekday needs no zone. */
5
+ const getWeekdayFromMonday = (day) => (new Date(`${day}T00:00:00.000Z`).getUTCDay() + 6) % 7;
6
+ exports.getWeekdayFromMonday = getWeekdayFromMonday;
7
+ //# sourceMappingURL=getWeekdayFromMonday.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getWeekdayFromMonday.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/getWeekdayFromMonday.ts"],"names":[],"mappings":";;;AAAA,wHAAwH;AACjH,MAAM,oBAAoB,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,gBAAgB,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAAvG,QAAA,oBAAoB,wBAAmF","sourcesContent":["/** The weekday of a calendar day (`YYYY-MM-DD`), 0 for Monday to 6 for Sunday. A civil date's weekday needs no zone. */\nexport const getWeekdayFromMonday = (day: string): number => (new Date(`${day}T00:00:00.000Z`).getUTCDay() + 6) % 7;\n"]}
@@ -1,4 +1,8 @@
1
+ export * from './addCalendarMonths';
1
2
  export * from './getDateNow';
2
3
  export * from './getMillisecondsBetween';
3
4
  export * from './getQpqIsoDateTimeFromDate';
5
+ export * from './getUtcOffsetMinutes';
4
6
  export * from './getValidQpqIsoDateTime';
7
+ export * from './getWeekdayFromMonday';
8
+ export * from './isQpqIsoDateTime';
@@ -14,8 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./addCalendarMonths"), exports);
17
18
  __exportStar(require("./getDateNow"), exports);
18
19
  __exportStar(require("./getMillisecondsBetween"), exports);
19
20
  __exportStar(require("./getQpqIsoDateTimeFromDate"), exports);
21
+ __exportStar(require("./getUtcOffsetMinutes"), exports);
20
22
  __exportStar(require("./getValidQpqIsoDateTime"), exports);
23
+ __exportStar(require("./getWeekdayFromMonday"), exports);
24
+ __exportStar(require("./isQpqIsoDateTime"), exports);
21
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,2DAAyC;AACzC,8DAA4C;AAC5C,2DAAyC","sourcesContent":["export * from './getDateNow';\nexport * from './getMillisecondsBetween';\nexport * from './getQpqIsoDateTimeFromDate';\nexport * from './getValidQpqIsoDateTime';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,+CAA6B;AAC7B,2DAAyC;AACzC,8DAA4C;AAC5C,wDAAsC;AACtC,2DAAyC;AACzC,yDAAuC;AACvC,qDAAmC","sourcesContent":["export * from './addCalendarMonths';\nexport * from './getDateNow';\nexport * from './getMillisecondsBetween';\nexport * from './getQpqIsoDateTimeFromDate';\nexport * from './getUtcOffsetMinutes';\nexport * from './getValidQpqIsoDateTime';\nexport * from './getWeekdayFromMonday';\nexport * from './isQpqIsoDateTime';\n"]}
@@ -0,0 +1,3 @@
1
+ import { QpqIsoDateTime } from '../../types/QpqIsoDateTime';
2
+ /** Whether a value is a real instant in exactly the QpqIsoDateTime form (`2026-11-09T05:12:40.118Z`): the guard form of getValidQpqIsoDateTime. */
3
+ export declare const isQpqIsoDateTime: (value: unknown) => value is QpqIsoDateTime;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isQpqIsoDateTime = void 0;
4
+ const getValidQpqIsoDateTime_1 = require("./getValidQpqIsoDateTime");
5
+ /** Whether a value is a real instant in exactly the QpqIsoDateTime form (`2026-11-09T05:12:40.118Z`): the guard form of getValidQpqIsoDateTime. */
6
+ const isQpqIsoDateTime = (value) => typeof value === 'string' && (0, getValidQpqIsoDateTime_1.getValidQpqIsoDateTime)(value) !== undefined;
7
+ exports.isQpqIsoDateTime = isQpqIsoDateTime;
8
+ //# sourceMappingURL=isQpqIsoDateTime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isQpqIsoDateTime.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/isQpqIsoDateTime.ts"],"names":[],"mappings":";;;AACA,qEAAkE;AAElE,mJAAmJ;AAC5I,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAA2B,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAA,+CAAsB,EAAC,KAAK,CAAC,KAAK,SAAS,CAAC;AAAzI,QAAA,gBAAgB,oBAAyH","sourcesContent":["import { QpqIsoDateTime } from '../../types/QpqIsoDateTime';\nimport { getValidQpqIsoDateTime } from './getValidQpqIsoDateTime';\n\n/** Whether a value is a real instant in exactly the QpqIsoDateTime form (`2026-11-09T05:12:40.118Z`): the guard form of getValidQpqIsoDateTime. */\nexport const isQpqIsoDateTime = (value: unknown): value is QpqIsoDateTime => typeof value === 'string' && getValidQpqIsoDateTime(value) !== undefined;\n"]}
@@ -0,0 +1,9 @@
1
+ import { AiStreamUsage } from './types/AiStreamUsage';
2
+ import { AiTokenRates } from './types/AiTokenRates';
3
+ import { AiCacheTtl } from './AiCacheTtl';
4
+ /**
5
+ * What a call's tokens come to at `rates`, in millionths of a US dollar, rounded to a whole number
6
+ * so totals add up exactly. Cache writes are priced at the five minute rate only when every write
7
+ * lived for five minutes (`cacheTtl` FiveMinutes); otherwise at the hour rate, the dearer one.
8
+ */
9
+ export declare const getAiUsageAmountMicroUsd: (usage: AiStreamUsage, rates: AiTokenRates, cacheTtl?: AiCacheTtl) => number;
@@ -0,0 +1,16 @@
1
+ import { AiCacheTtl } from './AiCacheTtl';
2
+ /**
3
+ * What a call's tokens come to at `rates`, in millionths of a US dollar, rounded to a whole number
4
+ * so totals add up exactly. Cache writes are priced at the five minute rate only when every write
5
+ * lived for five minutes (`cacheTtl` FiveMinutes); otherwise at the hour rate, the dearer one.
6
+ */
7
+ export const getAiUsageAmountMicroUsd = (usage, rates, cacheTtl) => {
8
+ const cacheReadTokens = usage.cacheReadInputTokens ?? 0;
9
+ const cacheWriteTokens = usage.cacheWriteInputTokens ?? 0;
10
+ // `inputTokens` is the total of the three input kinds, so only the uncached part is priced as input.
11
+ const noCacheTokens = usage.noCacheInputTokens ?? Math.max(0, (usage.inputTokens ?? 0) - cacheReadTokens - cacheWriteTokens);
12
+ const cacheWriteRate = cacheTtl === AiCacheTtl.FiveMinutes ? rates.cacheWriteFiveMinutes : (rates.cacheWriteOneHour ?? rates.cacheWriteFiveMinutes);
13
+ // A rate per million tokens times a token count is already millionths of a dollar.
14
+ return Math.round(noCacheTokens * rates.input + cacheReadTokens * rates.cacheRead + cacheWriteTokens * cacheWriteRate + (usage.outputTokens ?? 0) * rates.output);
15
+ };
16
+ //# sourceMappingURL=getAiUsageAmountMicroUsd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getAiUsageAmountMicroUsd.js","sourceRoot":"","sources":["../../../../src/actions/ai/getAiUsageAmountMicroUsd.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,KAAoB,EAAE,KAAmB,EAAE,QAAqB,EAAU,EAAE;IACnH,MAAM,eAAe,GAAG,KAAK,CAAC,oBAAoB,IAAI,CAAC,CAAC;IACxD,MAAM,gBAAgB,GAAG,KAAK,CAAC,qBAAqB,IAAI,CAAC,CAAC;IAE1D,qGAAqG;IACrG,MAAM,aAAa,GAAG,KAAK,CAAC,kBAAkB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,eAAe,GAAG,gBAAgB,CAAC,CAAC;IAE7H,MAAM,cAAc,GAAG,QAAQ,KAAK,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAEpJ,mFAAmF;IACnF,OAAO,IAAI,CAAC,KAAK,CACf,aAAa,GAAG,KAAK,CAAC,KAAK,GAAG,eAAe,GAAG,KAAK,CAAC,SAAS,GAAG,gBAAgB,GAAG,cAAc,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAC/I,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { AiStreamUsage } from './types/AiStreamUsage';\nimport { AiTokenRates } from './types/AiTokenRates';\nimport { AiCacheTtl } from './AiCacheTtl';\n\n/**\n * What a call's tokens come to at `rates`, in millionths of a US dollar, rounded to a whole number\n * so totals add up exactly. Cache writes are priced at the five minute rate only when every write\n * lived for five minutes (`cacheTtl` FiveMinutes); otherwise at the hour rate, the dearer one.\n */\nexport const getAiUsageAmountMicroUsd = (usage: AiStreamUsage, rates: AiTokenRates, cacheTtl?: AiCacheTtl): number => {\n const cacheReadTokens = usage.cacheReadInputTokens ?? 0;\n const cacheWriteTokens = usage.cacheWriteInputTokens ?? 0;\n\n // `inputTokens` is the total of the three input kinds, so only the uncached part is priced as input.\n const noCacheTokens = usage.noCacheInputTokens ?? Math.max(0, (usage.inputTokens ?? 0) - cacheReadTokens - cacheWriteTokens);\n\n const cacheWriteRate = cacheTtl === AiCacheTtl.FiveMinutes ? rates.cacheWriteFiveMinutes : (rates.cacheWriteOneHour ?? rates.cacheWriteFiveMinutes);\n\n // A rate per million tokens times a token count is already millionths of a dollar.\n return Math.round(\n noCacheTokens * rates.input + cacheReadTokens * rates.cacheRead + cacheWriteTokens * cacheWriteRate + (usage.outputTokens ?? 0) * rates.output,\n );\n};\n"]}
@@ -10,5 +10,6 @@ export * from './AiReasoningEffort';
10
10
  export * from './askAiGetModelRegions';
11
11
  export * from './askAiPrompt';
12
12
  export * from './askAiPromptStream';
13
+ export * from './getAiUsageAmountMicroUsd';
13
14
  export * from './sumAiStreamUsage';
14
15
  export * from './types';
@@ -10,6 +10,7 @@ export * from './AiReasoningEffort';
10
10
  export * from './askAiGetModelRegions';
11
11
  export * from './askAiPrompt';
12
12
  export * from './askAiPromptStream';
13
+ export * from './getAiUsageAmountMicroUsd';
13
14
  export * from './sumAiStreamUsage';
14
15
  export * from './types';
15
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/actions/ai/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,SAAS,CAAC","sourcesContent":["export * from './AiActionType';\nexport * from './AiCacheTtl';\nexport * from './AiDataRegion';\nexport * from './AiJsonSchema';\nexport * from './AiMessage';\nexport * from './AiModel';\nexport * from './AiModelRegionMap';\nexport * from './AiReasoningConfig';\nexport * from './AiReasoningEffort';\nexport * from './askAiGetModelRegions';\nexport * from './askAiPrompt';\nexport * from './askAiPromptStream';\nexport * from './sumAiStreamUsage';\nexport * from './types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/actions/ai/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,SAAS,CAAC","sourcesContent":["export * from './AiActionType';\nexport * from './AiCacheTtl';\nexport * from './AiDataRegion';\nexport * from './AiJsonSchema';\nexport * from './AiMessage';\nexport * from './AiModel';\nexport * from './AiModelRegionMap';\nexport * from './AiReasoningConfig';\nexport * from './AiReasoningEffort';\nexport * from './askAiGetModelRegions';\nexport * from './askAiPrompt';\nexport * from './askAiPromptStream';\nexport * from './getAiUsageAmountMicroUsd';\nexport * from './sumAiStreamUsage';\nexport * from './types';\n"]}
@@ -1,6 +1,6 @@
1
1
  import { AiStreamUsage } from './types/AiStreamUsage';
2
2
  /**
3
- * Adds token usages together field by field, for a chat's cost or a turn that spanned several
3
+ * Adds token usages (and their costs and charges) together field by field, for a chat's cost or a turn that spanned several
4
4
  * executions. A field no usage reported stays undefined rather than becoming zero.
5
5
  */
6
6
  export declare const sumAiStreamUsage: (usages: readonly AiStreamUsage[]) => AiStreamUsage;
@@ -1,6 +1,15 @@
1
- const USAGE_FIELDS = ['inputTokens', 'outputTokens', 'totalTokens', 'cacheReadInputTokens', 'cacheWriteInputTokens', 'noCacheInputTokens'];
1
+ const USAGE_FIELDS = [
2
+ 'inputTokens',
3
+ 'outputTokens',
4
+ 'totalTokens',
5
+ 'cacheReadInputTokens',
6
+ 'cacheWriteInputTokens',
7
+ 'noCacheInputTokens',
8
+ 'costMicroUsd',
9
+ 'chargeMicroUsd',
10
+ ];
2
11
  /**
3
- * Adds token usages together field by field, for a chat's cost or a turn that spanned several
12
+ * Adds token usages (and their costs and charges) together field by field, for a chat's cost or a turn that spanned several
4
13
  * executions. A field no usage reported stays undefined rather than becoming zero.
5
14
  */
6
15
  export const sumAiStreamUsage = (usages) => USAGE_FIELDS.reduce((sum, field) => {
@@ -1 +1 @@
1
- {"version":3,"file":"sumAiStreamUsage.js","sourceRoot":"","sources":["../../../../src/actions/ai/sumAiStreamUsage.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,CAAC,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,oBAAoB,CAAU,CAAC;AAEpJ;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAgC,EAAiB,EAAE,CAClF,YAAY,CAAC,MAAM,CAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAE7G,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9G,CAAC,EAAE,EAAE,CAAC,CAAC","sourcesContent":["import { AiStreamUsage } from './types/AiStreamUsage';\n\nconst USAGE_FIELDS = ['inputTokens', 'outputTokens', 'totalTokens', 'cacheReadInputTokens', 'cacheWriteInputTokens', 'noCacheInputTokens'] as const;\n\n/**\n * Adds token usages together field by field, for a chat's cost or a turn that spanned several\n * executions. A field no usage reported stays undefined rather than becoming zero.\n */\nexport const sumAiStreamUsage = (usages: readonly AiStreamUsage[]): AiStreamUsage =>\n USAGE_FIELDS.reduce<AiStreamUsage>((sum, field) => {\n const reported = usages.map((usage) => usage[field]).filter((value): value is number => value !== undefined);\n\n return reported.length > 0 ? { ...sum, [field]: reported.reduce((total, value) => total + value, 0) } : sum;\n }, {});\n"]}
1
+ {"version":3,"file":"sumAiStreamUsage.js","sourceRoot":"","sources":["../../../../src/actions/ai/sumAiStreamUsage.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG;IACnB,aAAa;IACb,cAAc;IACd,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,oBAAoB;IACpB,cAAc;IACd,gBAAgB;CACR,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAgC,EAAiB,EAAE,CAClF,YAAY,CAAC,MAAM,CAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAE7G,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9G,CAAC,EAAE,EAAE,CAAC,CAAC","sourcesContent":["import { AiStreamUsage } from './types/AiStreamUsage';\n\nconst USAGE_FIELDS = [\n 'inputTokens',\n 'outputTokens',\n 'totalTokens',\n 'cacheReadInputTokens',\n 'cacheWriteInputTokens',\n 'noCacheInputTokens',\n 'costMicroUsd',\n 'chargeMicroUsd',\n] as const;\n\n/**\n * Adds token usages (and their costs and charges) together field by field, for a chat's cost or a turn that spanned several\n * executions. A field no usage reported stays undefined rather than becoming zero.\n */\nexport const sumAiStreamUsage = (usages: readonly AiStreamUsage[]): AiStreamUsage =>\n USAGE_FIELDS.reduce<AiStreamUsage>((sum, field) => {\n const reported = usages.map((usage) => usage[field]).filter((value): value is number => value !== undefined);\n\n return reported.length > 0 ? { ...sum, [field]: reported.reduce((total, value) => total + value, 0) } : sum;\n }, {});\n"]}
@@ -0,0 +1,4 @@
1
+ import { AiModel } from '../AiModel';
2
+ import { AiTokenRates } from './AiTokenRates';
3
+ /** Token rates for each model that has them, in US dollars per million tokens. */
4
+ export type AiModelTokenRates = Partial<Record<AiModel, AiTokenRates>>;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AiModelTokenRates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiModelTokenRates.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/AiModelTokenRates.ts"],"names":[],"mappings":"","sourcesContent":["import { AiModel } from '../AiModel';\nimport { AiTokenRates } from './AiTokenRates';\n\n/** Token rates for each model that has them, in US dollars per million tokens. */\nexport type AiModelTokenRates = Partial<Record<AiModel, AiTokenRates>>;\n"]}
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Token usage reported by the model.
2
+ * Token usage reported by the model, what it cost when the platform knows its prices, and what it
3
+ * is charged at when an app bills for it.
3
4
  *
4
5
  * Each field may be undefined if the underlying provider doesn't report it.
5
6
  * `totalTokens` is the sum of input + output (plus any reasoning tokens, when applicable).
@@ -17,4 +18,8 @@ export type AiStreamUsage = {
17
18
  cacheWriteInputTokens?: number;
18
19
  /** Prompt tokens neither read from nor written to the cache. */
19
20
  noCacheInputTokens?: number;
21
+ /** What the call cost at the platform's list price, in millionths of a US dollar. Set only by a platform that knows its prices. */
22
+ costMicroUsd?: number;
23
+ /** What the call is charged at an app's own rates, in millionths of a US dollar. Set by the app that bills for it, never by a platform. */
24
+ chargeMicroUsd?: number;
20
25
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AiStreamUsage.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/AiStreamUsage.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Token usage reported by the model.\n *\n * Each field may be undefined if the underlying provider doesn't report it.\n * `totalTokens` is the sum of input + output (plus any reasoning tokens, when applicable).\n */\nexport type AiStreamUsage = {\n /** Prompt tokens consumed. */\n inputTokens?: number;\n /** Completion tokens produced. */\n outputTokens?: number;\n /** Total tokens, typically `inputTokens + outputTokens` (+ reasoning, when applicable). */\n totalTokens?: number;\n /** Prompt tokens served from the prompt cache. */\n cacheReadInputTokens?: number;\n /** Prompt tokens written to the prompt cache by this request. */\n cacheWriteInputTokens?: number;\n /** Prompt tokens neither read from nor written to the cache. */\n noCacheInputTokens?: number;\n};\n"]}
1
+ {"version":3,"file":"AiStreamUsage.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/AiStreamUsage.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Token usage reported by the model, what it cost when the platform knows its prices, and what it\n * is charged at when an app bills for it.\n *\n * Each field may be undefined if the underlying provider doesn't report it.\n * `totalTokens` is the sum of input + output (plus any reasoning tokens, when applicable).\n */\nexport type AiStreamUsage = {\n /** Prompt tokens consumed. */\n inputTokens?: number;\n /** Completion tokens produced. */\n outputTokens?: number;\n /** Total tokens, typically `inputTokens + outputTokens` (+ reasoning, when applicable). */\n totalTokens?: number;\n /** Prompt tokens served from the prompt cache. */\n cacheReadInputTokens?: number;\n /** Prompt tokens written to the prompt cache by this request. */\n cacheWriteInputTokens?: number;\n /** Prompt tokens neither read from nor written to the cache. */\n noCacheInputTokens?: number;\n /** What the call cost at the platform's list price, in millionths of a US dollar. Set only by a platform that knows its prices. */\n costMicroUsd?: number;\n /** What the call is charged at an app's own rates, in millionths of a US dollar. Set by the app that bills for it, never by a platform. */\n chargeMicroUsd?: number;\n};\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * What a model's tokens are priced at, in US dollars per million tokens: a platform's list price,
3
+ * or an app's own rates for what it charges.
4
+ */
5
+ export type AiTokenRates = {
6
+ /** Prompt tokens neither read from nor written to the cache. */
7
+ input: number;
8
+ output: number;
9
+ cacheRead: number;
10
+ /** A cache write that lives for five minutes. */
11
+ cacheWriteFiveMinutes: number;
12
+ /** A cache write that lives for an hour. Absent for a model that only caches for five minutes. */
13
+ cacheWriteOneHour?: number;
14
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AiTokenRates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiTokenRates.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/AiTokenRates.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * What a model's tokens are priced at, in US dollars per million tokens: a platform's list price,\n * or an app's own rates for what it charges.\n */\nexport type AiTokenRates = {\n /** Prompt tokens neither read from nor written to the cache. */\n input: number;\n output: number;\n cacheRead: number;\n /** A cache write that lives for five minutes. */\n cacheWriteFiveMinutes: number;\n /** A cache write that lives for an hour. Absent for a model that only caches for five minutes. */\n cacheWriteOneHour?: number;\n};\n"]}
@@ -1,3 +1,4 @@
1
+ export * from './AiModelTokenRates';
1
2
  export * from './AiStreamAbort';
2
3
  export * from './AiStreamCustom';
3
4
  export * from './AiStreamError';
@@ -30,3 +31,4 @@ export * from './AiStreamToolInputStart';
30
31
  export * from './AiStreamToolOutputDenied';
31
32
  export * from './AiStreamToolResult';
32
33
  export * from './AiStreamUsage';
34
+ export * from './AiTokenRates';
@@ -1,3 +1,4 @@
1
+ export * from './AiModelTokenRates';
1
2
  export * from './AiStreamAbort';
2
3
  export * from './AiStreamCustom';
3
4
  export * from './AiStreamError';
@@ -30,4 +31,5 @@ export * from './AiStreamToolInputStart';
30
31
  export * from './AiStreamToolOutputDenied';
31
32
  export * from './AiStreamToolResult';
32
33
  export * from './AiStreamUsage';
34
+ export * from './AiTokenRates';
33
35
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC","sourcesContent":["export * from './AiStreamAbort';\nexport * from './AiStreamCustom';\nexport * from './AiStreamError';\nexport * from './AiStreamFile';\nexport * from './AiStreamFilePart';\nexport * from './AiStreamFinish';\nexport * from './AiStreamFinishReason';\nexport * from './AiStreamFinishStep';\nexport * from './AiStreamPart';\nexport * from './AiStreamPartType';\nexport * from './AiStreamRaw';\nexport * from './AiStreamReasoningDelta';\nexport * from './AiStreamReasoningEnd';\nexport * from './AiStreamReasoningFilePart';\nexport * from './AiStreamReasoningStart';\nexport * from './AiStreamSource';\nexport * from './AiStreamSourcePart';\nexport * from './AiStreamStart';\nexport * from './AiStreamStartStep';\nexport * from './AiStreamTextDelta';\nexport * from './AiStreamTextEnd';\nexport * from './AiStreamTextStart';\nexport * from './AiStreamToolApprovalRequest';\nexport * from './AiStreamToolApprovalResponse';\nexport * from './AiStreamToolCall';\nexport * from './AiStreamToolError';\nexport * from './AiStreamToolInputDelta';\nexport * from './AiStreamToolInputEnd';\nexport * from './AiStreamToolInputStart';\nexport * from './AiStreamToolOutputDenied';\nexport * from './AiStreamToolResult';\nexport * from './AiStreamUsage';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/actions/ai/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC","sourcesContent":["export * from './AiModelTokenRates';\nexport * from './AiStreamAbort';\nexport * from './AiStreamCustom';\nexport * from './AiStreamError';\nexport * from './AiStreamFile';\nexport * from './AiStreamFilePart';\nexport * from './AiStreamFinish';\nexport * from './AiStreamFinishReason';\nexport * from './AiStreamFinishStep';\nexport * from './AiStreamPart';\nexport * from './AiStreamPartType';\nexport * from './AiStreamRaw';\nexport * from './AiStreamReasoningDelta';\nexport * from './AiStreamReasoningEnd';\nexport * from './AiStreamReasoningFilePart';\nexport * from './AiStreamReasoningStart';\nexport * from './AiStreamSource';\nexport * from './AiStreamSourcePart';\nexport * from './AiStreamStart';\nexport * from './AiStreamStartStep';\nexport * from './AiStreamTextDelta';\nexport * from './AiStreamTextEnd';\nexport * from './AiStreamTextStart';\nexport * from './AiStreamToolApprovalRequest';\nexport * from './AiStreamToolApprovalResponse';\nexport * from './AiStreamToolCall';\nexport * from './AiStreamToolError';\nexport * from './AiStreamToolInputDelta';\nexport * from './AiStreamToolInputEnd';\nexport * from './AiStreamToolInputStart';\nexport * from './AiStreamToolOutputDenied';\nexport * from './AiStreamToolResult';\nexport * from './AiStreamUsage';\nexport * from './AiTokenRates';\n"]}
@@ -1,9 +1,16 @@
1
+ /** The four-digit year of an ISO 8601 date, such as `2026`. */
1
2
  export type TYear = `${number}${number}${number}${number}`;
3
+ /** The two-digit month of an ISO 8601 date, `01` to `12`. */
2
4
  export type TMonth = `${number}${number}`;
5
+ /** The two-digit day of the month of an ISO 8601 date, `01` to `31`. */
3
6
  export type TDay = `${number}${number}`;
7
+ /** The two-digit hour of an ISO 8601 time on a 24-hour clock, `00` to `23`; also the hours of a UtcOffset. */
4
8
  export type THours = `${number}${number}`;
9
+ /** The two-digit minute of an ISO 8601 time, `00` to `59`; also the minutes of a UtcOffset. */
5
10
  export type TMinutes = `${number}${number}`;
11
+ /** The two-digit second of an ISO 8601 time, `00` to `59`. */
6
12
  export type TSeconds = `${number}${number}`;
13
+ /** The three-digit millisecond of an ISO 8601 time, `000` to `999`. */
7
14
  export type TMilliseconds = `${number}${number}${number}`;
8
15
  /**
9
16
  * Represent a string like `2021-01-08`
@@ -21,3 +28,7 @@ export type TDateISOTime = `${THours}:${TMinutes}:${TSeconds}.${TMilliseconds}`;
21
28
  * "Expression produces a union type that is too complex to represent. ts(2590)
22
29
  */
23
30
  export type QpqIsoDateTime = `${TDateISODate}T${TDateISOTime}Z`;
31
+ /**
32
+ * A fixed offset from UTC as `±HH:MM` ('+10:00', '+09:30', '-03:30'). Fixed: it never follows daylight saving.
33
+ */
34
+ export type UtcOffset = `${'+' | '-'}${THours}:${TMinutes}`;
@@ -1,4 +1,8 @@
1
+ /* eslint-disable qpq/one-export-per-file */
1
2
  // Template-literal typing for ISO-8601 timestamps
2
3
  // (from https://gist.github.com/MrChocolatine/367fb2a35d02f6175cc8ccb3d3a20054)
4
+ //
5
+ // Each `${number}` placeholder accepts any numeric text, so these types catch a missing part, a separator in the wrong
6
+ // place or letters, never an out-of-range value: '99' is a TMonth and '1.5' a THours. Check values at runtime.
3
7
  export {};
4
8
  //# sourceMappingURL=QpqIsoDateTime.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"QpqIsoDateTime.js","sourceRoot":"","sources":["../../../src/types/QpqIsoDateTime.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,gFAAgF","sourcesContent":["// Template-literal typing for ISO-8601 timestamps\n// (from https://gist.github.com/MrChocolatine/367fb2a35d02f6175cc8ccb3d3a20054)\n\nexport type TYear = `${number}${number}${number}${number}`;\nexport type TMonth = `${number}${number}`;\nexport type TDay = `${number}${number}`;\nexport type THours = `${number}${number}`;\nexport type TMinutes = `${number}${number}`;\nexport type TSeconds = `${number}${number}`;\nexport type TMilliseconds = `${number}${number}${number}`;\n\n/**\n * Represent a string like `2021-01-08`\n */\nexport type TDateISODate = `${TYear}-${TMonth}-${TDay}`;\n\n/**\n * Represent a string like `14:42:34.678`\n */\nexport type TDateISOTime = `${THours}:${TMinutes}:${TSeconds}.${TMilliseconds}`;\n\n/**\n * Represent a string like `2021-01-08T14:42:34.678Z` (format: ISO 8601).\n *\n * It is not possible to type more precisely (list every possible values for months, hours etc) as\n * it would result in a warning from TypeScript:\n * \"Expression produces a union type that is too complex to represent. ts(2590)\n */\nexport type QpqIsoDateTime = `${TDateISODate}T${TDateISOTime}Z`;\n"]}
1
+ {"version":3,"file":"QpqIsoDateTime.js","sourceRoot":"","sources":["../../../src/types/QpqIsoDateTime.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,kDAAkD;AAClD,gFAAgF;AAChF,EAAE;AACF,uHAAuH;AACvH,+GAA+G","sourcesContent":["/* eslint-disable qpq/one-export-per-file */\n// Template-literal typing for ISO-8601 timestamps\n// (from https://gist.github.com/MrChocolatine/367fb2a35d02f6175cc8ccb3d3a20054)\n//\n// Each `${number}` placeholder accepts any numeric text, so these types catch a missing part, a separator in the wrong\n// place or letters, never an out-of-range value: '99' is a TMonth and '1.5' a THours. Check values at runtime.\n\n/** The four-digit year of an ISO 8601 date, such as `2026`. */\nexport type TYear = `${number}${number}${number}${number}`;\n\n/** The two-digit month of an ISO 8601 date, `01` to `12`. */\nexport type TMonth = `${number}${number}`;\n\n/** The two-digit day of the month of an ISO 8601 date, `01` to `31`. */\nexport type TDay = `${number}${number}`;\n\n/** The two-digit hour of an ISO 8601 time on a 24-hour clock, `00` to `23`; also the hours of a UtcOffset. */\nexport type THours = `${number}${number}`;\n\n/** The two-digit minute of an ISO 8601 time, `00` to `59`; also the minutes of a UtcOffset. */\nexport type TMinutes = `${number}${number}`;\n\n/** The two-digit second of an ISO 8601 time, `00` to `59`. */\nexport type TSeconds = `${number}${number}`;\n\n/** The three-digit millisecond of an ISO 8601 time, `000` to `999`. */\nexport type TMilliseconds = `${number}${number}${number}`;\n\n/**\n * Represent a string like `2021-01-08`\n */\nexport type TDateISODate = `${TYear}-${TMonth}-${TDay}`;\n\n/**\n * Represent a string like `14:42:34.678`\n */\nexport type TDateISOTime = `${THours}:${TMinutes}:${TSeconds}.${TMilliseconds}`;\n\n/**\n * Represent a string like `2021-01-08T14:42:34.678Z` (format: ISO 8601).\n *\n * It is not possible to type more precisely (list every possible values for months, hours etc) as\n * it would result in a warning from TypeScript:\n * \"Expression produces a union type that is too complex to represent. ts(2590)\n */\nexport type QpqIsoDateTime = `${TDateISODate}T${TDateISOTime}Z`;\n\n/**\n * A fixed offset from UTC as `±HH:MM` ('+10:00', '+09:30', '-03:30'). Fixed: it never follows daylight saving.\n */\nexport type UtcOffset = `${'+' | '-'}${THours}:${TMinutes}`;\n"]}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The calendar day (`YYYY-MM-DD`) some whole months after `day` (negative for before), the day of the month kept where the
3
+ * target month has it and clamped to its last day where not: 31 March less a month is 28 or 29 February. Unlike
4
+ * addMonthsToTDateIso, which lets a short month overflow into the next (31 March less a month is 3 March).
5
+ */
6
+ export declare const addCalendarMonths: (day: string, months: number) => string;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The calendar day (`YYYY-MM-DD`) some whole months after `day` (negative for before), the day of the month kept where the
3
+ * target month has it and clamped to its last day where not: 31 March less a month is 28 or 29 February. Unlike
4
+ * addMonthsToTDateIso, which lets a short month overflow into the next (31 March less a month is 3 March).
5
+ */
6
+ export const addCalendarMonths = (day, months) => {
7
+ const [year = 0, month = 1, date = 1] = day.split('-').map(Number);
8
+ const index = year * 12 + (month - 1) + months;
9
+ const targetYear = Math.floor(index / 12);
10
+ const targetMonth = index - targetYear * 12 + 1;
11
+ // Day 0 of the month after is the last day of this one.
12
+ const lastDate = new Date(Date.UTC(targetYear, targetMonth, 0)).getUTCDate();
13
+ const pad = (value) => String(value).padStart(2, '0');
14
+ return `${String(targetYear).padStart(4, '0')}-${pad(targetMonth)}-${pad(Math.min(date, lastDate))}`;
15
+ };
16
+ //# sourceMappingURL=addCalendarMonths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addCalendarMonths.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/addCalendarMonths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAE,MAAc,EAAU,EAAE;IACvE,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,KAAK,GAAG,UAAU,GAAG,EAAE,GAAG,CAAC,CAAC;IAChD,wDAAwD;IACxD,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IAC7E,MAAM,GAAG,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAEtE,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;AACvG,CAAC,CAAC","sourcesContent":["/**\n * The calendar day (`YYYY-MM-DD`) some whole months after `day` (negative for before), the day of the month kept where the\n * target month has it and clamped to its last day where not: 31 March less a month is 28 or 29 February. Unlike\n * addMonthsToTDateIso, which lets a short month overflow into the next (31 March less a month is 3 March).\n */\nexport const addCalendarMonths = (day: string, months: number): string => {\n const [year = 0, month = 1, date = 1] = day.split('-').map(Number);\n const index = year * 12 + (month - 1) + months;\n const targetYear = Math.floor(index / 12);\n const targetMonth = index - targetYear * 12 + 1;\n // Day 0 of the month after is the last day of this one.\n const lastDate = new Date(Date.UTC(targetYear, targetMonth, 0)).getUTCDate();\n const pad = (value: number): string => String(value).padStart(2, '0');\n\n return `${String(targetYear).padStart(4, '0')}-${pad(targetMonth)}-${pad(Math.min(date, lastDate))}`;\n};\n"]}
@@ -0,0 +1,7 @@
1
+ import { Nullable } from '../../types/Nullable';
2
+ import { UtcOffset } from '../../types/QpqIsoDateTime';
3
+ /**
4
+ * The minutes an offset adds to UTC ('+09:30' is 570), or null when it is not a real one. The UtcOffset type only checks
5
+ * the shape (`'+99:00'` compiles), so the range and the quarter hours are checked here.
6
+ */
7
+ export declare const getUtcOffsetMinutes: (utcOffset: UtcOffset) => Nullable<number>;
@@ -0,0 +1,19 @@
1
+ // Every offset in use lies from -12:00 to +14:00, in whole quarter hours (Nepal is +05:45).
2
+ const MIN_OFFSET_MINUTES = -12 * 60;
3
+ const MAX_OFFSET_MINUTES = 14 * 60;
4
+ const OFFSET_PATTERN = /^([+-])(\d{2}):(\d{2})$/;
5
+ /**
6
+ * The minutes an offset adds to UTC ('+09:30' is 570), or null when it is not a real one. The UtcOffset type only checks
7
+ * the shape (`'+99:00'` compiles), so the range and the quarter hours are checked here.
8
+ */
9
+ export const getUtcOffsetMinutes = (utcOffset) => {
10
+ const match = OFFSET_PATTERN.exec(utcOffset);
11
+ if (!match) {
12
+ return null;
13
+ }
14
+ const [, sign, hours = '', minutes = ''] = match;
15
+ const total = (Number(hours) * 60 + Number(minutes)) * (sign === '-' ? -1 : 1);
16
+ const isQuarterHour = Number(minutes) % 15 === 0 && Number(minutes) < 60;
17
+ return isQuarterHour && total >= MIN_OFFSET_MINUTES && total <= MAX_OFFSET_MINUTES ? total : null;
18
+ };
19
+ //# sourceMappingURL=getUtcOffsetMinutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getUtcOffsetMinutes.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/getUtcOffsetMinutes.ts"],"names":[],"mappings":"AAGA,4FAA4F;AAC5F,MAAM,kBAAkB,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;AACpC,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,CAAC;AACnC,MAAM,cAAc,GAAG,yBAAyB,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAoB,EAAoB,EAAE;IAC5E,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEzE,OAAO,aAAa,IAAI,KAAK,IAAI,kBAAkB,IAAI,KAAK,IAAI,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACpG,CAAC,CAAC","sourcesContent":["import { Nullable } from '../../types/Nullable';\nimport { UtcOffset } from '../../types/QpqIsoDateTime';\n\n// Every offset in use lies from -12:00 to +14:00, in whole quarter hours (Nepal is +05:45).\nconst MIN_OFFSET_MINUTES = -12 * 60;\nconst MAX_OFFSET_MINUTES = 14 * 60;\nconst OFFSET_PATTERN = /^([+-])(\\d{2}):(\\d{2})$/;\n\n/**\n * The minutes an offset adds to UTC ('+09:30' is 570), or null when it is not a real one. The UtcOffset type only checks\n * the shape (`'+99:00'` compiles), so the range and the quarter hours are checked here.\n */\nexport const getUtcOffsetMinutes = (utcOffset: UtcOffset): Nullable<number> => {\n const match = OFFSET_PATTERN.exec(utcOffset);\n\n if (!match) {\n return null;\n }\n\n const [, sign, hours = '', minutes = ''] = match;\n const total = (Number(hours) * 60 + Number(minutes)) * (sign === '-' ? -1 : 1);\n const isQuarterHour = Number(minutes) % 15 === 0 && Number(minutes) < 60;\n\n return isQuarterHour && total >= MIN_OFFSET_MINUTES && total <= MAX_OFFSET_MINUTES ? total : null;\n};\n"]}
@@ -0,0 +1,2 @@
1
+ /** The weekday of a calendar day (`YYYY-MM-DD`), 0 for Monday to 6 for Sunday. A civil date's weekday needs no zone. */
2
+ export declare const getWeekdayFromMonday: (day: string) => number;
@@ -0,0 +1,3 @@
1
+ /** The weekday of a calendar day (`YYYY-MM-DD`), 0 for Monday to 6 for Sunday. A civil date's weekday needs no zone. */
2
+ export const getWeekdayFromMonday = (day) => (new Date(`${day}T00:00:00.000Z`).getUTCDay() + 6) % 7;
3
+ //# sourceMappingURL=getWeekdayFromMonday.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getWeekdayFromMonday.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/getWeekdayFromMonday.ts"],"names":[],"mappings":"AAAA,wHAAwH;AACxH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,gBAAgB,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC","sourcesContent":["/** The weekday of a calendar day (`YYYY-MM-DD`), 0 for Monday to 6 for Sunday. A civil date's weekday needs no zone. */\nexport const getWeekdayFromMonday = (day: string): number => (new Date(`${day}T00:00:00.000Z`).getUTCDay() + 6) % 7;\n"]}
@@ -1,4 +1,8 @@
1
+ export * from './addCalendarMonths';
1
2
  export * from './getDateNow';
2
3
  export * from './getMillisecondsBetween';
3
4
  export * from './getQpqIsoDateTimeFromDate';
5
+ export * from './getUtcOffsetMinutes';
4
6
  export * from './getValidQpqIsoDateTime';
7
+ export * from './getWeekdayFromMonday';
8
+ export * from './isQpqIsoDateTime';
@@ -1,5 +1,9 @@
1
+ export * from './addCalendarMonths';
1
2
  export * from './getDateNow';
2
3
  export * from './getMillisecondsBetween';
3
4
  export * from './getQpqIsoDateTimeFromDate';
5
+ export * from './getUtcOffsetMinutes';
4
6
  export * from './getValidQpqIsoDateTime';
7
+ export * from './getWeekdayFromMonday';
8
+ export * from './isQpqIsoDateTime';
5
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC","sourcesContent":["export * from './getDateNow';\nexport * from './getMillisecondsBetween';\nexport * from './getQpqIsoDateTimeFromDate';\nexport * from './getValidQpqIsoDateTime';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC","sourcesContent":["export * from './addCalendarMonths';\nexport * from './getDateNow';\nexport * from './getMillisecondsBetween';\nexport * from './getQpqIsoDateTimeFromDate';\nexport * from './getUtcOffsetMinutes';\nexport * from './getValidQpqIsoDateTime';\nexport * from './getWeekdayFromMonday';\nexport * from './isQpqIsoDateTime';\n"]}
@@ -0,0 +1,3 @@
1
+ import { QpqIsoDateTime } from '../../types/QpqIsoDateTime';
2
+ /** Whether a value is a real instant in exactly the QpqIsoDateTime form (`2026-11-09T05:12:40.118Z`): the guard form of getValidQpqIsoDateTime. */
3
+ export declare const isQpqIsoDateTime: (value: unknown) => value is QpqIsoDateTime;
@@ -0,0 +1,4 @@
1
+ import { getValidQpqIsoDateTime } from './getValidQpqIsoDateTime';
2
+ /** Whether a value is a real instant in exactly the QpqIsoDateTime form (`2026-11-09T05:12:40.118Z`): the guard form of getValidQpqIsoDateTime. */
3
+ export const isQpqIsoDateTime = (value) => typeof value === 'string' && getValidQpqIsoDateTime(value) !== undefined;
4
+ //# sourceMappingURL=isQpqIsoDateTime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isQpqIsoDateTime.js","sourceRoot":"","sources":["../../../../src/utils/dateTime/isQpqIsoDateTime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,mJAAmJ;AACnJ,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAA2B,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,sBAAsB,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC","sourcesContent":["import { QpqIsoDateTime } from '../../types/QpqIsoDateTime';\nimport { getValidQpqIsoDateTime } from './getValidQpqIsoDateTime';\n\n/** Whether a value is a real instant in exactly the QpqIsoDateTime form (`2026-11-09T05:12:40.118Z`): the guard form of getValidQpqIsoDateTime. */\nexport const isQpqIsoDateTime = (value: unknown): value is QpqIsoDateTime => typeof value === 'string' && getValidQpqIsoDateTime(value) !== undefined;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qpqjs/core",
3
- "version": "0.6.3",
3
+ "version": "0.7.0",
4
4
  "description": "Actions, stories and the runtime at the heart of quidproquo.",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -45,8 +45,8 @@
45
45
  },
46
46
  "homepage": "https://github.com/qpqjs/quidproquo#readme",
47
47
  "devDependencies": {
48
- "@qpqjs/testing": "0.6.3",
49
- "@qpqjs/tsconfig": "0.6.3",
48
+ "@qpqjs/testing": "0.7.0",
49
+ "@qpqjs/tsconfig": "0.7.0",
50
50
  "@types/node": "^24.2.1",
51
51
  "typescript": "^5.8.2"
52
52
  },