@neetru/sdk 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 (65) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/README.md +218 -0
  3. package/dist/auth.cjs +1137 -0
  4. package/dist/auth.cjs.map +1 -0
  5. package/dist/auth.d.cts +25 -0
  6. package/dist/auth.d.ts +25 -0
  7. package/dist/auth.mjs +1135 -0
  8. package/dist/auth.mjs.map +1 -0
  9. package/dist/catalog.cjs +179 -0
  10. package/dist/catalog.cjs.map +1 -0
  11. package/dist/catalog.d.cts +17 -0
  12. package/dist/catalog.d.ts +17 -0
  13. package/dist/catalog.mjs +177 -0
  14. package/dist/catalog.mjs.map +1 -0
  15. package/dist/db.cjs +232 -0
  16. package/dist/db.cjs.map +1 -0
  17. package/dist/db.d.cts +8 -0
  18. package/dist/db.d.ts +8 -0
  19. package/dist/db.mjs +230 -0
  20. package/dist/db.mjs.map +1 -0
  21. package/dist/entitlements.cjs +140 -0
  22. package/dist/entitlements.cjs.map +1 -0
  23. package/dist/entitlements.d.cts +14 -0
  24. package/dist/entitlements.d.ts +14 -0
  25. package/dist/entitlements.mjs +138 -0
  26. package/dist/entitlements.mjs.map +1 -0
  27. package/dist/errors.cjs +20 -0
  28. package/dist/errors.cjs.map +1 -0
  29. package/dist/errors.d.cts +27 -0
  30. package/dist/errors.d.ts +27 -0
  31. package/dist/errors.mjs +18 -0
  32. package/dist/errors.mjs.map +1 -0
  33. package/dist/index.cjs +1154 -0
  34. package/dist/index.cjs.map +1 -0
  35. package/dist/index.d.cts +24 -0
  36. package/dist/index.d.ts +24 -0
  37. package/dist/index.mjs +1142 -0
  38. package/dist/index.mjs.map +1 -0
  39. package/dist/mocks.cjs +281 -0
  40. package/dist/mocks.cjs.map +1 -0
  41. package/dist/mocks.d.cts +138 -0
  42. package/dist/mocks.d.ts +138 -0
  43. package/dist/mocks.mjs +274 -0
  44. package/dist/mocks.mjs.map +1 -0
  45. package/dist/support.cjs +176 -0
  46. package/dist/support.cjs.map +1 -0
  47. package/dist/support.d.cts +5 -0
  48. package/dist/support.d.ts +5 -0
  49. package/dist/support.mjs +174 -0
  50. package/dist/support.mjs.map +1 -0
  51. package/dist/telemetry.cjs +225 -0
  52. package/dist/telemetry.cjs.map +1 -0
  53. package/dist/telemetry.d.cts +35 -0
  54. package/dist/telemetry.d.ts +35 -0
  55. package/dist/telemetry.mjs +223 -0
  56. package/dist/telemetry.mjs.map +1 -0
  57. package/dist/types-PKUaFtBY.d.cts +408 -0
  58. package/dist/types-PKUaFtBY.d.ts +408 -0
  59. package/dist/usage.cjs +235 -0
  60. package/dist/usage.cjs.map +1 -0
  61. package/dist/usage.d.cts +5 -0
  62. package/dist/usage.d.ts +5 -0
  63. package/dist/usage.mjs +233 -0
  64. package/dist/usage.mjs.map +1 -0
  65. package/package.json +79 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/telemetry.ts"],"names":[],"mappings":"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","file":"telemetry.cjs","sourcesContent":["/**\n * Erros tipados do SDK.\n *\n * Todo erro lançado pelo SDK estende `NeetruError` — caller pode discriminar\n * por `.code` (string estável) sem parsing de message.\n */\n\n/** Códigos de erro estáveis do SDK. Adicionar aqui requer minor bump. */\nexport type NeetruErrorCode =\n | 'invalid_config'\n | 'missing_api_key'\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'rate_limited'\n | 'validation_failed'\n | 'network_error'\n | 'invalid_response'\n | 'server_error'\n | 'unknown';\n\n/**\n * Erro tipado padrão do SDK. Sempre lançado em vez de Error genérico.\n *\n * @example\n * ```ts\n * try { await client.catalog.list(); }\n * catch (e) {\n * if (e instanceof NeetruError && e.code === 'rate_limited') retry();\n * }\n * ```\n */\nexport class NeetruError extends Error {\n public readonly code: NeetruErrorCode | string;\n public readonly status?: number;\n public readonly requestId?: string;\n\n constructor(\n code: NeetruErrorCode | string,\n message: string,\n status?: number,\n requestId?: string,\n ) {\n super(message);\n this.name = 'NeetruError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n // Preserva o prototype chain ao herdar de Error (downlevel quirk de TS).\n Object.setPrototypeOf(this, NeetruError.prototype);\n }\n}\n","/**\n * HTTP transport interno do SDK.\n *\n * Responsabilidades:\n * - Construir URL absoluta a partir de `baseUrl` + path\n * - Injetar Bearer token quando `requireAuth=true`\n * - Mapear status HTTP → `NeetruError` com `code` estável\n * - Parse defensivo de JSON (não lança em body vazio em 204)\n *\n * Não faz retry/backoff em v0.1 (carry-over Sprint 3+).\n */\nimport { NeetruError, type NeetruErrorCode } from './errors';\nimport type { ResolvedConfig } from './types';\n\n/** Opções da request HTTP. */\nexport interface HttpRequestOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n /** Path relativo (ex: `/api/v1/cli/catalog`). Concatenado a `baseUrl`. */\n path: string;\n /** Query string params (chave → valor primitivo). Valores `undefined` ignorados. */\n query?: Record<string, string | number | boolean | undefined>;\n /** Body JSON-serializável. Ignorado em GET/DELETE. */\n body?: unknown;\n /**\n * Se true, injeta `Authorization: Bearer <apiKey>`. Lança `missing_api_key`\n * se config.apiKey ausente. Default false.\n */\n requireAuth?: boolean;\n /** Cabeçalhos extras. */\n headers?: Record<string, string>;\n}\n\n/** Mapeamento status → code estável do NeetruError. */\nfunction statusToCode(status: number): NeetruErrorCode {\n if (status === 401) return 'unauthorized';\n if (status === 403) return 'forbidden';\n if (status === 404) return 'not_found';\n if (status === 422 || status === 400) return 'validation_failed';\n if (status === 429) return 'rate_limited';\n if (status >= 500) return 'server_error';\n return 'unknown';\n}\n\nfunction buildUrl(baseUrl: string, path: string, query?: HttpRequestOptions['query']): string {\n // Trim trailing slash em base e leading em path pra evitar `//`.\n const base = baseUrl.replace(/\\/+$/, '');\n const p = path.startsWith('/') ? path : `/${path}`;\n const url = new URL(`${base}${p}`);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v === undefined) continue;\n url.searchParams.set(k, String(v));\n }\n }\n return url.toString();\n}\n\n/** Parse JSON defensivo — retorna `undefined` em body vazio. */\nasync function safeJson(res: Response): Promise<unknown> {\n const text = await res.text();\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Executa request HTTP. Em sucesso retorna body parseado; em erro lança\n * `NeetruError` com `code` derivado do status.\n */\nexport async function httpRequest<T>(\n config: ResolvedConfig,\n opts: HttpRequestOptions,\n): Promise<T> {\n const method = opts.method ?? 'GET';\n const url = buildUrl(config.baseUrl, opts.path, opts.query);\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...opts.headers,\n };\n\n if (opts.requireAuth) {\n if (!config.apiKey) {\n throw new NeetruError(\n 'missing_api_key',\n 'This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var.',\n );\n }\n headers.authorization = `Bearer ${config.apiKey}`;\n }\n\n const init: RequestInit = { method, headers };\n if (opts.body !== undefined && method !== 'GET' && method !== 'DELETE') {\n headers['content-type'] = 'application/json';\n init.body = JSON.stringify(opts.body);\n }\n\n let res: Response;\n try {\n res = await config.fetch(url, init);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'fetch failed';\n throw new NeetruError('network_error', `Network error: ${message}`);\n }\n\n const requestId = res.headers.get('x-request-id') ?? res.headers.get('x-correlation-id') ?? undefined;\n\n if (!res.ok) {\n const body = (await safeJson(res)) as { error?: { code?: string; message?: string } | string } | undefined;\n let code: string = statusToCode(res.status);\n let message = `HTTP ${res.status}`;\n if (body && typeof body === 'object' && 'error' in body) {\n const errField = body.error;\n if (typeof errField === 'string') {\n message = errField;\n } else if (errField && typeof errField === 'object') {\n if (typeof errField.code === 'string') code = errField.code;\n if (typeof errField.message === 'string') message = errField.message;\n }\n }\n throw new NeetruError(code, message, res.status, requestId);\n }\n\n const parsed = await safeJson(res);\n // Caller é responsável por validar shape; SDK assume backend correto.\n return parsed as T;\n}\n","/**\n * Telemetria — emite eventos do produto cliente pro Core.\n *\n * Endpoint legacy `event()`:\n * `POST /api/v1/sdk/telemetry/event` — persiste em `usage_events/{id}`.\n *\n * Sprint 6 — `log()`:\n * - Em `NEETRU_ENV=dev`: console.{level} apenas (sem network).\n * - Em `workspace`/`prod`: `POST /sdk/v1/telemetry/log` com Bearer +\n * correlationId injetado.\n *\n * v0.1 sem batching — cada chamada é uma request.\n */\nimport { NeetruError } from './errors';\nimport { httpRequest } from './http';\nimport type {\n ResolvedConfig,\n TelemetryEventAck,\n TelemetryEventInput,\n TelemetryLogAck,\n TelemetryLogInput,\n TelemetryLogLevel,\n} from './types';\n\ninterface RawTelemetryAck {\n ok?: boolean;\n eventId?: string;\n}\n\ninterface RawLogAck {\n ok?: boolean;\n logId?: string;\n}\n\nconst VALID_LOG_LEVELS: readonly TelemetryLogLevel[] = ['debug', 'info', 'warn', 'error', 'fatal'];\n\nfunction consoleFor(level: TelemetryLogLevel): (message?: unknown, ...optional: unknown[]) => void {\n switch (level) {\n case 'debug': return console.debug.bind(console);\n case 'info': return console.info.bind(console);\n case 'warn': return console.warn.bind(console);\n case 'error': return console.error.bind(console);\n case 'fatal': return console.error.bind(console);\n default: return console.log.bind(console);\n }\n}\n\nexport function createTelemetryNamespace(config: ResolvedConfig) {\n return {\n /**\n * Persiste um evento de uso. Lança `NeetruError` em qualquer falha\n * (incluindo rate-limit).\n *\n * @example\n * ```ts\n * await client.telemetry.event({\n * name: 'dashboard_opened',\n * properties: { plan: 'pro', tab: 'overview' },\n * });\n * ```\n */\n async event(input: TelemetryEventInput): Promise<TelemetryEventAck> {\n if (!input || typeof input !== 'object') {\n throw new NeetruError('validation_failed', 'event input is required');\n }\n if (typeof input.name !== 'string' || input.name.length === 0) {\n throw new NeetruError('validation_failed', 'event.name is required');\n }\n if (input.name.length > 128) {\n throw new NeetruError('validation_failed', 'event.name max 128 chars');\n }\n\n const body: Record<string, unknown> = { name: input.name };\n if (input.properties && typeof input.properties === 'object') {\n body.properties = input.properties;\n }\n if (input.timestamp) body.timestamp = input.timestamp;\n\n const raw = await httpRequest<RawTelemetryAck>(config, {\n method: 'POST',\n path: '/api/v1/sdk/telemetry/event',\n body,\n requireAuth: true,\n });\n\n if (!raw || raw.ok !== true || typeof raw.eventId !== 'string') {\n throw new NeetruError('invalid_response', 'Telemetry response missing eventId');\n }\n return { ok: true, eventId: raw.eventId };\n },\n\n /**\n * Registra um log estruturado per-product (Sprint 6).\n *\n * - `NEETRU_ENV=dev`: console.{level}, retorna ack mock.\n * - workspace/prod: HTTP POST com Bearer auth + correlationId no header.\n *\n * @example\n * ```ts\n * await client.telemetry.log({\n * level: 'error',\n * message: 'Falha ao calcular total',\n * metadata: { orderId: 'o-123' },\n * });\n * ```\n */\n async log(input: TelemetryLogInput): Promise<TelemetryLogAck> {\n if (!input || typeof input !== 'object') {\n throw new NeetruError('validation_failed', 'log input is required');\n }\n if (!VALID_LOG_LEVELS.includes(input.level)) {\n throw new NeetruError('validation_failed', `level must be one of ${VALID_LOG_LEVELS.join(', ')}`);\n }\n if (typeof input.message !== 'string' || input.message.length === 0) {\n throw new NeetruError('validation_failed', 'message is required');\n }\n if (input.message.length > 4_000) {\n throw new NeetruError('validation_failed', 'message max 4000 chars');\n }\n\n // Dev mode: console only, no network.\n if (config.env === 'dev') {\n const fn = consoleFor(input.level);\n fn(`[neetru-sdk] ${input.level}: ${input.message}`, input.metadata ?? {});\n return { ok: true, mode: 'mock' };\n }\n\n const body: Record<string, unknown> = {\n level: input.level,\n message: input.message,\n };\n if (input.metadata) body.metadata = input.metadata;\n if (input.productSlug) body.productSlug = input.productSlug;\n\n // CorrelationId: explicit input wins; senão tenta lê de globalThis (set\n // por instrumentação do consumer).\n let cid = input.correlationId;\n if (!cid) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const g = (globalThis as any).NEETRU_CORRELATION_ID;\n if (typeof g === 'string' && g.length > 0) cid = g;\n } catch {\n /* ignore */\n }\n }\n\n const headers: Record<string, string> = {};\n if (cid) headers['x-correlation-id'] = cid;\n\n const raw = await httpRequest<RawLogAck>(config, {\n method: 'POST',\n path: '/sdk/v1/telemetry/log',\n body,\n requireAuth: true,\n headers,\n });\n\n if (!raw || raw.ok !== true) {\n throw new NeetruError('invalid_response', 'Telemetry log response missing ok');\n }\n return {\n ok: true,\n logId: typeof raw.logId === 'string' ? raw.logId : undefined,\n mode: 'http',\n };\n },\n };\n}\n"]}
@@ -0,0 +1,35 @@
1
+ import { R as ResolvedConfig, q as TelemetryEventInput, T as TelemetryEventAck, t as TelemetryLogInput, u as TelemetryLogAck } from './types-PKUaFtBY.cjs';
2
+
3
+ declare function createTelemetryNamespace(config: ResolvedConfig): {
4
+ /**
5
+ * Persiste um evento de uso. Lança `NeetruError` em qualquer falha
6
+ * (incluindo rate-limit).
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * await client.telemetry.event({
11
+ * name: 'dashboard_opened',
12
+ * properties: { plan: 'pro', tab: 'overview' },
13
+ * });
14
+ * ```
15
+ */
16
+ event(input: TelemetryEventInput): Promise<TelemetryEventAck>;
17
+ /**
18
+ * Registra um log estruturado per-product (Sprint 6).
19
+ *
20
+ * - `NEETRU_ENV=dev`: console.{level}, retorna ack mock.
21
+ * - workspace/prod: HTTP POST com Bearer auth + correlationId no header.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * await client.telemetry.log({
26
+ * level: 'error',
27
+ * message: 'Falha ao calcular total',
28
+ * metadata: { orderId: 'o-123' },
29
+ * });
30
+ * ```
31
+ */
32
+ log(input: TelemetryLogInput): Promise<TelemetryLogAck>;
33
+ };
34
+
35
+ export { createTelemetryNamespace };
@@ -0,0 +1,35 @@
1
+ import { R as ResolvedConfig, q as TelemetryEventInput, T as TelemetryEventAck, t as TelemetryLogInput, u as TelemetryLogAck } from './types-PKUaFtBY.js';
2
+
3
+ declare function createTelemetryNamespace(config: ResolvedConfig): {
4
+ /**
5
+ * Persiste um evento de uso. Lança `NeetruError` em qualquer falha
6
+ * (incluindo rate-limit).
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * await client.telemetry.event({
11
+ * name: 'dashboard_opened',
12
+ * properties: { plan: 'pro', tab: 'overview' },
13
+ * });
14
+ * ```
15
+ */
16
+ event(input: TelemetryEventInput): Promise<TelemetryEventAck>;
17
+ /**
18
+ * Registra um log estruturado per-product (Sprint 6).
19
+ *
20
+ * - `NEETRU_ENV=dev`: console.{level}, retorna ack mock.
21
+ * - workspace/prod: HTTP POST com Bearer auth + correlationId no header.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * await client.telemetry.log({
26
+ * level: 'error',
27
+ * message: 'Falha ao calcular total',
28
+ * metadata: { orderId: 'o-123' },
29
+ * });
30
+ * ```
31
+ */
32
+ log(input: TelemetryLogInput): Promise<TelemetryLogAck>;
33
+ };
34
+
35
+ export { createTelemetryNamespace };
@@ -0,0 +1,223 @@
1
+ // src/errors.ts
2
+ var NeetruError = class _NeetruError extends Error {
3
+ code;
4
+ status;
5
+ requestId;
6
+ constructor(code, message, status, requestId) {
7
+ super(message);
8
+ this.name = "NeetruError";
9
+ this.code = code;
10
+ this.status = status;
11
+ this.requestId = requestId;
12
+ Object.setPrototypeOf(this, _NeetruError.prototype);
13
+ }
14
+ };
15
+
16
+ // src/http.ts
17
+ function statusToCode(status) {
18
+ if (status === 401) return "unauthorized";
19
+ if (status === 403) return "forbidden";
20
+ if (status === 404) return "not_found";
21
+ if (status === 422 || status === 400) return "validation_failed";
22
+ if (status === 429) return "rate_limited";
23
+ if (status >= 500) return "server_error";
24
+ return "unknown";
25
+ }
26
+ function buildUrl(baseUrl, path, query) {
27
+ const base = baseUrl.replace(/\/+$/, "");
28
+ const p = path.startsWith("/") ? path : `/${path}`;
29
+ const url = new URL(`${base}${p}`);
30
+ if (query) {
31
+ for (const [k, v] of Object.entries(query)) {
32
+ if (v === void 0) continue;
33
+ url.searchParams.set(k, String(v));
34
+ }
35
+ }
36
+ return url.toString();
37
+ }
38
+ async function safeJson(res) {
39
+ const text = await res.text();
40
+ if (!text) return void 0;
41
+ try {
42
+ return JSON.parse(text);
43
+ } catch {
44
+ return void 0;
45
+ }
46
+ }
47
+ async function httpRequest(config, opts) {
48
+ const method = opts.method ?? "GET";
49
+ const url = buildUrl(config.baseUrl, opts.path, opts.query);
50
+ const headers = {
51
+ accept: "application/json",
52
+ ...opts.headers
53
+ };
54
+ if (opts.requireAuth) {
55
+ if (!config.apiKey) {
56
+ throw new NeetruError(
57
+ "missing_api_key",
58
+ "This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var."
59
+ );
60
+ }
61
+ headers.authorization = `Bearer ${config.apiKey}`;
62
+ }
63
+ const init = { method, headers };
64
+ if (opts.body !== void 0 && method !== "GET" && method !== "DELETE") {
65
+ headers["content-type"] = "application/json";
66
+ init.body = JSON.stringify(opts.body);
67
+ }
68
+ let res;
69
+ try {
70
+ res = await config.fetch(url, init);
71
+ } catch (err) {
72
+ const message = err instanceof Error ? err.message : "fetch failed";
73
+ throw new NeetruError("network_error", `Network error: ${message}`);
74
+ }
75
+ const requestId = res.headers.get("x-request-id") ?? res.headers.get("x-correlation-id") ?? void 0;
76
+ if (!res.ok) {
77
+ const body = await safeJson(res);
78
+ let code = statusToCode(res.status);
79
+ let message = `HTTP ${res.status}`;
80
+ if (body && typeof body === "object" && "error" in body) {
81
+ const errField = body.error;
82
+ if (typeof errField === "string") {
83
+ message = errField;
84
+ } else if (errField && typeof errField === "object") {
85
+ if (typeof errField.code === "string") code = errField.code;
86
+ if (typeof errField.message === "string") message = errField.message;
87
+ }
88
+ }
89
+ throw new NeetruError(code, message, res.status, requestId);
90
+ }
91
+ const parsed = await safeJson(res);
92
+ return parsed;
93
+ }
94
+
95
+ // src/telemetry.ts
96
+ var VALID_LOG_LEVELS = ["debug", "info", "warn", "error", "fatal"];
97
+ function consoleFor(level) {
98
+ switch (level) {
99
+ case "debug":
100
+ return console.debug.bind(console);
101
+ case "info":
102
+ return console.info.bind(console);
103
+ case "warn":
104
+ return console.warn.bind(console);
105
+ case "error":
106
+ return console.error.bind(console);
107
+ case "fatal":
108
+ return console.error.bind(console);
109
+ default:
110
+ return console.log.bind(console);
111
+ }
112
+ }
113
+ function createTelemetryNamespace(config) {
114
+ return {
115
+ /**
116
+ * Persiste um evento de uso. Lança `NeetruError` em qualquer falha
117
+ * (incluindo rate-limit).
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * await client.telemetry.event({
122
+ * name: 'dashboard_opened',
123
+ * properties: { plan: 'pro', tab: 'overview' },
124
+ * });
125
+ * ```
126
+ */
127
+ async event(input) {
128
+ if (!input || typeof input !== "object") {
129
+ throw new NeetruError("validation_failed", "event input is required");
130
+ }
131
+ if (typeof input.name !== "string" || input.name.length === 0) {
132
+ throw new NeetruError("validation_failed", "event.name is required");
133
+ }
134
+ if (input.name.length > 128) {
135
+ throw new NeetruError("validation_failed", "event.name max 128 chars");
136
+ }
137
+ const body = { name: input.name };
138
+ if (input.properties && typeof input.properties === "object") {
139
+ body.properties = input.properties;
140
+ }
141
+ if (input.timestamp) body.timestamp = input.timestamp;
142
+ const raw = await httpRequest(config, {
143
+ method: "POST",
144
+ path: "/api/v1/sdk/telemetry/event",
145
+ body,
146
+ requireAuth: true
147
+ });
148
+ if (!raw || raw.ok !== true || typeof raw.eventId !== "string") {
149
+ throw new NeetruError("invalid_response", "Telemetry response missing eventId");
150
+ }
151
+ return { ok: true, eventId: raw.eventId };
152
+ },
153
+ /**
154
+ * Registra um log estruturado per-product (Sprint 6).
155
+ *
156
+ * - `NEETRU_ENV=dev`: console.{level}, retorna ack mock.
157
+ * - workspace/prod: HTTP POST com Bearer auth + correlationId no header.
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * await client.telemetry.log({
162
+ * level: 'error',
163
+ * message: 'Falha ao calcular total',
164
+ * metadata: { orderId: 'o-123' },
165
+ * });
166
+ * ```
167
+ */
168
+ async log(input) {
169
+ if (!input || typeof input !== "object") {
170
+ throw new NeetruError("validation_failed", "log input is required");
171
+ }
172
+ if (!VALID_LOG_LEVELS.includes(input.level)) {
173
+ throw new NeetruError("validation_failed", `level must be one of ${VALID_LOG_LEVELS.join(", ")}`);
174
+ }
175
+ if (typeof input.message !== "string" || input.message.length === 0) {
176
+ throw new NeetruError("validation_failed", "message is required");
177
+ }
178
+ if (input.message.length > 4e3) {
179
+ throw new NeetruError("validation_failed", "message max 4000 chars");
180
+ }
181
+ if (config.env === "dev") {
182
+ const fn = consoleFor(input.level);
183
+ fn(`[neetru-sdk] ${input.level}: ${input.message}`, input.metadata ?? {});
184
+ return { ok: true, mode: "mock" };
185
+ }
186
+ const body = {
187
+ level: input.level,
188
+ message: input.message
189
+ };
190
+ if (input.metadata) body.metadata = input.metadata;
191
+ if (input.productSlug) body.productSlug = input.productSlug;
192
+ let cid = input.correlationId;
193
+ if (!cid) {
194
+ try {
195
+ const g = globalThis.NEETRU_CORRELATION_ID;
196
+ if (typeof g === "string" && g.length > 0) cid = g;
197
+ } catch {
198
+ }
199
+ }
200
+ const headers = {};
201
+ if (cid) headers["x-correlation-id"] = cid;
202
+ const raw = await httpRequest(config, {
203
+ method: "POST",
204
+ path: "/sdk/v1/telemetry/log",
205
+ body,
206
+ requireAuth: true,
207
+ headers
208
+ });
209
+ if (!raw || raw.ok !== true) {
210
+ throw new NeetruError("invalid_response", "Telemetry log response missing ok");
211
+ }
212
+ return {
213
+ ok: true,
214
+ logId: typeof raw.logId === "string" ? raw.logId : void 0,
215
+ mode: "http"
216
+ };
217
+ }
218
+ };
219
+ }
220
+
221
+ export { createTelemetryNamespace };
222
+ //# sourceMappingURL=telemetry.mjs.map
223
+ //# sourceMappingURL=telemetry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/telemetry.ts"],"names":[],"mappings":"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","file":"telemetry.mjs","sourcesContent":["/**\n * Erros tipados do SDK.\n *\n * Todo erro lançado pelo SDK estende `NeetruError` — caller pode discriminar\n * por `.code` (string estável) sem parsing de message.\n */\n\n/** Códigos de erro estáveis do SDK. Adicionar aqui requer minor bump. */\nexport type NeetruErrorCode =\n | 'invalid_config'\n | 'missing_api_key'\n | 'unauthorized'\n | 'forbidden'\n | 'not_found'\n | 'rate_limited'\n | 'validation_failed'\n | 'network_error'\n | 'invalid_response'\n | 'server_error'\n | 'unknown';\n\n/**\n * Erro tipado padrão do SDK. Sempre lançado em vez de Error genérico.\n *\n * @example\n * ```ts\n * try { await client.catalog.list(); }\n * catch (e) {\n * if (e instanceof NeetruError && e.code === 'rate_limited') retry();\n * }\n * ```\n */\nexport class NeetruError extends Error {\n public readonly code: NeetruErrorCode | string;\n public readonly status?: number;\n public readonly requestId?: string;\n\n constructor(\n code: NeetruErrorCode | string,\n message: string,\n status?: number,\n requestId?: string,\n ) {\n super(message);\n this.name = 'NeetruError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n // Preserva o prototype chain ao herdar de Error (downlevel quirk de TS).\n Object.setPrototypeOf(this, NeetruError.prototype);\n }\n}\n","/**\n * HTTP transport interno do SDK.\n *\n * Responsabilidades:\n * - Construir URL absoluta a partir de `baseUrl` + path\n * - Injetar Bearer token quando `requireAuth=true`\n * - Mapear status HTTP → `NeetruError` com `code` estável\n * - Parse defensivo de JSON (não lança em body vazio em 204)\n *\n * Não faz retry/backoff em v0.1 (carry-over Sprint 3+).\n */\nimport { NeetruError, type NeetruErrorCode } from './errors';\nimport type { ResolvedConfig } from './types';\n\n/** Opções da request HTTP. */\nexport interface HttpRequestOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n /** Path relativo (ex: `/api/v1/cli/catalog`). Concatenado a `baseUrl`. */\n path: string;\n /** Query string params (chave → valor primitivo). Valores `undefined` ignorados. */\n query?: Record<string, string | number | boolean | undefined>;\n /** Body JSON-serializável. Ignorado em GET/DELETE. */\n body?: unknown;\n /**\n * Se true, injeta `Authorization: Bearer <apiKey>`. Lança `missing_api_key`\n * se config.apiKey ausente. Default false.\n */\n requireAuth?: boolean;\n /** Cabeçalhos extras. */\n headers?: Record<string, string>;\n}\n\n/** Mapeamento status → code estável do NeetruError. */\nfunction statusToCode(status: number): NeetruErrorCode {\n if (status === 401) return 'unauthorized';\n if (status === 403) return 'forbidden';\n if (status === 404) return 'not_found';\n if (status === 422 || status === 400) return 'validation_failed';\n if (status === 429) return 'rate_limited';\n if (status >= 500) return 'server_error';\n return 'unknown';\n}\n\nfunction buildUrl(baseUrl: string, path: string, query?: HttpRequestOptions['query']): string {\n // Trim trailing slash em base e leading em path pra evitar `//`.\n const base = baseUrl.replace(/\\/+$/, '');\n const p = path.startsWith('/') ? path : `/${path}`;\n const url = new URL(`${base}${p}`);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v === undefined) continue;\n url.searchParams.set(k, String(v));\n }\n }\n return url.toString();\n}\n\n/** Parse JSON defensivo — retorna `undefined` em body vazio. */\nasync function safeJson(res: Response): Promise<unknown> {\n const text = await res.text();\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Executa request HTTP. Em sucesso retorna body parseado; em erro lança\n * `NeetruError` com `code` derivado do status.\n */\nexport async function httpRequest<T>(\n config: ResolvedConfig,\n opts: HttpRequestOptions,\n): Promise<T> {\n const method = opts.method ?? 'GET';\n const url = buildUrl(config.baseUrl, opts.path, opts.query);\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...opts.headers,\n };\n\n if (opts.requireAuth) {\n if (!config.apiKey) {\n throw new NeetruError(\n 'missing_api_key',\n 'This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var.',\n );\n }\n headers.authorization = `Bearer ${config.apiKey}`;\n }\n\n const init: RequestInit = { method, headers };\n if (opts.body !== undefined && method !== 'GET' && method !== 'DELETE') {\n headers['content-type'] = 'application/json';\n init.body = JSON.stringify(opts.body);\n }\n\n let res: Response;\n try {\n res = await config.fetch(url, init);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'fetch failed';\n throw new NeetruError('network_error', `Network error: ${message}`);\n }\n\n const requestId = res.headers.get('x-request-id') ?? res.headers.get('x-correlation-id') ?? undefined;\n\n if (!res.ok) {\n const body = (await safeJson(res)) as { error?: { code?: string; message?: string } | string } | undefined;\n let code: string = statusToCode(res.status);\n let message = `HTTP ${res.status}`;\n if (body && typeof body === 'object' && 'error' in body) {\n const errField = body.error;\n if (typeof errField === 'string') {\n message = errField;\n } else if (errField && typeof errField === 'object') {\n if (typeof errField.code === 'string') code = errField.code;\n if (typeof errField.message === 'string') message = errField.message;\n }\n }\n throw new NeetruError(code, message, res.status, requestId);\n }\n\n const parsed = await safeJson(res);\n // Caller é responsável por validar shape; SDK assume backend correto.\n return parsed as T;\n}\n","/**\n * Telemetria — emite eventos do produto cliente pro Core.\n *\n * Endpoint legacy `event()`:\n * `POST /api/v1/sdk/telemetry/event` — persiste em `usage_events/{id}`.\n *\n * Sprint 6 — `log()`:\n * - Em `NEETRU_ENV=dev`: console.{level} apenas (sem network).\n * - Em `workspace`/`prod`: `POST /sdk/v1/telemetry/log` com Bearer +\n * correlationId injetado.\n *\n * v0.1 sem batching — cada chamada é uma request.\n */\nimport { NeetruError } from './errors';\nimport { httpRequest } from './http';\nimport type {\n ResolvedConfig,\n TelemetryEventAck,\n TelemetryEventInput,\n TelemetryLogAck,\n TelemetryLogInput,\n TelemetryLogLevel,\n} from './types';\n\ninterface RawTelemetryAck {\n ok?: boolean;\n eventId?: string;\n}\n\ninterface RawLogAck {\n ok?: boolean;\n logId?: string;\n}\n\nconst VALID_LOG_LEVELS: readonly TelemetryLogLevel[] = ['debug', 'info', 'warn', 'error', 'fatal'];\n\nfunction consoleFor(level: TelemetryLogLevel): (message?: unknown, ...optional: unknown[]) => void {\n switch (level) {\n case 'debug': return console.debug.bind(console);\n case 'info': return console.info.bind(console);\n case 'warn': return console.warn.bind(console);\n case 'error': return console.error.bind(console);\n case 'fatal': return console.error.bind(console);\n default: return console.log.bind(console);\n }\n}\n\nexport function createTelemetryNamespace(config: ResolvedConfig) {\n return {\n /**\n * Persiste um evento de uso. Lança `NeetruError` em qualquer falha\n * (incluindo rate-limit).\n *\n * @example\n * ```ts\n * await client.telemetry.event({\n * name: 'dashboard_opened',\n * properties: { plan: 'pro', tab: 'overview' },\n * });\n * ```\n */\n async event(input: TelemetryEventInput): Promise<TelemetryEventAck> {\n if (!input || typeof input !== 'object') {\n throw new NeetruError('validation_failed', 'event input is required');\n }\n if (typeof input.name !== 'string' || input.name.length === 0) {\n throw new NeetruError('validation_failed', 'event.name is required');\n }\n if (input.name.length > 128) {\n throw new NeetruError('validation_failed', 'event.name max 128 chars');\n }\n\n const body: Record<string, unknown> = { name: input.name };\n if (input.properties && typeof input.properties === 'object') {\n body.properties = input.properties;\n }\n if (input.timestamp) body.timestamp = input.timestamp;\n\n const raw = await httpRequest<RawTelemetryAck>(config, {\n method: 'POST',\n path: '/api/v1/sdk/telemetry/event',\n body,\n requireAuth: true,\n });\n\n if (!raw || raw.ok !== true || typeof raw.eventId !== 'string') {\n throw new NeetruError('invalid_response', 'Telemetry response missing eventId');\n }\n return { ok: true, eventId: raw.eventId };\n },\n\n /**\n * Registra um log estruturado per-product (Sprint 6).\n *\n * - `NEETRU_ENV=dev`: console.{level}, retorna ack mock.\n * - workspace/prod: HTTP POST com Bearer auth + correlationId no header.\n *\n * @example\n * ```ts\n * await client.telemetry.log({\n * level: 'error',\n * message: 'Falha ao calcular total',\n * metadata: { orderId: 'o-123' },\n * });\n * ```\n */\n async log(input: TelemetryLogInput): Promise<TelemetryLogAck> {\n if (!input || typeof input !== 'object') {\n throw new NeetruError('validation_failed', 'log input is required');\n }\n if (!VALID_LOG_LEVELS.includes(input.level)) {\n throw new NeetruError('validation_failed', `level must be one of ${VALID_LOG_LEVELS.join(', ')}`);\n }\n if (typeof input.message !== 'string' || input.message.length === 0) {\n throw new NeetruError('validation_failed', 'message is required');\n }\n if (input.message.length > 4_000) {\n throw new NeetruError('validation_failed', 'message max 4000 chars');\n }\n\n // Dev mode: console only, no network.\n if (config.env === 'dev') {\n const fn = consoleFor(input.level);\n fn(`[neetru-sdk] ${input.level}: ${input.message}`, input.metadata ?? {});\n return { ok: true, mode: 'mock' };\n }\n\n const body: Record<string, unknown> = {\n level: input.level,\n message: input.message,\n };\n if (input.metadata) body.metadata = input.metadata;\n if (input.productSlug) body.productSlug = input.productSlug;\n\n // CorrelationId: explicit input wins; senão tenta lê de globalThis (set\n // por instrumentação do consumer).\n let cid = input.correlationId;\n if (!cid) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const g = (globalThis as any).NEETRU_CORRELATION_ID;\n if (typeof g === 'string' && g.length > 0) cid = g;\n } catch {\n /* ignore */\n }\n }\n\n const headers: Record<string, string> = {};\n if (cid) headers['x-correlation-id'] = cid;\n\n const raw = await httpRequest<RawLogAck>(config, {\n method: 'POST',\n path: '/sdk/v1/telemetry/log',\n body,\n requireAuth: true,\n headers,\n });\n\n if (!raw || raw.ok !== true) {\n throw new NeetruError('invalid_response', 'Telemetry log response missing ok');\n }\n return {\n ok: true,\n logId: typeof raw.logId === 'string' ? raw.logId : undefined,\n mode: 'http',\n };\n },\n };\n}\n"]}