@tanvir1971/core 1.0.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 (46) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +47 -0
  3. package/dist/config.d.ts +91 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +78 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/crypto.d.ts +21 -0
  8. package/dist/crypto.d.ts.map +1 -0
  9. package/dist/crypto.js +76 -0
  10. package/dist/crypto.js.map +1 -0
  11. package/dist/errors.d.ts +49 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +94 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/index.d.ts +10 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +10 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/metrics.d.ts +60 -0
  20. package/dist/metrics.d.ts.map +1 -0
  21. package/dist/metrics.js +249 -0
  22. package/dist/metrics.js.map +1 -0
  23. package/dist/secrets.d.ts +37 -0
  24. package/dist/secrets.d.ts.map +1 -0
  25. package/dist/secrets.js +113 -0
  26. package/dist/secrets.js.map +1 -0
  27. package/dist/telemetry.d.ts +76 -0
  28. package/dist/telemetry.d.ts.map +1 -0
  29. package/dist/telemetry.js +155 -0
  30. package/dist/telemetry.js.map +1 -0
  31. package/dist/tokens.d.ts +7 -0
  32. package/dist/tokens.d.ts.map +1 -0
  33. package/dist/tokens.js +15 -0
  34. package/dist/tokens.js.map +1 -0
  35. package/dist/types.d.ts +130 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +7 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/version.d.ts +2 -0
  40. package/dist/version.d.ts.map +1 -0
  41. package/dist/version.js +2 -0
  42. package/dist/version.js.map +1 -0
  43. package/package.json +61 -0
  44. package/proto/axiom/v1/gateway.proto +84 -0
  45. package/proto/axiom/v1/knowledge.proto +62 -0
  46. package/proto/axiom/v1/telemetry.proto +46 -0
