@ai-billing/polar 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +5 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -44
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -27,47 +27,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
27
27
|
// src/destination/polar-destination.ts
|
|
28
28
|
var import_sdk = require("@polar-sh/sdk");
|
|
29
29
|
var import_core = require("@ai-billing/core");
|
|
30
|
-
function mapEventToPolarMetadata(event) {
|
|
31
|
-
const metadata = {
|
|
32
|
-
generation_id: event.generationId,
|
|
33
|
-
model_id: event.modelId,
|
|
34
|
-
provider: event.provider
|
|
35
|
-
};
|
|
36
|
-
const usageFields = {
|
|
37
|
-
usage_input_tokens: "inputTokens",
|
|
38
|
-
usage_output_tokens: "outputTokens",
|
|
39
|
-
usage_total_tokens: "totalTokens",
|
|
40
|
-
usage_reasoning_tokens: "reasoningTokens",
|
|
41
|
-
usage_cache_read_tokens: "cacheReadTokens",
|
|
42
|
-
usage_cache_write_tokens: "cacheWriteTokens",
|
|
43
|
-
usage_request_count: "requestCount",
|
|
44
|
-
usage_raw_provider_cost: "rawProviderCost"
|
|
45
|
-
};
|
|
46
|
-
for (const [polarKey, internalKey] of Object.entries(usageFields)) {
|
|
47
|
-
const value = event.usage?.[internalKey];
|
|
48
|
-
if (value !== void 0) {
|
|
49
|
-
metadata[polarKey] = value;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
if (event.cost) {
|
|
53
|
-
metadata.cost_amount_base = (0, import_core.costToNumber)(event.cost, "base");
|
|
54
|
-
metadata.cost_amount_cents = (0, import_core.costToNumber)(event.cost, "cents");
|
|
55
|
-
metadata.cost_amount_micros = (0, import_core.costToNumber)(event.cost, "micros");
|
|
56
|
-
metadata.cost_amount_nanos = (0, import_core.costToNumber)(event.cost, "nanos");
|
|
57
|
-
metadata.cost_currency = event.cost.currency;
|
|
58
|
-
}
|
|
59
|
-
if (!event.tags) return metadata;
|
|
60
|
-
for (const [key, value] of Object.entries(event.tags)) {
|
|
61
|
-
if (value == null) continue;
|
|
62
|
-
const metadataKey = `ai-billing-tag_${key}`;
|
|
63
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
64
|
-
metadata[metadataKey] = value;
|
|
65
|
-
} else {
|
|
66
|
-
metadata[metadataKey] = JSON.stringify(value);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return metadata;
|
|
70
|
-
}
|
|
71
30
|
function createPolarDestination(options) {
|
|
72
31
|
const polar = options.client ?? new import_sdk.Polar({
|
|
73
32
|
accessToken: options.accessToken,
|
|
@@ -83,13 +42,16 @@ function createPolarDestination(options) {
|
|
|
83
42
|
);
|
|
84
43
|
}
|
|
85
44
|
const meterName = typeof options.meterName === "function" ? options.meterName(event) : options.meterName;
|
|
86
|
-
const metadata = options.mapMetadata ? options.mapMetadata(event) :
|
|
45
|
+
const metadata = options.mapMetadata ? options.mapMetadata(event) : (0, import_core.buildMeterMetadata)(event);
|
|
87
46
|
await polar.events.ingest({
|
|
88
47
|
events: [
|
|
89
48
|
{
|
|
90
49
|
name: meterName,
|
|
91
|
-
// Priority: Internal Polar ID always wins if both are present
|
|
92
50
|
...internalId ? { customerId: String(internalId) } : { externalCustomerId: String(externalId) },
|
|
51
|
+
...event.cost ? {
|
|
52
|
+
cost_nanos: (0, import_core.costToNumber)(event.cost, "nanos"),
|
|
53
|
+
cost_currency: event.cost.currency
|
|
54
|
+
} : {},
|
|
93
55
|
metadata
|
|
94
56
|
}
|
|
95
57
|
]
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/destination/polar-destination.ts"],"sourcesContent":["export * from './destination/index.js';\n","import { Polar } from '@polar-sh/sdk';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/destination/polar-destination.ts"],"sourcesContent":["export * from './destination/index.js';\n","import { Polar } from '@polar-sh/sdk';\nimport {\n createDestination,\n costToNumber,\n buildMeterMetadata,\n} from '@ai-billing/core';\nimport type { BillingEvent, DefaultTags, Destination } from '@ai-billing/core';\n\nexport interface PolarDestinationOptions<\n TTags extends DefaultTags = DefaultTags,\n> {\n client?: Polar;\n accessToken?: string;\n server?: 'sandbox' | 'production';\n meterName: string | ((event: BillingEvent<TTags>) => string);\n\n /** * Custom key to look for in tags for Polar's internal customer ID (cus_...).\n * Defaults to: 'customerId' | 'polarCustomerId'\n */\n customerIdKey?: keyof TTags;\n\n /** * Custom key to look for in tags for your system's ID.\n * Defaults to: 'userId' | 'externalId'\n */\n externalCustomerIdKey?: keyof TTags;\n\n mapMetadata?: (\n event: BillingEvent<TTags>,\n ) => Record<string, string | number | boolean>;\n}\n\nexport function createPolarDestination<TTags extends DefaultTags = DefaultTags>(\n options: PolarDestinationOptions<TTags>,\n): Destination<TTags> {\n const polar =\n options.client ??\n new Polar({\n accessToken: options.accessToken,\n server: options.server,\n });\n\n return createDestination<TTags>('polar', async event => {\n const tags = (event.tags ?? {}) as Record<\n string,\n string | number | boolean\n >;\n\n const internalId = tags[options.customerIdKey as string] ?? tags.customerId;\n const externalId =\n tags[options.externalCustomerIdKey as string] ?? tags.userId;\n\n if (!internalId && !externalId) {\n console.warn(\n '[ai-billing] Polar: No identity found in tags. Skipping event.',\n );\n }\n\n const meterName =\n typeof options.meterName === 'function'\n ? options.meterName(event)\n : options.meterName;\n\n const metadata = options.mapMetadata\n ? options.mapMetadata(event)\n : (buildMeterMetadata(event) as Record<\n string,\n string | number | boolean\n >);\n\n await polar.events.ingest({\n events: [\n {\n name: meterName,\n ...(internalId\n ? { customerId: String(internalId) }\n : { externalCustomerId: String(externalId) }),\n ...(event.cost\n ? {\n cost_nanos: costToNumber(event.cost, 'nanos'),\n cost_currency: event.cost.currency,\n }\n : {}),\n metadata,\n },\n ],\n });\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAAsB;AACtB,kBAIO;AA0BA,SAAS,uBACd,SACoB;AACpB,QAAM,QACJ,QAAQ,UACR,IAAI,iBAAM;AAAA,IACR,aAAa,QAAQ;AAAA,IACrB,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAEH,aAAO,+BAAyB,SAAS,OAAM,UAAS;AACtD,UAAM,OAAQ,MAAM,QAAQ,CAAC;AAK7B,UAAM,aAAa,KAAK,QAAQ,aAAuB,KAAK,KAAK;AACjE,UAAM,aACJ,KAAK,QAAQ,qBAA+B,KAAK,KAAK;AAExD,QAAI,CAAC,cAAc,CAAC,YAAY;AAC9B,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YACJ,OAAO,QAAQ,cAAc,aACzB,QAAQ,UAAU,KAAK,IACvB,QAAQ;AAEd,UAAM,WAAW,QAAQ,cACrB,QAAQ,YAAY,KAAK,QACxB,gCAAmB,KAAK;AAK7B,UAAM,MAAM,OAAO,OAAO;AAAA,MACxB,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,GAAI,aACA,EAAE,YAAY,OAAO,UAAU,EAAE,IACjC,EAAE,oBAAoB,OAAO,UAAU,EAAE;AAAA,UAC7C,GAAI,MAAM,OACN;AAAA,YACE,gBAAY,0BAAa,MAAM,MAAM,OAAO;AAAA,YAC5C,eAAe,MAAM,KAAK;AAAA,UAC5B,IACA,CAAC;AAAA,UACL;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1,47 +1,10 @@
|
|
|
1
1
|
// src/destination/polar-destination.ts
|
|
2
2
|
import { Polar } from "@polar-sh/sdk";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
provider: event.provider
|
|
9
|
-
};
|
|
10
|
-
const usageFields = {
|
|
11
|
-
usage_input_tokens: "inputTokens",
|
|
12
|
-
usage_output_tokens: "outputTokens",
|
|
13
|
-
usage_total_tokens: "totalTokens",
|
|
14
|
-
usage_reasoning_tokens: "reasoningTokens",
|
|
15
|
-
usage_cache_read_tokens: "cacheReadTokens",
|
|
16
|
-
usage_cache_write_tokens: "cacheWriteTokens",
|
|
17
|
-
usage_request_count: "requestCount",
|
|
18
|
-
usage_raw_provider_cost: "rawProviderCost"
|
|
19
|
-
};
|
|
20
|
-
for (const [polarKey, internalKey] of Object.entries(usageFields)) {
|
|
21
|
-
const value = event.usage?.[internalKey];
|
|
22
|
-
if (value !== void 0) {
|
|
23
|
-
metadata[polarKey] = value;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (event.cost) {
|
|
27
|
-
metadata.cost_amount_base = costToNumber(event.cost, "base");
|
|
28
|
-
metadata.cost_amount_cents = costToNumber(event.cost, "cents");
|
|
29
|
-
metadata.cost_amount_micros = costToNumber(event.cost, "micros");
|
|
30
|
-
metadata.cost_amount_nanos = costToNumber(event.cost, "nanos");
|
|
31
|
-
metadata.cost_currency = event.cost.currency;
|
|
32
|
-
}
|
|
33
|
-
if (!event.tags) return metadata;
|
|
34
|
-
for (const [key, value] of Object.entries(event.tags)) {
|
|
35
|
-
if (value == null) continue;
|
|
36
|
-
const metadataKey = `ai-billing-tag_${key}`;
|
|
37
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
38
|
-
metadata[metadataKey] = value;
|
|
39
|
-
} else {
|
|
40
|
-
metadata[metadataKey] = JSON.stringify(value);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return metadata;
|
|
44
|
-
}
|
|
3
|
+
import {
|
|
4
|
+
createDestination,
|
|
5
|
+
costToNumber,
|
|
6
|
+
buildMeterMetadata
|
|
7
|
+
} from "@ai-billing/core";
|
|
45
8
|
function createPolarDestination(options) {
|
|
46
9
|
const polar = options.client ?? new Polar({
|
|
47
10
|
accessToken: options.accessToken,
|
|
@@ -57,13 +20,16 @@ function createPolarDestination(options) {
|
|
|
57
20
|
);
|
|
58
21
|
}
|
|
59
22
|
const meterName = typeof options.meterName === "function" ? options.meterName(event) : options.meterName;
|
|
60
|
-
const metadata = options.mapMetadata ? options.mapMetadata(event) :
|
|
23
|
+
const metadata = options.mapMetadata ? options.mapMetadata(event) : buildMeterMetadata(event);
|
|
61
24
|
await polar.events.ingest({
|
|
62
25
|
events: [
|
|
63
26
|
{
|
|
64
27
|
name: meterName,
|
|
65
|
-
// Priority: Internal Polar ID always wins if both are present
|
|
66
28
|
...internalId ? { customerId: String(internalId) } : { externalCustomerId: String(externalId) },
|
|
29
|
+
...event.cost ? {
|
|
30
|
+
cost_nanos: costToNumber(event.cost, "nanos"),
|
|
31
|
+
cost_currency: event.cost.currency
|
|
32
|
+
} : {},
|
|
67
33
|
metadata
|
|
68
34
|
}
|
|
69
35
|
]
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/destination/polar-destination.ts"],"sourcesContent":["import { Polar } from '@polar-sh/sdk';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/destination/polar-destination.ts"],"sourcesContent":["import { Polar } from '@polar-sh/sdk';\nimport {\n createDestination,\n costToNumber,\n buildMeterMetadata,\n} from '@ai-billing/core';\nimport type { BillingEvent, DefaultTags, Destination } from '@ai-billing/core';\n\nexport interface PolarDestinationOptions<\n TTags extends DefaultTags = DefaultTags,\n> {\n client?: Polar;\n accessToken?: string;\n server?: 'sandbox' | 'production';\n meterName: string | ((event: BillingEvent<TTags>) => string);\n\n /** * Custom key to look for in tags for Polar's internal customer ID (cus_...).\n * Defaults to: 'customerId' | 'polarCustomerId'\n */\n customerIdKey?: keyof TTags;\n\n /** * Custom key to look for in tags for your system's ID.\n * Defaults to: 'userId' | 'externalId'\n */\n externalCustomerIdKey?: keyof TTags;\n\n mapMetadata?: (\n event: BillingEvent<TTags>,\n ) => Record<string, string | number | boolean>;\n}\n\nexport function createPolarDestination<TTags extends DefaultTags = DefaultTags>(\n options: PolarDestinationOptions<TTags>,\n): Destination<TTags> {\n const polar =\n options.client ??\n new Polar({\n accessToken: options.accessToken,\n server: options.server,\n });\n\n return createDestination<TTags>('polar', async event => {\n const tags = (event.tags ?? {}) as Record<\n string,\n string | number | boolean\n >;\n\n const internalId = tags[options.customerIdKey as string] ?? tags.customerId;\n const externalId =\n tags[options.externalCustomerIdKey as string] ?? tags.userId;\n\n if (!internalId && !externalId) {\n console.warn(\n '[ai-billing] Polar: No identity found in tags. Skipping event.',\n );\n }\n\n const meterName =\n typeof options.meterName === 'function'\n ? options.meterName(event)\n : options.meterName;\n\n const metadata = options.mapMetadata\n ? options.mapMetadata(event)\n : (buildMeterMetadata(event) as Record<\n string,\n string | number | boolean\n >);\n\n await polar.events.ingest({\n events: [\n {\n name: meterName,\n ...(internalId\n ? { customerId: String(internalId) }\n : { externalCustomerId: String(externalId) }),\n ...(event.cost\n ? {\n cost_nanos: costToNumber(event.cost, 'nanos'),\n cost_currency: event.cost.currency,\n }\n : {}),\n metadata,\n },\n ],\n });\n });\n}\n"],"mappings":";AAAA,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AA0BA,SAAS,uBACd,SACoB;AACpB,QAAM,QACJ,QAAQ,UACR,IAAI,MAAM;AAAA,IACR,aAAa,QAAQ;AAAA,IACrB,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAEH,SAAO,kBAAyB,SAAS,OAAM,UAAS;AACtD,UAAM,OAAQ,MAAM,QAAQ,CAAC;AAK7B,UAAM,aAAa,KAAK,QAAQ,aAAuB,KAAK,KAAK;AACjE,UAAM,aACJ,KAAK,QAAQ,qBAA+B,KAAK,KAAK;AAExD,QAAI,CAAC,cAAc,CAAC,YAAY;AAC9B,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YACJ,OAAO,QAAQ,cAAc,aACzB,QAAQ,UAAU,KAAK,IACvB,QAAQ;AAEd,UAAM,WAAW,QAAQ,cACrB,QAAQ,YAAY,KAAK,IACxB,mBAAmB,KAAK;AAK7B,UAAM,MAAM,OAAO,OAAO;AAAA,MACxB,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,GAAI,aACA,EAAE,YAAY,OAAO,UAAU,EAAE,IACjC,EAAE,oBAAoB,OAAO,UAAU,EAAE;AAAA,UAC7C,GAAI,MAAM,OACN;AAAA,YACE,YAAY,aAAa,MAAM,MAAM,OAAO;AAAA,YAC5C,eAAe,MAAM,KAAK;AAAA,UAC5B,IACA,CAAC;AAAA,UACL;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-billing/polar",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@ai-billing/testing": "0.0.2"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@ai-billing/core": "0.0.
|
|
43
|
+
"@ai-billing/core": "0.0.4",
|
|
44
44
|
"@polar-sh/sdk": "^0.46.7"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|