@revenium/claude-code-metering 0.1.0 → 0.1.1

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 (59) hide show
  1. package/CHANGELOG.md +22 -28
  2. package/README.md +321 -139
  3. package/dist/cli/commands/backfill.d.ts +98 -1
  4. package/dist/cli/commands/backfill.d.ts.map +1 -1
  5. package/dist/cli/commands/backfill.js +356 -146
  6. package/dist/cli/commands/backfill.js.map +1 -1
  7. package/dist/cli/commands/setup.d.ts +2 -0
  8. package/dist/cli/commands/setup.d.ts.map +1 -1
  9. package/dist/cli/commands/setup.js +55 -49
  10. package/dist/cli/commands/setup.js.map +1 -1
  11. package/dist/cli/commands/status.d.ts.map +1 -1
  12. package/dist/cli/commands/status.js +2 -11
  13. package/dist/cli/commands/status.js.map +1 -1
  14. package/dist/cli/commands/test.d.ts.map +1 -1
  15. package/dist/cli/commands/test.js +23 -22
  16. package/dist/cli/commands/test.js.map +1 -1
  17. package/dist/cli/index.d.ts +2 -1
  18. package/dist/cli/index.d.ts.map +1 -1
  19. package/dist/cli/index.js +44 -30
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/core/api/client.d.ts +7 -6
  22. package/dist/core/api/client.d.ts.map +1 -1
  23. package/dist/core/api/client.js +52 -47
  24. package/dist/core/api/client.js.map +1 -1
  25. package/dist/core/config/loader.d.ts +5 -13
  26. package/dist/core/config/loader.d.ts.map +1 -1
  27. package/dist/core/config/loader.js +67 -46
  28. package/dist/core/config/loader.js.map +1 -1
  29. package/dist/core/config/validator.d.ts +5 -1
  30. package/dist/core/config/validator.d.ts.map +1 -1
  31. package/dist/core/config/validator.js +37 -22
  32. package/dist/core/config/validator.js.map +1 -1
  33. package/dist/core/config/writer.d.ts +1 -1
  34. package/dist/core/config/writer.d.ts.map +1 -1
  35. package/dist/core/config/writer.js +76 -72
  36. package/dist/core/config/writer.js.map +1 -1
  37. package/dist/core/shell/detector.d.ts +8 -1
  38. package/dist/core/shell/detector.d.ts.map +1 -1
  39. package/dist/core/shell/detector.js +38 -24
  40. package/dist/core/shell/detector.js.map +1 -1
  41. package/dist/core/shell/profile-updater.d.ts +1 -1
  42. package/dist/core/shell/profile-updater.d.ts.map +1 -1
  43. package/dist/core/shell/profile-updater.js +40 -27
  44. package/dist/core/shell/profile-updater.js.map +1 -1
  45. package/dist/index.d.ts +9 -8
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +1 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/types/index.d.ts +18 -23
  50. package/dist/types/index.d.ts.map +1 -1
  51. package/dist/utils/constants.d.ts +2 -2
  52. package/dist/utils/constants.d.ts.map +1 -1
  53. package/dist/utils/constants.js +21 -21
  54. package/dist/utils/constants.js.map +1 -1
  55. package/dist/utils/hashing.d.ts +18 -0
  56. package/dist/utils/hashing.d.ts.map +1 -0
  57. package/dist/utils/hashing.js +27 -0
  58. package/dist/utils/hashing.js.map +1 -0
  59. package/package.json +6 -3
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,kDAAmD;AACnD,oDAAqD;AACrD,gDAAiD;AACjD,wDAAyD;AAEzD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,mBAAmB,CAAC;KACzB,WAAW,CAAC,oDAAoD,CAAC;KACjE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,4DAA4D,CAAC;KACzE,MAAM,CAAC,qBAAqB,EAAE,4BAA4B,CAAC;KAC3D,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;KAC5D,MAAM,CAAC,mBAAmB,EAAE,yEAAyE,CAAC;KACtG,MAAM,CAAC,kBAAkB,EAAE,2BAA2B,CAAC;KACvD,MAAM,CAAC,qBAAqB,EAAE,qCAAqC,CAAC;KACpE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,IAAA,uBAAY,EAAC;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,eAAe,EAAE,OAAO,CAAC,eAAe;KACzC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,IAAA,yBAAa,GAAE,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,eAAe,EAAE,mCAAmC,CAAC;KAC5D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,iEAAiE,CAAC;KAC9E,MAAM,CAAC,gBAAgB,EAAE,wEAAwE,CAAC;KAClG,MAAM,CAAC,WAAW,EAAE,yCAAyC,CAAC;KAC9D,MAAM,CAAC,kBAAkB,EAAE,uCAAuC,EAAE,KAAK,CAAC;KAC1E,MAAM,CAAC,eAAe,EAAE,wBAAwB,CAAC;KACjD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,IAAA,6BAAe,EAAC;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,SAAS;QACT,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,23 @@
1
- import type { OTLPMetricsPayload, OTLPResponse, HealthCheckResult } from '../../types/index.js';
1
+ import type { OTLPLogsPayload, OTLPResponse, HealthCheckResult } from "../../types/index.js";
2
2
  /**
3
- * Sends an OTLP metrics payload to the Revenium endpoint.
4
- * Posts to /meter/v2/otel/v1/metrics with OTEL Metrics format.
3
+ * Sends an OTLP logs payload to the Revenium endpoint.
5
4
  */
