@openmdm/drizzle-adapter 0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * OpenMDM Drizzle Adapter\n *\n * Database adapter for Drizzle ORM, supporting PostgreSQL, MySQL, and SQLite.\n *\n * @example\n * ```typescript\n * import { drizzle } from 'drizzle-orm/node-postgres';\n * import { drizzleAdapter } from '@openmdm/drizzle-adapter';\n * import { mdmSchema } from '@openmdm/drizzle-adapter/postgres';\n * import { createMDM } from '@openmdm/core';\n *\n * const pool = new Pool({ connectionString: DATABASE_URL });\n * const db = drizzle(pool, { schema: mdmSchema });\n *\n * const mdm = createMDM({\n * database: drizzleAdapter(db),\n * // ...\n * });\n * ```\n */\n\nimport { eq, and, or, like, inArray, desc, sql, isNull, type SQL } from 'drizzle-orm';\nimport { nanoid } from 'nanoid';\nimport type {\n DatabaseAdapter,\n Device,\n DeviceFilter,\n DeviceListResult,\n CreateDeviceInput,\n UpdateDeviceInput,\n Policy,\n CreatePolicyInput,\n UpdatePolicyInput,\n Application,\n CreateApplicationInput,\n UpdateApplicationInput,\n Command,\n SendCommandInput,\n CommandFilter,\n MDMEvent,\n EventFilter,\n Group,\n CreateGroupInput,\n UpdateGroupInput,\n PushToken,\n RegisterPushTokenInput,\n PolicySettings,\n InstalledApp,\n DeviceLocation,\n} from '@openmdm/core';\n\n// Import postgres schema types\nimport type {\n mdmDevices,\n mdmPolicies,\n mdmApplications,\n mdmCommands,\n mdmEvents,\n mdmGroups,\n mdmDeviceGroups,\n mdmPushTokens,\n} from './postgres';\n\n// Type for Drizzle database instance\ntype DrizzleDB = {\n select: (columns?: unknown) => unknown;\n insert: (table: unknown) => unknown;\n update: (table: unknown) => unknown;\n delete: (table: unknown) => unknown;\n query: Record<string, unknown>;\n transaction: <T>(fn: (tx: DrizzleDB) => Promise<T>) => Promise<T>;\n};\n\nexport interface DrizzleAdapterOptions {\n /**\n * Table references - pass your imported Drizzle tables\n */\n tables: {\n devices: typeof mdmDevices;\n policies: typeof mdmPolicies;\n applications: typeof mdmApplications;\n commands: typeof mdmCommands;\n events: typeof mdmEvents;\n groups: typeof mdmGroups;\n deviceGroups: typeof mdmDeviceGroups;\n pushTokens: typeof mdmPushTokens;\n };\n}\n\n/**\n * Create a Drizzle database adapter for OpenMDM\n */\nexport function drizzleAdapter(\n db: DrizzleDB,\n options: DrizzleAdapterOptions\n): DatabaseAdapter {\n const { tables } = options;\n const {\n devices,\n policies,\n applications,\n commands,\n events,\n groups,\n deviceGroups,\n pushTokens,\n } = tables;\n\n // Helper to generate IDs\n const generateId = () => nanoid(21);\n\n // Helper to transform DB row to Device\n const toDevice = (row: Record<string, unknown>): Device => ({\n id: row.id as string,\n externalId: row.externalId as string | null,\n enrollmentId: row.enrollmentId as string,\n status: row.status as Device['status'],\n model: row.model as string | null,\n manufacturer: row.manufacturer as string | null,\n osVersion: row.osVersion as string | null,\n serialNumber: row.serialNumber as string | null,\n imei: row.imei as string | null,\n macAddress: row.macAddress as string | null,\n androidId: row.androidId as string | null,\n policyId: row.policyId as string | null,\n lastHeartbeat: row.lastHeartbeat as Date | null,\n lastSync: row.lastSync as Date | null,\n batteryLevel: row.batteryLevel as number | null,\n storageUsed: row.storageUsed as number | null,\n storageTotal: row.storageTotal as number | null,\n location:\n row.latitude && row.longitude\n ? {\n latitude: parseFloat(row.latitude as string),\n longitude: parseFloat(row.longitude as string),\n timestamp: row.locationTimestamp as Date,\n }\n : null,\n installedApps: row.installedApps as InstalledApp[] | null,\n tags: row.tags as Record<string, string> | null,\n metadata: row.metadata as Record<string, unknown> | null,\n createdAt: row.createdAt as Date,\n updatedAt: row.updatedAt as Date,\n });\n\n // Helper to transform DB row to Policy\n const toPolicy = (row: Record<string, unknown>): Policy => ({\n id: row.id as string,\n name: row.name as string,\n description: row.description as string | null,\n isDefault: row.isDefault as boolean,\n settings: row.settings as PolicySettings,\n createdAt: row.createdAt as Date,\n updatedAt: row.updatedAt as Date,\n });\n\n // Helper to transform DB row to Application\n const toApplication = (row: Record<string, unknown>): Application => ({\n id: row.id as string,\n name: row.name as string,\n packageName: row.packageName as string,\n version: row.version as string,\n versionCode: row.versionCode as number,\n url: row.url as string,\n hash: row.hash as string | null,\n size: row.size as number | null,\n minSdkVersion: row.minSdkVersion as number | null,\n showIcon: row.showIcon as boolean,\n runAfterInstall: row.runAfterInstall as boolean,\n runAtBoot: row.runAtBoot as boolean,\n isSystem: row.isSystem as boolean,\n isActive: row.isActive as boolean,\n metadata: row.metadata as Record<string, unknown> | null,\n createdAt: row.createdAt as Date,\n updatedAt: row.updatedAt as Date,\n });\n\n // Helper to transform DB row to Command\n const toCommand = (row: Record<string, unknown>): Command => ({\n id: row.id as string,\n deviceId: row.deviceId as string,\n type: row.type as Command['type'],\n payload: row.payload as Record<string, unknown> | null,\n status: row.status as Command['status'],\n result: row.result as Command['result'],\n error: row.error as string | null,\n createdAt: row.createdAt as Date,\n sentAt: row.sentAt as Date | null,\n acknowledgedAt: row.acknowledgedAt as Date | null,\n completedAt: row.completedAt as Date | null,\n });\n\n // Helper to transform DB row to Event\n const toEvent = (row: Record<string, unknown>): MDMEvent => ({\n id: row.id as string,\n deviceId: row.deviceId as string,\n type: row.type as MDMEvent['type'],\n payload: row.payload as Record<string, unknown>,\n createdAt: row.createdAt as Date,\n });\n\n // Helper to transform DB row to Group\n const toGroup = (row: Record<string, unknown>): Group => ({\n id: row.id as string,\n name: row.name as string,\n description: row.description as string | null,\n policyId: row.policyId as string | null,\n parentId: row.parentId as string | null,\n metadata: row.metadata as Record<string, unknown> | null,\n createdAt: row.createdAt as Date,\n updatedAt: row.updatedAt as Date,\n });\n\n // Helper to transform DB row to PushToken\n const toPushToken = (row: Record<string, unknown>): PushToken => ({\n id: row.id as string,\n deviceId: row.deviceId as string,\n provider: row.provider as PushToken['provider'],\n token: row.token as string,\n isActive: row.isActive as boolean,\n createdAt: row.createdAt as Date,\n updatedAt: row.updatedAt as Date,\n });\n\n return {\n // ============================================\n // Device Methods\n // ============================================\n\n async findDevice(id: string): Promise<Device | null> {\n const result = await (db as any)\n .select()\n .from(devices)\n .where(eq(devices.id, id))\n .limit(1);\n return result[0] ? toDevice(result[0]) : null;\n },\n\n async findDeviceByEnrollmentId(\n enrollmentId: string\n ): Promise<Device | null> {\n const result = await (db as any)\n .select()\n .from(devices)\n .where(eq(devices.enrollmentId, enrollmentId))\n .limit(1);\n return result[0] ? toDevice(result[0]) : null;\n },\n\n async listDevices(filter?: DeviceFilter): Promise<DeviceListResult> {\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n\n let query = (db as any).select().from(devices);\n\n // Build WHERE conditions\n const conditions: (SQL | undefined)[] = [];\n\n if (filter?.status) {\n if (Array.isArray(filter.status)) {\n conditions.push(inArray(devices.status, filter.status));\n } else {\n conditions.push(eq(devices.status, filter.status));\n }\n }\n\n if (filter?.policyId) {\n conditions.push(eq(devices.policyId, filter.policyId));\n }\n\n if (filter?.search) {\n const searchPattern = `%${filter.search}%`;\n conditions.push(\n or(\n like(devices.model, searchPattern),\n like(devices.manufacturer, searchPattern),\n like(devices.enrollmentId, searchPattern),\n like(devices.serialNumber, searchPattern)\n )\n );\n }\n\n if (conditions.length > 0) {\n query = query.where(and(...conditions));\n }\n\n // Get total count\n const countResult = await (db as any)\n .select({ count: sql<number>`count(*)` })\n .from(devices)\n .where(conditions.length > 0 ? and(...conditions) : undefined);\n const total = Number(countResult[0]?.count ?? 0);\n\n // Get paginated results\n const result = await query\n .orderBy(desc(devices.createdAt))\n .limit(limit)\n .offset(offset);\n\n return {\n devices: result.map(toDevice),\n total,\n limit,\n offset,\n };\n },\n\n async createDevice(data: CreateDeviceInput): Promise<Device> {\n const id = generateId();\n const now = new Date();\n\n const deviceData = {\n id,\n enrollmentId: data.enrollmentId,\n externalId: data.externalId ?? null,\n status: 'pending' as const,\n model: data.model ?? null,\n manufacturer: data.manufacturer ?? null,\n osVersion: data.osVersion ?? null,\n serialNumber: data.serialNumber ?? null,\n imei: data.imei ?? null,\n macAddress: data.macAddress ?? null,\n androidId: data.androidId ?? null,\n policyId: data.policyId ?? null,\n tags: data.tags ?? null,\n metadata: data.metadata ?? null,\n createdAt: now,\n updatedAt: now,\n };\n\n await (db as any).insert(devices).values(deviceData);\n\n return this.findDevice(id) as Promise<Device>;\n },\n\n async updateDevice(id: string, data: UpdateDeviceInput): Promise<Device> {\n const updateData: Record<string, unknown> = {\n updatedAt: new Date(),\n };\n\n if (data.externalId !== undefined) updateData.externalId = data.externalId;\n if (data.status !== undefined) updateData.status = data.status;\n if (data.policyId !== undefined) updateData.policyId = data.policyId;\n if (data.model !== undefined) updateData.model = data.model;\n if (data.manufacturer !== undefined)\n updateData.manufacturer = data.manufacturer;\n if (data.osVersion !== undefined) updateData.osVersion = data.osVersion;\n if (data.batteryLevel !== undefined)\n updateData.batteryLevel = data.batteryLevel;\n if (data.storageUsed !== undefined)\n updateData.storageUsed = data.storageUsed;\n if (data.storageTotal !== undefined)\n updateData.storageTotal = data.storageTotal;\n if (data.lastHeartbeat !== undefined)\n updateData.lastHeartbeat = data.lastHeartbeat;\n if (data.lastSync !== undefined) updateData.lastSync = data.lastSync;\n if (data.installedApps !== undefined)\n updateData.installedApps = data.installedApps;\n if (data.tags !== undefined) updateData.tags = data.tags;\n if (data.metadata !== undefined) updateData.metadata = data.metadata;\n\n if (data.location) {\n updateData.latitude = data.location.latitude.toString();\n updateData.longitude = data.location.longitude.toString();\n updateData.locationTimestamp = data.location.timestamp;\n }\n\n await (db as any)\n .update(devices)\n .set(updateData)\n .where(eq(devices.id, id));\n\n return this.findDevice(id) as Promise<Device>;\n },\n\n async deleteDevice(id: string): Promise<void> {\n await (db as any).delete(devices).where(eq(devices.id, id));\n },\n\n async countDevices(filter?: DeviceFilter): Promise<number> {\n const result = await this.listDevices({ ...filter, limit: 0 });\n return result.total;\n },\n\n // ============================================\n // Policy Methods\n // ============================================\n\n async findPolicy(id: string): Promise<Policy | null> {\n const result = await (db as any)\n .select()\n .from(policies)\n .where(eq(policies.id, id))\n .limit(1);\n return result[0] ? toPolicy(result[0]) : null;\n },\n\n async findDefaultPolicy(): Promise<Policy | null> {\n const result = await (db as any)\n .select()\n .from(policies)\n .where(eq(policies.isDefault, true))\n .limit(1);\n return result[0] ? toPolicy(result[0]) : null;\n },\n\n async listPolicies(): Promise<Policy[]> {\n const result = await (db as any)\n .select()\n .from(policies)\n .orderBy(desc(policies.createdAt));\n return result.map(toPolicy);\n },\n\n async createPolicy(data: CreatePolicyInput): Promise<Policy> {\n const id = generateId();\n const now = new Date();\n\n const policyData = {\n id,\n name: data.name,\n description: data.description ?? null,\n isDefault: data.isDefault ?? false,\n settings: data.settings,\n createdAt: now,\n updatedAt: now,\n };\n\n await (db as any).insert(policies).values(policyData);\n\n return this.findPolicy(id) as Promise<Policy>;\n },\n\n async updatePolicy(id: string, data: UpdatePolicyInput): Promise<Policy> {\n const updateData: Record<string, unknown> = {\n updatedAt: new Date(),\n };\n\n if (data.name !== undefined) updateData.name = data.name;\n if (data.description !== undefined)\n updateData.description = data.description;\n if (data.isDefault !== undefined) updateData.isDefault = data.isDefault;\n if (data.settings !== undefined) updateData.settings = data.settings;\n\n await (db as any)\n .update(policies)\n .set(updateData)\n .where(eq(policies.id, id));\n\n return this.findPolicy(id) as Promise<Policy>;\n },\n\n async deletePolicy(id: string): Promise<void> {\n await (db as any).delete(policies).where(eq(policies.id, id));\n },\n\n // ============================================\n // Application Methods\n // ============================================\n\n async findApplication(id: string): Promise<Application | null> {\n const result = await (db as any)\n .select()\n .from(applications)\n .where(eq(applications.id, id))\n .limit(1);\n return result[0] ? toApplication(result[0]) : null;\n },\n\n async findApplicationByPackage(\n packageName: string,\n version?: string\n ): Promise<Application | null> {\n let query = (db as any)\n .select()\n .from(applications)\n .where(eq(applications.packageName, packageName));\n\n if (version) {\n query = query.where(eq(applications.version, version));\n }\n\n const result = await query.orderBy(desc(applications.versionCode)).limit(1);\n return result[0] ? toApplication(result[0]) : null;\n },\n\n async listApplications(activeOnly?: boolean): Promise<Application[]> {\n let query = (db as any).select().from(applications);\n\n if (activeOnly) {\n query = query.where(eq(applications.isActive, true));\n }\n\n const result = await query.orderBy(desc(applications.createdAt));\n return result.map(toApplication);\n },\n\n async createApplication(data: CreateApplicationInput): Promise<Application> {\n const id = generateId();\n const now = new Date();\n\n const appData = {\n id,\n name: data.name,\n packageName: data.packageName,\n version: data.version,\n versionCode: data.versionCode,\n url: data.url,\n hash: data.hash ?? null,\n size: data.size ?? null,\n minSdkVersion: data.minSdkVersion ?? null,\n showIcon: data.showIcon ?? true,\n runAfterInstall: data.runAfterInstall ?? false,\n runAtBoot: data.runAtBoot ?? false,\n isSystem: data.isSystem ?? false,\n isActive: true,\n metadata: data.metadata ?? null,\n createdAt: now,\n updatedAt: now,\n };\n\n await (db as any).insert(applications).values(appData);\n\n return this.findApplication(id) as Promise<Application>;\n },\n\n async updateApplication(\n id: string,\n data: UpdateApplicationInput\n ): Promise<Application> {\n const updateData: Record<string, unknown> = {\n updatedAt: new Date(),\n };\n\n if (data.name !== undefined) updateData.name = data.name;\n if (data.version !== undefined) updateData.version = data.version;\n if (data.versionCode !== undefined)\n updateData.versionCode = data.versionCode;\n if (data.url !== undefined) updateData.url = data.url;\n if (data.hash !== undefined) updateData.hash = data.hash;\n if (data.size !== undefined) updateData.size = data.size;\n if (data.minSdkVersion !== undefined)\n updateData.minSdkVersion = data.minSdkVersion;\n if (data.showIcon !== undefined) updateData.showIcon = data.showIcon;\n if (data.runAfterInstall !== undefined)\n updateData.runAfterInstall = data.runAfterInstall;\n if (data.runAtBoot !== undefined) updateData.runAtBoot = data.runAtBoot;\n if (data.isActive !== undefined) updateData.isActive = data.isActive;\n if (data.metadata !== undefined) updateData.metadata = data.metadata;\n\n await (db as any)\n .update(applications)\n .set(updateData)\n .where(eq(applications.id, id));\n\n return this.findApplication(id) as Promise<Application>;\n },\n\n async deleteApplication(id: string): Promise<void> {\n await (db as any).delete(applications).where(eq(applications.id, id));\n },\n\n // ============================================\n // Command Methods\n // ============================================\n\n async findCommand(id: string): Promise<Command | null> {\n const result = await (db as any)\n .select()\n .from(commands)\n .where(eq(commands.id, id))\n .limit(1);\n return result[0] ? toCommand(result[0]) : null;\n },\n\n async listCommands(filter?: CommandFilter): Promise<Command[]> {\n let query = (db as any).select().from(commands);\n\n const conditions: (SQL | undefined)[] = [];\n\n if (filter?.deviceId) {\n conditions.push(eq(commands.deviceId, filter.deviceId));\n }\n\n if (filter?.status) {\n if (Array.isArray(filter.status)) {\n conditions.push(inArray(commands.status, filter.status));\n } else {\n conditions.push(eq(commands.status, filter.status));\n }\n }\n\n if (filter?.type) {\n if (Array.isArray(filter.type)) {\n conditions.push(inArray(commands.type, filter.type));\n } else {\n conditions.push(eq(commands.type, filter.type));\n }\n }\n\n if (conditions.length > 0) {\n query = query.where(and(...conditions));\n }\n\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n\n const result = await query\n .orderBy(desc(commands.createdAt))\n .limit(limit)\n .offset(offset);\n\n return result.map(toCommand);\n },\n\n async createCommand(data: SendCommandInput): Promise<Command> {\n const id = generateId();\n const now = new Date();\n\n const commandData = {\n id,\n deviceId: data.deviceId,\n type: data.type,\n payload: data.payload ?? null,\n status: 'pending' as const,\n createdAt: now,\n };\n\n await (db as any).insert(commands).values(commandData);\n\n return this.findCommand(id) as Promise<Command>;\n },\n\n async updateCommand(id: string, data: Partial<Command>): Promise<Command> {\n const updateData: Record<string, unknown> = {};\n\n if (data.status !== undefined) updateData.status = data.status;\n if (data.result !== undefined) updateData.result = data.result;\n if (data.error !== undefined) updateData.error = data.error;\n if (data.sentAt !== undefined) updateData.sentAt = data.sentAt;\n if (data.acknowledgedAt !== undefined)\n updateData.acknowledgedAt = data.acknowledgedAt;\n if (data.completedAt !== undefined)\n updateData.completedAt = data.completedAt;\n\n await (db as any)\n .update(commands)\n .set(updateData)\n .where(eq(commands.id, id));\n\n return this.findCommand(id) as Promise<Command>;\n },\n\n async getPendingCommands(deviceId: string): Promise<Command[]> {\n return this.listCommands({\n deviceId,\n status: ['pending', 'sent'],\n });\n },\n\n // ============================================\n // Event Methods\n // ============================================\n\n async createEvent(\n data: Omit<MDMEvent, 'id' | 'createdAt'>\n ): Promise<MDMEvent> {\n const id = generateId();\n const now = new Date();\n\n const eventData = {\n id,\n deviceId: data.deviceId,\n type: data.type,\n payload: data.payload,\n createdAt: now,\n };\n\n await (db as any).insert(events).values(eventData);\n\n return {\n ...eventData,\n createdAt: now,\n };\n },\n\n async listEvents(filter?: EventFilter): Promise<MDMEvent[]> {\n let query = (db as any).select().from(events);\n\n const conditions: (SQL | undefined)[] = [];\n\n if (filter?.deviceId) {\n conditions.push(eq(events.deviceId, filter.deviceId));\n }\n\n if (filter?.type) {\n if (Array.isArray(filter.type)) {\n conditions.push(inArray(events.type, filter.type));\n } else {\n conditions.push(eq(events.type, filter.type));\n }\n }\n\n if (conditions.length > 0) {\n query = query.where(and(...conditions));\n }\n\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n\n const result = await query\n .orderBy(desc(events.createdAt))\n .limit(limit)\n .offset(offset);\n\n return result.map(toEvent);\n },\n\n // ============================================\n // Group Methods\n // ============================================\n\n async findGroup(id: string): Promise<Group | null> {\n const result = await (db as any)\n .select()\n .from(groups)\n .where(eq(groups.id, id))\n .limit(1);\n return result[0] ? toGroup(result[0]) : null;\n },\n\n async listGroups(): Promise<Group[]> {\n const result = await (db as any)\n .select()\n .from(groups)\n .orderBy(groups.name);\n return result.map(toGroup);\n },\n\n async createGroup(data: CreateGroupInput): Promise<Group> {\n const id = generateId();\n const now = new Date();\n\n const groupData = {\n id,\n name: data.name,\n description: data.description ?? null,\n policyId: data.policyId ?? null,\n parentId: data.parentId ?? null,\n metadata: data.metadata ?? null,\n createdAt: now,\n updatedAt: now,\n };\n\n await (db as any).insert(groups).values(groupData);\n\n return this.findGroup(id) as Promise<Group>;\n },\n\n async updateGroup(id: string, data: UpdateGroupInput): Promise<Group> {\n const updateData: Record<string, unknown> = {\n updatedAt: new Date(),\n };\n\n if (data.name !== undefined) updateData.name = data.name;\n if (data.description !== undefined)\n updateData.description = data.description;\n if (data.policyId !== undefined) updateData.policyId = data.policyId;\n if (data.parentId !== undefined) updateData.parentId = data.parentId;\n if (data.metadata !== undefined) updateData.metadata = data.metadata;\n\n await (db as any)\n .update(groups)\n .set(updateData)\n .where(eq(groups.id, id));\n\n return this.findGroup(id) as Promise<Group>;\n },\n\n async deleteGroup(id: string): Promise<void> {\n await (db as any).delete(groups).where(eq(groups.id, id));\n },\n\n async listDevicesInGroup(groupId: string): Promise<Device[]> {\n const result = await (db as any)\n .select({ device: devices })\n .from(deviceGroups)\n .innerJoin(devices, eq(deviceGroups.deviceId, devices.id))\n .where(eq(deviceGroups.groupId, groupId));\n\n return result.map((r: { device: Record<string, unknown> }) =>\n toDevice(r.device)\n );\n },\n\n async addDeviceToGroup(deviceId: string, groupId: string): Promise<void> {\n await (db as any).insert(deviceGroups).values({\n deviceId,\n groupId,\n createdAt: new Date(),\n });\n },\n\n async removeDeviceFromGroup(\n deviceId: string,\n groupId: string\n ): Promise<void> {\n await (db as any)\n .delete(deviceGroups)\n .where(\n and(\n eq(deviceGroups.deviceId, deviceId),\n eq(deviceGroups.groupId, groupId)\n )\n );\n },\n\n async getDeviceGroups(deviceId: string): Promise<Group[]> {\n const result = await (db as any)\n .select({ group: groups })\n .from(deviceGroups)\n .innerJoin(groups, eq(deviceGroups.groupId, groups.id))\n .where(eq(deviceGroups.deviceId, deviceId));\n\n return result.map((r: { group: Record<string, unknown> }) =>\n toGroup(r.group)\n );\n },\n\n // ============================================\n // Push Token Methods\n // ============================================\n\n async findPushToken(\n deviceId: string,\n provider: string\n ): Promise<PushToken | null> {\n const result = await (db as any)\n .select()\n .from(pushTokens)\n .where(\n and(\n eq(pushTokens.deviceId, deviceId),\n eq(pushTokens.provider, provider as any)\n )\n )\n .limit(1);\n return result[0] ? toPushToken(result[0]) : null;\n },\n\n async upsertPushToken(data: RegisterPushTokenInput): Promise<PushToken> {\n const existing = await this.findPushToken(data.deviceId, data.provider);\n const now = new Date();\n\n if (existing) {\n await (db as any)\n .update(pushTokens)\n .set({\n token: data.token,\n isActive: true,\n updatedAt: now,\n })\n .where(eq(pushTokens.id, existing.id));\n\n return this.findPushToken(data.deviceId, data.provider) as Promise<PushToken>;\n }\n\n const id = generateId();\n await (db as any).insert(pushTokens).values({\n id,\n deviceId: data.deviceId,\n provider: data.provider,\n token: data.token,\n isActive: true,\n createdAt: now,\n updatedAt: now,\n });\n\n return this.findPushToken(data.deviceId, data.provider) as Promise<PushToken>;\n },\n\n async deletePushToken(deviceId: string, provider?: string): Promise<void> {\n if (provider) {\n await (db as any)\n .delete(pushTokens)\n .where(\n and(\n eq(pushTokens.deviceId, deviceId),\n eq(pushTokens.provider, provider as any)\n )\n );\n } else {\n await (db as any)\n .delete(pushTokens)\n .where(eq(pushTokens.deviceId, deviceId));\n }\n },\n\n // ============================================\n // Transaction Support\n // ============================================\n\n async transaction<T>(fn: () => Promise<T>): Promise<T> {\n return db.transaction(async () => {\n return fn();\n });\n },\n };\n}\n\n// Re-export schema utilities\nexport { DEFAULT_TABLE_PREFIX } from './schema';\nexport type { SchemaOptions } from './schema';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * OpenMDM Drizzle Schema for MySQL
3
+ *
4
+ * Ready-to-use Drizzle table definitions for MySQL databases.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { mdmDevices, mdmPolicies } from '@openmdm/drizzle-adapter/mysql';
9
+ * import { drizzle } from 'drizzle-orm/mysql2';
10
+ *
11
+ * const db = drizzle(connection, { schema: { mdmDevices, mdmPolicies, ... } });
12
+ * ```
13
+ */
14
+ declare const placeholder = "MySQL schema coming soon";
15
+
16
+ export { placeholder };
package/dist/mysql.js ADDED
@@ -0,0 +1,9 @@
1
+ // src/mysql.ts
2
+ var placeholder = "MySQL schema coming soon";
3
+ throw new Error(
4
+ "@openmdm/drizzle-adapter/mysql is not yet implemented. Please use @openmdm/drizzle-adapter/postgres for now, or contribute the MySQL schema!"
5
+ );
6
+ export {
7
+ placeholder
8
+ };
9
+ //# sourceMappingURL=mysql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mysql.ts"],"sourcesContent":["/**\n * OpenMDM Drizzle Schema for MySQL\n *\n * Ready-to-use Drizzle table definitions for MySQL databases.\n *\n * @example\n * ```typescript\n * import { mdmDevices, mdmPolicies } from '@openmdm/drizzle-adapter/mysql';\n * import { drizzle } from 'drizzle-orm/mysql2';\n *\n * const db = drizzle(connection, { schema: { mdmDevices, mdmPolicies, ... } });\n * ```\n */\n\n// MySQL schema implementation\n// TODO: Implement MySQL-specific schema\n// For now, users should use the PostgreSQL schema as reference\n\nexport const placeholder = 'MySQL schema coming soon';\n\nthrow new Error(\n '@openmdm/drizzle-adapter/mysql is not yet implemented. ' +\n 'Please use @openmdm/drizzle-adapter/postgres for now, or contribute the MySQL schema!'\n);\n"],"mappings":";AAkBO,IAAM,cAAc;AAE3B,MAAM,IAAI;AAAA,EACR;AAEF;","names":[]}