package/dist/errors.js ADDED
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Axiom AI error taxonomy. Every service throws AxiomError (or maps upstream
3
+ * failures into one) so clients receive a stable machine-readable contract.
4
+ */
5
+ const HTTP_STATUS = {
6
+ AXIOM_UNAUTHENTICATED: 401,
7
+ AXIOM_FORBIDDEN_TENANT: 403,
8
+ AXIOM_QUOTA_EXCEEDED: 402,
9
+ AXIOM_RATE_LIMITED: 429,
10
+ AXIOM_VALIDATION_FAILED: 400,
11
+ AXIOM_MODEL_NOT_ALLOWED: 403,
12
+ AXIOM_UPSTREAM_TIMEOUT: 504,
13
+ AXIOM_UPSTREAM_UNAVAILABLE: 502,
14
+ AXIOM_ALL_UPSTREAMS_FAILED: 502,
15
+ AXIOM_SANDBOX_VIOLATION: 400,
16
+ AXIOM_WEBHOOK_SIGNATURE_INVALID: 401,
17
+ AXIOM_NOT_FOUND: 404,
18
+ AXIOM_CONFLICT: 409,
19
+ AXIOM_INTERNAL: 500,
20
+ };
21
+ export class AxiomError extends Error {
22
+ code;
23
+ statusCode;
24
+ retryable;
25
+ details;
26
+ constructor(code, message, options) {
27
+ super(message);
28
+ this.name = "AxiomError";
29
+ this.code = code;
30
+ this.statusCode = HTTP_STATUS[code];
31
+ this.retryable = options?.retryable ?? false;
32
+ if (options?.details !== undefined) {
33
+ this.details = options.details;
34
+ }
35
+ if (options?.cause !== undefined) {
36
+ this.cause = options.cause;
37
+ }
38
+ }
39
+ toJSON() {
40
+ return {
41
+ error: {
42
+ code: this.code,
43
+ message: this.message,
44
+ retryable: this.retryable,
45
+ ...(this.details !== undefined ? { details: this.details } : {}),
46
+ },
47
+ };
48
+ }
49
+ static from(error) {
50
+ if (error instanceof AxiomError) {
51
+ return error;
52
+ }
53
+ return new AxiomError("AXIOM_INTERNAL", toMessage(error), {
54
+ cause: error,
55
+ retryable: true,
56
+ });
57
+ }
58
+ }
59
+ function toMessage(value) {
60
+ return value instanceof Error ? value.message : String(value);
61
+ }
62
+ /* ------------------------------ Factories --------------------------------- */
63
+ export const errors = {
64
+ unauthenticated: (message = "Missing or invalid API key.") => new AxiomError("AXIOM_UNAUTHENTICATED", message),
65
+ forbiddenTenant: (message = "Resource is outside the caller's tenant scope.") => new AxiomError("AXIOM_FORBIDDEN_TENANT", message),
66
+ quotaExceeded: (details) => new AxiomError("AXIOM_QUOTA_EXCEEDED", "Token or spend quota exhausted for this period.", {
67
+ details,
68
+ retryable: true,
69
+ }),
70
+ rateLimited: (retryAfterSeconds) => new AxiomError("AXIOM_RATE_LIMITED", "Too many requests.", {
71
+ details: { retryAfterSeconds },
72
+ retryable: true,
73
+ }),
74
+ validationFailed: (details) => new AxiomError("AXIOM_VALIDATION_FAILED", "Request failed schema validation.", { details }),
75
+ modelNotAllowed: (model) => new AxiomError("AXIOM_MODEL_NOT_ALLOWED", `Model '${model}' is not enabled for this tenant.`),
76
+ upstreamTimeout: (provider) => new AxiomError("AXIOM_UPSTREAM_TIMEOUT", `Upstream provider '${provider}' timed out.`, {
77
+ retryable: true,
78
+ details: { provider },
79
+ }),
80
+ upstreamUnavailable: (provider) => new AxiomError("AXIOM_UPSTREAM_UNAVAILABLE", `Upstream provider '${provider}' is unavailable.`, {
81
+ retryable: true,
82
+ details: { provider },
83
+ }),
84
+ allUpstreamsFailed: (attempts) => new AxiomError("AXIOM_ALL_UPSTREAMS_FAILED", "All routed providers failed.", {
85
+ retryable: true,
86
+ details: { attempts },
87
+ }),
88
+ sandboxViolation: (reason) => new AxiomError("AXIOM_SANDBOX_VIOLATION", `Tool execution blocked: ${reason}`),
89
+ webhookSignatureInvalid: () => new AxiomError("AXIOM_WEBHOOK_SIGNATURE_INVALID", "Webhook signature verification failed."),
90
+ notFound: (resource) => new AxiomError("AXIOM_NOT_FOUND", `${resource} not found.`),
91
+ conflict: (message) => new AxiomError("AXIOM_CONFLICT", message),
92
+ internal: (cause) => new AxiomError("AXIOM_INTERNAL", "Internal server error.", { cause, retryable: true }),
93
+ };
94
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export * from "./version.js";
2
+ export * from "./tokens.js";
3
+ export * from "./types.js";
4
+ export * from "./errors.js";
5
+ export * from "./crypto.js";
6
+ export * from "./config.js";
7
+ export * from "./telemetry.js";
8
+ export * from "./metrics.js";
9
+ export * from "./secrets.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export * from "./version.js";
2
+ export * from "./tokens.js";
3
+ export * from "./types.js";
4
+ export * from "./errors.js";
5
+ export * from "./crypto.js";
6
+ export * from "./config.js";
7
+ export * from "./telemetry.js";
8
+ export * from "./metrics.js";
9
+ export * from "./secrets.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Prometheus / OpenMetrics registry and instrumentation primitives.
3
+ * Shared across TypeScript services to export standard /metrics endpoints
4
+ * consumed by Prometheus and Grafana (O5, Milestone 5.1).
5
+ */
6
+ export interface MetricLabels {
7
+ [key: string]: string | number;
8
+ }
9
+ export declare class Counter {
10
+ readonly name: string;
11
+ readonly help: string;
12
+ private values;
13
+ constructor(name: string, help: string);
14
+ inc(labels?: MetricLabels, value?: number): void;
15
+ get(labels?: MetricLabels): number;
16
+ reset(): void;
17
+ toPrometheus(): string;
18
+ }
19
+ export declare class Gauge {
20
+ readonly name: string;
21
+ readonly help: string;
22
+ private values;
23
+ constructor(name: string, help: string);
24
+ set(value: number, labels?: MetricLabels): void;
25
+ inc(labels?: MetricLabels, value?: number): void;
26
+ dec(labels?: MetricLabels, value?: number): void;
27
+ get(labels?: MetricLabels): number;
28
+ reset(): void;
29
+ toPrometheus(): string;
30
+ }
31
+ export declare const DEFAULT_LATENCY_BUCKETS: number[];
32
+ export declare class Histogram {
33
+ readonly name: string;
34
+ readonly help: string;
35
+ private values;
36
+ readonly buckets: readonly number[];
37
+ constructor(name: string, help: string, buckets?: readonly number[]);
38
+ observe(value: number, labels?: MetricLabels): void;
39
+ reset(): void;
40
+ toPrometheus(): string;
41
+ }
42
+ export declare class MetricsRegistry {
43
+ private counters;
44
+ private gauges;
45
+ private histograms;
46
+ registerCounter(name: string, help: string): Counter;
47
+ registerGauge(name: string, help: string): Gauge;
48
+ registerHistogram(name: string, help: string, buckets?: readonly number[]): Histogram;
49
+ getMetricsAsText(): string;
50
+ clear(): void;
51
+ }
52
+ export declare const globalMetrics: MetricsRegistry;
53
+ export interface HttpMetrics {
54
+ durationHistogram: Histogram;
55
+ requestsTotal: Counter;
56
+ errorsTotal: Counter;
57
+ record(method: string, route: string, statusCode: number, durationSeconds: number): void;
58
+ }
59
+ export declare function createHttpMetrics(serviceName: string, registry?: MetricsRegistry): HttpMetrics;
60
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAChC;AAoBD,qBAAa,OAAO;aAIA,IAAI,EAAE,MAAM;aACZ,IAAI,EAAE,MAAM;IAJ9B,OAAO,CAAC,MAAM,CAA+D;gBAG3D,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM;IAG9B,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,KAAK,SAAI,GAAG,IAAI;IAO3C,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM;IAIlC,KAAK,IAAI,IAAI;IAIb,YAAY,IAAI,MAAM;CAcvB;AAED,qBAAa,KAAK;aAIE,IAAI,EAAE,MAAM;aACZ,IAAI,EAAE,MAAM;IAJ9B,OAAO,CAAC,MAAM,CAA+D;gBAG3D,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM;IAG9B,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI;IAK/C,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,KAAK,SAAI,GAAG,IAAI;IAM3C,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,KAAK,SAAI,GAAG,IAAI;IAM3C,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM;IAIlC,KAAK,IAAI,IAAI;IAIb,YAAY,IAAI,MAAM;CAcvB;AAED,eAAO,MAAM,uBAAuB,UAEnC,CAAC;AASF,qBAAa,SAAS;aAKF,IAAI,EAAE,MAAM;aACZ,IAAI,EAAE,MAAM;IAL9B,OAAO,CAAC,MAAM,CAA2C;IACzD,SAAgB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;gBAGzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAC5B,OAAO,GAAE,SAAS,MAAM,EAA4B;IAKtD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI;IAsBnD,KAAK,IAAI,IAAI;IAIb,YAAY,IAAI,MAAM;CAqCvB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,UAAU,CAAgC;IAElD,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IASpD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK;IAShD,iBAAiB,CACf,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,SAAS,MAAM,EAA4B,GACnD,SAAS;IASZ,gBAAgB,IAAI,MAAM;IAc1B,KAAK,IAAI,IAAI;CAKd;AAED,eAAO,MAAM,aAAa,iBAAwB,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,SAAS,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1F;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,QAAQ,GAAE,eAA+B,GACxC,WAAW,CAoCb"}
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Prometheus / OpenMetrics registry and instrumentation primitives.
3
+ * Shared across TypeScript services to export standard /metrics endpoints
4
+ * consumed by Prometheus and Grafana (O5, Milestone 5.1).
5
+ */
6
+ function formatLabels(labels) {
7
+ if (!labels)
8
+ return "";
9
+ const entries = Object.entries(labels).filter(([, v]) => v !== undefined && v !== null);
10
+ if (entries.length === 0)
11
+ return "";
12
+ const formatted = entries
13
+ .map(([k, v]) => `${k}="${String(v).replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n")}"`)
14
+ .join(",");
15
+ return `{${formatted}}`;
16
+ }
17
+ function labelsKey(labels) {
18
+ if (!labels)
19
+ return "";
20
+ return Object.entries(labels)
21
+ .sort(([a], [b]) => a.localeCompare(b))
22
+ .map(([k, v]) => `${k}=${v}`)
23
+ .join(",");
24
+ }
25
+ export class Counter {
26
+ name;
27
+ help;
28
+ values = new Map();
29
+ constructor(name, help) {
30
+ this.name = name;
31
+ this.help = help;
32
+ }
33
+ inc(labels, value = 1) {
34
+ if (value < 0)
35
+ throw new Error("Counter value must be non-negative");
36
+ const key = labelsKey(labels);
37
+ const current = this.values.get(key)?.value ?? 0;
38
+ this.values.set(key, { value: current + value, labels });
39
+ }
40
+ get(labels) {
41
+ return this.values.get(labelsKey(labels))?.value ?? 0;
42
+ }
43
+ reset() {
44
+ this.values.clear();
45
+ }
46
+ toPrometheus() {
47
+ const lines = [
48
+ `# HELP ${this.name} ${this.help}`,
49
+ `# TYPE ${this.name} counter`,
50
+ ];
51
+ if (this.values.size === 0) {
52
+ lines.push(`${this.name} 0`);
53
+ }
54
+ else {
55
+ for (const { value, labels } of this.values.values()) {
56
+ lines.push(`${this.name}${formatLabels(labels)} ${value}`);
57
+ }
58
+ }
59
+ return lines.join("\n");
60
+ }
61
+ }
62
+ export class Gauge {
63
+ name;
64
+ help;
65
+ values = new Map();
66
+ constructor(name, help) {
67
+ this.name = name;
68
+ this.help = help;
69
+ }
70
+ set(value, labels) {
71
+ const key = labelsKey(labels);
72
+ this.values.set(key, { value, labels });
73
+ }
74
+ inc(labels, value = 1) {
75
+ const key = labelsKey(labels);
76
+ const current = this.values.get(key)?.value ?? 0;
77
+ this.values.set(key, { value: current + value, labels });
78
+ }
79
+ dec(labels, value = 1) {
80
+ const key = labelsKey(labels);
81
+ const current = this.values.get(key)?.value ?? 0;
82
+ this.values.set(key, { value: current - value, labels });
83
+ }
84
+ get(labels) {
85
+ return this.values.get(labelsKey(labels))?.value ?? 0;
86
+ }
87
+ reset() {
88
+ this.values.clear();
89
+ }
90
+ toPrometheus() {
91
+ const lines = [
92
+ `# HELP ${this.name} ${this.help}`,
93
+ `# TYPE ${this.name} gauge`,
94
+ ];
95
+ if (this.values.size === 0) {
96
+ lines.push(`${this.name} 0`);
97
+ }
98
+ else {
99
+ for (const { value, labels } of this.values.values()) {
100
+ lines.push(`${this.name}${formatLabels(labels)} ${value}`);
101
+ }
102
+ }
103
+ return lines.join("\n");
104
+ }
105
+ }
106
+ export const DEFAULT_LATENCY_BUCKETS = [
107
+ 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10,
108
+ ];
109
+ export class Histogram {
110
+ name;
111
+ help;
112
+ values = new Map();
113
+ buckets;
114
+ constructor(name, help, buckets = DEFAULT_LATENCY_BUCKETS) {
115
+ this.name = name;
116
+ this.help = help;
117
+ this.buckets = [...buckets].sort((a, b) => a - b);
118
+ }
119
+ observe(value, labels) {
120
+ const key = labelsKey(labels);
121
+ let state = this.values.get(key);
122
+ if (!state) {
123
+ state = {
124
+ count: 0,
125
+ sum: 0,
126
+ buckets: new Array(this.buckets.length).fill(0),
127
+ labels,
128
+ };
129
+ this.values.set(key, state);
130
+ }
131
+ state.count += 1;
132
+ state.sum += value;
133
+ for (let i = 0; i < this.buckets.length; i++) {
134
+ const bound = this.buckets[i];
135
+ if (bound !== undefined && value <= bound) {
136
+ state.buckets[i] = (state.buckets[i] ?? 0) + 1;
137
+ }
138
+ }
139
+ }
140
+ reset() {
141
+ this.values.clear();
142
+ }
143
+ toPrometheus() {
144
+ const lines = [
145
+ `# HELP ${this.name} ${this.help}`,
146
+ `# TYPE ${this.name} histogram`,
147
+ ];
148
+ if (this.values.size === 0) {
149
+ for (const b of this.buckets) {
150
+ lines.push(`${this.name}_bucket{le="${b}"} 0`);
151
+ }
152
+ lines.push(`${this.name}_bucket{le="+Inf"} 0`);
153
+ lines.push(`${this.name}_sum 0`);
154
+ lines.push(`${this.name}_count 0`);
155
+ }
156
+ else {
157
+ for (const state of this.values.values()) {
158
+ const baseLabels = state.labels ?? {};
159
+ for (let i = 0; i < this.buckets.length; i++) {
160
+ const bound = this.buckets[i];
161
+ const count = state.buckets[i] ?? 0;
162
+ if (bound !== undefined) {
163
+ lines.push(`${this.name}_bucket${formatLabels({ ...baseLabels, le: bound })} ${count}`);
164
+ }
165
+ }
166
+ lines.push(`${this.name}_bucket${formatLabels({ ...baseLabels, le: "+Inf" })} ${state.count}`);
167
+ lines.push(`${this.name}_sum${formatLabels(baseLabels)} ${state.sum}`);
168
+ lines.push(`${this.name}_count${formatLabels(baseLabels)} ${state.count}`);
169
+ }
170
+ }
171
+ return lines.join("\n");
172
+ }
173
+ }
174
+ export class MetricsRegistry {
175
+ counters = new Map();
176
+ gauges = new Map();
177
+ histograms = new Map();
178
+ registerCounter(name, help) {
179
+ let counter = this.counters.get(name);
180
+ if (!counter) {
181
+ counter = new Counter(name, help);
182
+ this.counters.set(name, counter);
183
+ }
184
+ return counter;
185
+ }
186
+ registerGauge(name, help) {
187
+ let gauge = this.gauges.get(name);
188
+ if (!gauge) {
189
+ gauge = new Gauge(name, help);
190
+ this.gauges.set(name, gauge);
191
+ }
192
+ return gauge;
193
+ }
194
+ registerHistogram(name, help, buckets = DEFAULT_LATENCY_BUCKETS) {
195
+ let histogram = this.histograms.get(name);
196
+ if (!histogram) {
197
+ histogram = new Histogram(name, help, buckets);
198
+ this.histograms.set(name, histogram);
199
+ }
200
+ return histogram;
201
+ }
202
+ getMetricsAsText() {
203
+ const parts = [];
204
+ for (const c of this.counters.values()) {
205
+ parts.push(c.toPrometheus());
206
+ }
207
+ for (const g of this.gauges.values()) {
208
+ parts.push(g.toPrometheus());
209
+ }
210
+ for (const h of this.histograms.values()) {
211
+ parts.push(h.toPrometheus());
212
+ }
213
+ return parts.join("\n\n") + "\n";
214
+ }
215
+ clear() {
216
+ this.counters.clear();
217
+ this.gauges.clear();
218
+ this.histograms.clear();
219
+ }
220
+ }
221
+ export const globalMetrics = new MetricsRegistry();
222
+ export function createHttpMetrics(serviceName, registry = globalMetrics) {
223
+ const durationHistogram = registry.registerHistogram("http_server_request_duration_seconds", "HTTP server request duration in seconds");
224
+ const requestsTotal = registry.registerCounter("http_server_requests_total", "Total count of HTTP server requests");
225
+ const errorsTotal = registry.registerCounter("http_server_requests_errors_total", "Total count of HTTP server 5xx errors");
226
+ return {
227
+ durationHistogram,
228
+ requestsTotal,
229
+ errorsTotal,
230
+ record(method, route, statusCode, durationSeconds) {
231
+ const labels = {
232
+ job: serviceName,
233
+ method: method.toUpperCase(),
234
+ route: route || "unknown",
235
+ status: String(statusCode),
236
+ };
237
+ durationHistogram.observe(durationSeconds, labels);
238
+ requestsTotal.inc(labels);
239
+ if (statusCode >= 500) {
240
+ errorsTotal.inc({
241
+ job: serviceName,
242
+ method: method.toUpperCase(),
243
+ route: route || "unknown",
244
+ });
245
+ }
246
+ },
247
+ };
248
+ }
249
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Secret scrubbing (X6). Central redaction engine used by every service so
3
+ * that sensitive headers, API keys, and bearer tokens never reach stdout
4
+ * logs or OpenTelemetry span attributes.
5
+ */
6
+ /** Header names scrubbed from any serialized request context. */
7
+ export declare const SENSITIVE_HEADERS: readonly ["authorization", "x-api-key", "x-axiom-signature", "x-goog-api-key", "cookie", "set-cookie", "proxy-authorization"];
8
+ export declare const REDACTED = "[REDACTED]";
9
+ /** Redact a single string value that may embed credentials. */
10
+ export declare function scrubText(value: string): string;
11
+ /** Serialize a headers object with every sensitive header redacted. */
12
+ export declare function scrubHeaders(headers: Record<string, string>): Record<string, string>;
13
+ /**
14
+ * Deep-scrub an arbitrary object (log payloads, span attribute bags):
15
+ * sensitive-named keys are redacted outright, string values are pattern-scrubbed.
16
+ */
17
+ export declare function scrubObject<T>(input: T): T;
18
+ export type LogLevel = "debug" | "info" | "warn" | "error";
19
+ export interface Logger {
20
+ debug(message: string, fields?: Record<string, unknown>): void;
21
+ info(message: string, message2?: Record<string, unknown>): void;
22
+ warn(message: string, fields?: Record<string, unknown>): void;
23
+ error(message: string, fields?: Record<string, unknown>): void;
24
+ }
25
+ export interface SafeLoggerOptions {
26
+ /** Default: process.stdout / process.stderr. Injectable for tests. */
27
+ write?: (line: string) => void;
28
+ }
29
+ /**
30
+ * Structured JSON-lines logger that scrubs every message and field before
31
+ * writing. All services should log through this instead of console.log so a
32
+ * leaked provider key in an error message cannot reach stdout.
33
+ */
34
+ export declare function createSafeLogger(options?: SafeLoggerOptions): Logger;
35
+ /** Guard used before attaching an attribute to a span. */
36
+ export declare function scrubSpanAttribute(name: string, value: string): string;
37
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,+HAQpB,CAAC;AAcX,eAAO,MAAM,QAAQ,eAAe,CAAC;AAOrC,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMpF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAE1C;AAcD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAChE;AAED,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAiBxE;AAED,0DAA0D;AAC1D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtE"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Secret scrubbing (X6). Central redaction engine used by every service so
3
+ * that sensitive headers, API keys, and bearer tokens never reach stdout
4
+ * logs or OpenTelemetry span attributes.
5
+ */
6
+ /** Attribute/field names that must never be emitted verbatim. */
7
+ const SENSITIVE_NAME_FRAGMENTS = [
8
+ "authorization",
9
+ "api-key",
10
+ "apikey",
11
+ "api_key",
12
+ "x-api-key",
13
+ "x-axiom-signature",
14
+ "signature",
15
+ "token",
16
+ "secret",
17
+ "password",
18
+ "cookie",
19
+ "session",
20
+ "credential",
21
+ ];
22
+ /** Header names scrubbed from any serialized request context. */
23
+ export const SENSITIVE_HEADERS = [
24
+ "authorization",
25
+ "x-api-key",
26
+ "x-axiom-signature",
27
+ "x-goog-api-key",
28
+ "cookie",
29
+ "set-cookie",
30
+ "proxy-authorization",
31
+ ];
32
+ /** Value patterns that look like credentials even under an innocent key. */
33
+ const VALUE_PATTERNS = [
34
+ { id: "bearer", re: /\bBearer\s+[A-Za-z0-9\-._~+/=]{8,}/gi },
35
+ { id: "openai-key", re: /\bsk-[A-Za-z0-9_-]{16,}\b/g },
36
+ { id: "groq-key", re: /\bgsk_[A-Za-z0-9]{16,}\b/g },
37
+ { id: "mistral-key", re: /\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
38
+ { id: "aws-key", re: /\bAKIA[0-9A-Z]{16}\b/g },
39
+ { id: "hmac-hex", re: /\bsha256=[a-f0-9]{32,}\b/gi },
40
+ { id: "stripe-key", re: /\b(sk|rk)_(test|live)_[A-Za-z0-9]{16,}\b/g },
41
+ { id: "private-key", re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g },
42
+ ];
43
+ export const REDACTED = "[REDACTED]";
44
+ function isSensitiveName(name) {
45
+ const lower = name.toLowerCase();
46
+ return SENSITIVE_NAME_FRAGMENTS.some((fragment) => lower.includes(fragment));
47
+ }
48
+ /** Redact a single string value that may embed credentials. */
49
+ export function scrubText(value) {
50
+ let out = value;
51
+ for (const { re } of VALUE_PATTERNS) {
52
+ out = out.replace(re, REDACTED);
53
+ }
54
+ return out;
55
+ }
56
+ /** Serialize a headers object with every sensitive header redacted. */
57
+ export function scrubHeaders(headers) {
58
+ const out = {};
59
+ for (const [name, value] of Object.entries(headers)) {
60
+ out[name] = isSensitiveName(name) ? REDACTED : scrubText(value);
61
+ }
62
+ return out;
63
+ }
64
+ /**
65
+ * Deep-scrub an arbitrary object (log payloads, span attribute bags):
66
+ * sensitive-named keys are redacted outright, string values are pattern-scrubbed.
67
+ */
68
+ export function scrubObject(input) {
69
+ return scrubValue(input);
70
+ }
71
+ function scrubValue(value, depth = 0) {
72
+ if (depth > 12 || value === null || value === undefined)
73
+ return value;
74
+ if (typeof value === "string")
75
+ return scrubText(value);
76
+ if (typeof value !== "object")
77
+ return value;
78
+ if (Array.isArray(value))
79
+ return value.map((item) => scrubValue(item, depth + 1));
80
+ const out = {};
81
+ for (const [key, item] of Object.entries(value)) {
82
+ out[key] = isSensitiveName(key) ? REDACTED : scrubValue(item, depth + 1);
83
+ }
84
+ return out;
85
+ }
86
+ /**
87
+ * Structured JSON-lines logger that scrubs every message and field before
88
+ * writing. All services should log through this instead of console.log so a
89
+ * leaked provider key in an error message cannot reach stdout.
90
+ */
91
+ export function createSafeLogger(options = {}) {
92
+ const write = options.write ?? ((line) => process.stdout.write(`${line}\n`));
93
+ const emit = (level, message, fields) => {
94
+ const record = {
95
+ level,
96
+ time: new Date().toISOString(),
97
+ message: scrubText(message),
98
+ ...(fields ? scrubObject(fields) : {}),
99
+ };
100
+ write(JSON.stringify(record));
101
+ };
102
+ return {
103
+ debug: (m, f) => emit("debug", m, f),
104
+ info: (m, f) => emit("info", m, f),
105
+ warn: (m, f) => emit("warn", m, f),
106
+ error: (m, f) => emit("error", m, f),
107
+ };
108
+ }
109
+ /** Guard used before attaching an attribute to a span. */
110
+ export function scrubSpanAttribute(name, value) {
111
+ return isSensitiveName(name) ? REDACTED : scrubText(value);
112
+ }
113
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"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"}