6
- export declare function sendOtlpMetrics(baseEndpoint: string, apiKey: string, payload: OTLPMetricsPayload): Promise<OTLPResponse>;
5
+ export declare function sendOtlpLogs(baseEndpoint: string, apiKey: string, payload: OTLPLogsPayload): Promise<OTLPResponse>;
7
6
  /**
8
7
  * Options for creating a test payload.
9
8
  */
10
9
  export interface TestPayloadOptions {
10
+ /** Optional subscriber email for attribution */
11
+ email?: string;
11
12
  /** Optional organization ID to attribute costs to */
12
13
  organizationId?: string;
13
14
  /** Optional product ID to attribute costs to */
14
15
  productId?: string;
15
16
  }
16
17
  /**
17
- * Creates a minimal test OTEL metrics payload.
18
+ * Creates a minimal test OTLP logs payload.
18
19
  */
19
- export declare function createTestPayload(sessionId: string, options?: TestPayloadOptions): OTLPMetricsPayload;
20
+ export declare function createTestPayload(sessionId: string, options?: TestPayloadOptions): OTLPLogsPayload;
20
21
  /**
21
22
  * Generates a unique session ID for test payloads.
22
23
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGhG;;;GAGG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAmBvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,CA4DrG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAI9C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CA+B5B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAG9B;;GAEG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,YAAY,CAAC,CAuBvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,eAAe,CAoEjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAI9C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CA+B5B"}
@@ -1,82 +1,87 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sendOtlpMetrics = sendOtlpMetrics;
3
+ exports.sendOtlpLogs = sendOtlpLogs;
4
4
  exports.createTestPayload = createTestPayload;
5
5
  exports.generateTestSessionId = generateTestSessionId;
6
6
  exports.checkEndpointHealth = checkEndpointHealth;
7
7
  const loader_js_1 = require("../config/loader.js");
8
8
  /**
9
- * Sends an OTLP metrics payload to the Revenium endpoint.
10
- * Posts to /meter/v2/otel/v1/metrics with OTEL Metrics format.
9
+ * Sends an OTLP logs payload to the Revenium endpoint.
11
10
  */
