@neetru/sdk 1.1.0 → 1.2.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.
- package/CHANGELOG.md +33 -3
- package/README.md +135 -159
- package/dist/auth.cjs +486 -40
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +486 -40
- package/dist/auth.mjs.map +1 -1
- package/dist/catalog.cjs +64 -21
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +2 -2
- package/dist/catalog.d.ts +2 -2
- package/dist/catalog.mjs +64 -21
- package/dist/catalog.mjs.map +1 -1
- package/dist/checkout.cjs +61 -15
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +61 -15
- package/dist/checkout.mjs.map +1 -1
- package/dist/db.cjs +67 -22
- package/dist/db.cjs.map +1 -1
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +67 -22
- package/dist/db.mjs.map +1 -1
- package/dist/entitlements.cjs +102 -21
- package/dist/entitlements.cjs.map +1 -1
- package/dist/entitlements.d.cts +11 -5
- package/dist/entitlements.d.ts +11 -5
- package/dist/entitlements.mjs +102 -21
- package/dist/entitlements.mjs.map +1 -1
- package/dist/index.cjs +491 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +488 -42
- package/dist/index.mjs.map +1 -1
- package/dist/mocks.cjs +3 -2
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.cts +4 -2
- package/dist/mocks.d.ts +4 -2
- package/dist/mocks.mjs +3 -2
- package/dist/mocks.mjs.map +1 -1
- package/dist/notifications.cjs +296 -0
- package/dist/notifications.cjs.map +1 -0
- package/dist/notifications.d.cts +1 -0
- package/dist/notifications.d.ts +1 -0
- package/dist/notifications.mjs +293 -0
- package/dist/notifications.mjs.map +1 -0
- package/dist/react.cjs +7 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +7 -3
- package/dist/react.mjs.map +1 -1
- package/dist/support.cjs +61 -15
- package/dist/support.cjs.map +1 -1
- package/dist/support.d.cts +1 -1
- package/dist/support.d.ts +1 -1
- package/dist/support.mjs +61 -15
- package/dist/support.mjs.map +1 -1
- package/dist/telemetry.cjs +131 -16
- package/dist/telemetry.cjs.map +1 -1
- package/dist/telemetry.d.cts +17 -1
- package/dist/telemetry.d.ts +17 -1
- package/dist/telemetry.mjs +131 -16
- package/dist/telemetry.mjs.map +1 -1
- package/dist/{types-BA53dd8S.d.cts → types-CQAfwqUS.d.cts} +172 -8
- package/dist/{types-BA53dd8S.d.ts → types-CQAfwqUS.d.ts} +172 -8
- package/dist/usage.cjs +61 -15
- package/dist/usage.cjs.map +1 -1
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +61 -15
- package/dist/usage.mjs.map +1 -1
- package/dist/webhooks.cjs +316 -0
- package/dist/webhooks.cjs.map +1 -0
- package/dist/webhooks.d.cts +1 -0
- package/dist/webhooks.d.ts +1 -0
- package/dist/webhooks.mjs +312 -0
- package/dist/webhooks.mjs.map +1 -0
- package/package.json +22 -6
package/dist/mocks.cjs
CHANGED
|
@@ -135,14 +135,14 @@ var MockUsage = class {
|
|
|
135
135
|
this._counters.clear();
|
|
136
136
|
}
|
|
137
137
|
};
|
|
138
|
-
var mockTicketSeq = 0;
|
|
139
138
|
var MockSupport = class {
|
|
140
139
|
_tickets = [];
|
|
140
|
+
_ticketSeq = 0;
|
|
141
141
|
async createTicket(input) {
|
|
142
142
|
if (!input?.subject) throw new Error("subject required");
|
|
143
143
|
if (!input?.message) throw new Error("message required");
|
|
144
144
|
const ticket = {
|
|
145
|
-
id: `mock-ticket-${++
|
|
145
|
+
id: `mock-ticket-${++this._ticketSeq}`,
|
|
146
146
|
subject: input.subject,
|
|
147
147
|
message: input.message,
|
|
148
148
|
severity: input.severity ?? "normal",
|
|
@@ -159,6 +159,7 @@ var MockSupport = class {
|
|
|
159
159
|
/** Test helper. */
|
|
160
160
|
__reset() {
|
|
161
161
|
this._tickets = [];
|
|
162
|
+
this._ticketSeq = 0;
|
|
162
163
|
}
|
|
163
164
|
};
|
|
164
165
|
var MockEntitlements = class {
|
package/dist/mocks.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mocks.ts"],"names":[],"mappings":"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","file":"mocks.cjs","sourcesContent":["/**\n * Mocks determinísticos do SDK — overridáveis em tests do consumer ou\n * ativados automaticamente quando `NEETRU_ENV=dev`.\n *\n * Nada aqui faz I/O. Tudo é puro/sincrono/in-memory. Compat total com\n * runtimes browser/Node/Edge — sem `node:` builtins.\n *\n * Cada mock implementa o mesmo namespace interface das implementações reais\n * (`AuthNamespace`, `UsageNamespace`, `SupportNamespace`) — caller pode\n * substituir 1:1 sem branching.\n *\n * @example\n * ```ts\n * import { createNeetruClient, MockAuth } from '@neetru/sdk';\n *\n * const client = createNeetruClient({\n * mocks: { auth: new MockAuth({ uid: 'fake-user', email: 'x@x.com' }) },\n * });\n * ```\n */\n\nimport type {\n AuthNamespace,\n AuthStateListener,\n CreateTicketInput,\n DbCollectionRef,\n DbListOptions,\n DbNamespace,\n DbWhereFilter,\n EntitlementCheck,\n NeetruUser,\n SignInOptions,\n SupportNamespace,\n SupportTicket,\n UsageNamespace,\n UsageQuota,\n} from './types';\n\n// ─── User fixture default ──────────────────────────────────────────────────\n\n/**\n * User fixture determinístico — usado quando `NEETRU_ENV=dev` e nenhum mock\n * custom é injetado. Email/uid estáveis pra snapshot tests.\n */\nexport const DEV_FIXTURE_USER: NeetruUser = Object.freeze({\n uid: 'dev-fixture-uid-0001',\n email: 'dev@neetru.local',\n emailVerified: true,\n displayName: 'Dev Fixture',\n isCustomer: true,\n isStaff: false,\n}) as NeetruUser;\n\n// ─── MockAuth ──────────────────────────────────────────────────────────────\n\n/**\n * Implementação in-memory do `AuthNamespace`. signIn marca o user como\n * logado; signOut limpa. onAuthStateChanged dispara callback síncrono no\n * subscribe + a cada mudança.\n */\nexport class MockAuth implements AuthNamespace {\n private _user: NeetruUser | null;\n private _listeners: Set<AuthStateListener>;\n\n constructor(initialUser: NeetruUser | null = null) {\n this._user = initialUser;\n this._listeners = new Set();\n }\n\n async signIn(_options?: SignInOptions): Promise<NeetruUser> {\n // Mock: apenas marca user como logado (usa fixture se não havia).\n if (!this._user) this._user = { ...DEV_FIXTURE_USER };\n this._notify();\n return this._user;\n }\n\n async signOut(): Promise<void> {\n this._user = null;\n this._notify();\n }\n\n getUser(): NeetruUser | null {\n return this._user;\n }\n\n onAuthStateChanged(listener: AuthStateListener): () => void {\n this._listeners.add(listener);\n // Dispara imediatamente com estado atual (espelha API Firebase Auth).\n try {\n listener(this._user);\n } catch {\n // Callback do consumer não pode quebrar o subscribe.\n }\n return () => {\n this._listeners.delete(listener);\n };\n }\n\n /** Helper de tests — força um user state arbitrário. */\n __setUser(user: NeetruUser | null): void {\n this._user = user;\n this._notify();\n }\n\n private _notify(): void {\n for (const l of this._listeners) {\n try {\n l(this._user);\n } catch {\n // ignore consumer errors\n }\n }\n }\n}\n\n// ─── MockUsage ─────────────────────────────────────────────────────────────\n\ninterface UsageRecord {\n event: string;\n properties?: Record<string, string | number | boolean | null>;\n timestamp: string;\n}\n\n/**\n * In-memory `UsageNamespace`. `track()` apenas acumula no array\n * `__getRecords()` (útil pra asserts em test). `getQuota()` retorna fixture\n * com `used = trackedCount` da metric.\n */\nexport class MockUsage implements UsageNamespace {\n private _records: UsageRecord[] = [];\n private _quotas: Map<string, UsageQuota>;\n /** v0.3 — counters in-memory pra `report()` / `check()`. */\n private _counters: Map<string, number> = new Map();\n\n constructor(initialQuotas: Record<string, UsageQuota> = {}) {\n this._quotas = new Map(Object.entries(initialQuotas));\n }\n\n async track(\n event: string,\n properties?: Record<string, string | number | boolean | null>,\n ): Promise<{ ok: true }> {\n this._records.push({\n event,\n properties,\n timestamp: new Date().toISOString(),\n });\n return { ok: true };\n }\n\n async getQuota(metric: string): Promise<UsageQuota> {\n const existing = this._quotas.get(metric);\n if (existing) return existing;\n return {\n metric,\n used: this._records.filter((r) => r.event === metric).length,\n limit: -1, // unlimited em mock por default\n plan: 'mock',\n };\n }\n\n /** v0.3 — Mock report incrementa o counter local. */\n async report(\n resource: string,\n qty: number = 1,\n _options?: { productId?: string; tenantId?: string },\n ): Promise<{\n ok: true;\n counterId?: string;\n value?: number;\n limit?: number;\n remaining?: number;\n status?: string;\n }> {\n if (!resource) throw new Error('resource required');\n const safeQty = Number.isFinite(qty) && qty > 0 ? Math.floor(qty) : 1;\n const existing = this._counters.get(resource) ?? 0;\n const next = existing + safeQty;\n this._counters.set(resource, next);\n const limitFixture = this._quotas.get(resource);\n const limit = limitFixture?.limit ?? -1;\n return {\n ok: true,\n counterId: `mock_${resource}`,\n value: next,\n limit,\n remaining: limit < 0 ? -1 : Math.max(0, limit - next),\n status: limit > 0 && next >= limit ? 'read_only_overlimit' : 'ok',\n };\n }\n\n /** v0.3 — Mock check usa quotas + counters in-memory. */\n async check(\n resource: string,\n _options?: { productId?: string; tenantId?: string },\n ): Promise<{\n allowed: boolean;\n reason?: string;\n remaining?: number;\n limit?: number;\n planId?: string | null;\n planFeatures?: string[];\n }> {\n const quota = this._quotas.get(resource);\n const used = this._counters.get(resource) ?? 0;\n if (!quota) {\n return { allowed: true, reason: 'granted', limit: -1, remaining: -1 };\n }\n const remaining = quota.limit < 0 ? -1 : Math.max(0, quota.limit - used);\n if (remaining === 0) {\n return {\n allowed: false,\n reason: 'limit_exceeded',\n limit: quota.limit,\n remaining: 0,\n };\n }\n return {\n allowed: true,\n reason: 'granted',\n limit: quota.limit,\n remaining,\n };\n }\n\n /** Test helper. */\n __getRecords(): readonly UsageRecord[] {\n return [...this._records];\n }\n /** Test helper — substitui quota fixture. */\n __setQuota(metric: string, quota: UsageQuota): void {\n this._quotas.set(metric, quota);\n }\n /** Test helper — limpa estado. */\n __reset(): void {\n this._records = [];\n this._quotas.clear();\n this._counters.clear();\n }\n}\n\n// ─── MockSupport ───────────────────────────────────────────────────────────\n\nlet mockTicketSeq = 0;\n\n/**\n * In-memory `SupportNamespace`. createTicket gera ID `mock-ticket-{n}`;\n * listMyTickets retorna todos criados (FIFO).\n */\nexport class MockSupport implements SupportNamespace {\n private _tickets: SupportTicket[] = [];\n\n async createTicket(input: CreateTicketInput): Promise<SupportTicket> {\n if (!input?.subject) throw new Error('subject required');\n if (!input?.message) throw new Error('message required');\n const ticket: SupportTicket = {\n id: `mock-ticket-${++mockTicketSeq}`,\n subject: input.subject,\n message: input.message,\n severity: input.severity ?? 'normal',\n status: 'open',\n createdAt: new Date().toISOString(),\n productSlug: input.productSlug,\n };\n this._tickets.push(ticket);\n return ticket;\n }\n\n async listMyTickets(): Promise<SupportTicket[]> {\n return [...this._tickets];\n }\n\n /** Test helper. */\n __reset(): void {\n this._tickets = [];\n }\n}\n\n// ─── MockEntitlements ──────────────────────────────────────────────────────\n\n/**\n * In-memory entitlements. Por default `allowed=true` em tudo (dev convém).\n * Use `__deny(slug, feature)` em tests pra simular bloqueio.\n */\nexport class MockEntitlements {\n private _denied: Set<string> = new Set();\n\n async check(productSlug: string, feature: string): Promise<boolean> {\n return !this._denied.has(`${productSlug}:${feature}`);\n }\n\n async checkDetailed(productSlug: string, feature: string): Promise<EntitlementCheck> {\n const allowed = await this.check(productSlug, feature);\n return {\n allowed,\n productSlug,\n feature,\n reason: allowed ? 'granted' : 'mock_denied',\n };\n }\n\n /** Test helper. */\n __deny(productSlug: string, feature: string): void {\n this._denied.add(`${productSlug}:${feature}`);\n }\n /** Test helper. */\n __reset(): void {\n this._denied.clear();\n }\n}\n\n// ─── MockDb (v0.3) ─────────────────────────────────────────────────────────\n\n/**\n * In-memory `DbNamespace`. Cada `collection(name)` aponta para um Map; ops\n * são totalmente síncronas (mas API await-friendly).\n *\n * Útil para testar produtos consumidores sem rodar Core REST.\n */\nexport class MockDb implements DbNamespace {\n private _store: Map<string, Map<string, Record<string, unknown>>> = new Map();\n private _fixtures: Map<string, Record<string, Record<string, unknown>>>;\n\n constructor(initialFixtures: Record<string, Record<string, Record<string, unknown>>> = {}) {\n this._fixtures = new Map(Object.entries(initialFixtures));\n }\n\n collection(name: string): DbCollectionRef {\n const _store = this._store;\n const _fixtures = this._fixtures;\n if (!_store.has(name)) {\n const init = _fixtures.get(name);\n _store.set(\n name,\n init ? new Map(Object.entries(init)) : new Map(),\n );\n }\n const coll = _store.get(name)!;\n\n const matchesFilter = (\n doc: Record<string, unknown>,\n f: DbWhereFilter,\n ): boolean => {\n const v = doc[f.field];\n switch (f.op) {\n case '==':\n return v === f.value;\n case '!=':\n return v !== f.value;\n case '<':\n return typeof v === 'number' && typeof f.value === 'number' && v < f.value;\n case '<=':\n return typeof v === 'number' && typeof f.value === 'number' && v <= f.value;\n case '>':\n return typeof v === 'number' && typeof f.value === 'number' && v > f.value;\n case '>=':\n return typeof v === 'number' && typeof f.value === 'number' && v >= f.value;\n case 'in':\n return Array.isArray(f.value) && (f.value as unknown[]).includes(v);\n default:\n return true;\n }\n };\n\n let autoSeq = 0;\n\n return {\n async list<T = Record<string, unknown>>(opts?: DbListOptions): Promise<T[]> {\n let items = Array.from(coll.values());\n if (opts?.where && opts.where.length > 0) {\n items = items.filter((doc) =>\n (opts.where as DbWhereFilter[]).every((f) => matchesFilter(doc, f)),\n );\n }\n if (opts?.limit !== undefined) items = items.slice(0, opts.limit);\n return items as T[];\n },\n async get<T = Record<string, unknown>>(id: string): Promise<T | null> {\n return (coll.get(id) as T | undefined) ?? null;\n },\n async add(data: Record<string, unknown>): Promise<{ ok: true; id: string }> {\n const id = `mock-${++autoSeq}-${Math.random().toString(36).slice(2, 8)}`;\n coll.set(id, { ...data, id });\n return { ok: true, id };\n },\n async set(id: string, data: Record<string, unknown>): Promise<{ ok: true }> {\n coll.set(id, { ...data, id });\n return { ok: true };\n },\n async update(id: string, data: Record<string, unknown>): Promise<{ ok: true }> {\n const cur = coll.get(id);\n if (!cur) {\n // mock-friendly: cria se não existir (mimic Firestore set merge).\n coll.set(id, { ...data, id });\n } else {\n coll.set(id, { ...cur, ...data });\n }\n return { ok: true };\n },\n async remove(id: string): Promise<{ ok: true }> {\n coll.delete(id);\n return { ok: true };\n },\n };\n }\n\n /** Test helper — substitui fixture inteira de uma collection. */\n __setFixture(name: string, items: Record<string, Record<string, unknown>>): void {\n this._store.set(name, new Map(Object.entries(items)));\n }\n\n /** Test helper — reset total. */\n __reset(): void {\n this._store.clear();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/mocks.ts"],"names":[],"mappings":"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","file":"mocks.cjs","sourcesContent":["/**\n * Mocks determinísticos do SDK — overridáveis em tests do consumer ou\n * ativados automaticamente quando `NEETRU_ENV=dev`.\n *\n * Nada aqui faz I/O. Tudo é puro/sincrono/in-memory. Compat total com\n * runtimes browser/Node/Edge — sem `node:` builtins.\n *\n * Cada mock implementa o mesmo namespace interface das implementações reais\n * (`AuthNamespace`, `UsageNamespace`, `SupportNamespace`) — caller pode\n * substituir 1:1 sem branching.\n *\n * @example\n * ```ts\n * import { createNeetruClient, MockAuth } from '@neetru/sdk';\n *\n * const client = createNeetruClient({\n * mocks: { auth: new MockAuth({ uid: 'fake-user', email: 'x@x.com' }) },\n * });\n * ```\n */\n\nimport type {\n AuthNamespace,\n AuthStateListener,\n CreateTicketInput,\n DbCollectionRef,\n DbListOptions,\n DbNamespace,\n DbWhereFilter,\n EntitlementCheck,\n NeetruUser,\n SignInOptions,\n SupportNamespace,\n SupportTicket,\n UsageNamespace,\n UsageQuota,\n} from './types';\n\n// ─── User fixture default ──────────────────────────────────────────────────\n\n/**\n * User fixture determinístico — usado quando `NEETRU_ENV=dev` e nenhum mock\n * custom é injetado. Email/uid estáveis pra snapshot tests.\n */\nexport const DEV_FIXTURE_USER: NeetruUser = Object.freeze({\n uid: 'dev-fixture-uid-0001',\n email: 'dev@neetru.local',\n emailVerified: true,\n displayName: 'Dev Fixture',\n isCustomer: true,\n isStaff: false,\n}) as NeetruUser;\n\n// ─── MockAuth ──────────────────────────────────────────────────────────────\n\n/**\n * Implementação in-memory do `AuthNamespace`. signIn marca o user como\n * logado; signOut limpa. onAuthStateChanged dispara callback síncrono no\n * subscribe + a cada mudança.\n */\nexport class MockAuth implements AuthNamespace {\n private _user: NeetruUser | null;\n private _listeners: Set<AuthStateListener>;\n\n constructor(initialUser: NeetruUser | null = null) {\n this._user = initialUser;\n this._listeners = new Set();\n }\n\n async signIn(_options?: SignInOptions): Promise<NeetruUser> {\n // Mock: apenas marca user como logado (usa fixture se não havia).\n if (!this._user) this._user = { ...DEV_FIXTURE_USER };\n this._notify();\n return this._user;\n }\n\n async signOut(): Promise<void> {\n this._user = null;\n this._notify();\n }\n\n getUser(): NeetruUser | null {\n return this._user;\n }\n\n onAuthStateChanged(listener: AuthStateListener): () => void {\n this._listeners.add(listener);\n // Dispara imediatamente com estado atual (espelha API Firebase Auth).\n try {\n listener(this._user);\n } catch {\n // Callback do consumer não pode quebrar o subscribe.\n }\n return () => {\n this._listeners.delete(listener);\n };\n }\n\n /** Helper de tests — força um user state arbitrário. */\n __setUser(user: NeetruUser | null): void {\n this._user = user;\n this._notify();\n }\n\n private _notify(): void {\n for (const l of this._listeners) {\n try {\n l(this._user);\n } catch {\n // ignore consumer errors\n }\n }\n }\n}\n\n// ─── MockUsage ─────────────────────────────────────────────────────────────\n\ninterface UsageRecord {\n event: string;\n properties?: Record<string, string | number | boolean | null>;\n timestamp: string;\n}\n\n/**\n * In-memory `UsageNamespace`. `track()` apenas acumula no array\n * `__getRecords()` (útil pra asserts em test). `getQuota()` retorna fixture\n * com `used = trackedCount` da metric.\n */\nexport class MockUsage implements UsageNamespace {\n private _records: UsageRecord[] = [];\n private _quotas: Map<string, UsageQuota>;\n /** v0.3 — counters in-memory pra `report()` / `check()`. */\n private _counters: Map<string, number> = new Map();\n\n constructor(initialQuotas: Record<string, UsageQuota> = {}) {\n this._quotas = new Map(Object.entries(initialQuotas));\n }\n\n async track(\n event: string,\n properties?: Record<string, string | number | boolean | null>,\n ): Promise<{ ok: true }> {\n this._records.push({\n event,\n properties,\n timestamp: new Date().toISOString(),\n });\n return { ok: true };\n }\n\n async getQuota(metric: string): Promise<UsageQuota> {\n const existing = this._quotas.get(metric);\n if (existing) return existing;\n return {\n metric,\n used: this._records.filter((r) => r.event === metric).length,\n limit: -1, // unlimited em mock por default\n plan: 'mock',\n };\n }\n\n /** v0.3 — Mock report incrementa o counter local. */\n async report(\n resource: string,\n qty: number = 1,\n _options?: { productId?: string; tenantId?: string },\n ): Promise<{\n ok: true;\n counterId?: string;\n value?: number;\n limit?: number;\n remaining?: number;\n status?: string;\n }> {\n if (!resource) throw new Error('resource required');\n const safeQty = Number.isFinite(qty) && qty > 0 ? Math.floor(qty) : 1;\n const existing = this._counters.get(resource) ?? 0;\n const next = existing + safeQty;\n this._counters.set(resource, next);\n const limitFixture = this._quotas.get(resource);\n const limit = limitFixture?.limit ?? -1;\n return {\n ok: true,\n counterId: `mock_${resource}`,\n value: next,\n limit,\n remaining: limit < 0 ? -1 : Math.max(0, limit - next),\n status: limit > 0 && next >= limit ? 'read_only_overlimit' : 'ok',\n };\n }\n\n /** v0.3 — Mock check usa quotas + counters in-memory. */\n async check(\n resource: string,\n _options?: { productId?: string; tenantId?: string },\n ): Promise<{\n allowed: boolean;\n reason?: string;\n remaining?: number;\n limit?: number;\n planId?: string | null;\n planFeatures?: string[];\n }> {\n const quota = this._quotas.get(resource);\n const used = this._counters.get(resource) ?? 0;\n if (!quota) {\n return { allowed: true, reason: 'granted', limit: -1, remaining: -1 };\n }\n const remaining = quota.limit < 0 ? -1 : Math.max(0, quota.limit - used);\n if (remaining === 0) {\n return {\n allowed: false,\n reason: 'limit_exceeded',\n limit: quota.limit,\n remaining: 0,\n };\n }\n return {\n allowed: true,\n reason: 'granted',\n limit: quota.limit,\n remaining,\n };\n }\n\n /** Test helper. */\n __getRecords(): readonly UsageRecord[] {\n return [...this._records];\n }\n /** Test helper — substitui quota fixture. */\n __setQuota(metric: string, quota: UsageQuota): void {\n this._quotas.set(metric, quota);\n }\n /** Test helper — limpa estado. */\n __reset(): void {\n this._records = [];\n this._quotas.clear();\n this._counters.clear();\n }\n}\n\n// ─── MockSupport ───────────────────────────────────────────────────────────\n\n/**\n * In-memory `SupportNamespace`. createTicket gera ID `mock-ticket-{n}`;\n * listMyTickets retorna todos criados (FIFO). Sequência por instância\n * (evita poluição cross-test do estado de módulo).\n */\nexport class MockSupport implements SupportNamespace {\n private _tickets: SupportTicket[] = [];\n private _ticketSeq = 0;\n\n async createTicket(input: CreateTicketInput): Promise<SupportTicket> {\n if (!input?.subject) throw new Error('subject required');\n if (!input?.message) throw new Error('message required');\n const ticket: SupportTicket = {\n id: `mock-ticket-${++this._ticketSeq}`,\n subject: input.subject,\n message: input.message,\n severity: input.severity ?? 'normal',\n status: 'open',\n createdAt: new Date().toISOString(),\n productSlug: input.productSlug,\n };\n this._tickets.push(ticket);\n return ticket;\n }\n\n async listMyTickets(): Promise<SupportTicket[]> {\n return [...this._tickets];\n }\n\n /** Test helper. */\n __reset(): void {\n this._tickets = [];\n this._ticketSeq = 0;\n }\n}\n\n// ─── MockEntitlements ──────────────────────────────────────────────────────\n\n/**\n * In-memory entitlements. Por default `allowed=true` em tudo (dev convém).\n * Use `__deny(slug, feature)` em tests pra simular bloqueio.\n */\nexport class MockEntitlements {\n private _denied: Set<string> = new Set();\n\n async check(productSlug: string, feature: string): Promise<boolean> {\n return !this._denied.has(`${productSlug}:${feature}`);\n }\n\n async checkDetailed(productSlug: string, feature: string): Promise<EntitlementCheck> {\n const allowed = await this.check(productSlug, feature);\n return {\n allowed,\n productSlug,\n feature,\n reason: allowed ? 'granted' : 'mock_denied',\n };\n }\n\n /** Test helper. */\n __deny(productSlug: string, feature: string): void {\n this._denied.add(`${productSlug}:${feature}`);\n }\n /** Test helper. */\n __reset(): void {\n this._denied.clear();\n }\n}\n\n// ─── MockDb (v0.3) ─────────────────────────────────────────────────────────\n\n/**\n * In-memory `DbNamespace`. Cada `collection(name)` aponta para um Map; ops\n * são totalmente síncronas (mas API await-friendly).\n *\n * Útil para testar produtos consumidores sem rodar Core REST.\n */\nexport class MockDb implements DbNamespace {\n private _store: Map<string, Map<string, Record<string, unknown>>> = new Map();\n private _fixtures: Map<string, Record<string, Record<string, unknown>>>;\n\n constructor(initialFixtures: Record<string, Record<string, Record<string, unknown>>> = {}) {\n this._fixtures = new Map(Object.entries(initialFixtures));\n }\n\n collection(name: string): DbCollectionRef {\n const _store = this._store;\n const _fixtures = this._fixtures;\n if (!_store.has(name)) {\n const init = _fixtures.get(name);\n _store.set(\n name,\n init ? new Map(Object.entries(init)) : new Map(),\n );\n }\n const coll = _store.get(name)!;\n\n const matchesFilter = (\n doc: Record<string, unknown>,\n f: DbWhereFilter,\n ): boolean => {\n const v = doc[f.field];\n switch (f.op) {\n case '==':\n return v === f.value;\n case '!=':\n return v !== f.value;\n case '<':\n return typeof v === 'number' && typeof f.value === 'number' && v < f.value;\n case '<=':\n return typeof v === 'number' && typeof f.value === 'number' && v <= f.value;\n case '>':\n return typeof v === 'number' && typeof f.value === 'number' && v > f.value;\n case '>=':\n return typeof v === 'number' && typeof f.value === 'number' && v >= f.value;\n case 'in':\n return Array.isArray(f.value) && (f.value as unknown[]).includes(v);\n default:\n return true;\n }\n };\n\n let autoSeq = 0;\n\n return {\n async list<T = Record<string, unknown>>(opts?: DbListOptions): Promise<T[]> {\n let items = Array.from(coll.values());\n if (opts?.where && opts.where.length > 0) {\n items = items.filter((doc) =>\n (opts.where as DbWhereFilter[]).every((f) => matchesFilter(doc, f)),\n );\n }\n if (opts?.limit !== undefined) items = items.slice(0, opts.limit);\n return items as T[];\n },\n async get<T = Record<string, unknown>>(id: string): Promise<T | null> {\n return (coll.get(id) as T | undefined) ?? null;\n },\n async add(data: Record<string, unknown>): Promise<{ ok: true; id: string }> {\n const id = `mock-${++autoSeq}-${Math.random().toString(36).slice(2, 8)}`;\n coll.set(id, { ...data, id });\n return { ok: true, id };\n },\n async set(id: string, data: Record<string, unknown>): Promise<{ ok: true }> {\n coll.set(id, { ...data, id });\n return { ok: true };\n },\n async update(id: string, data: Record<string, unknown>): Promise<{ ok: true }> {\n const cur = coll.get(id);\n if (!cur) {\n // mock-friendly: cria se não existir (mimic Firestore set merge).\n coll.set(id, { ...data, id });\n } else {\n coll.set(id, { ...cur, ...data });\n }\n return { ok: true };\n },\n async remove(id: string): Promise<{ ok: true }> {\n coll.delete(id);\n return { ok: true };\n },\n };\n }\n\n /** Test helper — substitui fixture inteira de uma collection. */\n __setFixture(name: string, items: Record<string, Record<string, unknown>>): void {\n this._store.set(name, new Map(Object.entries(items)));\n }\n\n /** Test helper — reset total. */\n __reset(): void {\n this._store.clear();\n }\n}\n"]}
|
package/dist/mocks.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as NeetruUser, A as AuthNamespace, y as SignInOptions, b as AuthStateListener, m as DbNamespace, k as DbCollectionRef, E as EntitlementCheck, z as SupportNamespace, j as CreateTicketInput, G as SupportTicket, I as UsageNamespace, J as UsageQuota } from './types-CQAfwqUS.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Mocks determinísticos do SDK — overridáveis em tests do consumer ou
|
|
@@ -96,10 +96,12 @@ declare class MockUsage implements UsageNamespace {
|
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* In-memory `SupportNamespace`. createTicket gera ID `mock-ticket-{n}`;
|
|
99
|
-
* listMyTickets retorna todos criados (FIFO).
|
|
99
|
+
* listMyTickets retorna todos criados (FIFO). Sequência por instância
|
|
100
|
+
* (evita poluição cross-test do estado de módulo).
|
|
100
101
|
*/
|
|
101
102
|
declare class MockSupport implements SupportNamespace {
|
|
102
103
|
private _tickets;
|
|
104
|
+
private _ticketSeq;
|
|
103
105
|
createTicket(input: CreateTicketInput): Promise<SupportTicket>;
|
|
104
106
|
listMyTickets(): Promise<SupportTicket[]>;
|
|
105
107
|
/** Test helper. */
|
package/dist/mocks.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as NeetruUser, A as AuthNamespace, y as SignInOptions, b as AuthStateListener, m as DbNamespace, k as DbCollectionRef, E as EntitlementCheck, z as SupportNamespace, j as CreateTicketInput, G as SupportTicket, I as UsageNamespace, J as UsageQuota } from './types-CQAfwqUS.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Mocks determinísticos do SDK — overridáveis em tests do consumer ou
|
|
@@ -96,10 +96,12 @@ declare class MockUsage implements UsageNamespace {
|
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* In-memory `SupportNamespace`. createTicket gera ID `mock-ticket-{n}`;
|
|
99
|
-
* listMyTickets retorna todos criados (FIFO).
|
|
99
|
+
* listMyTickets retorna todos criados (FIFO). Sequência por instância
|
|
100
|
+
* (evita poluição cross-test do estado de módulo).
|
|
100
101
|
*/
|
|
101
102
|
declare class MockSupport implements SupportNamespace {
|
|
102
103
|
private _tickets;
|
|
104
|
+
private _ticketSeq;
|
|
103
105
|
createTicket(input: CreateTicketInput): Promise<SupportTicket>;
|
|
104
106
|
listMyTickets(): Promise<SupportTicket[]>;
|
|
105
107
|
/** Test helper. */
|
package/dist/mocks.mjs
CHANGED
|
@@ -133,14 +133,14 @@ var MockUsage = class {
|
|
|
133
133
|
this._counters.clear();
|
|
134
134
|
}
|
|
135
135
|
};
|
|
136
|
-
var mockTicketSeq = 0;
|
|
137
136
|
var MockSupport = class {
|
|
138
137
|
_tickets = [];
|
|
138
|
+
_ticketSeq = 0;
|
|
139
139
|
async createTicket(input) {
|
|
140
140
|
if (!input?.subject) throw new Error("subject required");
|
|
141
141
|
if (!input?.message) throw new Error("message required");
|
|
142
142
|
const ticket = {
|
|
143
|
-
id: `mock-ticket-${++
|
|
143
|
+
id: `mock-ticket-${++this._ticketSeq}`,
|
|
144
144
|
subject: input.subject,
|
|
145
145
|
message: input.message,
|
|
146
146
|
severity: input.severity ?? "normal",
|
|
@@ -157,6 +157,7 @@ var MockSupport = class {
|
|
|
157
157
|
/** Test helper. */
|
|
158
158
|
__reset() {
|
|
159
159
|
this._tickets = [];
|
|
160
|
+
this._ticketSeq = 0;
|
|
160
161
|
}
|
|
161
162
|
};
|
|
162
163
|
var MockEntitlements = class {
|
package/dist/mocks.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mocks.ts"],"names":[],"mappings":"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","file":"mocks.mjs","sourcesContent":["/**\n * Mocks determinísticos do SDK — overridáveis em tests do consumer ou\n * ativados automaticamente quando `NEETRU_ENV=dev`.\n *\n * Nada aqui faz I/O. Tudo é puro/sincrono/in-memory. Compat total com\n * runtimes browser/Node/Edge — sem `node:` builtins.\n *\n * Cada mock implementa o mesmo namespace interface das implementações reais\n * (`AuthNamespace`, `UsageNamespace`, `SupportNamespace`) — caller pode\n * substituir 1:1 sem branching.\n *\n * @example\n * ```ts\n * import { createNeetruClient, MockAuth } from '@neetru/sdk';\n *\n * const client = createNeetruClient({\n * mocks: { auth: new MockAuth({ uid: 'fake-user', email: 'x@x.com' }) },\n * });\n * ```\n */\n\nimport type {\n AuthNamespace,\n AuthStateListener,\n CreateTicketInput,\n DbCollectionRef,\n DbListOptions,\n DbNamespace,\n DbWhereFilter,\n EntitlementCheck,\n NeetruUser,\n SignInOptions,\n SupportNamespace,\n SupportTicket,\n UsageNamespace,\n UsageQuota,\n} from './types';\n\n// ─── User fixture default ──────────────────────────────────────────────────\n\n/**\n * User fixture determinístico — usado quando `NEETRU_ENV=dev` e nenhum mock\n * custom é injetado. Email/uid estáveis pra snapshot tests.\n */\nexport const DEV_FIXTURE_USER: NeetruUser = Object.freeze({\n uid: 'dev-fixture-uid-0001',\n email: 'dev@neetru.local',\n emailVerified: true,\n displayName: 'Dev Fixture',\n isCustomer: true,\n isStaff: false,\n}) as NeetruUser;\n\n// ─── MockAuth ──────────────────────────────────────────────────────────────\n\n/**\n * Implementação in-memory do `AuthNamespace`. signIn marca o user como\n * logado; signOut limpa. onAuthStateChanged dispara callback síncrono no\n * subscribe + a cada mudança.\n */\nexport class MockAuth implements AuthNamespace {\n private _user: NeetruUser | null;\n private _listeners: Set<AuthStateListener>;\n\n constructor(initialUser: NeetruUser | null = null) {\n this._user = initialUser;\n this._listeners = new Set();\n }\n\n async signIn(_options?: SignInOptions): Promise<NeetruUser> {\n // Mock: apenas marca user como logado (usa fixture se não havia).\n if (!this._user) this._user = { ...DEV_FIXTURE_USER };\n this._notify();\n return this._user;\n }\n\n async signOut(): Promise<void> {\n this._user = null;\n this._notify();\n }\n\n getUser(): NeetruUser | null {\n return this._user;\n }\n\n onAuthStateChanged(listener: AuthStateListener): () => void {\n this._listeners.add(listener);\n // Dispara imediatamente com estado atual (espelha API Firebase Auth).\n try {\n listener(this._user);\n } catch {\n // Callback do consumer não pode quebrar o subscribe.\n }\n return () => {\n this._listeners.delete(listener);\n };\n }\n\n /** Helper de tests — força um user state arbitrário. */\n __setUser(user: NeetruUser | null): void {\n this._user = user;\n this._notify();\n }\n\n private _notify(): void {\n for (const l of this._listeners) {\n try {\n l(this._user);\n } catch {\n // ignore consumer errors\n }\n }\n }\n}\n\n// ─── MockUsage ─────────────────────────────────────────────────────────────\n\ninterface UsageRecord {\n event: string;\n properties?: Record<string, string | number | boolean | null>;\n timestamp: string;\n}\n\n/**\n * In-memory `UsageNamespace`. `track()` apenas acumula no array\n * `__getRecords()` (útil pra asserts em test). `getQuota()` retorna fixture\n * com `used = trackedCount` da metric.\n */\nexport class MockUsage implements UsageNamespace {\n private _records: UsageRecord[] = [];\n private _quotas: Map<string, UsageQuota>;\n /** v0.3 — counters in-memory pra `report()` / `check()`. */\n private _counters: Map<string, number> = new Map();\n\n constructor(initialQuotas: Record<string, UsageQuota> = {}) {\n this._quotas = new Map(Object.entries(initialQuotas));\n }\n\n async track(\n event: string,\n properties?: Record<string, string | number | boolean | null>,\n ): Promise<{ ok: true }> {\n this._records.push({\n event,\n properties,\n timestamp: new Date().toISOString(),\n });\n return { ok: true };\n }\n\n async getQuota(metric: string): Promise<UsageQuota> {\n const existing = this._quotas.get(metric);\n if (existing) return existing;\n return {\n metric,\n used: this._records.filter((r) => r.event === metric).length,\n limit: -1, // unlimited em mock por default\n plan: 'mock',\n };\n }\n\n /** v0.3 — Mock report incrementa o counter local. */\n async report(\n resource: string,\n qty: number = 1,\n _options?: { productId?: string; tenantId?: string },\n ): Promise<{\n ok: true;\n counterId?: string;\n value?: number;\n limit?: number;\n remaining?: number;\n status?: string;\n }> {\n if (!resource) throw new Error('resource required');\n const safeQty = Number.isFinite(qty) && qty > 0 ? Math.floor(qty) : 1;\n const existing = this._counters.get(resource) ?? 0;\n const next = existing + safeQty;\n this._counters.set(resource, next);\n const limitFixture = this._quotas.get(resource);\n const limit = limitFixture?.limit ?? -1;\n return {\n ok: true,\n counterId: `mock_${resource}`,\n value: next,\n limit,\n remaining: limit < 0 ? -1 : Math.max(0, limit - next),\n status: limit > 0 && next >= limit ? 'read_only_overlimit' : 'ok',\n };\n }\n\n /** v0.3 — Mock check usa quotas + counters in-memory. */\n async check(\n resource: string,\n _options?: { productId?: string; tenantId?: string },\n ): Promise<{\n allowed: boolean;\n reason?: string;\n remaining?: number;\n limit?: number;\n planId?: string | null;\n planFeatures?: string[];\n }> {\n const quota = this._quotas.get(resource);\n const used = this._counters.get(resource) ?? 0;\n if (!quota) {\n return { allowed: true, reason: 'granted', limit: -1, remaining: -1 };\n }\n const remaining = quota.limit < 0 ? -1 : Math.max(0, quota.limit - used);\n if (remaining === 0) {\n return {\n allowed: false,\n reason: 'limit_exceeded',\n limit: quota.limit,\n remaining: 0,\n };\n }\n return {\n allowed: true,\n reason: 'granted',\n limit: quota.limit,\n remaining,\n };\n }\n\n /** Test helper. */\n __getRecords(): readonly UsageRecord[] {\n return [...this._records];\n }\n /** Test helper — substitui quota fixture. */\n __setQuota(metric: string, quota: UsageQuota): void {\n this._quotas.set(metric, quota);\n }\n /** Test helper — limpa estado. */\n __reset(): void {\n this._records = [];\n this._quotas.clear();\n this._counters.clear();\n }\n}\n\n// ─── MockSupport ───────────────────────────────────────────────────────────\n\nlet mockTicketSeq = 0;\n\n/**\n * In-memory `SupportNamespace`. createTicket gera ID `mock-ticket-{n}`;\n * listMyTickets retorna todos criados (FIFO).\n */\nexport class MockSupport implements SupportNamespace {\n private _tickets: SupportTicket[] = [];\n\n async createTicket(input: CreateTicketInput): Promise<SupportTicket> {\n if (!input?.subject) throw new Error('subject required');\n if (!input?.message) throw new Error('message required');\n const ticket: SupportTicket = {\n id: `mock-ticket-${++mockTicketSeq}`,\n subject: input.subject,\n message: input.message,\n severity: input.severity ?? 'normal',\n status: 'open',\n createdAt: new Date().toISOString(),\n productSlug: input.productSlug,\n };\n this._tickets.push(ticket);\n return ticket;\n }\n\n async listMyTickets(): Promise<SupportTicket[]> {\n return [...this._tickets];\n }\n\n /** Test helper. */\n __reset(): void {\n this._tickets = [];\n }\n}\n\n// ─── MockEntitlements ──────────────────────────────────────────────────────\n\n/**\n * In-memory entitlements. Por default `allowed=true` em tudo (dev convém).\n * Use `__deny(slug, feature)` em tests pra simular bloqueio.\n */\nexport class MockEntitlements {\n private _denied: Set<string> = new Set();\n\n async check(productSlug: string, feature: string): Promise<boolean> {\n return !this._denied.has(`${productSlug}:${feature}`);\n }\n\n async checkDetailed(productSlug: string, feature: string): Promise<EntitlementCheck> {\n const allowed = await this.check(productSlug, feature);\n return {\n allowed,\n productSlug,\n feature,\n reason: allowed ? 'granted' : 'mock_denied',\n };\n }\n\n /** Test helper. */\n __deny(productSlug: string, feature: string): void {\n this._denied.add(`${productSlug}:${feature}`);\n }\n /** Test helper. */\n __reset(): void {\n this._denied.clear();\n }\n}\n\n// ─── MockDb (v0.3) ─────────────────────────────────────────────────────────\n\n/**\n * In-memory `DbNamespace`. Cada `collection(name)` aponta para um Map; ops\n * são totalmente síncronas (mas API await-friendly).\n *\n * Útil para testar produtos consumidores sem rodar Core REST.\n */\nexport class MockDb implements DbNamespace {\n private _store: Map<string, Map<string, Record<string, unknown>>> = new Map();\n private _fixtures: Map<string, Record<string, Record<string, unknown>>>;\n\n constructor(initialFixtures: Record<string, Record<string, Record<string, unknown>>> = {}) {\n this._fixtures = new Map(Object.entries(initialFixtures));\n }\n\n collection(name: string): DbCollectionRef {\n const _store = this._store;\n const _fixtures = this._fixtures;\n if (!_store.has(name)) {\n const init = _fixtures.get(name);\n _store.set(\n name,\n init ? new Map(Object.entries(init)) : new Map(),\n );\n }\n const coll = _store.get(name)!;\n\n const matchesFilter = (\n doc: Record<string, unknown>,\n f: DbWhereFilter,\n ): boolean => {\n const v = doc[f.field];\n switch (f.op) {\n case '==':\n return v === f.value;\n case '!=':\n return v !== f.value;\n case '<':\n return typeof v === 'number' && typeof f.value === 'number' && v < f.value;\n case '<=':\n return typeof v === 'number' && typeof f.value === 'number' && v <= f.value;\n case '>':\n return typeof v === 'number' && typeof f.value === 'number' && v > f.value;\n case '>=':\n return typeof v === 'number' && typeof f.value === 'number' && v >= f.value;\n case 'in':\n return Array.isArray(f.value) && (f.value as unknown[]).includes(v);\n default:\n return true;\n }\n };\n\n let autoSeq = 0;\n\n return {\n async list<T = Record<string, unknown>>(opts?: DbListOptions): Promise<T[]> {\n let items = Array.from(coll.values());\n if (opts?.where && opts.where.length > 0) {\n items = items.filter((doc) =>\n (opts.where as DbWhereFilter[]).every((f) => matchesFilter(doc, f)),\n );\n }\n if (opts?.limit !== undefined) items = items.slice(0, opts.limit);\n return items as T[];\n },\n async get<T = Record<string, unknown>>(id: string): Promise<T | null> {\n return (coll.get(id) as T | undefined) ?? null;\n },\n async add(data: Record<string, unknown>): Promise<{ ok: true; id: string }> {\n const id = `mock-${++autoSeq}-${Math.random().toString(36).slice(2, 8)}`;\n coll.set(id, { ...data, id });\n return { ok: true, id };\n },\n async set(id: string, data: Record<string, unknown>): Promise<{ ok: true }> {\n coll.set(id, { ...data, id });\n return { ok: true };\n },\n async update(id: string, data: Record<string, unknown>): Promise<{ ok: true }> {\n const cur = coll.get(id);\n if (!cur) {\n // mock-friendly: cria se não existir (mimic Firestore set merge).\n coll.set(id, { ...data, id });\n } else {\n coll.set(id, { ...cur, ...data });\n }\n return { ok: true };\n },\n async remove(id: string): Promise<{ ok: true }> {\n coll.delete(id);\n return { ok: true };\n },\n };\n }\n\n /** Test helper — substitui fixture inteira de uma collection. */\n __setFixture(name: string, items: Record<string, Record<string, unknown>>): void {\n this._store.set(name, new Map(Object.entries(items)));\n }\n\n /** Test helper — reset total. */\n __reset(): void {\n this._store.clear();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/mocks.ts"],"names":[],"mappings":"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","file":"mocks.mjs","sourcesContent":["/**\n * Mocks determinísticos do SDK — overridáveis em tests do consumer ou\n * ativados automaticamente quando `NEETRU_ENV=dev`.\n *\n * Nada aqui faz I/O. Tudo é puro/sincrono/in-memory. Compat total com\n * runtimes browser/Node/Edge — sem `node:` builtins.\n *\n * Cada mock implementa o mesmo namespace interface das implementações reais\n * (`AuthNamespace`, `UsageNamespace`, `SupportNamespace`) — caller pode\n * substituir 1:1 sem branching.\n *\n * @example\n * ```ts\n * import { createNeetruClient, MockAuth } from '@neetru/sdk';\n *\n * const client = createNeetruClient({\n * mocks: { auth: new MockAuth({ uid: 'fake-user', email: 'x@x.com' }) },\n * });\n * ```\n */\n\nimport type {\n AuthNamespace,\n AuthStateListener,\n CreateTicketInput,\n DbCollectionRef,\n DbListOptions,\n DbNamespace,\n DbWhereFilter,\n EntitlementCheck,\n NeetruUser,\n SignInOptions,\n SupportNamespace,\n SupportTicket,\n UsageNamespace,\n UsageQuota,\n} from './types';\n\n// ─── User fixture default ──────────────────────────────────────────────────\n\n/**\n * User fixture determinístico — usado quando `NEETRU_ENV=dev` e nenhum mock\n * custom é injetado. Email/uid estáveis pra snapshot tests.\n */\nexport const DEV_FIXTURE_USER: NeetruUser = Object.freeze({\n uid: 'dev-fixture-uid-0001',\n email: 'dev@neetru.local',\n emailVerified: true,\n displayName: 'Dev Fixture',\n isCustomer: true,\n isStaff: false,\n}) as NeetruUser;\n\n// ─── MockAuth ──────────────────────────────────────────────────────────────\n\n/**\n * Implementação in-memory do `AuthNamespace`. signIn marca o user como\n * logado; signOut limpa. onAuthStateChanged dispara callback síncrono no\n * subscribe + a cada mudança.\n */\nexport class MockAuth implements AuthNamespace {\n private _user: NeetruUser | null;\n private _listeners: Set<AuthStateListener>;\n\n constructor(initialUser: NeetruUser | null = null) {\n this._user = initialUser;\n this._listeners = new Set();\n }\n\n async signIn(_options?: SignInOptions): Promise<NeetruUser> {\n // Mock: apenas marca user como logado (usa fixture se não havia).\n if (!this._user) this._user = { ...DEV_FIXTURE_USER };\n this._notify();\n return this._user;\n }\n\n async signOut(): Promise<void> {\n this._user = null;\n this._notify();\n }\n\n getUser(): NeetruUser | null {\n return this._user;\n }\n\n onAuthStateChanged(listener: AuthStateListener): () => void {\n this._listeners.add(listener);\n // Dispara imediatamente com estado atual (espelha API Firebase Auth).\n try {\n listener(this._user);\n } catch {\n // Callback do consumer não pode quebrar o subscribe.\n }\n return () => {\n this._listeners.delete(listener);\n };\n }\n\n /** Helper de tests — força um user state arbitrário. */\n __setUser(user: NeetruUser | null): void {\n this._user = user;\n this._notify();\n }\n\n private _notify(): void {\n for (const l of this._listeners) {\n try {\n l(this._user);\n } catch {\n // ignore consumer errors\n }\n }\n }\n}\n\n// ─── MockUsage ─────────────────────────────────────────────────────────────\n\ninterface UsageRecord {\n event: string;\n properties?: Record<string, string | number | boolean | null>;\n timestamp: string;\n}\n\n/**\n * In-memory `UsageNamespace`. `track()` apenas acumula no array\n * `__getRecords()` (útil pra asserts em test). `getQuota()` retorna fixture\n * com `used = trackedCount` da metric.\n */\nexport class MockUsage implements UsageNamespace {\n private _records: UsageRecord[] = [];\n private _quotas: Map<string, UsageQuota>;\n /** v0.3 — counters in-memory pra `report()` / `check()`. */\n private _counters: Map<string, number> = new Map();\n\n constructor(initialQuotas: Record<string, UsageQuota> = {}) {\n this._quotas = new Map(Object.entries(initialQuotas));\n }\n\n async track(\n event: string,\n properties?: Record<string, string | number | boolean | null>,\n ): Promise<{ ok: true }> {\n this._records.push({\n event,\n properties,\n timestamp: new Date().toISOString(),\n });\n return { ok: true };\n }\n\n async getQuota(metric: string): Promise<UsageQuota> {\n const existing = this._quotas.get(metric);\n if (existing) return existing;\n return {\n metric,\n used: this._records.filter((r) => r.event === metric).length,\n limit: -1, // unlimited em mock por default\n plan: 'mock',\n };\n }\n\n /** v0.3 — Mock report incrementa o counter local. */\n async report(\n resource: string,\n qty: number = 1,\n _options?: { productId?: string; tenantId?: string },\n ): Promise<{\n ok: true;\n counterId?: string;\n value?: number;\n limit?: number;\n remaining?: number;\n status?: string;\n }> {\n if (!resource) throw new Error('resource required');\n const safeQty = Number.isFinite(qty) && qty > 0 ? Math.floor(qty) : 1;\n const existing = this._counters.get(resource) ?? 0;\n const next = existing + safeQty;\n this._counters.set(resource, next);\n const limitFixture = this._quotas.get(resource);\n const limit = limitFixture?.limit ?? -1;\n return {\n ok: true,\n counterId: `mock_${resource}`,\n value: next,\n limit,\n remaining: limit < 0 ? -1 : Math.max(0, limit - next),\n status: limit > 0 && next >= limit ? 'read_only_overlimit' : 'ok',\n };\n }\n\n /** v0.3 — Mock check usa quotas + counters in-memory. */\n async check(\n resource: string,\n _options?: { productId?: string; tenantId?: string },\n ): Promise<{\n allowed: boolean;\n reason?: string;\n remaining?: number;\n limit?: number;\n planId?: string | null;\n planFeatures?: string[];\n }> {\n const quota = this._quotas.get(resource);\n const used = this._counters.get(resource) ?? 0;\n if (!quota) {\n return { allowed: true, reason: 'granted', limit: -1, remaining: -1 };\n }\n const remaining = quota.limit < 0 ? -1 : Math.max(0, quota.limit - used);\n if (remaining === 0) {\n return {\n allowed: false,\n reason: 'limit_exceeded',\n limit: quota.limit,\n remaining: 0,\n };\n }\n return {\n allowed: true,\n reason: 'granted',\n limit: quota.limit,\n remaining,\n };\n }\n\n /** Test helper. */\n __getRecords(): readonly UsageRecord[] {\n return [...this._records];\n }\n /** Test helper — substitui quota fixture. */\n __setQuota(metric: string, quota: UsageQuota): void {\n this._quotas.set(metric, quota);\n }\n /** Test helper — limpa estado. */\n __reset(): void {\n this._records = [];\n this._quotas.clear();\n this._counters.clear();\n }\n}\n\n// ─── MockSupport ───────────────────────────────────────────────────────────\n\n/**\n * In-memory `SupportNamespace`. createTicket gera ID `mock-ticket-{n}`;\n * listMyTickets retorna todos criados (FIFO). Sequência por instância\n * (evita poluição cross-test do estado de módulo).\n */\nexport class MockSupport implements SupportNamespace {\n private _tickets: SupportTicket[] = [];\n private _ticketSeq = 0;\n\n async createTicket(input: CreateTicketInput): Promise<SupportTicket> {\n if (!input?.subject) throw new Error('subject required');\n if (!input?.message) throw new Error('message required');\n const ticket: SupportTicket = {\n id: `mock-ticket-${++this._ticketSeq}`,\n subject: input.subject,\n message: input.message,\n severity: input.severity ?? 'normal',\n status: 'open',\n createdAt: new Date().toISOString(),\n productSlug: input.productSlug,\n };\n this._tickets.push(ticket);\n return ticket;\n }\n\n async listMyTickets(): Promise<SupportTicket[]> {\n return [...this._tickets];\n }\n\n /** Test helper. */\n __reset(): void {\n this._tickets = [];\n this._ticketSeq = 0;\n }\n}\n\n// ─── MockEntitlements ──────────────────────────────────────────────────────\n\n/**\n * In-memory entitlements. Por default `allowed=true` em tudo (dev convém).\n * Use `__deny(slug, feature)` em tests pra simular bloqueio.\n */\nexport class MockEntitlements {\n private _denied: Set<string> = new Set();\n\n async check(productSlug: string, feature: string): Promise<boolean> {\n return !this._denied.has(`${productSlug}:${feature}`);\n }\n\n async checkDetailed(productSlug: string, feature: string): Promise<EntitlementCheck> {\n const allowed = await this.check(productSlug, feature);\n return {\n allowed,\n productSlug,\n feature,\n reason: allowed ? 'granted' : 'mock_denied',\n };\n }\n\n /** Test helper. */\n __deny(productSlug: string, feature: string): void {\n this._denied.add(`${productSlug}:${feature}`);\n }\n /** Test helper. */\n __reset(): void {\n this._denied.clear();\n }\n}\n\n// ─── MockDb (v0.3) ─────────────────────────────────────────────────────────\n\n/**\n * In-memory `DbNamespace`. Cada `collection(name)` aponta para um Map; ops\n * são totalmente síncronas (mas API await-friendly).\n *\n * Útil para testar produtos consumidores sem rodar Core REST.\n */\nexport class MockDb implements DbNamespace {\n private _store: Map<string, Map<string, Record<string, unknown>>> = new Map();\n private _fixtures: Map<string, Record<string, Record<string, unknown>>>;\n\n constructor(initialFixtures: Record<string, Record<string, Record<string, unknown>>> = {}) {\n this._fixtures = new Map(Object.entries(initialFixtures));\n }\n\n collection(name: string): DbCollectionRef {\n const _store = this._store;\n const _fixtures = this._fixtures;\n if (!_store.has(name)) {\n const init = _fixtures.get(name);\n _store.set(\n name,\n init ? new Map(Object.entries(init)) : new Map(),\n );\n }\n const coll = _store.get(name)!;\n\n const matchesFilter = (\n doc: Record<string, unknown>,\n f: DbWhereFilter,\n ): boolean => {\n const v = doc[f.field];\n switch (f.op) {\n case '==':\n return v === f.value;\n case '!=':\n return v !== f.value;\n case '<':\n return typeof v === 'number' && typeof f.value === 'number' && v < f.value;\n case '<=':\n return typeof v === 'number' && typeof f.value === 'number' && v <= f.value;\n case '>':\n return typeof v === 'number' && typeof f.value === 'number' && v > f.value;\n case '>=':\n return typeof v === 'number' && typeof f.value === 'number' && v >= f.value;\n case 'in':\n return Array.isArray(f.value) && (f.value as unknown[]).includes(v);\n default:\n return true;\n }\n };\n\n let autoSeq = 0;\n\n return {\n async list<T = Record<string, unknown>>(opts?: DbListOptions): Promise<T[]> {\n let items = Array.from(coll.values());\n if (opts?.where && opts.where.length > 0) {\n items = items.filter((doc) =>\n (opts.where as DbWhereFilter[]).every((f) => matchesFilter(doc, f)),\n );\n }\n if (opts?.limit !== undefined) items = items.slice(0, opts.limit);\n return items as T[];\n },\n async get<T = Record<string, unknown>>(id: string): Promise<T | null> {\n return (coll.get(id) as T | undefined) ?? null;\n },\n async add(data: Record<string, unknown>): Promise<{ ok: true; id: string }> {\n const id = `mock-${++autoSeq}-${Math.random().toString(36).slice(2, 8)}`;\n coll.set(id, { ...data, id });\n return { ok: true, id };\n },\n async set(id: string, data: Record<string, unknown>): Promise<{ ok: true }> {\n coll.set(id, { ...data, id });\n return { ok: true };\n },\n async update(id: string, data: Record<string, unknown>): Promise<{ ok: true }> {\n const cur = coll.get(id);\n if (!cur) {\n // mock-friendly: cria se não existir (mimic Firestore set merge).\n coll.set(id, { ...data, id });\n } else {\n coll.set(id, { ...cur, ...data });\n }\n return { ok: true };\n },\n async remove(id: string): Promise<{ ok: true }> {\n coll.delete(id);\n return { ok: true };\n },\n };\n }\n\n /** Test helper — substitui fixture inteira de uma collection. */\n __setFixture(name: string, items: Record<string, Record<string, unknown>>): void {\n this._store.set(name, new Map(Object.entries(items)));\n }\n\n /** Test helper — reset total. */\n __reset(): void {\n this._store.clear();\n }\n}\n"]}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/errors.ts
|
|
4
|
+
var NeetruError = class _NeetruError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
status;
|
|
7
|
+
requestId;
|
|
8
|
+
constructor(code, message, status, requestId) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "NeetruError";
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.requestId = requestId;
|
|
14
|
+
Object.setPrototypeOf(this, _NeetruError.prototype);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/http.ts
|
|
19
|
+
var DEFAULT_RETRIES = 2;
|
|
20
|
+
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
21
|
+
"rate_limited",
|
|
22
|
+
"server_error",
|
|
23
|
+
"network_error"
|
|
24
|
+
]);
|
|
25
|
+
function backoffMs(attempt) {
|
|
26
|
+
const base = 200 * Math.pow(4, attempt);
|
|
27
|
+
const jitter = base * 0.2 * (Math.random() * 2 - 1);
|
|
28
|
+
return Math.max(50, Math.round(base + jitter));
|
|
29
|
+
}
|
|
30
|
+
function parseRetryAfter(value) {
|
|
31
|
+
if (!value) return null;
|
|
32
|
+
const secs = Number(value);
|
|
33
|
+
if (Number.isFinite(secs) && secs >= 0) return Math.round(secs * 1e3);
|
|
34
|
+
const dateMs = Date.parse(value);
|
|
35
|
+
if (Number.isFinite(dateMs)) {
|
|
36
|
+
const delta = dateMs - Date.now();
|
|
37
|
+
if (delta > 0) return delta;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function sleep(ms) {
|
|
42
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
43
|
+
}
|
|
44
|
+
function statusToCode(status) {
|
|
45
|
+
if (status === 401) return "unauthorized";
|
|
46
|
+
if (status === 403) return "forbidden";
|
|
47
|
+
if (status === 404) return "not_found";
|
|
48
|
+
if (status === 422 || status === 400) return "validation_failed";
|
|
49
|
+
if (status === 429) return "rate_limited";
|
|
50
|
+
if (status >= 500) return "server_error";
|
|
51
|
+
return "unknown";
|
|
52
|
+
}
|
|
53
|
+
function buildUrl(baseUrl, path, query) {
|
|
54
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
55
|
+
const p = path.startsWith("/") ? path : `/${path}`;
|
|
56
|
+
const url = new URL(`${base}${p}`);
|
|
57
|
+
if (query) {
|
|
58
|
+
for (const [k, v] of Object.entries(query)) {
|
|
59
|
+
if (v === void 0) continue;
|
|
60
|
+
url.searchParams.set(k, String(v));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return url.toString();
|
|
64
|
+
}
|
|
65
|
+
async function safeJson(res) {
|
|
66
|
+
const text = await res.text();
|
|
67
|
+
if (!text) return void 0;
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(text);
|
|
70
|
+
} catch {
|
|
71
|
+
return void 0;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function httpRequest(config, opts) {
|
|
75
|
+
const method = opts.method ?? "GET";
|
|
76
|
+
const url = buildUrl(config.baseUrl, opts.path, opts.query);
|
|
77
|
+
const maxRetries = opts.retries ?? DEFAULT_RETRIES;
|
|
78
|
+
const headers = {
|
|
79
|
+
accept: "application/json",
|
|
80
|
+
...opts.headers
|
|
81
|
+
};
|
|
82
|
+
if (opts.requireAuth) {
|
|
83
|
+
if (!config.apiKey) {
|
|
84
|
+
throw new NeetruError(
|
|
85
|
+
"missing_api_key",
|
|
86
|
+
"This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var."
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
headers.authorization = `Bearer ${config.apiKey}`;
|
|
90
|
+
}
|
|
91
|
+
const bodyString = opts.body !== void 0 && method !== "GET" && method !== "DELETE" ? JSON.stringify(opts.body) : void 0;
|
|
92
|
+
if (bodyString !== void 0) {
|
|
93
|
+
headers["content-type"] = "application/json";
|
|
94
|
+
}
|
|
95
|
+
let lastError = null;
|
|
96
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
97
|
+
const init = { method, headers };
|
|
98
|
+
if (bodyString !== void 0) init.body = bodyString;
|
|
99
|
+
init.signal = AbortSignal.timeout(3e4);
|
|
100
|
+
let res;
|
|
101
|
+
try {
|
|
102
|
+
res = await config.fetch(url, init);
|
|
103
|
+
} catch (err2) {
|
|
104
|
+
const message2 = err2 instanceof DOMException && err2.name === "TimeoutError" ? "Network error: timeout after 30s" : `Network error: ${err2 instanceof Error ? err2.message : "fetch failed"}`;
|
|
105
|
+
lastError = new NeetruError("network_error", message2);
|
|
106
|
+
if (attempt < maxRetries) {
|
|
107
|
+
await sleep(backoffMs(attempt));
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
throw lastError;
|
|
111
|
+
}
|
|
112
|
+
const requestId = res.headers.get("x-request-id") ?? res.headers.get("x-correlation-id") ?? void 0;
|
|
113
|
+
if (res.ok) {
|
|
114
|
+
const parsed = await safeJson(res);
|
|
115
|
+
return parsed;
|
|
116
|
+
}
|
|
117
|
+
const body = await safeJson(res);
|
|
118
|
+
let code = statusToCode(res.status);
|
|
119
|
+
let message = `HTTP ${res.status}`;
|
|
120
|
+
if (body && typeof body === "object" && "error" in body) {
|
|
121
|
+
const errField = body.error;
|
|
122
|
+
if (typeof errField === "string") {
|
|
123
|
+
message = errField;
|
|
124
|
+
} else if (errField && typeof errField === "object") {
|
|
125
|
+
if (typeof errField.code === "string") code = errField.code;
|
|
126
|
+
if (typeof errField.message === "string") message = errField.message;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const err = new NeetruError(code, message, res.status, requestId);
|
|
130
|
+
lastError = err;
|
|
131
|
+
const isRetryable = RETRYABLE_CODES.has(code);
|
|
132
|
+
if (isRetryable && attempt < maxRetries) {
|
|
133
|
+
const retryAfter = parseRetryAfter(res.headers.get("retry-after"));
|
|
134
|
+
const delay = retryAfter ?? backoffMs(attempt);
|
|
135
|
+
await sleep(delay);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
throw lastError ?? new NeetruError("unknown", "unexpected httpRequest exit");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// src/notifications.ts
|
|
144
|
+
var VALID_SEVERITIES = [
|
|
145
|
+
"info",
|
|
146
|
+
"success",
|
|
147
|
+
"warning",
|
|
148
|
+
"error"
|
|
149
|
+
];
|
|
150
|
+
function toNotification(raw) {
|
|
151
|
+
if (!raw || typeof raw !== "object") {
|
|
152
|
+
throw new NeetruError("invalid_response", "Notification response is not an object");
|
|
153
|
+
}
|
|
154
|
+
const r = raw;
|
|
155
|
+
if (typeof r.id !== "string") {
|
|
156
|
+
throw new NeetruError("invalid_response", "Notification missing id");
|
|
157
|
+
}
|
|
158
|
+
const sev = VALID_SEVERITIES.includes(r.severity) ? r.severity : "info";
|
|
159
|
+
return {
|
|
160
|
+
id: r.id,
|
|
161
|
+
userId: typeof r.userId === "string" ? r.userId : "",
|
|
162
|
+
kind: typeof r.kind === "string" ? r.kind : "unknown",
|
|
163
|
+
severity: sev,
|
|
164
|
+
title: typeof r.title === "string" ? r.title : "",
|
|
165
|
+
body: typeof r.body === "string" ? r.body : void 0,
|
|
166
|
+
link: typeof r.link === "string" ? r.link : void 0,
|
|
167
|
+
metadata: r.metadata && typeof r.metadata === "object" ? r.metadata : void 0,
|
|
168
|
+
createdAt: typeof r.createdAt === "string" ? r.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
169
|
+
readAt: typeof r.readAt === "string" ? r.readAt : void 0,
|
|
170
|
+
dismissedAt: typeof r.dismissedAt === "string" ? r.dismissedAt : void 0
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function validateInput(input) {
|
|
174
|
+
if (!input.userId) throw new NeetruError("validation_failed", "userId obrigat\xF3rio");
|
|
175
|
+
if (!input.kind) throw new NeetruError("validation_failed", "kind obrigat\xF3rio");
|
|
176
|
+
if (!input.title) throw new NeetruError("validation_failed", "title obrigat\xF3rio");
|
|
177
|
+
if (input.severity && !VALID_SEVERITIES.includes(input.severity)) {
|
|
178
|
+
throw new NeetruError(
|
|
179
|
+
"validation_failed",
|
|
180
|
+
`severity inv\xE1lida: ${input.severity} (use ${VALID_SEVERITIES.join("|")})`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
if (input.title.length > 200) {
|
|
184
|
+
throw new NeetruError("validation_failed", "title m\xE1x 200 chars");
|
|
185
|
+
}
|
|
186
|
+
if (input.body && input.body.length > 2e3) {
|
|
187
|
+
throw new NeetruError("validation_failed", "body m\xE1x 2000 chars");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function createNotificationsNamespace(config) {
|
|
191
|
+
return {
|
|
192
|
+
async send(input) {
|
|
193
|
+
validateInput(input);
|
|
194
|
+
const raw = await httpRequest(config, {
|
|
195
|
+
method: "POST",
|
|
196
|
+
path: "/api/sdk/v1/notifications",
|
|
197
|
+
body: input,
|
|
198
|
+
requireAuth: true
|
|
199
|
+
});
|
|
200
|
+
return toNotification(raw);
|
|
201
|
+
},
|
|
202
|
+
async list(userId, options) {
|
|
203
|
+
if (!userId) throw new NeetruError("validation_failed", "userId obrigat\xF3rio");
|
|
204
|
+
const params = new URLSearchParams();
|
|
205
|
+
if (options?.includeDismissed) params.set("includeDismissed", "true");
|
|
206
|
+
if (options?.onlyUnread) params.set("onlyUnread", "true");
|
|
207
|
+
if (options?.limit) {
|
|
208
|
+
params.set("limit", Math.min(Math.max(1, options.limit), 200).toString());
|
|
209
|
+
}
|
|
210
|
+
const qs = params.toString();
|
|
211
|
+
const raw = await httpRequest(config, {
|
|
212
|
+
method: "GET",
|
|
213
|
+
path: `/api/sdk/v1/notifications/user/${encodeURIComponent(userId)}${qs ? `?${qs}` : ""}`,
|
|
214
|
+
requireAuth: true
|
|
215
|
+
});
|
|
216
|
+
const list = Array.isArray(raw?.notifications) ? raw.notifications : [];
|
|
217
|
+
return list.map(toNotification);
|
|
218
|
+
},
|
|
219
|
+
async markRead(id) {
|
|
220
|
+
if (!id) throw new NeetruError("validation_failed", "id obrigat\xF3rio");
|
|
221
|
+
await httpRequest(config, {
|
|
222
|
+
method: "POST",
|
|
223
|
+
path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/read`,
|
|
224
|
+
requireAuth: true
|
|
225
|
+
});
|
|
226
|
+
return { ok: true };
|
|
227
|
+
},
|
|
228
|
+
async dismiss(id) {
|
|
229
|
+
if (!id) throw new NeetruError("validation_failed", "id obrigat\xF3rio");
|
|
230
|
+
await httpRequest(config, {
|
|
231
|
+
method: "POST",
|
|
232
|
+
path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/dismiss`,
|
|
233
|
+
requireAuth: true
|
|
234
|
+
});
|
|
235
|
+
return { ok: true };
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
var MockNotifications = class {
|
|
240
|
+
notifications = /* @__PURE__ */ new Map();
|
|
241
|
+
nextId = 1;
|
|
242
|
+
async send(input) {
|
|
243
|
+
validateInput(input);
|
|
244
|
+
if (input.fingerprint) {
|
|
245
|
+
const dayAgo = Date.now() - 864e5;
|
|
246
|
+
for (const existing of this.notifications.values()) {
|
|
247
|
+
const meta = existing.metadata ?? {};
|
|
248
|
+
if (meta.fingerprint === input.fingerprint && existing.userId === input.userId && new Date(existing.createdAt).getTime() > dayAgo) {
|
|
249
|
+
return existing;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const id = `mock_notif_${this.nextId++}`;
|
|
254
|
+
const notif = {
|
|
255
|
+
id,
|
|
256
|
+
userId: input.userId,
|
|
257
|
+
kind: input.kind,
|
|
258
|
+
severity: input.severity ?? "info",
|
|
259
|
+
title: input.title,
|
|
260
|
+
body: input.body,
|
|
261
|
+
link: input.link,
|
|
262
|
+
metadata: input.fingerprint ? { ...input.metadata ?? {}, fingerprint: input.fingerprint } : input.metadata,
|
|
263
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
264
|
+
};
|
|
265
|
+
this.notifications.set(id, notif);
|
|
266
|
+
return notif;
|
|
267
|
+
}
|
|
268
|
+
async list(userId, options) {
|
|
269
|
+
if (!userId) throw new NeetruError("validation_failed", "userId obrigat\xF3rio");
|
|
270
|
+
const limit = Math.min(Math.max(1, options?.limit ?? 50), 200);
|
|
271
|
+
return [...this.notifications.values()].filter((n) => n.userId === userId).filter((n) => options?.includeDismissed || !n.dismissedAt).filter((n) => !options?.onlyUnread || !n.readAt).sort((a, b) => b.createdAt.localeCompare(a.createdAt)).slice(0, limit);
|
|
272
|
+
}
|
|
273
|
+
async markRead(id) {
|
|
274
|
+
const n = this.notifications.get(id);
|
|
275
|
+
if (!n) throw new NeetruError("not_found", `Notification ${id} n\xE3o encontrada`);
|
|
276
|
+
if (!n.readAt) {
|
|
277
|
+
n.readAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
278
|
+
this.notifications.set(id, n);
|
|
279
|
+
}
|
|
280
|
+
return { ok: true };
|
|
281
|
+
}
|
|
282
|
+
async dismiss(id) {
|
|
283
|
+
const n = this.notifications.get(id);
|
|
284
|
+
if (!n) throw new NeetruError("not_found", `Notification ${id} n\xE3o encontrada`);
|
|
285
|
+
if (!n.dismissedAt) {
|
|
286
|
+
n.dismissedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
287
|
+
this.notifications.set(id, n);
|
|
288
|
+
}
|
|
289
|
+
return { ok: true };
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
exports.MockNotifications = MockNotifications;
|
|
294
|
+
exports.createNotificationsNamespace = createNotificationsNamespace;
|
|
295
|
+
//# sourceMappingURL=notifications.cjs.map
|
|
296
|
+
//# sourceMappingURL=notifications.cjs.map
|