@drivemetadata-ai/sdk 0.1.1-beta.2 → 0.1.1-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/angular/index.cjs +780 -94
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.d.cts +2 -2
- package/dist/angular/index.d.ts +2 -2
- package/dist/angular/index.js +780 -94
- package/dist/angular/index.js.map +1 -1
- package/dist/browser/index.cjs +781 -95
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.d.cts +2 -2
- package/dist/browser/index.d.ts +2 -2
- package/dist/browser/index.js +781 -95
- package/dist/browser/index.js.map +1 -1
- package/dist/next/index.cjs +780 -94
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +780 -94
- package/dist/next/index.js.map +1 -1
- package/dist/node/index.cjs +81 -9
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +81 -9
- package/dist/node/index.js.map +1 -1
- package/dist/react/index.cjs +780 -94
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +780 -94
- package/dist/react/index.js.map +1 -1
- package/dist/{types--V8TVIqT.d.cts → types-mgbdL1V7.d.cts} +17 -4
- package/dist/{types--V8TVIqT.d.ts → types-mgbdL1V7.d.ts} +17 -4
- package/docs/architecture.md +109 -0
- package/docs/index.md +1 -0
- package/docs/integration.md +26 -0
- package/docs/npm-browser-sdk.md +4 -0
- package/package.json +3 -2
package/dist/node/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/node/index.ts","../../src/node/errors.ts","../../src/core/backend-payload.ts","../../src/node/retry.ts","../../src/node/validation.ts","../../src/node/client.ts"],"sourcesContent":["export { createDmdServerClient } from './client';\nexport {\n DmdServerRequestError,\n DmdServerSdkError,\n DmdServerValidationError\n} from './errors';\nexport type {\n DmdServerAliasPayload,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerRetryConfig,\n DmdServerTrackPayload\n} from './types';\n","export class DmdServerSdkError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DmdServerSdkError';\n }\n}\n\nexport class DmdServerValidationError extends DmdServerSdkError {\n constructor(message: string) {\n super(message);\n this.name = 'DmdServerValidationError';\n }\n}\n\nexport class DmdServerRequestError extends DmdServerSdkError {\n constructor(message: string, public readonly status?: number, cause?: unknown) {\n super(message, cause);\n this.name = 'DmdServerRequestError';\n }\n}\n","function formatUtcTimestamp(value: unknown): string {\n if (typeof value !== 'string') return new Date().toISOString().replace('T', ' ').slice(0, 19);\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toISOString().replace('T', ' ').slice(0, 19);\n}\n\nfunction cleanObject(value: unknown): unknown {\n if (Array.isArray(value)) {\n const cleaned = value\n .map(item => cleanObject(item))\n .filter(item => item !== null && item !== undefined && item !== '');\n return cleaned.length > 0 ? cleaned : undefined;\n }\n\n if (value && typeof value === 'object') {\n const cleaned = Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .map(([key, item]) => [key, cleanObject(item)])\n .filter(([, item]) => {\n if (item === null || item === undefined || item === '') return false;\n if (typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) return false;\n return true;\n })\n );\n return Object.keys(cleaned).length > 0 ? cleaned : undefined;\n }\n\n return value;\n}\n\nexport function createBackendCollectorPayload(input: Record<string, unknown>): Record<string, unknown> {\n const eventData = input.eventData && typeof input.eventData === 'object'\n ? input.eventData as Record<string, unknown>\n : {};\n const page = eventData.page && typeof eventData.page === 'object'\n ? eventData.page as Record<string, unknown>\n : {};\n const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);\n const normalizedEventData = {\n ...eventData,\n timestamp,\n requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),\n requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)\n };\n\n const metaData: Record<string, unknown> = {\n ...normalizedEventData,\n requestId: input.requestId,\n timestamp,\n eventType: input.eventType,\n requestFrom: input.requestFrom ?? '3',\n clientId: input.clientId,\n workspaceId: input.workspaceId,\n token: input.token,\n anonymousId: eventData.anonymousId ?? input.anonymousId,\n sessionId: eventData.sessionId ?? input.sessionId,\n ua: input.ua,\n appDetails: { app_id: input.appId },\n page: { ...page, url: page.url ?? input.pageUrl },\n requestSentAt: normalizedEventData.requestSentAt,\n requestReceivedAt: normalizedEventData.requestReceivedAt\n };\n\n const payload = { metaData };\n\n return cleanObject(payload) as Record<string, unknown>;\n}\n","import type { DmdServerRetryConfig } from './types';\n\nexport function isRetryableStatus(status: number): boolean {\n return status === 408 || status === 429 || status >= 500;\n}\n\nexport function getRetryDelayMs(attemptIndex: number, retry: DmdServerRetryConfig = {}): number {\n const minDelayMs = retry.minDelayMs ?? 250;\n const maxDelayMs = retry.maxDelayMs ?? 2000;\n const exponentialDelay = minDelayMs * 2 ** attemptIndex;\n\n return Math.min(exponentialDelay, maxDelayMs);\n}\n\nexport function getRetryAttempts(retry: DmdServerRetryConfig | undefined): number {\n return retry?.attempts ?? 0;\n}\n","import { DmdServerValidationError } from './errors';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerTrackPayload\n} from './types';\n\nfunction requireString(value: string | undefined, message: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new DmdServerValidationError(message);\n }\n\n return value;\n}\n\nexport function validateServerConfig(config: DmdServerConfig): void {\n requireString(config.writeKey || config.token, 'DMD server SDK config writeKey or token is required');\n}\n\nexport function validateTrackPayload(payload: DmdServerTrackPayload): void {\n requireString(payload.event, 'DMD server SDK track event is required');\n\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK track requires userId or anonymousId');\n }\n}\n\nexport function validateIdentifyPayload(payload: DmdServerIdentifyPayload): void {\n requireString(payload.userId, 'DMD server SDK identify requires userId');\n}\n\nexport function validatePagePayload(payload: DmdServerPagePayload): void {\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK page requires userId or anonymousId');\n }\n}\n\nexport function validateAliasPayload(payload: DmdServerAliasPayload): void {\n const hasPreviousId = typeof payload.previousId === 'string' && payload.previousId.trim() !== '';\n const hasUserId = typeof payload.userId === 'string' && payload.userId.trim() !== '';\n if (!hasPreviousId || !hasUserId) {\n throw new DmdServerValidationError('DMD server SDK alias requires previousId and userId');\n }\n}\n\nexport function validateGroupPayload(payload: DmdServerGroupPayload): void {\n requireString(payload.groupId, 'DMD server SDK group requires groupId');\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK group requires userId or anonymousId');\n }\n}\n\nexport function validateBatchPayload(items: DmdServerBatchItem[]): void {\n if (!Array.isArray(items) || items.length === 0) {\n throw new DmdServerValidationError('DMD server SDK batch requires at least one item');\n }\n\n for (const item of items) {\n if (item.type === 'track') validateTrackPayload(item.payload);\n else if (item.type === 'identify') validateIdentifyPayload(item.payload);\n else if (item.type === 'page') validatePagePayload(item.payload);\n else if (item.type === 'alias') validateAliasPayload(item.payload);\n else if (item.type === 'group') validateGroupPayload(item.payload);\n else throw new DmdServerValidationError('DMD server SDK batch item has invalid type');\n }\n}\n","import { DmdServerRequestError } from './errors';\nimport { createBackendCollectorPayload } from '../core/backend-payload';\nimport { getRetryAttempts, getRetryDelayMs, isRetryableStatus } from './retry';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerSingleRequestPayload,\n DmdServerTrackPayload\n} from './types';\nimport {\n validateAliasPayload,\n validateBatchPayload,\n validateGroupPayload,\n validateIdentifyPayload,\n validatePagePayload,\n validateServerConfig,\n validateTrackPayload\n} from './validation';\n\nconst DEFAULT_ENDPOINT = 'https://sdk.drivemetadata.com/v2/data-collector';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction withTimestamp<T extends { timestamp?: string }>(payload: T): T {\n return {\n ...payload,\n timestamp: payload.timestamp ?? new Date().toISOString()\n };\n}\n\nfunction withBatchItemTimestamp(item: DmdServerBatchItem): DmdServerBatchItem {\n if (item.type === 'track') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'identify') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'page') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'alias') return { type: item.type, payload: withTimestamp(item.payload) };\n return { type: item.type, payload: withTimestamp(item.payload) };\n}\n\nfunction toCollectorPayload(\n config: DmdServerConfig,\n type: DmdServerSingleRequestPayload['type'],\n payload: DmdServerSingleRequestPayload['payload'],\n token: string | undefined\n) {\n const basePayload = payload as DmdServerTrackPayload & { anonymousId?: string; sessionId?: string };\n const properties = 'properties' in payload && payload.properties ? payload.properties : {};\n return createBackendCollectorPayload({\n requestId: payload.messageId ?? `${type}_${Date.now()}`,\n timestamp: payload.timestamp ?? new Date().toISOString(),\n eventType: type === 'track' ? basePayload.event : type,\n requestFrom: config.requestFrom ?? '3',\n clientId: config.clientId,\n workspaceId: config.workspaceId,\n token,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n appId: config.appId,\n eventData: {\n ...properties,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n timestamp: payload.timestamp ?? new Date().toISOString()\n }\n });\n}\n\nfunction createTimeoutController(timeoutMs: number | undefined): { signal?: AbortSignal; cleanup: () => void } {\n if (!timeoutMs) {\n return { cleanup: () => undefined };\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timer)\n };\n}\n\nexport function createDmdServerClient(config: DmdServerConfig): DmdServerClient {\n validateServerConfig(config);\n\n const endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n const fetchImpl = config.fetch ?? globalThis.fetch;\n const authorizationToken = config.writeKey || config.token;\n\n if (typeof fetchImpl !== 'function') {\n throw new Error('DMD server SDK requires fetch. Use Node.js 18+ or pass config.fetch.');\n }\n\n async function send(requestPayload: Record<string, unknown>): Promise<void> {\n const attempts = getRetryAttempts(config.retry);\n let lastError: unknown;\n\n for (let attemptIndex = 0; attemptIndex <= attempts; attemptIndex += 1) {\n try {\n const requestInit: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(requestPayload)\n };\n const timeout = createTimeoutController(config.timeoutMs);\n if (timeout.signal !== undefined) {\n requestInit.signal = timeout.signal;\n }\n\n const response = await fetchImpl(endpoint, requestInit).finally(timeout.cleanup);\n\n if (response.ok) {\n return;\n }\n\n if (!isRetryableStatus(response.status) || attemptIndex === attempts) {\n throw new DmdServerRequestError(\n `DMD server SDK request failed with status ${response.status}`,\n response.status\n );\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n } catch (error) {\n lastError = error;\n\n if (error instanceof DmdServerRequestError || attemptIndex === attempts) {\n throw error;\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n }\n }\n\n throw new DmdServerRequestError('DMD server SDK request failed', undefined, lastError);\n }\n\n function envelope(type: DmdServerSingleRequestPayload['type'], payload: DmdServerSingleRequestPayload['payload']) {\n return toCollectorPayload(config, type, payload, authorizationToken);\n }\n\n return {\n async track(payload: DmdServerTrackPayload) {\n validateTrackPayload(payload);\n await send(envelope('track', withTimestamp(payload)));\n },\n async identify(payload: DmdServerIdentifyPayload) {\n validateIdentifyPayload(payload);\n await send(envelope('identify', withTimestamp(payload)));\n },\n async page(payload: DmdServerPagePayload) {\n validatePagePayload(payload);\n await send(envelope('page', withTimestamp(payload)));\n },\n async alias(payload: DmdServerAliasPayload) {\n validateAliasPayload(payload);\n await send(envelope('alias', withTimestamp(payload)));\n },\n async group(payload: DmdServerGroupPayload) {\n validateGroupPayload(payload);\n await send(envelope('group', withTimestamp(payload)));\n },\n async batch(items: DmdServerBatchItem[]) {\n validateBatchPayload(items);\n await send({\n type: 'batch',\n batch: items.map(withBatchItemTimestamp),\n sentAt: new Date().toISOString()\n });\n },\n async flush() {\n return Promise.resolve();\n }\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/node/index.ts","../../src/node/errors.ts","../../src/core/uuid.ts","../../src/core/backend-payload.ts","../../src/core/backend-schema.ts","../../src/node/retry.ts","../../src/node/validation.ts","../../src/node/client.ts"],"sourcesContent":["export { createDmdServerClient } from './client';\nexport {\n DmdServerRequestError,\n DmdServerSdkError,\n DmdServerValidationError\n} from './errors';\nexport type {\n DmdServerAliasPayload,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerRetryConfig,\n DmdServerTrackPayload\n} from './types';\n","export class DmdServerSdkError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DmdServerSdkError';\n }\n}\n\nexport class DmdServerValidationError extends DmdServerSdkError {\n constructor(message: string) {\n super(message);\n this.name = 'DmdServerValidationError';\n }\n}\n\nexport class DmdServerRequestError extends DmdServerSdkError {\n constructor(message: string, public readonly status?: number, cause?: unknown) {\n super(message, cause);\n this.name = 'DmdServerRequestError';\n }\n}\n","export function createUuid(): string {\n const cryptoApi = globalThis.crypto;\n if (typeof cryptoApi?.randomUUID === 'function') {\n return cryptoApi.randomUUID();\n }\n\n const bytes = new Uint8Array(16);\n if (typeof cryptoApi?.getRandomValues === 'function') {\n cryptoApi.getRandomValues(bytes);\n } else {\n for (let index = 0; index < bytes.length; index += 1) {\n bytes[index] = Math.floor(Math.random() * 256);\n }\n }\n\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n\n const hex = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nexport function isUuid(value: unknown): value is string {\n return typeof value === 'string'\n && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n}\n\nexport function ensureUuid(value?: string): string {\n return isUuid(value) ? value : createUuid();\n}\n","import { ensureUuid } from './uuid';\n\nfunction formatUtcTimestamp(value: unknown): string {\n const date =\n typeof value === 'string' || typeof value === 'number' || value instanceof Date\n ? new Date(value)\n : new Date();\n const safeDate = Number.isNaN(date.getTime()) ? new Date() : date;\n return safeDate.toISOString().replace('T', ' ').slice(0, 19);\n}\n\nfunction cleanObject(value: unknown): unknown {\n if (Array.isArray(value)) {\n const cleaned = value\n .map(item => cleanObject(item))\n .filter(item => item !== null && item !== undefined && item !== '');\n return cleaned.length > 0 ? cleaned : undefined;\n }\n\n if (value && typeof value === 'object') {\n const cleaned = Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .map(([key, item]) => [key, cleanObject(item)])\n .filter(([, item]) => {\n if (item === null || item === undefined || item === '') return false;\n if (typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) return false;\n return true;\n })\n );\n return Object.keys(cleaned).length > 0 ? cleaned : undefined;\n }\n\n return value;\n}\n\nexport function createBackendCollectorPayload(input: Record<string, unknown>): Record<string, unknown> {\n const eventData = input.eventData && typeof input.eventData === 'object'\n ? input.eventData as Record<string, unknown>\n : {};\n const page = eventData.page && typeof eventData.page === 'object'\n ? eventData.page as Record<string, unknown>\n : {};\n const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);\n const normalizedEventData = {\n ...eventData,\n timestamp,\n requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),\n requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)\n };\n\n const metaData: Record<string, unknown> = {\n ...normalizedEventData,\n requestId: ensureUuid(typeof input.requestId === 'string' ? input.requestId : undefined),\n timestamp,\n eventType: input.eventType,\n requestFrom: input.requestFrom ?? '3',\n clientId: input.clientId,\n workspaceId: input.workspaceId,\n token: input.token,\n anonymousId: ensureUuid(\n typeof eventData.anonymousId === 'string'\n ? eventData.anonymousId\n : typeof input.anonymousId === 'string'\n ? input.anonymousId\n : undefined\n ),\n sessionId: ensureUuid(\n typeof eventData.sessionId === 'string'\n ? eventData.sessionId\n : typeof input.sessionId === 'string'\n ? input.sessionId\n : undefined\n ),\n ua: input.ua,\n appDetails: { app_id: input.appId },\n page: { ...page, url: page.url ?? input.pageUrl },\n requestSentAt: normalizedEventData.requestSentAt,\n requestReceivedAt: normalizedEventData.requestReceivedAt\n };\n\n const payload = { metaData };\n\n return cleanObject(payload) as Record<string, unknown>;\n}\n","const requiredMetaDataFields = [\n 'requestId',\n 'timestamp',\n 'eventType',\n 'requestFrom',\n 'clientId',\n 'workspaceId',\n 'anonymousId',\n 'sessionId'\n] as const;\n\nexport interface DmdBackendPayloadValidation {\n ok: boolean;\n errors: string[];\n}\n\nfunction isPresent(value: unknown): boolean {\n return value !== null && value !== undefined && value !== '';\n}\n\nexport function validateBackendCollectorPayload(payload: Record<string, unknown>): DmdBackendPayloadValidation {\n const errors: string[] = [];\n const metaData = payload.metaData;\n\n if (!metaData || typeof metaData !== 'object' || Array.isArray(metaData)) {\n return {\n ok: false,\n errors: ['metaData is required']\n };\n }\n\n const metadataRecord = metaData as Record<string, unknown>;\n for (const field of requiredMetaDataFields) {\n if (!isPresent(metadataRecord[field])) {\n errors.push(`metaData.${field} is required`);\n }\n }\n\n if (isPresent(metadataRecord.eventType) && typeof metadataRecord.eventType !== 'string') {\n errors.push('metaData.eventType must be a string');\n }\n\n return {\n ok: errors.length === 0,\n errors\n };\n}\n","import type { DmdServerRetryConfig } from './types';\n\nexport function isRetryableStatus(status: number): boolean {\n return status === 408 || status === 429 || status >= 500;\n}\n\nexport function getRetryDelayMs(attemptIndex: number, retry: DmdServerRetryConfig = {}): number {\n const minDelayMs = retry.minDelayMs ?? 250;\n const maxDelayMs = retry.maxDelayMs ?? 2000;\n const exponentialDelay = minDelayMs * 2 ** attemptIndex;\n\n return Math.min(exponentialDelay, maxDelayMs);\n}\n\nexport function getRetryAttempts(retry: DmdServerRetryConfig | undefined): number {\n return retry?.attempts ?? 0;\n}\n","import { DmdServerValidationError } from './errors';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerTrackPayload\n} from './types';\n\nfunction requireString(value: string | undefined, message: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new DmdServerValidationError(message);\n }\n\n return value;\n}\n\nexport function validateServerConfig(config: DmdServerConfig): void {\n requireString(config.writeKey || config.token, 'DMD server SDK config writeKey or token is required');\n}\n\nexport function validateTrackPayload(payload: DmdServerTrackPayload): void {\n requireString(payload.event, 'DMD server SDK track event is required');\n\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK track requires userId or anonymousId');\n }\n}\n\nexport function validateIdentifyPayload(payload: DmdServerIdentifyPayload): void {\n requireString(payload.userId, 'DMD server SDK identify requires userId');\n}\n\nexport function validatePagePayload(payload: DmdServerPagePayload): void {\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK page requires userId or anonymousId');\n }\n}\n\nexport function validateAliasPayload(payload: DmdServerAliasPayload): void {\n const hasPreviousId = typeof payload.previousId === 'string' && payload.previousId.trim() !== '';\n const hasUserId = typeof payload.userId === 'string' && payload.userId.trim() !== '';\n if (!hasPreviousId || !hasUserId) {\n throw new DmdServerValidationError('DMD server SDK alias requires previousId and userId');\n }\n}\n\nexport function validateGroupPayload(payload: DmdServerGroupPayload): void {\n requireString(payload.groupId, 'DMD server SDK group requires groupId');\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK group requires userId or anonymousId');\n }\n}\n\nexport function validateBatchPayload(items: DmdServerBatchItem[]): void {\n if (!Array.isArray(items) || items.length === 0) {\n throw new DmdServerValidationError('DMD server SDK batch requires at least one item');\n }\n\n for (const item of items) {\n if (item.type === 'track') validateTrackPayload(item.payload);\n else if (item.type === 'identify') validateIdentifyPayload(item.payload);\n else if (item.type === 'page') validatePagePayload(item.payload);\n else if (item.type === 'alias') validateAliasPayload(item.payload);\n else if (item.type === 'group') validateGroupPayload(item.payload);\n else throw new DmdServerValidationError('DMD server SDK batch item has invalid type');\n }\n}\n","import { DmdServerRequestError, DmdServerValidationError } from './errors';\nimport { createBackendCollectorPayload } from '../core/backend-payload';\nimport { validateBackendCollectorPayload } from '../core/backend-schema';\nimport { ensureUuid } from '../core/uuid';\nimport { getRetryAttempts, getRetryDelayMs, isRetryableStatus } from './retry';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerSingleRequestPayload,\n DmdServerTrackPayload\n} from './types';\nimport {\n validateAliasPayload,\n validateBatchPayload,\n validateGroupPayload,\n validateIdentifyPayload,\n validatePagePayload,\n validateServerConfig,\n validateTrackPayload\n} from './validation';\n\nconst DEFAULT_ENDPOINT = 'https://sdk.drivemetadata.com/v2/data-collector';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction withTimestamp<T extends { timestamp?: string }>(payload: T): T {\n return {\n ...payload,\n timestamp: payload.timestamp ?? new Date().toISOString()\n };\n}\n\nfunction withBatchItemTimestamp(item: DmdServerBatchItem): DmdServerBatchItem {\n if (item.type === 'track') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'identify') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'page') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'alias') return { type: item.type, payload: withTimestamp(item.payload) };\n return { type: item.type, payload: withTimestamp(item.payload) };\n}\n\nfunction toCollectorPayload(\n config: DmdServerConfig,\n type: DmdServerSingleRequestPayload['type'],\n payload: DmdServerSingleRequestPayload['payload'],\n token: string | undefined\n) {\n const basePayload = payload as DmdServerTrackPayload & { anonymousId?: string; sessionId?: string };\n const properties = 'properties' in payload && payload.properties ? payload.properties : {};\n const collectorPayload = createBackendCollectorPayload({\n requestId: ensureUuid(payload.messageId),\n timestamp: payload.timestamp ?? new Date().toISOString(),\n eventType: type === 'track' ? basePayload.event : type,\n requestFrom: config.requestFrom ?? '3',\n clientId: config.clientId,\n workspaceId: config.workspaceId,\n token,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n appId: config.appId,\n eventData: {\n ...properties,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n timestamp: payload.timestamp ?? new Date().toISOString()\n }\n });\n const validation = validateBackendCollectorPayload(collectorPayload);\n if (!validation.ok) {\n throw new DmdServerValidationError(`DMD server SDK backend payload invalid: ${validation.errors.join(', ')}`);\n }\n return collectorPayload;\n}\n\nfunction createTimeoutController(timeoutMs: number | undefined): { signal?: AbortSignal; cleanup: () => void } {\n if (!timeoutMs) {\n return { cleanup: () => undefined };\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timer)\n };\n}\n\nexport function createDmdServerClient(config: DmdServerConfig): DmdServerClient {\n validateServerConfig(config);\n\n const endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n const fetchImpl = config.fetch ?? globalThis.fetch;\n const authorizationToken = config.writeKey || config.token;\n\n if (typeof fetchImpl !== 'function') {\n throw new Error('DMD server SDK requires fetch. Use Node.js 18+ or pass config.fetch.');\n }\n\n async function send(requestPayload: Record<string, unknown>): Promise<void> {\n const attempts = getRetryAttempts(config.retry);\n let lastError: unknown;\n\n for (let attemptIndex = 0; attemptIndex <= attempts; attemptIndex += 1) {\n try {\n const requestInit: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(requestPayload)\n };\n const timeout = createTimeoutController(config.timeoutMs);\n if (timeout.signal !== undefined) {\n requestInit.signal = timeout.signal;\n }\n\n const response = await fetchImpl(endpoint, requestInit).finally(timeout.cleanup);\n\n if (response.ok) {\n return;\n }\n\n if (!isRetryableStatus(response.status) || attemptIndex === attempts) {\n throw new DmdServerRequestError(\n `DMD server SDK request failed with status ${response.status}`,\n response.status\n );\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n } catch (error) {\n lastError = error;\n\n if (error instanceof DmdServerRequestError || attemptIndex === attempts) {\n throw error;\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n }\n }\n\n throw new DmdServerRequestError('DMD server SDK request failed', undefined, lastError);\n }\n\n function envelope(type: DmdServerSingleRequestPayload['type'], payload: DmdServerSingleRequestPayload['payload']) {\n return toCollectorPayload(config, type, payload, authorizationToken);\n }\n\n return {\n async track(payload: DmdServerTrackPayload) {\n validateTrackPayload(payload);\n await send(envelope('track', withTimestamp(payload)));\n },\n async identify(payload: DmdServerIdentifyPayload) {\n validateIdentifyPayload(payload);\n await send(envelope('identify', withTimestamp(payload)));\n },\n async page(payload: DmdServerPagePayload) {\n validatePagePayload(payload);\n await send(envelope('page', withTimestamp(payload)));\n },\n async alias(payload: DmdServerAliasPayload) {\n validateAliasPayload(payload);\n await send(envelope('alias', withTimestamp(payload)));\n },\n async group(payload: DmdServerGroupPayload) {\n validateGroupPayload(payload);\n await send(envelope('group', withTimestamp(payload)));\n },\n async batch(items: DmdServerBatchItem[]) {\n validateBatchPayload(items);\n await send({\n type: 'batch',\n batch: items.map(withBatchItemTimestamp),\n sentAt: new Date().toISOString()\n });\n },\n async flush() {\n return Promise.resolve();\n }\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/node/index.js
CHANGED
|
@@ -20,12 +20,37 @@ var DmdServerRequestError = class extends DmdServerSdkError {
|
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
// src/core/uuid.ts
|
|
24
|
+
function createUuid() {
|
|
25
|
+
const cryptoApi = globalThis.crypto;
|
|
26
|
+
if (typeof cryptoApi?.randomUUID === "function") {
|
|
27
|
+
return cryptoApi.randomUUID();
|
|
28
|
+
}
|
|
29
|
+
const bytes = new Uint8Array(16);
|
|
30
|
+
if (typeof cryptoApi?.getRandomValues === "function") {
|
|
31
|
+
cryptoApi.getRandomValues(bytes);
|
|
32
|
+
} else {
|
|
33
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
34
|
+
bytes[index] = Math.floor(Math.random() * 256);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
bytes[6] = (bytes[6] ?? 0) & 15 | 64;
|
|
38
|
+
bytes[8] = (bytes[8] ?? 0) & 63 | 128;
|
|
39
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
40
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
41
|
+
}
|
|
42
|
+
function isUuid(value) {
|
|
43
|
+
return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
44
|
+
}
|
|
45
|
+
function ensureUuid(value) {
|
|
46
|
+
return isUuid(value) ? value : createUuid();
|
|
47
|
+
}
|
|
48
|
+
|
|
23
49
|
// src/core/backend-payload.ts
|
|
24
50
|
function formatUtcTimestamp(value) {
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
return date.toISOString().replace("T", " ").slice(0, 19);
|
|
51
|
+
const date = typeof value === "string" || typeof value === "number" || value instanceof Date ? new Date(value) : /* @__PURE__ */ new Date();
|
|
52
|
+
const safeDate = Number.isNaN(date.getTime()) ? /* @__PURE__ */ new Date() : date;
|
|
53
|
+
return safeDate.toISOString().replace("T", " ").slice(0, 19);
|
|
29
54
|
}
|
|
30
55
|
function cleanObject(value) {
|
|
31
56
|
if (Array.isArray(value)) {
|
|
@@ -56,15 +81,19 @@ function createBackendCollectorPayload(input) {
|
|
|
56
81
|
};
|
|
57
82
|
const metaData = {
|
|
58
83
|
...normalizedEventData,
|
|
59
|
-
requestId: input.requestId,
|
|
84
|
+
requestId: ensureUuid(typeof input.requestId === "string" ? input.requestId : void 0),
|
|
60
85
|
timestamp,
|
|
61
86
|
eventType: input.eventType,
|
|
62
87
|
requestFrom: input.requestFrom ?? "3",
|
|
63
88
|
clientId: input.clientId,
|
|
64
89
|
workspaceId: input.workspaceId,
|
|
65
90
|
token: input.token,
|
|
66
|
-
anonymousId:
|
|
67
|
-
|
|
91
|
+
anonymousId: ensureUuid(
|
|
92
|
+
typeof eventData.anonymousId === "string" ? eventData.anonymousId : typeof input.anonymousId === "string" ? input.anonymousId : void 0
|
|
93
|
+
),
|
|
94
|
+
sessionId: ensureUuid(
|
|
95
|
+
typeof eventData.sessionId === "string" ? eventData.sessionId : typeof input.sessionId === "string" ? input.sessionId : void 0
|
|
96
|
+
),
|
|
68
97
|
ua: input.ua,
|
|
69
98
|
appDetails: { app_id: input.appId },
|
|
70
99
|
page: { ...page, url: page.url ?? input.pageUrl },
|
|
@@ -75,6 +104,44 @@ function createBackendCollectorPayload(input) {
|
|
|
75
104
|
return cleanObject(payload);
|
|
76
105
|
}
|
|
77
106
|
|
|
107
|
+
// src/core/backend-schema.ts
|
|
108
|
+
var requiredMetaDataFields = [
|
|
109
|
+
"requestId",
|
|
110
|
+
"timestamp",
|
|
111
|
+
"eventType",
|
|
112
|
+
"requestFrom",
|
|
113
|
+
"clientId",
|
|
114
|
+
"workspaceId",
|
|
115
|
+
"anonymousId",
|
|
116
|
+
"sessionId"
|
|
117
|
+
];
|
|
118
|
+
function isPresent(value) {
|
|
119
|
+
return value !== null && value !== void 0 && value !== "";
|
|
120
|
+
}
|
|
121
|
+
function validateBackendCollectorPayload(payload) {
|
|
122
|
+
const errors = [];
|
|
123
|
+
const metaData = payload.metaData;
|
|
124
|
+
if (!metaData || typeof metaData !== "object" || Array.isArray(metaData)) {
|
|
125
|
+
return {
|
|
126
|
+
ok: false,
|
|
127
|
+
errors: ["metaData is required"]
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const metadataRecord = metaData;
|
|
131
|
+
for (const field of requiredMetaDataFields) {
|
|
132
|
+
if (!isPresent(metadataRecord[field])) {
|
|
133
|
+
errors.push(`metaData.${field} is required`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (isPresent(metadataRecord.eventType) && typeof metadataRecord.eventType !== "string") {
|
|
137
|
+
errors.push("metaData.eventType must be a string");
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
ok: errors.length === 0,
|
|
141
|
+
errors
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
78
145
|
// src/node/retry.ts
|
|
79
146
|
function isRetryableStatus(status) {
|
|
80
147
|
return status === 408 || status === 429 || status >= 500;
|
|
@@ -161,8 +228,8 @@ function withBatchItemTimestamp(item) {
|
|
|
161
228
|
function toCollectorPayload(config, type, payload, token) {
|
|
162
229
|
const basePayload = payload;
|
|
163
230
|
const properties = "properties" in payload && payload.properties ? payload.properties : {};
|
|
164
|
-
|
|
165
|
-
requestId: payload.messageId
|
|
231
|
+
const collectorPayload = createBackendCollectorPayload({
|
|
232
|
+
requestId: ensureUuid(payload.messageId),
|
|
166
233
|
timestamp: payload.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
167
234
|
eventType: type === "track" ? basePayload.event : type,
|
|
168
235
|
requestFrom: config.requestFrom ?? "3",
|
|
@@ -179,6 +246,11 @@ function toCollectorPayload(config, type, payload, token) {
|
|
|
179
246
|
timestamp: payload.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
180
247
|
}
|
|
181
248
|
});
|
|
249
|
+
const validation = validateBackendCollectorPayload(collectorPayload);
|
|
250
|
+
if (!validation.ok) {
|
|
251
|
+
throw new DmdServerValidationError(`DMD server SDK backend payload invalid: ${validation.errors.join(", ")}`);
|
|
252
|
+
}
|
|
253
|
+
return collectorPayload;
|
|
182
254
|
}
|
|
183
255
|
function createTimeoutController(timeoutMs) {
|
|
184
256
|
if (!timeoutMs) {
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/node/errors.ts","../../src/core/backend-payload.ts","../../src/node/retry.ts","../../src/node/validation.ts","../../src/node/client.ts"],"sourcesContent":["export class DmdServerSdkError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DmdServerSdkError';\n }\n}\n\nexport class DmdServerValidationError extends DmdServerSdkError {\n constructor(message: string) {\n super(message);\n this.name = 'DmdServerValidationError';\n }\n}\n\nexport class DmdServerRequestError extends DmdServerSdkError {\n constructor(message: string, public readonly status?: number, cause?: unknown) {\n super(message, cause);\n this.name = 'DmdServerRequestError';\n }\n}\n","function formatUtcTimestamp(value: unknown): string {\n if (typeof value !== 'string') return new Date().toISOString().replace('T', ' ').slice(0, 19);\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toISOString().replace('T', ' ').slice(0, 19);\n}\n\nfunction cleanObject(value: unknown): unknown {\n if (Array.isArray(value)) {\n const cleaned = value\n .map(item => cleanObject(item))\n .filter(item => item !== null && item !== undefined && item !== '');\n return cleaned.length > 0 ? cleaned : undefined;\n }\n\n if (value && typeof value === 'object') {\n const cleaned = Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .map(([key, item]) => [key, cleanObject(item)])\n .filter(([, item]) => {\n if (item === null || item === undefined || item === '') return false;\n if (typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) return false;\n return true;\n })\n );\n return Object.keys(cleaned).length > 0 ? cleaned : undefined;\n }\n\n return value;\n}\n\nexport function createBackendCollectorPayload(input: Record<string, unknown>): Record<string, unknown> {\n const eventData = input.eventData && typeof input.eventData === 'object'\n ? input.eventData as Record<string, unknown>\n : {};\n const page = eventData.page && typeof eventData.page === 'object'\n ? eventData.page as Record<string, unknown>\n : {};\n const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);\n const normalizedEventData = {\n ...eventData,\n timestamp,\n requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),\n requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)\n };\n\n const metaData: Record<string, unknown> = {\n ...normalizedEventData,\n requestId: input.requestId,\n timestamp,\n eventType: input.eventType,\n requestFrom: input.requestFrom ?? '3',\n clientId: input.clientId,\n workspaceId: input.workspaceId,\n token: input.token,\n anonymousId: eventData.anonymousId ?? input.anonymousId,\n sessionId: eventData.sessionId ?? input.sessionId,\n ua: input.ua,\n appDetails: { app_id: input.appId },\n page: { ...page, url: page.url ?? input.pageUrl },\n requestSentAt: normalizedEventData.requestSentAt,\n requestReceivedAt: normalizedEventData.requestReceivedAt\n };\n\n const payload = { metaData };\n\n return cleanObject(payload) as Record<string, unknown>;\n}\n","import type { DmdServerRetryConfig } from './types';\n\nexport function isRetryableStatus(status: number): boolean {\n return status === 408 || status === 429 || status >= 500;\n}\n\nexport function getRetryDelayMs(attemptIndex: number, retry: DmdServerRetryConfig = {}): number {\n const minDelayMs = retry.minDelayMs ?? 250;\n const maxDelayMs = retry.maxDelayMs ?? 2000;\n const exponentialDelay = minDelayMs * 2 ** attemptIndex;\n\n return Math.min(exponentialDelay, maxDelayMs);\n}\n\nexport function getRetryAttempts(retry: DmdServerRetryConfig | undefined): number {\n return retry?.attempts ?? 0;\n}\n","import { DmdServerValidationError } from './errors';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerTrackPayload\n} from './types';\n\nfunction requireString(value: string | undefined, message: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new DmdServerValidationError(message);\n }\n\n return value;\n}\n\nexport function validateServerConfig(config: DmdServerConfig): void {\n requireString(config.writeKey || config.token, 'DMD server SDK config writeKey or token is required');\n}\n\nexport function validateTrackPayload(payload: DmdServerTrackPayload): void {\n requireString(payload.event, 'DMD server SDK track event is required');\n\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK track requires userId or anonymousId');\n }\n}\n\nexport function validateIdentifyPayload(payload: DmdServerIdentifyPayload): void {\n requireString(payload.userId, 'DMD server SDK identify requires userId');\n}\n\nexport function validatePagePayload(payload: DmdServerPagePayload): void {\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK page requires userId or anonymousId');\n }\n}\n\nexport function validateAliasPayload(payload: DmdServerAliasPayload): void {\n const hasPreviousId = typeof payload.previousId === 'string' && payload.previousId.trim() !== '';\n const hasUserId = typeof payload.userId === 'string' && payload.userId.trim() !== '';\n if (!hasPreviousId || !hasUserId) {\n throw new DmdServerValidationError('DMD server SDK alias requires previousId and userId');\n }\n}\n\nexport function validateGroupPayload(payload: DmdServerGroupPayload): void {\n requireString(payload.groupId, 'DMD server SDK group requires groupId');\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK group requires userId or anonymousId');\n }\n}\n\nexport function validateBatchPayload(items: DmdServerBatchItem[]): void {\n if (!Array.isArray(items) || items.length === 0) {\n throw new DmdServerValidationError('DMD server SDK batch requires at least one item');\n }\n\n for (const item of items) {\n if (item.type === 'track') validateTrackPayload(item.payload);\n else if (item.type === 'identify') validateIdentifyPayload(item.payload);\n else if (item.type === 'page') validatePagePayload(item.payload);\n else if (item.type === 'alias') validateAliasPayload(item.payload);\n else if (item.type === 'group') validateGroupPayload(item.payload);\n else throw new DmdServerValidationError('DMD server SDK batch item has invalid type');\n }\n}\n","import { DmdServerRequestError } from './errors';\nimport { createBackendCollectorPayload } from '../core/backend-payload';\nimport { getRetryAttempts, getRetryDelayMs, isRetryableStatus } from './retry';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerSingleRequestPayload,\n DmdServerTrackPayload\n} from './types';\nimport {\n validateAliasPayload,\n validateBatchPayload,\n validateGroupPayload,\n validateIdentifyPayload,\n validatePagePayload,\n validateServerConfig,\n validateTrackPayload\n} from './validation';\n\nconst DEFAULT_ENDPOINT = 'https://sdk.drivemetadata.com/v2/data-collector';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction withTimestamp<T extends { timestamp?: string }>(payload: T): T {\n return {\n ...payload,\n timestamp: payload.timestamp ?? new Date().toISOString()\n };\n}\n\nfunction withBatchItemTimestamp(item: DmdServerBatchItem): DmdServerBatchItem {\n if (item.type === 'track') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'identify') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'page') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'alias') return { type: item.type, payload: withTimestamp(item.payload) };\n return { type: item.type, payload: withTimestamp(item.payload) };\n}\n\nfunction toCollectorPayload(\n config: DmdServerConfig,\n type: DmdServerSingleRequestPayload['type'],\n payload: DmdServerSingleRequestPayload['payload'],\n token: string | undefined\n) {\n const basePayload = payload as DmdServerTrackPayload & { anonymousId?: string; sessionId?: string };\n const properties = 'properties' in payload && payload.properties ? payload.properties : {};\n return createBackendCollectorPayload({\n requestId: payload.messageId ?? `${type}_${Date.now()}`,\n timestamp: payload.timestamp ?? new Date().toISOString(),\n eventType: type === 'track' ? basePayload.event : type,\n requestFrom: config.requestFrom ?? '3',\n clientId: config.clientId,\n workspaceId: config.workspaceId,\n token,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n appId: config.appId,\n eventData: {\n ...properties,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n timestamp: payload.timestamp ?? new Date().toISOString()\n }\n });\n}\n\nfunction createTimeoutController(timeoutMs: number | undefined): { signal?: AbortSignal; cleanup: () => void } {\n if (!timeoutMs) {\n return { cleanup: () => undefined };\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timer)\n };\n}\n\nexport function createDmdServerClient(config: DmdServerConfig): DmdServerClient {\n validateServerConfig(config);\n\n const endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n const fetchImpl = config.fetch ?? globalThis.fetch;\n const authorizationToken = config.writeKey || config.token;\n\n if (typeof fetchImpl !== 'function') {\n throw new Error('DMD server SDK requires fetch. Use Node.js 18+ or pass config.fetch.');\n }\n\n async function send(requestPayload: Record<string, unknown>): Promise<void> {\n const attempts = getRetryAttempts(config.retry);\n let lastError: unknown;\n\n for (let attemptIndex = 0; attemptIndex <= attempts; attemptIndex += 1) {\n try {\n const requestInit: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(requestPayload)\n };\n const timeout = createTimeoutController(config.timeoutMs);\n if (timeout.signal !== undefined) {\n requestInit.signal = timeout.signal;\n }\n\n const response = await fetchImpl(endpoint, requestInit).finally(timeout.cleanup);\n\n if (response.ok) {\n return;\n }\n\n if (!isRetryableStatus(response.status) || attemptIndex === attempts) {\n throw new DmdServerRequestError(\n `DMD server SDK request failed with status ${response.status}`,\n response.status\n );\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n } catch (error) {\n lastError = error;\n\n if (error instanceof DmdServerRequestError || attemptIndex === attempts) {\n throw error;\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n }\n }\n\n throw new DmdServerRequestError('DMD server SDK request failed', undefined, lastError);\n }\n\n function envelope(type: DmdServerSingleRequestPayload['type'], payload: DmdServerSingleRequestPayload['payload']) {\n return toCollectorPayload(config, type, payload, authorizationToken);\n }\n\n return {\n async track(payload: DmdServerTrackPayload) {\n validateTrackPayload(payload);\n await send(envelope('track', withTimestamp(payload)));\n },\n async identify(payload: DmdServerIdentifyPayload) {\n validateIdentifyPayload(payload);\n await send(envelope('identify', withTimestamp(payload)));\n },\n async page(payload: DmdServerPagePayload) {\n validatePagePayload(payload);\n await send(envelope('page', withTimestamp(payload)));\n },\n async alias(payload: DmdServerAliasPayload) {\n validateAliasPayload(payload);\n await send(envelope('alias', withTimestamp(payload)));\n },\n async group(payload: DmdServerGroupPayload) {\n validateGroupPayload(payload);\n await send(envelope('group', withTimestamp(payload)));\n },\n async batch(items: DmdServerBatchItem[]) {\n validateBatchPayload(items);\n await send({\n type: 'batch',\n batch: items.map(withBatchItemTimestamp),\n sentAt: new Date().toISOString()\n });\n },\n async flush() {\n return Promise.resolve();\n }\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/node/errors.ts","../../src/core/uuid.ts","../../src/core/backend-payload.ts","../../src/core/backend-schema.ts","../../src/node/retry.ts","../../src/node/validation.ts","../../src/node/client.ts"],"sourcesContent":["export class DmdServerSdkError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DmdServerSdkError';\n }\n}\n\nexport class DmdServerValidationError extends DmdServerSdkError {\n constructor(message: string) {\n super(message);\n this.name = 'DmdServerValidationError';\n }\n}\n\nexport class DmdServerRequestError extends DmdServerSdkError {\n constructor(message: string, public readonly status?: number, cause?: unknown) {\n super(message, cause);\n this.name = 'DmdServerRequestError';\n }\n}\n","export function createUuid(): string {\n const cryptoApi = globalThis.crypto;\n if (typeof cryptoApi?.randomUUID === 'function') {\n return cryptoApi.randomUUID();\n }\n\n const bytes = new Uint8Array(16);\n if (typeof cryptoApi?.getRandomValues === 'function') {\n cryptoApi.getRandomValues(bytes);\n } else {\n for (let index = 0; index < bytes.length; index += 1) {\n bytes[index] = Math.floor(Math.random() * 256);\n }\n }\n\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n\n const hex = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nexport function isUuid(value: unknown): value is string {\n return typeof value === 'string'\n && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n}\n\nexport function ensureUuid(value?: string): string {\n return isUuid(value) ? value : createUuid();\n}\n","import { ensureUuid } from './uuid';\n\nfunction formatUtcTimestamp(value: unknown): string {\n const date =\n typeof value === 'string' || typeof value === 'number' || value instanceof Date\n ? new Date(value)\n : new Date();\n const safeDate = Number.isNaN(date.getTime()) ? new Date() : date;\n return safeDate.toISOString().replace('T', ' ').slice(0, 19);\n}\n\nfunction cleanObject(value: unknown): unknown {\n if (Array.isArray(value)) {\n const cleaned = value\n .map(item => cleanObject(item))\n .filter(item => item !== null && item !== undefined && item !== '');\n return cleaned.length > 0 ? cleaned : undefined;\n }\n\n if (value && typeof value === 'object') {\n const cleaned = Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .map(([key, item]) => [key, cleanObject(item)])\n .filter(([, item]) => {\n if (item === null || item === undefined || item === '') return false;\n if (typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) return false;\n return true;\n })\n );\n return Object.keys(cleaned).length > 0 ? cleaned : undefined;\n }\n\n return value;\n}\n\nexport function createBackendCollectorPayload(input: Record<string, unknown>): Record<string, unknown> {\n const eventData = input.eventData && typeof input.eventData === 'object'\n ? input.eventData as Record<string, unknown>\n : {};\n const page = eventData.page && typeof eventData.page === 'object'\n ? eventData.page as Record<string, unknown>\n : {};\n const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);\n const normalizedEventData = {\n ...eventData,\n timestamp,\n requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),\n requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)\n };\n\n const metaData: Record<string, unknown> = {\n ...normalizedEventData,\n requestId: ensureUuid(typeof input.requestId === 'string' ? input.requestId : undefined),\n timestamp,\n eventType: input.eventType,\n requestFrom: input.requestFrom ?? '3',\n clientId: input.clientId,\n workspaceId: input.workspaceId,\n token: input.token,\n anonymousId: ensureUuid(\n typeof eventData.anonymousId === 'string'\n ? eventData.anonymousId\n : typeof input.anonymousId === 'string'\n ? input.anonymousId\n : undefined\n ),\n sessionId: ensureUuid(\n typeof eventData.sessionId === 'string'\n ? eventData.sessionId\n : typeof input.sessionId === 'string'\n ? input.sessionId\n : undefined\n ),\n ua: input.ua,\n appDetails: { app_id: input.appId },\n page: { ...page, url: page.url ?? input.pageUrl },\n requestSentAt: normalizedEventData.requestSentAt,\n requestReceivedAt: normalizedEventData.requestReceivedAt\n };\n\n const payload = { metaData };\n\n return cleanObject(payload) as Record<string, unknown>;\n}\n","const requiredMetaDataFields = [\n 'requestId',\n 'timestamp',\n 'eventType',\n 'requestFrom',\n 'clientId',\n 'workspaceId',\n 'anonymousId',\n 'sessionId'\n] as const;\n\nexport interface DmdBackendPayloadValidation {\n ok: boolean;\n errors: string[];\n}\n\nfunction isPresent(value: unknown): boolean {\n return value !== null && value !== undefined && value !== '';\n}\n\nexport function validateBackendCollectorPayload(payload: Record<string, unknown>): DmdBackendPayloadValidation {\n const errors: string[] = [];\n const metaData = payload.metaData;\n\n if (!metaData || typeof metaData !== 'object' || Array.isArray(metaData)) {\n return {\n ok: false,\n errors: ['metaData is required']\n };\n }\n\n const metadataRecord = metaData as Record<string, unknown>;\n for (const field of requiredMetaDataFields) {\n if (!isPresent(metadataRecord[field])) {\n errors.push(`metaData.${field} is required`);\n }\n }\n\n if (isPresent(metadataRecord.eventType) && typeof metadataRecord.eventType !== 'string') {\n errors.push('metaData.eventType must be a string');\n }\n\n return {\n ok: errors.length === 0,\n errors\n };\n}\n","import type { DmdServerRetryConfig } from './types';\n\nexport function isRetryableStatus(status: number): boolean {\n return status === 408 || status === 429 || status >= 500;\n}\n\nexport function getRetryDelayMs(attemptIndex: number, retry: DmdServerRetryConfig = {}): number {\n const minDelayMs = retry.minDelayMs ?? 250;\n const maxDelayMs = retry.maxDelayMs ?? 2000;\n const exponentialDelay = minDelayMs * 2 ** attemptIndex;\n\n return Math.min(exponentialDelay, maxDelayMs);\n}\n\nexport function getRetryAttempts(retry: DmdServerRetryConfig | undefined): number {\n return retry?.attempts ?? 0;\n}\n","import { DmdServerValidationError } from './errors';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerTrackPayload\n} from './types';\n\nfunction requireString(value: string | undefined, message: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new DmdServerValidationError(message);\n }\n\n return value;\n}\n\nexport function validateServerConfig(config: DmdServerConfig): void {\n requireString(config.writeKey || config.token, 'DMD server SDK config writeKey or token is required');\n}\n\nexport function validateTrackPayload(payload: DmdServerTrackPayload): void {\n requireString(payload.event, 'DMD server SDK track event is required');\n\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK track requires userId or anonymousId');\n }\n}\n\nexport function validateIdentifyPayload(payload: DmdServerIdentifyPayload): void {\n requireString(payload.userId, 'DMD server SDK identify requires userId');\n}\n\nexport function validatePagePayload(payload: DmdServerPagePayload): void {\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK page requires userId or anonymousId');\n }\n}\n\nexport function validateAliasPayload(payload: DmdServerAliasPayload): void {\n const hasPreviousId = typeof payload.previousId === 'string' && payload.previousId.trim() !== '';\n const hasUserId = typeof payload.userId === 'string' && payload.userId.trim() !== '';\n if (!hasPreviousId || !hasUserId) {\n throw new DmdServerValidationError('DMD server SDK alias requires previousId and userId');\n }\n}\n\nexport function validateGroupPayload(payload: DmdServerGroupPayload): void {\n requireString(payload.groupId, 'DMD server SDK group requires groupId');\n if (!payload.userId && !payload.anonymousId) {\n throw new DmdServerValidationError('DMD server SDK group requires userId or anonymousId');\n }\n}\n\nexport function validateBatchPayload(items: DmdServerBatchItem[]): void {\n if (!Array.isArray(items) || items.length === 0) {\n throw new DmdServerValidationError('DMD server SDK batch requires at least one item');\n }\n\n for (const item of items) {\n if (item.type === 'track') validateTrackPayload(item.payload);\n else if (item.type === 'identify') validateIdentifyPayload(item.payload);\n else if (item.type === 'page') validatePagePayload(item.payload);\n else if (item.type === 'alias') validateAliasPayload(item.payload);\n else if (item.type === 'group') validateGroupPayload(item.payload);\n else throw new DmdServerValidationError('DMD server SDK batch item has invalid type');\n }\n}\n","import { DmdServerRequestError, DmdServerValidationError } from './errors';\nimport { createBackendCollectorPayload } from '../core/backend-payload';\nimport { validateBackendCollectorPayload } from '../core/backend-schema';\nimport { ensureUuid } from '../core/uuid';\nimport { getRetryAttempts, getRetryDelayMs, isRetryableStatus } from './retry';\nimport type {\n DmdServerAliasPayload,\n DmdServerBatchItem,\n DmdServerClient,\n DmdServerConfig,\n DmdServerGroupPayload,\n DmdServerIdentifyPayload,\n DmdServerPagePayload,\n DmdServerSingleRequestPayload,\n DmdServerTrackPayload\n} from './types';\nimport {\n validateAliasPayload,\n validateBatchPayload,\n validateGroupPayload,\n validateIdentifyPayload,\n validatePagePayload,\n validateServerConfig,\n validateTrackPayload\n} from './validation';\n\nconst DEFAULT_ENDPOINT = 'https://sdk.drivemetadata.com/v2/data-collector';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction withTimestamp<T extends { timestamp?: string }>(payload: T): T {\n return {\n ...payload,\n timestamp: payload.timestamp ?? new Date().toISOString()\n };\n}\n\nfunction withBatchItemTimestamp(item: DmdServerBatchItem): DmdServerBatchItem {\n if (item.type === 'track') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'identify') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'page') return { type: item.type, payload: withTimestamp(item.payload) };\n if (item.type === 'alias') return { type: item.type, payload: withTimestamp(item.payload) };\n return { type: item.type, payload: withTimestamp(item.payload) };\n}\n\nfunction toCollectorPayload(\n config: DmdServerConfig,\n type: DmdServerSingleRequestPayload['type'],\n payload: DmdServerSingleRequestPayload['payload'],\n token: string | undefined\n) {\n const basePayload = payload as DmdServerTrackPayload & { anonymousId?: string; sessionId?: string };\n const properties = 'properties' in payload && payload.properties ? payload.properties : {};\n const collectorPayload = createBackendCollectorPayload({\n requestId: ensureUuid(payload.messageId),\n timestamp: payload.timestamp ?? new Date().toISOString(),\n eventType: type === 'track' ? basePayload.event : type,\n requestFrom: config.requestFrom ?? '3',\n clientId: config.clientId,\n workspaceId: config.workspaceId,\n token,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n appId: config.appId,\n eventData: {\n ...properties,\n anonymousId: basePayload.anonymousId,\n sessionId: basePayload.sessionId,\n timestamp: payload.timestamp ?? new Date().toISOString()\n }\n });\n const validation = validateBackendCollectorPayload(collectorPayload);\n if (!validation.ok) {\n throw new DmdServerValidationError(`DMD server SDK backend payload invalid: ${validation.errors.join(', ')}`);\n }\n return collectorPayload;\n}\n\nfunction createTimeoutController(timeoutMs: number | undefined): { signal?: AbortSignal; cleanup: () => void } {\n if (!timeoutMs) {\n return { cleanup: () => undefined };\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n return {\n signal: controller.signal,\n cleanup: () => clearTimeout(timer)\n };\n}\n\nexport function createDmdServerClient(config: DmdServerConfig): DmdServerClient {\n validateServerConfig(config);\n\n const endpoint = config.endpoint ?? DEFAULT_ENDPOINT;\n const fetchImpl = config.fetch ?? globalThis.fetch;\n const authorizationToken = config.writeKey || config.token;\n\n if (typeof fetchImpl !== 'function') {\n throw new Error('DMD server SDK requires fetch. Use Node.js 18+ or pass config.fetch.');\n }\n\n async function send(requestPayload: Record<string, unknown>): Promise<void> {\n const attempts = getRetryAttempts(config.retry);\n let lastError: unknown;\n\n for (let attemptIndex = 0; attemptIndex <= attempts; attemptIndex += 1) {\n try {\n const requestInit: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(requestPayload)\n };\n const timeout = createTimeoutController(config.timeoutMs);\n if (timeout.signal !== undefined) {\n requestInit.signal = timeout.signal;\n }\n\n const response = await fetchImpl(endpoint, requestInit).finally(timeout.cleanup);\n\n if (response.ok) {\n return;\n }\n\n if (!isRetryableStatus(response.status) || attemptIndex === attempts) {\n throw new DmdServerRequestError(\n `DMD server SDK request failed with status ${response.status}`,\n response.status\n );\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n } catch (error) {\n lastError = error;\n\n if (error instanceof DmdServerRequestError || attemptIndex === attempts) {\n throw error;\n }\n\n await sleep(getRetryDelayMs(attemptIndex, config.retry));\n }\n }\n\n throw new DmdServerRequestError('DMD server SDK request failed', undefined, lastError);\n }\n\n function envelope(type: DmdServerSingleRequestPayload['type'], payload: DmdServerSingleRequestPayload['payload']) {\n return toCollectorPayload(config, type, payload, authorizationToken);\n }\n\n return {\n async track(payload: DmdServerTrackPayload) {\n validateTrackPayload(payload);\n await send(envelope('track', withTimestamp(payload)));\n },\n async identify(payload: DmdServerIdentifyPayload) {\n validateIdentifyPayload(payload);\n await send(envelope('identify', withTimestamp(payload)));\n },\n async page(payload: DmdServerPagePayload) {\n validatePagePayload(payload);\n await send(envelope('page', withTimestamp(payload)));\n },\n async alias(payload: DmdServerAliasPayload) {\n validateAliasPayload(payload);\n await send(envelope('alias', withTimestamp(payload)));\n },\n async group(payload: DmdServerGroupPayload) {\n validateGroupPayload(payload);\n await send(envelope('group', withTimestamp(payload)));\n },\n async batch(items: DmdServerBatchItem[]) {\n validateBatchPayload(items);\n await send({\n type: 'batch',\n batch: items.map(withBatchItemTimestamp),\n sentAt: new Date().toISOString()\n });\n },\n async flush() {\n return Promise.resolve();\n }\n };\n}\n"],"mappings":"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","names":[]}
|