@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.
- package/LICENSE +21 -0
- package/dist/chunk-ULFOOXEW.js +11 -0
- package/dist/chunk-ULFOOXEW.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +588 -0
- package/dist/index.js.map +1 -0
- package/dist/mysql.d.ts +16 -0
- package/dist/mysql.js +9 -0
- package/dist/mysql.js.map +1 -0
- package/dist/postgres.d.ts +3505 -0
- package/dist/postgres.js +374 -0
- package/dist/postgres.js.map +1 -0
- package/dist/schema.d.ts +28 -0
- package/dist/schema.js +13 -0
- package/dist/schema.js.map +1 -0
- package/dist/sqlite.d.ts +16 -0
- package/dist/sqlite.js +9 -0
- package/dist/sqlite.js.map +1 -0
- package/package.json +75 -0
- package/src/index.ts +914 -0
- package/src/mysql.ts +24 -0
- package/src/postgres.ts +487 -0
- package/src/schema.ts +27 -0
- package/src/sqlite.ts +24 -0
package/src/mysql.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
|
|
15
|
+
// MySQL schema implementation
|
|
16
|
+
// TODO: Implement MySQL-specific schema
|
|
17
|
+
// For now, users should use the PostgreSQL schema as reference
|
|
18
|
+
|
|
19
|
+
export const placeholder = 'MySQL schema coming soon';
|
|
20
|
+
|
|
21
|
+
throw new Error(
|
|
22
|
+
'@openmdm/drizzle-adapter/mysql is not yet implemented. ' +
|
|
23
|
+
'Please use @openmdm/drizzle-adapter/postgres for now, or contribute the MySQL schema!'
|
|
24
|
+
);
|
package/src/postgres.ts
ADDED
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenMDM Drizzle Schema for PostgreSQL
|
|
3
|
+
*
|
|
4
|
+
* Ready-to-use Drizzle table definitions for PostgreSQL databases.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { mdmDevices, mdmPolicies } from '@openmdm/drizzle-adapter/postgres';
|
|
9
|
+
* import { drizzle } from 'drizzle-orm/node-postgres';
|
|
10
|
+
*
|
|
11
|
+
* const db = drizzle(pool, { schema: { mdmDevices, mdmPolicies, ... } });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
pgTable,
|
|
17
|
+
pgEnum,
|
|
18
|
+
text,
|
|
19
|
+
varchar,
|
|
20
|
+
boolean,
|
|
21
|
+
integer,
|
|
22
|
+
bigint,
|
|
23
|
+
timestamp,
|
|
24
|
+
json,
|
|
25
|
+
index,
|
|
26
|
+
uniqueIndex,
|
|
27
|
+
primaryKey,
|
|
28
|
+
} from 'drizzle-orm/pg-core';
|
|
29
|
+
import { relations } from 'drizzle-orm';
|
|
30
|
+
|
|
31
|
+
// ============================================
|
|
32
|
+
// Enums
|
|
33
|
+
// ============================================
|
|
34
|
+
|
|
35
|
+
export const deviceStatusEnum = pgEnum('mdm_device_status', [
|
|
36
|
+
'pending',
|
|
37
|
+
'enrolled',
|
|
38
|
+
'unenrolled',
|
|
39
|
+
'blocked',
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
export const commandStatusEnum = pgEnum('mdm_command_status', [
|
|
43
|
+
'pending',
|
|
44
|
+
'sent',
|
|
45
|
+
'acknowledged',
|
|
46
|
+
'completed',
|
|
47
|
+
'failed',
|
|
48
|
+
'cancelled',
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
export const pushProviderEnum = pgEnum('mdm_push_provider', [
|
|
52
|
+
'fcm',
|
|
53
|
+
'mqtt',
|
|
54
|
+
'websocket',
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
export const deployTargetTypeEnum = pgEnum('mdm_deploy_target_type', [
|
|
58
|
+
'policy',
|
|
59
|
+
'group',
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
export const deployActionEnum = pgEnum('mdm_deploy_action', [
|
|
63
|
+
'install',
|
|
64
|
+
'update',
|
|
65
|
+
'uninstall',
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
// ============================================
|
|
69
|
+
// Devices Table
|
|
70
|
+
// ============================================
|
|
71
|
+
|
|
72
|
+
export const mdmDevices = pgTable(
|
|
73
|
+
'mdm_devices',
|
|
74
|
+
{
|
|
75
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
76
|
+
externalId: varchar('external_id', { length: 255 }),
|
|
77
|
+
enrollmentId: varchar('enrollment_id', { length: 255 }).notNull().unique(),
|
|
78
|
+
status: deviceStatusEnum('status').notNull().default('pending'),
|
|
79
|
+
|
|
80
|
+
// Device Info
|
|
81
|
+
model: varchar('model', { length: 255 }),
|
|
82
|
+
manufacturer: varchar('manufacturer', { length: 255 }),
|
|
83
|
+
osVersion: varchar('os_version', { length: 50 }),
|
|
84
|
+
serialNumber: varchar('serial_number', { length: 255 }),
|
|
85
|
+
imei: varchar('imei', { length: 50 }),
|
|
86
|
+
macAddress: varchar('mac_address', { length: 50 }),
|
|
87
|
+
androidId: varchar('android_id', { length: 100 }),
|
|
88
|
+
|
|
89
|
+
// MDM State
|
|
90
|
+
policyId: varchar('policy_id', { length: 36 }).references(
|
|
91
|
+
() => mdmPolicies.id,
|
|
92
|
+
{ onDelete: 'set null' }
|
|
93
|
+
),
|
|
94
|
+
lastHeartbeat: timestamp('last_heartbeat', { withTimezone: true }),
|
|
95
|
+
lastSync: timestamp('last_sync', { withTimezone: true }),
|
|
96
|
+
|
|
97
|
+
// Telemetry
|
|
98
|
+
batteryLevel: integer('battery_level'),
|
|
99
|
+
storageUsed: bigint('storage_used', { mode: 'number' }),
|
|
100
|
+
storageTotal: bigint('storage_total', { mode: 'number' }),
|
|
101
|
+
latitude: varchar('latitude', { length: 50 }),
|
|
102
|
+
longitude: varchar('longitude', { length: 50 }),
|
|
103
|
+
locationTimestamp: timestamp('location_timestamp', { withTimezone: true }),
|
|
104
|
+
|
|
105
|
+
// JSON fields
|
|
106
|
+
installedApps: json('installed_apps').$type<
|
|
107
|
+
Array<{ packageName: string; version: string; versionCode?: number }>
|
|
108
|
+
>(),
|
|
109
|
+
tags: json('tags').$type<Record<string, string>>(),
|
|
110
|
+
metadata: json('metadata').$type<Record<string, unknown>>(),
|
|
111
|
+
|
|
112
|
+
// Timestamps
|
|
113
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
114
|
+
.notNull()
|
|
115
|
+
.defaultNow(),
|
|
116
|
+
updatedAt: timestamp('updated_at', { withTimezone: true })
|
|
117
|
+
.notNull()
|
|
118
|
+
.defaultNow(),
|
|
119
|
+
},
|
|
120
|
+
(table) => [
|
|
121
|
+
index('mdm_devices_status_idx').on(table.status),
|
|
122
|
+
index('mdm_devices_policy_id_idx').on(table.policyId),
|
|
123
|
+
index('mdm_devices_last_heartbeat_idx').on(table.lastHeartbeat),
|
|
124
|
+
index('mdm_devices_mac_address_idx').on(table.macAddress),
|
|
125
|
+
index('mdm_devices_serial_number_idx').on(table.serialNumber),
|
|
126
|
+
]
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// ============================================
|
|
130
|
+
// Policies Table
|
|
131
|
+
// ============================================
|
|
132
|
+
|
|
133
|
+
export const mdmPolicies = pgTable(
|
|
134
|
+
'mdm_policies',
|
|
135
|
+
{
|
|
136
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
137
|
+
name: varchar('name', { length: 255 }).notNull(),
|
|
138
|
+
description: text('description'),
|
|
139
|
+
isDefault: boolean('is_default').notNull().default(false),
|
|
140
|
+
settings: json('settings').notNull().$type<Record<string, unknown>>(),
|
|
141
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
142
|
+
.notNull()
|
|
143
|
+
.defaultNow(),
|
|
144
|
+
updatedAt: timestamp('updated_at', { withTimezone: true })
|
|
145
|
+
.notNull()
|
|
146
|
+
.defaultNow(),
|
|
147
|
+
},
|
|
148
|
+
(table) => [
|
|
149
|
+
index('mdm_policies_name_idx').on(table.name),
|
|
150
|
+
index('mdm_policies_is_default_idx').on(table.isDefault),
|
|
151
|
+
]
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
// ============================================
|
|
155
|
+
// Applications Table
|
|
156
|
+
// ============================================
|
|
157
|
+
|
|
158
|
+
export const mdmApplications = pgTable(
|
|
159
|
+
'mdm_applications',
|
|
160
|
+
{
|
|
161
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
162
|
+
name: varchar('name', { length: 255 }).notNull(),
|
|
163
|
+
packageName: varchar('package_name', { length: 255 }).notNull(),
|
|
164
|
+
version: varchar('version', { length: 50 }).notNull(),
|
|
165
|
+
versionCode: integer('version_code').notNull(),
|
|
166
|
+
url: text('url').notNull(),
|
|
167
|
+
hash: varchar('hash', { length: 64 }), // SHA-256
|
|
168
|
+
size: bigint('size', { mode: 'number' }),
|
|
169
|
+
minSdkVersion: integer('min_sdk_version'),
|
|
170
|
+
|
|
171
|
+
// Deployment settings
|
|
172
|
+
showIcon: boolean('show_icon').notNull().default(true),
|
|
173
|
+
runAfterInstall: boolean('run_after_install').notNull().default(false),
|
|
174
|
+
runAtBoot: boolean('run_at_boot').notNull().default(false),
|
|
175
|
+
isSystem: boolean('is_system').notNull().default(false),
|
|
176
|
+
|
|
177
|
+
// State
|
|
178
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
179
|
+
|
|
180
|
+
// Metadata
|
|
181
|
+
metadata: json('metadata').$type<Record<string, unknown>>(),
|
|
182
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
183
|
+
.notNull()
|
|
184
|
+
.defaultNow(),
|
|
185
|
+
updatedAt: timestamp('updated_at', { withTimezone: true })
|
|
186
|
+
.notNull()
|
|
187
|
+
.defaultNow(),
|
|
188
|
+
},
|
|
189
|
+
(table) => [
|
|
190
|
+
index('mdm_applications_package_name_idx').on(table.packageName),
|
|
191
|
+
uniqueIndex('mdm_applications_package_version_idx').on(
|
|
192
|
+
table.packageName,
|
|
193
|
+
table.version
|
|
194
|
+
),
|
|
195
|
+
index('mdm_applications_is_active_idx').on(table.isActive),
|
|
196
|
+
]
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// ============================================
|
|
200
|
+
// Commands Table
|
|
201
|
+
// ============================================
|
|
202
|
+
|
|
203
|
+
export const mdmCommands = pgTable(
|
|
204
|
+
'mdm_commands',
|
|
205
|
+
{
|
|
206
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
207
|
+
deviceId: varchar('device_id', { length: 36 })
|
|
208
|
+
.notNull()
|
|
209
|
+
.references(() => mdmDevices.id, { onDelete: 'cascade' }),
|
|
210
|
+
type: varchar('type', { length: 50 }).notNull(),
|
|
211
|
+
payload: json('payload').$type<Record<string, unknown>>(),
|
|
212
|
+
status: commandStatusEnum('status').notNull().default('pending'),
|
|
213
|
+
result: json('result').$type<{
|
|
214
|
+
success: boolean;
|
|
215
|
+
message?: string;
|
|
216
|
+
data?: unknown;
|
|
217
|
+
}>(),
|
|
218
|
+
error: text('error'),
|
|
219
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
220
|
+
.notNull()
|
|
221
|
+
.defaultNow(),
|
|
222
|
+
sentAt: timestamp('sent_at', { withTimezone: true }),
|
|
223
|
+
acknowledgedAt: timestamp('acknowledged_at', { withTimezone: true }),
|
|
224
|
+
completedAt: timestamp('completed_at', { withTimezone: true }),
|
|
225
|
+
},
|
|
226
|
+
(table) => [
|
|
227
|
+
index('mdm_commands_device_id_idx').on(table.deviceId),
|
|
228
|
+
index('mdm_commands_status_idx').on(table.status),
|
|
229
|
+
index('mdm_commands_device_status_idx').on(table.deviceId, table.status),
|
|
230
|
+
index('mdm_commands_created_at_idx').on(table.createdAt),
|
|
231
|
+
]
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
// ============================================
|
|
235
|
+
// Events Table
|
|
236
|
+
// ============================================
|
|
237
|
+
|
|
238
|
+
export const mdmEvents = pgTable(
|
|
239
|
+
'mdm_events',
|
|
240
|
+
{
|
|
241
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
242
|
+
deviceId: varchar('device_id', { length: 36 })
|
|
243
|
+
.notNull()
|
|
244
|
+
.references(() => mdmDevices.id, { onDelete: 'cascade' }),
|
|
245
|
+
type: varchar('type', { length: 100 }).notNull(),
|
|
246
|
+
payload: json('payload').notNull().$type<Record<string, unknown>>(),
|
|
247
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
248
|
+
.notNull()
|
|
249
|
+
.defaultNow(),
|
|
250
|
+
},
|
|
251
|
+
(table) => [
|
|
252
|
+
index('mdm_events_device_id_idx').on(table.deviceId),
|
|
253
|
+
index('mdm_events_type_idx').on(table.type),
|
|
254
|
+
index('mdm_events_device_type_idx').on(table.deviceId, table.type),
|
|
255
|
+
index('mdm_events_created_at_idx').on(table.createdAt),
|
|
256
|
+
]
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
// ============================================
|
|
260
|
+
// Groups Table
|
|
261
|
+
// ============================================
|
|
262
|
+
|
|
263
|
+
export const mdmGroups = pgTable(
|
|
264
|
+
'mdm_groups',
|
|
265
|
+
{
|
|
266
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
267
|
+
name: varchar('name', { length: 255 }).notNull(),
|
|
268
|
+
description: text('description'),
|
|
269
|
+
policyId: varchar('policy_id', { length: 36 }).references(
|
|
270
|
+
() => mdmPolicies.id,
|
|
271
|
+
{ onDelete: 'set null' }
|
|
272
|
+
),
|
|
273
|
+
parentId: varchar('parent_id', { length: 36 }),
|
|
274
|
+
metadata: json('metadata').$type<Record<string, unknown>>(),
|
|
275
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
276
|
+
.notNull()
|
|
277
|
+
.defaultNow(),
|
|
278
|
+
updatedAt: timestamp('updated_at', { withTimezone: true })
|
|
279
|
+
.notNull()
|
|
280
|
+
.defaultNow(),
|
|
281
|
+
},
|
|
282
|
+
(table) => [
|
|
283
|
+
index('mdm_groups_name_idx').on(table.name),
|
|
284
|
+
index('mdm_groups_policy_id_idx').on(table.policyId),
|
|
285
|
+
index('mdm_groups_parent_id_idx').on(table.parentId),
|
|
286
|
+
]
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
// ============================================
|
|
290
|
+
// Device Groups (Many-to-Many)
|
|
291
|
+
// ============================================
|
|
292
|
+
|
|
293
|
+
export const mdmDeviceGroups = pgTable(
|
|
294
|
+
'mdm_device_groups',
|
|
295
|
+
{
|
|
296
|
+
deviceId: varchar('device_id', { length: 36 })
|
|
297
|
+
.notNull()
|
|
298
|
+
.references(() => mdmDevices.id, { onDelete: 'cascade' }),
|
|
299
|
+
groupId: varchar('group_id', { length: 36 })
|
|
300
|
+
.notNull()
|
|
301
|
+
.references(() => mdmGroups.id, { onDelete: 'cascade' }),
|
|
302
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
303
|
+
.notNull()
|
|
304
|
+
.defaultNow(),
|
|
305
|
+
},
|
|
306
|
+
(table) => [
|
|
307
|
+
primaryKey({ columns: [table.deviceId, table.groupId] }),
|
|
308
|
+
index('mdm_device_groups_group_id_idx').on(table.groupId),
|
|
309
|
+
]
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
// ============================================
|
|
313
|
+
// Push Tokens Table
|
|
314
|
+
// ============================================
|
|
315
|
+
|
|
316
|
+
export const mdmPushTokens = pgTable(
|
|
317
|
+
'mdm_push_tokens',
|
|
318
|
+
{
|
|
319
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
320
|
+
deviceId: varchar('device_id', { length: 36 })
|
|
321
|
+
.notNull()
|
|
322
|
+
.references(() => mdmDevices.id, { onDelete: 'cascade' }),
|
|
323
|
+
provider: pushProviderEnum('provider').notNull(),
|
|
324
|
+
token: text('token').notNull(),
|
|
325
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
326
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
327
|
+
.notNull()
|
|
328
|
+
.defaultNow(),
|
|
329
|
+
updatedAt: timestamp('updated_at', { withTimezone: true })
|
|
330
|
+
.notNull()
|
|
331
|
+
.defaultNow(),
|
|
332
|
+
},
|
|
333
|
+
(table) => [
|
|
334
|
+
index('mdm_push_tokens_device_id_idx').on(table.deviceId),
|
|
335
|
+
uniqueIndex('mdm_push_tokens_provider_token_idx').on(
|
|
336
|
+
table.provider,
|
|
337
|
+
table.token
|
|
338
|
+
),
|
|
339
|
+
index('mdm_push_tokens_is_active_idx').on(table.isActive),
|
|
340
|
+
]
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
// ============================================
|
|
344
|
+
// App Deployments Table
|
|
345
|
+
// ============================================
|
|
346
|
+
|
|
347
|
+
export const mdmAppDeployments = pgTable(
|
|
348
|
+
'mdm_app_deployments',
|
|
349
|
+
{
|
|
350
|
+
id: varchar('id', { length: 36 }).primaryKey(),
|
|
351
|
+
applicationId: varchar('application_id', { length: 36 })
|
|
352
|
+
.notNull()
|
|
353
|
+
.references(() => mdmApplications.id, { onDelete: 'cascade' }),
|
|
354
|
+
targetType: deployTargetTypeEnum('target_type').notNull(),
|
|
355
|
+
targetId: varchar('target_id', { length: 36 }).notNull(),
|
|
356
|
+
action: deployActionEnum('action').notNull().default('install'),
|
|
357
|
+
isRequired: boolean('is_required').notNull().default(false),
|
|
358
|
+
createdAt: timestamp('created_at', { withTimezone: true })
|
|
359
|
+
.notNull()
|
|
360
|
+
.defaultNow(),
|
|
361
|
+
},
|
|
362
|
+
(table) => [
|
|
363
|
+
index('mdm_app_deployments_application_id_idx').on(table.applicationId),
|
|
364
|
+
index('mdm_app_deployments_target_idx').on(table.targetType, table.targetId),
|
|
365
|
+
]
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
// ============================================
|
|
369
|
+
// Relations
|
|
370
|
+
// ============================================
|
|
371
|
+
|
|
372
|
+
export const mdmDevicesRelations = relations(mdmDevices, ({ one, many }) => ({
|
|
373
|
+
policy: one(mdmPolicies, {
|
|
374
|
+
fields: [mdmDevices.policyId],
|
|
375
|
+
references: [mdmPolicies.id],
|
|
376
|
+
}),
|
|
377
|
+
commands: many(mdmCommands),
|
|
378
|
+
events: many(mdmEvents),
|
|
379
|
+
pushTokens: many(mdmPushTokens),
|
|
380
|
+
deviceGroups: many(mdmDeviceGroups),
|
|
381
|
+
}));
|
|
382
|
+
|
|
383
|
+
export const mdmPoliciesRelations = relations(mdmPolicies, ({ many }) => ({
|
|
384
|
+
devices: many(mdmDevices),
|
|
385
|
+
groups: many(mdmGroups),
|
|
386
|
+
}));
|
|
387
|
+
|
|
388
|
+
export const mdmCommandsRelations = relations(mdmCommands, ({ one }) => ({
|
|
389
|
+
device: one(mdmDevices, {
|
|
390
|
+
fields: [mdmCommands.deviceId],
|
|
391
|
+
references: [mdmDevices.id],
|
|
392
|
+
}),
|
|
393
|
+
}));
|
|
394
|
+
|
|
395
|
+
export const mdmEventsRelations = relations(mdmEvents, ({ one }) => ({
|
|
396
|
+
device: one(mdmDevices, {
|
|
397
|
+
fields: [mdmEvents.deviceId],
|
|
398
|
+
references: [mdmDevices.id],
|
|
399
|
+
}),
|
|
400
|
+
}));
|
|
401
|
+
|
|
402
|
+
export const mdmGroupsRelations = relations(mdmGroups, ({ one, many }) => ({
|
|
403
|
+
policy: one(mdmPolicies, {
|
|
404
|
+
fields: [mdmGroups.policyId],
|
|
405
|
+
references: [mdmPolicies.id],
|
|
406
|
+
}),
|
|
407
|
+
parent: one(mdmGroups, {
|
|
408
|
+
fields: [mdmGroups.parentId],
|
|
409
|
+
references: [mdmGroups.id],
|
|
410
|
+
relationName: 'parentChild',
|
|
411
|
+
}),
|
|
412
|
+
children: many(mdmGroups, { relationName: 'parentChild' }),
|
|
413
|
+
deviceGroups: many(mdmDeviceGroups),
|
|
414
|
+
}));
|
|
415
|
+
|
|
416
|
+
export const mdmDeviceGroupsRelations = relations(
|
|
417
|
+
mdmDeviceGroups,
|
|
418
|
+
({ one }) => ({
|
|
419
|
+
device: one(mdmDevices, {
|
|
420
|
+
fields: [mdmDeviceGroups.deviceId],
|
|
421
|
+
references: [mdmDevices.id],
|
|
422
|
+
}),
|
|
423
|
+
group: one(mdmGroups, {
|
|
424
|
+
fields: [mdmDeviceGroups.groupId],
|
|
425
|
+
references: [mdmGroups.id],
|
|
426
|
+
}),
|
|
427
|
+
})
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
export const mdmPushTokensRelations = relations(mdmPushTokens, ({ one }) => ({
|
|
431
|
+
device: one(mdmDevices, {
|
|
432
|
+
fields: [mdmPushTokens.deviceId],
|
|
433
|
+
references: [mdmDevices.id],
|
|
434
|
+
}),
|
|
435
|
+
}));
|
|
436
|
+
|
|
437
|
+
export const mdmApplicationsRelations = relations(
|
|
438
|
+
mdmApplications,
|
|
439
|
+
({ many }) => ({
|
|
440
|
+
deployments: many(mdmAppDeployments),
|
|
441
|
+
})
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
export const mdmAppDeploymentsRelations = relations(
|
|
445
|
+
mdmAppDeployments,
|
|
446
|
+
({ one }) => ({
|
|
447
|
+
application: one(mdmApplications, {
|
|
448
|
+
fields: [mdmAppDeployments.applicationId],
|
|
449
|
+
references: [mdmApplications.id],
|
|
450
|
+
}),
|
|
451
|
+
})
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
// ============================================
|
|
455
|
+
// Export all tables for easy schema setup
|
|
456
|
+
// ============================================
|
|
457
|
+
|
|
458
|
+
export const mdmSchema = {
|
|
459
|
+
// Tables
|
|
460
|
+
mdmDevices,
|
|
461
|
+
mdmPolicies,
|
|
462
|
+
mdmApplications,
|
|
463
|
+
mdmCommands,
|
|
464
|
+
mdmEvents,
|
|
465
|
+
mdmGroups,
|
|
466
|
+
mdmDeviceGroups,
|
|
467
|
+
mdmPushTokens,
|
|
468
|
+
mdmAppDeployments,
|
|
469
|
+
// Enums
|
|
470
|
+
deviceStatusEnum,
|
|
471
|
+
commandStatusEnum,
|
|
472
|
+
pushProviderEnum,
|
|
473
|
+
deployTargetTypeEnum,
|
|
474
|
+
deployActionEnum,
|
|
475
|
+
// Relations
|
|
476
|
+
mdmDevicesRelations,
|
|
477
|
+
mdmPoliciesRelations,
|
|
478
|
+
mdmCommandsRelations,
|
|
479
|
+
mdmEventsRelations,
|
|
480
|
+
mdmGroupsRelations,
|
|
481
|
+
mdmDeviceGroupsRelations,
|
|
482
|
+
mdmPushTokensRelations,
|
|
483
|
+
mdmApplicationsRelations,
|
|
484
|
+
mdmAppDeploymentsRelations,
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
export type MDMSchema = typeof mdmSchema;
|
package/src/schema.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenMDM Drizzle Schema
|
|
3
|
+
*
|
|
4
|
+
* This file exports the schema definition for use with schema generators.
|
|
5
|
+
* For ready-to-use Drizzle tables, import from:
|
|
6
|
+
* - @openmdm/drizzle-adapter/postgres
|
|
7
|
+
* - @openmdm/drizzle-adapter/mysql
|
|
8
|
+
* - @openmdm/drizzle-adapter/sqlite
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export { mdmSchema, getTableNames, getColumnNames } from '@openmdm/core/schema';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Table prefix for MDM tables.
|
|
15
|
+
* Can be customized via the adapter options.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_TABLE_PREFIX = 'mdm_';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Schema options for customizing table generation
|
|
21
|
+
*/
|
|
22
|
+
export interface SchemaOptions {
|
|
23
|
+
/** Prefix for all MDM tables (default: 'mdm_') */
|
|
24
|
+
tablePrefix?: string;
|
|
25
|
+
/** Custom schema name (PostgreSQL only) */
|
|
26
|
+
schema?: string;
|
|
27
|
+
}
|
package/src/sqlite.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenMDM Drizzle Schema for SQLite
|
|
3
|
+
*
|
|
4
|
+
* Ready-to-use Drizzle table definitions for SQLite databases.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { mdmDevices, mdmPolicies } from '@openmdm/drizzle-adapter/sqlite';
|
|
9
|
+
* import { drizzle } from 'drizzle-orm/better-sqlite3';
|
|
10
|
+
*
|
|
11
|
+
* const db = drizzle(sqlite, { schema: { mdmDevices, mdmPolicies, ... } });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// SQLite schema implementation
|
|
16
|
+
// TODO: Implement SQLite-specific schema
|
|
17
|
+
// For now, users should use the PostgreSQL schema as reference
|
|
18
|
+
|
|
19
|
+
export const placeholder = 'SQLite schema coming soon';
|
|
20
|
+
|
|
21
|
+
throw new Error(
|
|
22
|
+
'@openmdm/drizzle-adapter/sqlite is not yet implemented. ' +
|
|
23
|
+
'Please use @openmdm/drizzle-adapter/postgres for now, or contribute the SQLite schema!'
|
|
24
|
+
);
|