12
- async function sendOtlpMetrics(baseEndpoint, apiKey, payload) {
11
+ async function sendOtlpLogs(baseEndpoint, apiKey, payload) {
13
12
  const fullEndpoint = (0, loader_js_1.getFullOtlpEndpoint)(baseEndpoint);
14
- const url = `${fullEndpoint}/v1/metrics`;
13
+ const url = `${fullEndpoint}/v1/logs`;
15
14
  const response = await fetch(url, {
16
- method: 'POST',
15
+ method: "POST",
17
16
  headers: {
18
- 'Content-Type': 'application/json',
19
- 'x-api-key': apiKey,
17
+ "Content-Type": "application/json",
18
+ "x-api-key": apiKey,
20
19
  },
21
20
  body: JSON.stringify(payload),
22
21
  });
23
22
  if (!response.ok) {
24
23
  const errorText = await response.text();
25
- throw new Error(`OTLP request failed: ${response.status} ${response.statusText} - ${errorText}`);
24
+ const safeErrorText = errorText.length > 200 ? errorText.substring(0, 200) + "..." : errorText;
25
+ throw new Error(`OTLP request failed: ${response.status} ${response.statusText} - ${safeErrorText}`);
26
26
  }
27
27
  return response.json();
28
28
  }
29
29
  /**
30
- * Creates a minimal test OTEL metrics payload.
30
+ * Creates a minimal test OTLP logs payload.
31
31
  */
32
32
  function createTestPayload(sessionId, options) {
33
33
  const now = Date.now() * 1_000_000; // Convert to nanoseconds
34
- // Common attributes for all metrics
35
- const commonAttributes = [
36
- { key: 'ai.transaction_id', value: { stringValue: sessionId } },
37
- { key: 'ai.model', value: { stringValue: 'cli-connectivity-test' } },
38
- { key: 'ai.provider', value: { stringValue: 'anthropic' } },
34
+ // Build log record attributes
35
+ // Note: organization.name and product.name go here because ClaudeCodeMapper reads from log record attrs
36
+ const logAttributes = [
37
+ { key: "session.id", value: { stringValue: sessionId } },
38
+ { key: "model", value: { stringValue: "cli-connectivity-test" } },
39
+ { key: "input_tokens", value: { stringValue: "0" } },
40
+ { key: "output_tokens", value: { stringValue: "0" } },
41
+ { key: "cache_read_tokens", value: { stringValue: "0" } },
42
+ { key: "cache_creation_tokens", value: { stringValue: "0" } },
43
+ { key: "cost_usd", value: { stringValue: "0.0" } },
44
+ { key: "duration_ms", value: { stringValue: "0" } },
39
45
  ];
40
- // Add optional organization ID
46
+ // Add optional subscriber/attribution attributes at log record level
47
+ // (backend ClaudeCodeMapper reads these from log record attrs, not resource attrs)
48
+ if (options?.email) {
49
+ logAttributes.push({
50
+ key: "user.email",
51
+ value: { stringValue: options.email },
52
+ });
53
+ }
41
54
  if (options?.organizationId) {
42
- commonAttributes.push({ key: 'organization.id', value: { stringValue: options.organizationId } });
55
+ logAttributes.push({
56
+ key: "organization.name",
57
+ value: { stringValue: options.organizationId },
58
+ });
43
59
  }
44
- // Add optional product ID
45
60
  if (options?.productId) {
46
- commonAttributes.push({ key: 'product.id', value: { stringValue: options.productId } });
61
+ logAttributes.push({
62
+ key: "product.name",
63
+ value: { stringValue: options.productId },
64
+ });
47
65
  }
48
- // Build resource attributes
49
- const resourceAttributes = [
50
- { key: 'service.name', value: { stringValue: 'claude-code' } },
51
- ];
66
+ // Build resource attributes (only service.name needed here)
67
+ const resourceAttributes = [{ key: "service.name", value: { stringValue: "claude-code" } }];
52
68
  return {
53
- resourceMetrics: [
69
+ resourceLogs: [
54
70
  {
55
71
  resource: {
56
72
  attributes: resourceAttributes,
57
73
  },
58
- scopeMetrics: [
74
+ scopeLogs: [
59
75
  {
60
- metrics: [
61
- {
62
- name: 'ai.tokens.input',
63
- sum: {
64
- dataPoints: [{
65
- attributes: commonAttributes,
66
- timeUnixNano: now.toString(),
67
- asInt: 0,
68
- }],
69
- },
70
- },
76
+ scope: {
77
+ name: "claude_code",
78
+ version: "0.1.0",
79
+ },
80
+ logRecords: [
71
81
  {
72
- name: 'ai.tokens.output',
73
- sum: {
74
- dataPoints: [{
75
- attributes: commonAttributes,
76
- timeUnixNano: now.toString(),
77
- asInt: 0,
78
- }],
79
- },
82
+ timeUnixNano: now.toString(),
83
+ body: { stringValue: "claude_code.api_request" },
84
+ attributes: logAttributes,
80
85
  },
81
86
  ],
82
87
  },
@@ -101,18 +106,18 @@ async function checkEndpointHealth(baseEndpoint, apiKey, options) {
101
106
  try {
102
107
  const sessionId = generateTestSessionId();
103
108
  const payload = createTestPayload(sessionId, options);
104
- const response = await sendOtlpMetrics(baseEndpoint, apiKey, payload);
109
+ const response = await sendOtlpLogs(baseEndpoint, apiKey, payload);
105
110
  const latencyMs = Date.now() - startTime;
106
111
  return {
107
112
  healthy: true,
108
113
  statusCode: 200,
109
- message: `Endpoint healthy. Processed ${response.processedMetrics} metric(s).`,
114
+ message: `Endpoint healthy. Processed ${response.processedEvents} event(s).`,
110
115
  latencyMs,
111
116
  };
112
117
  }
113
118
  catch (error) {
114
119
  const latencyMs = Date.now() - startTime;
115
- const message = error instanceof Error ? error.message : 'Unknown error';
120
+ const message = error instanceof Error ? error.message : "Unknown error";
116
121
  // Try to extract status code from error message
117
122
  const statusMatch = message.match(/(\d{3})/);
118
123
  const statusCode = statusMatch ? parseInt(statusMatch[1], 10) : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/core/api/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/core/api/client.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ReveniumConfig } from '../../types/index.js';
1
+ import type { ReveniumConfig } from "../../types/index.js";
2
2
  /**
3
3
  * Gets the path to the Revenium configuration file.
4
4
  */
@@ -7,6 +7,10 @@ export declare function getConfigPath(): string;
7
7
  * Checks if the configuration file exists.
8
8
  */
9
9
  export declare function configExists(): boolean;
10
+ /**
11
+ * Parses an .env file content into key-value pairs.
12
+ */
13
+ export declare function parseEnvContent(content: string): Record<string, string>;
10
14
  /**
11
15
  * Loads the Revenium configuration from the .env file.
12
16
  * Returns null if the file doesn't exist.
@@ -16,18 +20,6 @@ export declare function loadConfig(): Promise<ReveniumConfig | null>;
16
20
  * Checks if the environment variables are currently loaded in the shell.
17
21
  */
18
22
  export declare function isEnvLoaded(): boolean;
19
- /**
20
- * Migration status for config file updates.
21
- */
22
- export interface MigrationStatus {
23
- needsMigration: boolean;
24
- issues: string[];
25
- }
26
- /**
27
- * Checks if the config file needs migration from old format.
28
- * Detects: OTEL_LOGS_EXPORTER (should be OTEL_METRICS_EXPORTER)
29
- */
30
- export declare function checkMigrationStatus(): Promise<MigrationStatus>;
31
23
  /**
32
24
  * Gets the full OTLP endpoint URL from a base URL.
33
25
  */
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/loader.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAuED;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAmCjE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAKrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,eAAe,CAAC,CA4BrE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI3D"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/loader.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA2CvE;AA4DD;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAyDjE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAKrC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI3D"}
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getConfigPath = getConfigPath;
4
4
  exports.configExists = configExists;
5
+ exports.parseEnvContent = parseEnvContent;
5
6
  exports.loadConfig = loadConfig;
6
7
  exports.isEnvLoaded = isEnvLoaded;
7
- exports.checkMigrationStatus = checkMigrationStatus;
8
8
  exports.getFullOtlpEndpoint = getFullOtlpEndpoint;
9
9
  const node_os_1 = require("node:os");
10
10
  const node_path_1 = require("node:path");
@@ -28,26 +28,33 @@ function configExists() {
28
28
  */
29
29
  function parseEnvContent(content) {
30
30
  const result = {};
31
- for (const line of content.split('\n')) {
31
+ for (const line of content.split("\n")) {
32
32
  let trimmed = line.trim();
33
33
  // Skip empty lines and comments
34
- if (!trimmed || trimmed.startsWith('#')) {
34
+ if (!trimmed || trimmed.startsWith("#")) {
35
35
  continue;
36
36
  }
37
37
  // Handle 'export' prefix
38
- if (trimmed.startsWith('export ')) {
38
+ if (trimmed.startsWith("export ")) {
39
39
  trimmed = trimmed.substring(7).trim();
40
40
  }
41
- const equalsIndex = trimmed.indexOf('=');
41
+ const equalsIndex = trimmed.indexOf("=");
42
42
  if (equalsIndex === -1) {
43
43
  continue;
44
44
  }
45
45
  const key = trimmed.substring(0, equalsIndex).trim();
46
46
  let value = trimmed.substring(equalsIndex + 1).trim();
47
- // Remove surrounding quotes if present
47
+ // Remove surrounding quotes if present and unescape
48
48
  if ((value.startsWith('"') && value.endsWith('"')) ||
49
49
  (value.startsWith("'") && value.endsWith("'"))) {
50
50
  value = value.substring(1, value.length - 1);
51
+ // Unescape common shell escape sequences
52
+ value = value
53
+ .replace(/\\"/g, '"')
54
+ .replace(/\\'/g, "'")
55
+ .replace(/\\\$/g, "$")
56
+ .replace(/\\`/g, "`")
57
+ .replace(/\\\\/g, "\\");
51
58
  }
52
59
  result[key] = value;
53
60
  }
@@ -71,8 +78,8 @@ function extractBaseEndpoint(fullEndpoint) {
71
78
  // Remove the OTLP path suffix to get the base URL
72
79
  // Handle both old path (/meter/v2/ai/otlp) and new path (/meter/v2/otlp)
73
80
  const path = url.pathname;
74
- if (path.includes('/meter/v2/otlp') || path.includes('/meter/v2/ai/otlp')) {
75
- url.pathname = '';
81
+ if (path.includes("/meter/v2/otlp") || path.includes("/meter/v2/ai/otlp")) {
82
+ url.pathname = "";
76
83
  }
77
84
  return url.origin;
78
85
  }
@@ -80,6 +87,35 @@ function extractBaseEndpoint(fullEndpoint) {
80
87
  return fullEndpoint;
81
88
  }
82
89
  }
90
+ /**
91
+ * Parses OTEL_RESOURCE_ATTRIBUTES value into key-value pairs.
92
+ * Format: "key1=value1,key2=value2"
93
+ */
94
+ function parseOtelResourceAttributes(value) {
95
+ const result = {};
96
+ if (!value || typeof value !== "string")
97
+ return result;
98
+ const pairs = value.split(",");
99
+ for (const pair of pairs) {
100
+ const trimmed = pair.trim();
101
+ if (!trimmed)
102
+ continue;
103
+ const equalsIndex = trimmed.indexOf("=");
104
+ if (equalsIndex === -1)
105
+ continue;
106
+ const key = trimmed.substring(0, equalsIndex).trim();
107
+ let attrValue = trimmed.substring(equalsIndex + 1).trim();
108
+ try {
109
+ attrValue = decodeURIComponent(attrValue);
110
+ }
111
+ catch {
112
+ // If decoding fails, use raw value
113
+ }
114
+ if (key)
115
+ result[key] = attrValue;
116
+ }
117
+ return result;
118
+ }
83
119
  /**
84
120
  * Loads the Revenium configuration from the .env file.
85
121
  * Returns null if the file doesn't exist.
@@ -90,25 +126,39 @@ async function loadConfig() {
90
126
  return null;
91
127
  }
92
128
  try {
93
- const content = await (0, promises_1.readFile)(configPath, 'utf-8');
129
+ const content = await (0, promises_1.readFile)(configPath, "utf-8");
94
130
  const env = parseEnvContent(content);
95
- const fullEndpoint = env[constants_js_1.ENV_VARS.OTLP_ENDPOINT] || '';
96
- const headers = env[constants_js_1.ENV_VARS.OTLP_HEADERS] || '';
131
+ const fullEndpoint = env[constants_js_1.ENV_VARS.OTLP_ENDPOINT] || "";
132
+ const headers = env[constants_js_1.ENV_VARS.OTLP_HEADERS] || "";
97
133
  const apiKey = extractApiKeyFromHeaders(headers);
98
134
  if (!apiKey) {
99
135
  return null;
100
136
  }
101
137
  // Parse cost multiplier override if present
102
138
  const costMultiplierStr = env[constants_js_1.ENV_VARS.COST_MULTIPLIER];
103
- const costMultiplierOverride = costMultiplierStr ? parseFloat(costMultiplierStr) : undefined;
139
+ const costMultiplierOverride = costMultiplierStr
140
+ ? parseFloat(costMultiplierStr)
141
+ : undefined;
142
+ // Parse OTEL_RESOURCE_ATTRIBUTES for org/product (primary source)
143
+ const resourceAttrsStr = env["OTEL_RESOURCE_ATTRIBUTES"] || "";
144
+ const resourceAttrs = parseOtelResourceAttributes(resourceAttrsStr);
145
+ // Support both .name (preferred) and .id (legacy), with fallback to standalone vars
146
+ const organizationId = resourceAttrs["organization.name"] ||
147
+ resourceAttrs["organization.id"] ||
148
+ env[constants_js_1.ENV_VARS.ORGANIZATION_ID];
149
+ const productId = resourceAttrs["product.name"] ||
150
+ resourceAttrs["product.id"] ||
151
+ env[constants_js_1.ENV_VARS.PRODUCT_ID];
104
152
  return {
105
153
  apiKey,
106
154
  endpoint: extractBaseEndpoint(fullEndpoint),
107
155
  email: env[constants_js_1.ENV_VARS.SUBSCRIBER_EMAIL],
108
156
  subscriptionTier: env[constants_js_1.ENV_VARS.SUBSCRIPTION],
109
- costMultiplierOverride: costMultiplierOverride && !isNaN(costMultiplierOverride) ? costMultiplierOverride : undefined,
110
- organizationId: env[constants_js_1.ENV_VARS.ORGANIZATION_ID],
111
- productId: env[constants_js_1.ENV_VARS.PRODUCT_ID],
157
+ costMultiplierOverride: costMultiplierOverride !== undefined && !isNaN(costMultiplierOverride)
158
+ ? costMultiplierOverride
159
+ : undefined,
160
+ organizationId,
161
+ productId,
112
162
  };
113
163
  }
114
164
  catch {
@@ -119,44 +169,15 @@ async function loadConfig() {
119
169
  * Checks if the environment variables are currently loaded in the shell.
120
170
  */
121
171
  function isEnvLoaded() {
122
- return (process.env[constants_js_1.ENV_VARS.TELEMETRY_ENABLED] === '1' &&
172
+ return (process.env[constants_js_1.ENV_VARS.TELEMETRY_ENABLED] === "1" &&
123
173
  !!process.env[constants_js_1.ENV_VARS.OTLP_ENDPOINT]);
124
174
  }
125
- /**
126
- * Checks if the config file needs migration from old format.
127
- * Detects: OTEL_LOGS_EXPORTER (should be OTEL_METRICS_EXPORTER)
128
- */
129
- async function checkMigrationStatus() {
130
- const configPath = getConfigPath();
131
- const issues = [];
132
- if (!(0, node_fs_1.existsSync)(configPath)) {
133
- return { needsMigration: false, issues: [] };
134
- }
135
- try {
136
- const content = await (0, promises_1.readFile)(configPath, 'utf-8');
137
- // Check for old OTEL_LOGS_EXPORTER (should be OTEL_METRICS_EXPORTER)
138
- if (content.includes('OTEL_LOGS_EXPORTER')) {
139
- issues.push('Config uses OTEL_LOGS_EXPORTER (should be OTEL_METRICS_EXPORTER)');
140
- }
141
- // Check for old endpoint path
142
- if (content.includes('/meter/v2/ai/otlp')) {
143
- issues.push('Config uses old endpoint path /meter/v2/ai/otlp (should be /meter/v2/otel)');
144
- }
145
- return {
146
- needsMigration: issues.length > 0,
147
- issues,
148
- };
149
- }
150
- catch {
151
- return { needsMigration: false, issues: [] };
152
- }
153
- }
154
175
  /**
155
176
  * Gets the full OTLP endpoint URL from a base URL.
156
177
  */
157
178
  function getFullOtlpEndpoint(baseUrl) {
158
179
  // Remove trailing slash if present
159
- const cleanUrl = baseUrl.replace(/\/$/, '');
180
+ const cleanUrl = baseUrl.replace(/\/$/, "");
160
181
  return `${cleanUrl}${constants_js_1.OTLP_PATH}`;
161
182
  }
162
183
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/core/config/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/core/config/loader.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ReveniumConfig, ValidationResult } from '../../types/index.js';
1
+ import type { ReveniumConfig, ValidationResult } from "../../types/index.js";
2
2
  /**
3
3
  * Validates that an API key has the correct format.
4
4
  * Valid format: hak_{tenant}_{random}
@@ -12,6 +12,10 @@ export declare function validateEmail(email: string): ValidationResult;
12
12
  * Validates a subscription tier.
13
13
  */
14
14
  export declare function validateSubscriptionTier(tier: string): ValidationResult;
15
+ /**
16
+ * Validates an endpoint URL and ensures it uses HTTPS.
17
+ */
18
+ export declare function validateEndpointUrl(endpoint: string): ValidationResult;
15
19
  /**
16
20
  * Validates a complete Revenium configuration.
17
21
  */
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/core/config/validator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7E;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CA2B/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAiB7D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAmBvE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,gBAAgB,CA4BhF"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/core/config/validator.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7E;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CA2B/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAiB7D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAmBvE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAuBtE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAC9B,gBAAgB,CAqBlB"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateApiKey = validateApiKey;
4
4
  exports.validateEmail = validateEmail;
5
5
  exports.validateSubscriptionTier = validateSubscriptionTier;
6
+ exports.validateEndpointUrl = validateEndpointUrl;
6
7
  exports.validateConfig = validateConfig;
7
8
  const constants_js_1 = require("../../utils/constants.js");
8
9
  const VALID_TIERS = Object.keys(constants_js_1.SUBSCRIPTION_TIER_CONFIG);
@@ -12,21 +13,21 @@ const VALID_TIERS = Object.keys(constants_js_1.SUBSCRIPTION_TIER_CONFIG);
12
13
  */
13
14
  function validateApiKey(apiKey) {
14
15
  const errors = [];
15
- if (!apiKey || apiKey.trim() === '') {
16
- errors.push('API key is required');
16
+ if (!apiKey || apiKey.trim() === "") {
17
+ errors.push("API key is required");
17
18
  return { valid: false, errors };
18
19
  }
19
20
  if (!apiKey.startsWith(constants_js_1.API_KEY_PREFIX)) {
20
21
  errors.push(`API key must start with "${constants_js_1.API_KEY_PREFIX}"`);
21
22
  }
22
23
  // Check for at least two underscores (hak_tenant_random)
23
- const parts = apiKey.split('_');
24
+ const parts = apiKey.split("_");
24
25
  if (parts.length < 3) {
25
- errors.push('API key format should be: hak_{tenant}_{key}');
26
+ errors.push("API key format should be: hak_{tenant}_{key}");
26
27
  }
27
28
  // Minimum length check
28
29
  if (apiKey.length < 12) {
29
- errors.push('API key appears too short');
30
+ errors.push("API key appears too short");
30
31
  }
31
32
  return {
32
33
  valid: errors.length === 0,
@@ -38,13 +39,13 @@ function validateApiKey(apiKey) {
38
39
  */
39
40
  function validateEmail(email) {
40
41
  const errors = [];
41
- if (!email || email.trim() === '') {
42
+ if (!email || email.trim() === "") {
42
43
  // Email is optional
43
44
  return { valid: true, errors: [] };
44
45
  }
45
46
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
46
47
  if (!emailRegex.test(email)) {
47
- errors.push('Invalid email format');
48
+ errors.push("Invalid email format");
48
49
  }
49
50
  return {
50
51
  valid: errors.length === 0,
@@ -56,13 +57,36 @@ function validateEmail(email) {
56
57
  */
57
58
  function validateSubscriptionTier(tier) {
58
59
  const errors = [];
59
- if (!tier || tier.trim() === '') {
60
+ if (!tier || tier.trim() === "") {
60
61
  // Tier is optional
61
62
  return { valid: true, errors: [] };
62
63
  }
63
64
  const lowerTier = tier.toLowerCase();
64
65
  if (!VALID_TIERS.includes(lowerTier)) {
65
- errors.push(`Invalid subscription tier. Valid options: ${VALID_TIERS.join(', ')}`);
66
+ errors.push(`Invalid subscription tier. Valid options: ${VALID_TIERS.join(", ")}`);
67
+ }
68
+ return {
69
+ valid: errors.length === 0,
70
+ errors,
71
+ };
72
+ }
73
+ /**
74
+ * Validates an endpoint URL and ensures it uses HTTPS.
75
+ */
76
+ function validateEndpointUrl(endpoint) {
77
+ const errors = [];
78
+ if (!endpoint || endpoint.trim() === "") {
79
+ errors.push("Endpoint URL is required");
80
+ return { valid: false, errors };
81
+ }
82
+ try {
83
+ const url = new URL(endpoint);
84
+ if (url.protocol !== "https:") {
85
+ errors.push("Insecure endpoint: HTTPS is required. Only HTTPS endpoints are allowed.");
86
+ }
87
+ }
88
+ catch {
89
+ errors.push("Invalid endpoint URL format");
66
90
  }
67
91
  return {
68
92
  valid: errors.length === 0,
@@ -74,25 +98,16 @@ function validateSubscriptionTier(tier) {
74
98
  */
75
99
  function validateConfig(config) {
76
100
  const allErrors = [];
77
- const apiKeyResult = validateApiKey(config.apiKey || '');
101
+ const apiKeyResult = validateApiKey(config.apiKey || "");
78
102
  allErrors.push(...apiKeyResult.errors);
79
- const emailResult = validateEmail(config.email || '');
103
+ const emailResult = validateEmail(config.email || "");
80
104
  allErrors.push(...emailResult.errors);
81
105
  if (config.subscriptionTier) {
82
106
  const tierResult = validateSubscriptionTier(config.subscriptionTier);
83
107
  allErrors.push(...tierResult.errors);
84
108
  }
85
- if (!config.endpoint || config.endpoint.trim() === '') {
86
- allErrors.push('Endpoint URL is required');
87
- }
88
- else {
89
- try {
90
- new URL(config.endpoint);
91
- }
92
- catch {
93
- allErrors.push('Invalid endpoint URL format');
94
- }
95
- }
109
+ const endpointResult = validateEndpointUrl(config.endpoint || "");
110
+ allErrors.push(...endpointResult.errors);
96
111
  return {
97
112
  valid: allErrors.length === 0,
98
113
  errors: allErrors,